feat(F006): 后台UI统一规范 - DataTable默认borderless/全局表格表头底色圆角统一/页面内边距统一/状态色token化(暗色适配)/标题字号20px统一/统计页echarts异步组件拆分(509KB->6.9KB)
This commit is contained in:
parent
508c84e571
commit
99bc522b24
@ -63,7 +63,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
pageSizes: () => [10, 20, 50, 100],
|
pageSizes: () => [10, 20, 50, 100],
|
||||||
rowKey: 'id',
|
rowKey: 'id',
|
||||||
stripe: false,
|
stripe: false,
|
||||||
borderless: false,
|
// 2026-08-18 UI 统一: 默认无边框 (带 border 的老页面由全局样式消除, 见 styles/global-ui.scss)
|
||||||
|
borderless: true,
|
||||||
emptyText: '暂无数据',
|
emptyText: '暂无数据',
|
||||||
errorText: '',
|
errorText: '',
|
||||||
error: null
|
error: null
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import 'element-plus/dist/index.css'
|
|||||||
import './theme/tokens.scss'
|
import './theme/tokens.scss'
|
||||||
import './theme/themes.scss'
|
import './theme/themes.scss'
|
||||||
import './styles/global-popper.scss'
|
import './styles/global-popper.scss'
|
||||||
|
import './styles/global-ui.scss' // 2026-08-18 UI 统一规范 (表格/卡片/内边距/暗色状态色)
|
||||||
import { loadTheme } from './theme/presets'
|
import { loadTheme } from './theme/presets'
|
||||||
|
|
||||||
// 启动时恢复用户主题
|
// 启动时恢复用户主题
|
||||||
|
|||||||
@ -414,7 +414,7 @@ window.addEventListener('resize', () => { trendChart?.resize(); statusChart?.res
|
|||||||
.rr-dashboard { max-width: 1400px; }
|
.rr-dashboard { max-width: 1400px; }
|
||||||
.rr-page-header { margin-bottom: 20px; }
|
.rr-page-header { margin-bottom: 20px; }
|
||||||
.rr-page-title {
|
.rr-page-title {
|
||||||
font-size: 22px; font-weight: 600; letter-spacing: -0.02em;
|
font-size: 20px; font-weight: 700;
|
||||||
color: var(--ink); margin-bottom: 4px;
|
color: var(--ink); margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
.rr-page-sub { color: var(--ink-3); font-size: 13px; }
|
.rr-page-sub { color: var(--ink-3); font-size: 13px; }
|
||||||
|
|||||||
@ -241,7 +241,7 @@ onMounted(load)
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-dialog v-model="auditVisible" title="品牌审核" width="440px" :close-on-click-modal="false">
|
<el-dialog v-model="auditVisible" title="品牌审核" width="480px" :close-on-click-modal="false">
|
||||||
<el-form label-width="80px">
|
<el-form label-width="80px">
|
||||||
<el-form-item label="审核结果">
|
<el-form-item label="审核结果">
|
||||||
<el-radio-group v-model="auditForm.status">
|
<el-radio-group v-model="auditForm.status">
|
||||||
@ -279,7 +279,7 @@ onMounted(load)
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.rr-page { max-width: 1500px; }
|
.rr-page { max-width: 1500px; }
|
||||||
.rr-card { background: var(--el-bg-color); border-radius: 8px; border: 1px solid var(--el-border-color-light); overflow: hidden; }
|
.rr-card { background: var(--el-bg-color); border-radius: 12px; border: 1px solid var(--el-border-color-light); overflow: hidden; }
|
||||||
.rr-pagination { padding: 12px 20px; display: flex; justify-content: flex-end; border-top: 1px solid var(--el-border-color-light); }
|
.rr-pagination { padding: 12px 20px; display: flex; justify-content: flex-end; border-top: 1px solid var(--el-border-color-light); }
|
||||||
.brand-auth { width: 50px; height: 50px; border-radius: 4px; border: 1px solid var(--el-border-color-light); cursor: pointer; }
|
.brand-auth { width: 50px; height: 50px; border-radius: 4px; border: 1px solid var(--el-border-color-light); cursor: pointer; }
|
||||||
.rr-muted { color: var(--el-text-color-placeholder); }
|
.rr-muted { color: var(--el-text-color-placeholder); }
|
||||||
|
|||||||
@ -15,16 +15,13 @@
|
|||||||
*
|
*
|
||||||
* 失败回退: FALLBACK_*
|
* 失败回退: FALLBACK_*
|
||||||
*/
|
*/
|
||||||
import { ref, onMounted, watch, nextTick } from 'vue'
|
import { ref, onMounted, defineAsyncComponent } from 'vue'
|
||||||
import { httpGet } from '@/utils/request'
|
import { httpGet } from '@/utils/request'
|
||||||
import DataTable from '@/components/DataTable/DataTable.vue'
|
import DataTable from '@/components/DataTable/DataTable.vue'
|
||||||
import * as echarts from 'echarts/core'
|
|
||||||
import { LineChart, PieChart } from 'echarts/charts'
|
|
||||||
import { TooltipComponent, GridComponent, LegendComponent } from 'echarts/components'
|
|
||||||
import { CanvasRenderer } from 'echarts/renderers'
|
|
||||||
import { useThemeStore } from '@/stores/theme'
|
|
||||||
|
|
||||||
echarts.use([LineChart, PieChart, TooltipComponent, GridComponent, LegendComponent, CanvasRenderer])
|
// 图表组件: echarts 在组件内动态 import, 独立 chunk 懒加载 (2026-08-18)
|
||||||
|
const TrendChart = defineAsyncComponent(() => import('./charts/EchartsTrendChart.vue'))
|
||||||
|
const StatusPie = defineAsyncComponent(() => import('./charts/EchartsStatusPie.vue'))
|
||||||
|
|
||||||
interface OrderItem {
|
interface OrderItem {
|
||||||
orderId: string
|
orderId: string
|
||||||
@ -51,12 +48,6 @@ const recentOrders = ref<any[]>([])
|
|||||||
const trendData = ref<{ dates: string[]; counts: number[]; amounts: number[] }>({ dates: [], counts: [], amounts: [] })
|
const trendData = ref<{ dates: string[]; counts: number[]; amounts: number[] }>({ dates: [], counts: [], amounts: [] })
|
||||||
const statusSlices = ref<{ name: string; value: number; color: string }[]>([])
|
const statusSlices = ref<{ name: string; value: number; color: string }[]>([])
|
||||||
const apiStatus = ref<'loading' | 'live' | 'fallback'>('loading')
|
const apiStatus = ref<'loading' | 'live' | 'fallback'>('loading')
|
||||||
const trendChartEl = ref<HTMLDivElement | null>(null)
|
|
||||||
const statusChartEl = ref<HTMLDivElement | null>(null)
|
|
||||||
let trendChart: echarts.ECharts | null = null
|
|
||||||
let statusChart: echarts.ECharts | null = null
|
|
||||||
const themeStore = useThemeStore()
|
|
||||||
|
|
||||||
// 订单状态映射 (老 renren: 1=待付款 2=已付款 3=已发货 4=已完成 5=已取消)
|
// 订单状态映射 (老 renren: 1=待付款 2=已付款 3=已发货 4=已完成 5=已取消)
|
||||||
const ORDER_STATUS: Record<number, { label: string; type: string }> = {
|
const ORDER_STATUS: Record<number, { label: string; type: string }> = {
|
||||||
1: { label: '待付款', type: 'warning' },
|
1: { label: '待付款', type: 'warning' },
|
||||||
@ -213,73 +204,8 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
apiStatus.value = isLive ? 'live' : 'fallback'
|
apiStatus.value = isLive ? 'live' : 'fallback'
|
||||||
|
|
||||||
await nextTick()
|
|
||||||
renderTrend()
|
|
||||||
renderStatus()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// ECharts 渲染
|
|
||||||
function getBrand(): string { return getComputedStyle(document.body).getPropertyValue('--brand').trim() || '#2563EB' }
|
|
||||||
function getInk(): string { return getComputedStyle(document.body).getPropertyValue('--ink-3').trim() || '#64748B' }
|
|
||||||
function getBorder(): string { return getComputedStyle(document.body).getPropertyValue('--border').trim() || '#E2E8F0' }
|
|
||||||
function getSurface(): string { return getComputedStyle(document.body).getPropertyValue('--surface').trim() || '#FFFFFF' }
|
|
||||||
function getChartColors(): string[] {
|
|
||||||
return ['--chart-1', '--chart-2', '--chart-3', '--chart-4', '--red'].map(v =>
|
|
||||||
getComputedStyle(document.body).getPropertyValue(v).trim()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderTrend() {
|
|
||||||
if (!trendChartEl.value) return
|
|
||||||
if (!trendChart) trendChart = echarts.init(trendChartEl.value)
|
|
||||||
const ink = getInk(), border = getBorder(), surface = getSurface(), brand = getBrand()
|
|
||||||
const chart2 = getComputedStyle(document.body).getPropertyValue('--chart-2').trim() || '#7C3AED'
|
|
||||||
trendChart.setOption({
|
|
||||||
grid: { left: 50, right: 50, top: 40, bottom: 30 },
|
|
||||||
tooltip: { trigger: 'axis', backgroundColor: surface, borderColor: border, textStyle: { color: ink } },
|
|
||||||
legend: { top: 0, textStyle: { color: ink } },
|
|
||||||
xAxis: { type: 'category', data: trendData.value.dates, axisLine: { lineStyle: { color: border } }, axisLabel: { color: ink } },
|
|
||||||
yAxis: [
|
|
||||||
{ type: 'value', name: '订单数', position: 'left', splitLine: { lineStyle: { color: border } }, axisLabel: { color: ink } },
|
|
||||||
{ type: 'value', name: '交易额', position: 'right', splitLine: { show: false }, axisLabel: { color: ink, formatter: (v: number) => v >= 1000 ? `${(v/1000).toFixed(0)}K` : String(v) } }
|
|
||||||
],
|
|
||||||
series: [
|
|
||||||
{ name: '订单数', type: 'line', data: trendData.value.counts, smooth: true, itemStyle: { color: brand }, lineStyle: { color: brand, width: 2 }, areaStyle: { color: brand, opacity: 0.15 } },
|
|
||||||
{ name: '交易额', type: 'line', yAxisIndex: 1, data: trendData.value.amounts, smooth: true, itemStyle: { color: chart2 }, lineStyle: { color: chart2, width: 2 } }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderStatus() {
|
|
||||||
if (!statusChartEl.value) return
|
|
||||||
if (!statusChart) statusChart = echarts.init(statusChartEl.value)
|
|
||||||
const ink = getInk(), border = getBorder(), surface = getSurface()
|
|
||||||
const colors = getChartColors()
|
|
||||||
const total = statusSlices.value.reduce((a, b) => a + b.value, 0)
|
|
||||||
statusChart.setOption({
|
|
||||||
tooltip: { trigger: 'item', backgroundColor: surface, borderColor: border, textStyle: { color: ink } },
|
|
||||||
legend: { bottom: 0, textStyle: { color: ink } },
|
|
||||||
series: [{
|
|
||||||
type: 'pie', radius: ['58%', '80%'], center: ['50%', '45%'],
|
|
||||||
avoidLabelOverlap: true,
|
|
||||||
label: { show: false }, labelLine: { show: false },
|
|
||||||
data: statusSlices.value.map((s, i) => ({ name: s.name, value: s.value, itemStyle: { color: colors[i] } })),
|
|
||||||
emphasis: { label: { show: true, fontSize: 14, fontWeight: 600, color: ink } }
|
|
||||||
}],
|
|
||||||
graphic: total > 0 ? [
|
|
||||||
{ type: 'text', left: 'center', top: '38%', style: { text: '总计', fontSize: 10, fill: ink, opacity: 0.5 } },
|
|
||||||
{ type: 'text', left: 'center', top: '45%', style: { text: String(total), fontSize: 24, fontWeight: 700, fill: ink } }
|
|
||||||
] : []
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
watch([() => trendData.value, () => statusSlices.value, () => themeStore.current], async () => {
|
|
||||||
await nextTick()
|
|
||||||
renderTrend()
|
|
||||||
renderStatus()
|
|
||||||
})
|
|
||||||
|
|
||||||
window.addEventListener('resize', () => { trendChart?.resize(); statusChart?.resize() })
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -315,13 +241,13 @@ window.addEventListener('resize', () => { trendChart?.resize(); statusChart?.res
|
|||||||
<div class="rr-card-header">
|
<div class="rr-card-header">
|
||||||
<h3 class="rr-card-title">订单趋势(近 7 天)</h3>
|
<h3 class="rr-card-title">订单趋势(近 7 天)</h3>
|
||||||
</div>
|
</div>
|
||||||
<div ref="trendChartEl" class="rr-chart"></div>
|
<TrendChart :dates="trendData.dates" :counts="trendData.counts" :amounts="trendData.amounts" />
|
||||||
</div>
|
</div>
|
||||||
<div class="rr-card rr-chart-card">
|
<div class="rr-card rr-chart-card">
|
||||||
<div class="rr-card-header">
|
<div class="rr-card-header">
|
||||||
<h3 class="rr-card-title">订单状态分布</h3>
|
<h3 class="rr-card-title">订单状态分布</h3>
|
||||||
</div>
|
</div>
|
||||||
<div ref="statusChartEl" class="rr-chart"></div>
|
<StatusPie :slices="statusSlices" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -338,7 +264,7 @@ window.addEventListener('resize', () => { trendChart?.resize(); statusChart?.res
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.rr-dashboard { max-width: 1400px; }
|
.rr-dashboard { max-width: 1400px; }
|
||||||
.rr-page-header { margin-bottom: 20px; }
|
.rr-page-header { margin-bottom: 20px; }
|
||||||
.rr-page-title { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); margin-bottom: 4px; }
|
.rr-page-title { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; color: var(--ink); margin-bottom: 4px; }
|
||||||
.rr-page-sub { color: var(--ink-3); font-size: 13px; }
|
.rr-page-sub { color: var(--ink-3); font-size: 13px; }
|
||||||
.rr-api-badge { margin-left: 8px; }
|
.rr-api-badge { margin-left: 8px; }
|
||||||
.rr-stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 20px; }
|
.rr-stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 20px; }
|
||||||
|
|||||||
94
src/modules/statistics/charts/EchartsStatusPie.vue
Normal file
94
src/modules/statistics/charts/EchartsStatusPie.vue
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
/**
|
||||||
|
* 统计页 - 订单状态分布环形图 (2026-08-18 从 StatisticsView 抽出)
|
||||||
|
* echarts 动态 import → 独立 chunk 懒加载
|
||||||
|
*/
|
||||||
|
import { ref, onMounted, onUnmounted, watch, computed } from 'vue'
|
||||||
|
import { useThemeStore } from '@/stores/theme'
|
||||||
|
|
||||||
|
defineOptions({ name: 'EchartsStatusPie' })
|
||||||
|
|
||||||
|
const props = defineProps<{ slices: { name: string; value: number; color?: string }[] }>()
|
||||||
|
|
||||||
|
const el = ref<HTMLDivElement | null>(null)
|
||||||
|
let chart: any = null
|
||||||
|
let echartsMod: any = null
|
||||||
|
const themeStore = useThemeStore()
|
||||||
|
|
||||||
|
const total = computed(() => props.slices.reduce((a, b) => a + b.value, 0))
|
||||||
|
|
||||||
|
async function ensureEcharts() {
|
||||||
|
if (echartsMod) return echartsMod
|
||||||
|
const core = await import('echarts/core')
|
||||||
|
const { PieChart } = await import('echarts/charts')
|
||||||
|
const { TooltipComponent, LegendComponent } = await import('echarts/components')
|
||||||
|
const { CanvasRenderer } = await import('echarts/renderers')
|
||||||
|
core.use([PieChart, TooltipComponent, LegendComponent, CanvasRenderer])
|
||||||
|
echartsMod = core
|
||||||
|
return core
|
||||||
|
}
|
||||||
|
|
||||||
|
function cssVar(name: string, fb: string): string {
|
||||||
|
return getComputedStyle(document.body).getPropertyValue(name).trim() || fb
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChartColors(): string[] {
|
||||||
|
return ['--chart-1', '--chart-2', '--chart-3', '--chart-4', '--red'].map(v => cssVar(v, '')) || ['#2563EB', '#7C3AED', '#10B981', '#D97706', '#DC2626']
|
||||||
|
}
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
if (!el.value || !chart) return
|
||||||
|
const ink = cssVar('--ink-3', '#64748B')
|
||||||
|
const border = cssVar('--border', '#E2E8F0')
|
||||||
|
const surface = cssVar('--surface', '#FFFFFF')
|
||||||
|
const colors = getChartColors()
|
||||||
|
chart.setOption({
|
||||||
|
tooltip: { trigger: 'item', backgroundColor: surface, borderColor: border, textStyle: { color: ink } },
|
||||||
|
legend: { bottom: 0, textStyle: { color: ink } },
|
||||||
|
series: [{
|
||||||
|
type: 'pie', radius: ['58%', '80%'], center: ['50%', '45%'],
|
||||||
|
avoidLabelOverlap: true,
|
||||||
|
label: { show: false }, labelLine: { show: false },
|
||||||
|
data: props.slices.map((s, i) => ({ name: s.name, value: s.value, itemStyle: { color: colors[i % colors.length] } })),
|
||||||
|
emphasis: { label: { show: true, fontSize: 14, fontWeight: 600, color: ink } }
|
||||||
|
}],
|
||||||
|
graphic: total.value > 0 ? [
|
||||||
|
{ type: 'text', left: 'center', top: '38%', style: { text: '总计', fontSize: 10, fill: ink, opacity: 0.5 } },
|
||||||
|
{ type: 'text', left: 'center', top: '45%', style: { text: String(total.value), fontSize: 24, fontWeight: 700, fill: ink } }
|
||||||
|
] : []
|
||||||
|
}, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onResize() { chart?.resize() }
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
const mod = await ensureEcharts()
|
||||||
|
if (el.value) {
|
||||||
|
chart = mod.init(el.value)
|
||||||
|
render()
|
||||||
|
}
|
||||||
|
} catch { /* 懒加载失败静默 */ }
|
||||||
|
window.addEventListener('resize', onResize)
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [props.slices, themeStore.current],
|
||||||
|
() => render(),
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', onResize)
|
||||||
|
chart?.dispose()
|
||||||
|
chart = null
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div ref="el" class="rr-chart"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.rr-chart { width: 100%; height: 300px; }
|
||||||
|
</style>
|
||||||
89
src/modules/statistics/charts/EchartsTrendChart.vue
Normal file
89
src/modules/statistics/charts/EchartsTrendChart.vue
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
/**
|
||||||
|
* 统计页 - 订单趋势折线图 (2026-08-18 从 StatisticsView 抽出)
|
||||||
|
* echarts 动态 import → 独立 chunk 懒加载 (StatisticsView 主 chunk 减重)
|
||||||
|
* 主题/数据变化自动重绘
|
||||||
|
*/
|
||||||
|
import { ref, onMounted, onUnmounted, watch } from 'vue'
|
||||||
|
import { useThemeStore } from '@/stores/theme'
|
||||||
|
|
||||||
|
defineOptions({ name: 'EchartsTrendChart' })
|
||||||
|
|
||||||
|
const props = defineProps<{ dates: string[]; counts: number[]; amounts: number[] }>()
|
||||||
|
|
||||||
|
const el = ref<HTMLDivElement | null>(null)
|
||||||
|
let chart: any = null
|
||||||
|
let echartsMod: any = null
|
||||||
|
const themeStore = useThemeStore()
|
||||||
|
|
||||||
|
/** 动态加载 echarts (独立 chunk, 不随主 bundle) */
|
||||||
|
async function ensureEcharts() {
|
||||||
|
if (echartsMod) return echartsMod
|
||||||
|
const core = await import('echarts/core')
|
||||||
|
const { LineChart } = await import('echarts/charts')
|
||||||
|
const { TooltipComponent, GridComponent, LegendComponent } = await import('echarts/components')
|
||||||
|
const { CanvasRenderer } = await import('echarts/renderers')
|
||||||
|
core.use([LineChart, TooltipComponent, GridComponent, LegendComponent, CanvasRenderer])
|
||||||
|
echartsMod = core
|
||||||
|
return core
|
||||||
|
}
|
||||||
|
|
||||||
|
function cssVar(name: string, fb: string): string {
|
||||||
|
return getComputedStyle(document.body).getPropertyValue(name).trim() || fb
|
||||||
|
}
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
if (!el.value || !chart) return
|
||||||
|
const ink = cssVar('--ink-3', '#64748B')
|
||||||
|
const border = cssVar('--border', '#E2E8F0')
|
||||||
|
const surface = cssVar('--surface', '#FFFFFF')
|
||||||
|
const brand = cssVar('--brand', '#2563EB')
|
||||||
|
const chart2 = cssVar('--chart-2', '#7C3AED')
|
||||||
|
chart.setOption({
|
||||||
|
grid: { left: 50, right: 50, top: 40, bottom: 30 },
|
||||||
|
tooltip: { trigger: 'axis', backgroundColor: surface, borderColor: border, textStyle: { color: ink } },
|
||||||
|
legend: { top: 0, textStyle: { color: ink } },
|
||||||
|
xAxis: { type: 'category', data: props.dates, axisLine: { lineStyle: { color: border } }, axisLabel: { color: ink } },
|
||||||
|
yAxis: [
|
||||||
|
{ type: 'value', name: '订单数', position: 'left', splitLine: { lineStyle: { color: border } }, axisLabel: { color: ink } },
|
||||||
|
{ type: 'value', name: '交易额', position: 'right', splitLine: { show: false }, axisLabel: { color: ink, formatter: (v: number) => v >= 1000 ? `${(v / 1000).toFixed(0)}K` : String(v) } }
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{ name: '订单数', type: 'line', data: props.counts, smooth: true, itemStyle: { color: brand }, lineStyle: { color: brand, width: 2 }, areaStyle: { color: brand, opacity: 0.15 } },
|
||||||
|
{ name: '交易额', type: 'line', yAxisIndex: 1, data: props.amounts, smooth: true, itemStyle: { color: chart2 }, lineStyle: { color: chart2, width: 2 } }
|
||||||
|
]
|
||||||
|
}, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onResize() { chart?.resize() }
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
const mod = await ensureEcharts()
|
||||||
|
if (el.value) {
|
||||||
|
chart = mod.init(el.value)
|
||||||
|
render()
|
||||||
|
}
|
||||||
|
} catch { /* echarts 懒加载失败时静默 (图表留空) */ }
|
||||||
|
window.addEventListener('resize', onResize)
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [props.dates, props.counts, props.amounts, themeStore.current],
|
||||||
|
() => render()
|
||||||
|
)
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', onResize)
|
||||||
|
chart?.dispose()
|
||||||
|
chart = null
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div ref="el" class="rr-chart"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.rr-chart { width: 100%; height: 300px; }
|
||||||
|
</style>
|
||||||
@ -226,7 +226,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-list-card { background: var(--el-bg-color); border-radius: 12px; padding: 4px; }
|
.rr-list-card { background: var(--el-bg-color); border-radius: 12px; padding: 4px; }
|
||||||
|
|||||||
@ -229,7 +229,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
||||||
|
|||||||
@ -213,7 +213,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
||||||
|
|||||||
@ -137,7 +137,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-list-card { background: var(--el-bg-color); border-radius: 12px; padding: 4px; }
|
.rr-list-card { background: var(--el-bg-color); border-radius: 12px; padding: 4px; }
|
||||||
|
|||||||
@ -275,7 +275,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-list-card { background: var(--el-bg-color); border-radius: 12px; padding: 4px; }
|
.rr-list-card { background: var(--el-bg-color); border-radius: 12px; padding: 4px; }
|
||||||
|
|||||||
@ -260,7 +260,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
||||||
|
|||||||
@ -221,7 +221,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
||||||
|
|||||||
@ -254,7 +254,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
||||||
|
|||||||
@ -189,7 +189,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
||||||
|
|||||||
@ -193,7 +193,7 @@ onMounted(load)
|
|||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
.rr-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
|
||||||
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
.rr-page-titles { display: flex; flex-direction: column; gap: 2px; }
|
||||||
.rr-page-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
.rr-page-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--el-text-color-primary); }
|
||||||
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
.rr-page-sub { margin: 0; font-size: 12px; color: var(--el-text-color-secondary); }
|
||||||
.rr-page-actions { display: flex; gap: 8px; }
|
.rr-page-actions { display: flex; gap: 8px; }
|
||||||
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
.rr-filters-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 12px 16px; background: var(--el-fill-color-light); border-radius: 8px; }
|
||||||
|
|||||||
@ -86,19 +86,20 @@ const filters = reactive({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// status 映射 (老 vue: 1=待审核,2=已认证,3=已驳回)
|
// status 映射 (老 vue: 1=待审核,2=已认证,3=已驳回)
|
||||||
|
// 状态/等级色引用全局 token (styles/global-ui.scss), 主题切换自动适配暗色
|
||||||
const STATUS_META: Record<string, { label: string; color: string; bg: string }> = {
|
const STATUS_META: Record<string, { label: string; color: string; bg: string }> = {
|
||||||
'1': { label: '待审核', color: '#b45309', bg: '#fef3c7' },
|
'1': { label: '待审核', color: 'var(--st-warn-fg)', bg: 'var(--st-warn-bg)' },
|
||||||
'2': { label: '已认证', color: '#15803d', bg: '#dcfce7' },
|
'2': { label: '已认证', color: 'var(--st-ok-fg)', bg: 'var(--st-ok-bg)' },
|
||||||
'3': { label: '已驳回', color: '#b91c1c', bg: '#fee2e2' }
|
'3': { label: '已驳回', color: 'var(--st-err-fg)', bg: 'var(--st-err-bg)' }
|
||||||
}
|
}
|
||||||
|
|
||||||
// supplierLevel 映射 (老 vue: 1=优质,2=钻石,3=金牌,4=银牌,5=铜牌)
|
// supplierLevel 映射 (老 vue: 1=优质,2=钻石,3=金牌,4=银牌,5=铜牌)
|
||||||
const LEVEL_META: Record<number, { label: string; color: string; bg: string }> = {
|
const LEVEL_META: Record<number, { label: string; color: string; bg: string }> = {
|
||||||
1: { label: '优质供应商', color: '#92400e', bg: '#fef3c7' },
|
1: { label: '优质供应商', color: 'var(--st-lv1-fg)', bg: 'var(--st-lv1-bg)' },
|
||||||
2: { label: '钻石供应商', color: '#6d28d9', bg: '#ede9fe' },
|
2: { label: '钻石供应商', color: 'var(--st-lv2-fg)', bg: 'var(--st-lv2-bg)' },
|
||||||
3: { label: '金牌供应商', color: '#c2410c', bg: '#ffedd5' },
|
3: { label: '金牌供应商', color: 'var(--st-lv3-fg)', bg: 'var(--st-lv3-bg)' },
|
||||||
4: { label: '银牌供应商', color: '#475569', bg: '#f1f5f9' },
|
4: { label: '银牌供应商', color: 'var(--st-lv4-fg)', bg: 'var(--st-lv4-bg)' },
|
||||||
5: { label: '铜牌供应商', color: '#a16207', bg: '#fefce8' }
|
5: { label: '铜牌供应商', color: 'var(--st-lv5-fg)', bg: 'var(--st-lv5-bg)' }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 头像品牌渐变色组 (企业无 logo 时交替使用)
|
// 头像品牌渐变色组 (企业无 logo 时交替使用)
|
||||||
|
|||||||
99
src/styles/global-ui.scss
Normal file
99
src/styles/global-ui.scss
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* 后台全局 UI 统一规范 (2026-08-18 建立)
|
||||||
|
* 由 UI 审查驱动, 解决跨页视觉一致性缺口:
|
||||||
|
* 1. 页面骨架统一 (rr-page 默认内边距)
|
||||||
|
* 2. 表格视觉统一 (表头底色/圆角/消除老页面 border 竖线)
|
||||||
|
* 3. 卡片圆角统一
|
||||||
|
* 4. 状态标签/el-tag 暗色主题适配
|
||||||
|
* 设计原则: 只做"兜底默认", 页面 scoped 样式优先覆盖
|
||||||
|
* ============================================================ */
|
||||||
|
|
||||||
|
/* ---------- 1. 页面骨架: 默认 16px 内边距 (页面未定义时生效) ---------- */
|
||||||
|
.rr-page { padding: 16px; }
|
||||||
|
|
||||||
|
/* ---------- 2. 表格视觉统一 ---------- */
|
||||||
|
/* 表头底色/文字统一 (el-table 全局) */
|
||||||
|
.el-table {
|
||||||
|
--el-table-header-bg-color: var(--surface-2, #f1f5f9);
|
||||||
|
--el-table-header-text-color: var(--ink-3, #64748b);
|
||||||
|
}
|
||||||
|
.el-table th.el-table__cell {
|
||||||
|
background: var(--surface-2, #f1f5f9) !important; /* !important 覆盖 EP .el-table--border 表头白底 */
|
||||||
|
color: var(--ink-3, #64748b);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
/* 单元格内边距统一 (与 DataTable 规范一致) */
|
||||||
|
.el-table td.el-table__cell { padding: 10px 12px; }
|
||||||
|
|
||||||
|
/* 消除老页面裸 el-table border 属性产生的边框/竖线 → 统一 borderless 视觉 */
|
||||||
|
.el-table--border,
|
||||||
|
.el-table--border .el-table__cell,
|
||||||
|
.el-table--border th.el-table__cell,
|
||||||
|
.el-table--border td.el-table__cell {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
.el-table--border .el-table__inner-wrapper::after,
|
||||||
|
.el-table--border .el-table__inner-wrapper::before,
|
||||||
|
.el-table::before,
|
||||||
|
.el-table::after {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- 3. 卡片圆角统一 ---------- */
|
||||||
|
.rr-list-card,
|
||||||
|
.rr-card,
|
||||||
|
.info-card {
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- 4. 状态色暗色适配 ---------- */
|
||||||
|
/* 状态语义色 token (亮色默认) — 各页面状态标签通过 var() 引用, 主题切换自动适配 */
|
||||||
|
:root,
|
||||||
|
[data-theme="tech-blue"],
|
||||||
|
[data-theme="red"],
|
||||||
|
[data-theme="purple"] {
|
||||||
|
--st-warn-fg: #b45309; --st-warn-bg: #fef3c7;
|
||||||
|
--st-ok-fg: #15803d; --st-ok-bg: #dcfce7;
|
||||||
|
--st-err-fg: #b91c1c; --st-err-bg: #fee2e2;
|
||||||
|
--st-lv1-fg: #92400e; --st-lv1-bg: #fef3c7;
|
||||||
|
--st-lv2-fg: #6d28d9; --st-lv2-bg: #ede9fe;
|
||||||
|
--st-lv3-fg: #c2410c; --st-lv3-bg: #ffedd5;
|
||||||
|
--st-lv4-fg: #475569; --st-lv4-bg: #f1f5f9;
|
||||||
|
--st-lv5-fg: #a16207; --st-lv5-bg: #fefce8;
|
||||||
|
}
|
||||||
|
[data-theme="dark"] {
|
||||||
|
--st-warn-fg: #fcd34d; --st-warn-bg: rgba(245, 158, 11, 0.16);
|
||||||
|
--st-ok-fg: #6ee7b7; --st-ok-bg: rgba(16, 185, 129, 0.16);
|
||||||
|
--st-err-fg: #fca5a5; --st-err-bg: rgba(239, 68, 68, 0.16);
|
||||||
|
--st-lv1-fg: #fcd34d; --st-lv1-bg: rgba(245, 158, 11, 0.14);
|
||||||
|
--st-lv2-fg: #c4b5fd; --st-lv2-bg: rgba(109, 40, 217, 0.2);
|
||||||
|
--st-lv3-fg: #fdba74; --st-lv3-bg: rgba(194, 65, 12, 0.2);
|
||||||
|
--st-lv4-fg: #cbd5e1; --st-lv4-bg: rgba(100, 116, 139, 0.2);
|
||||||
|
--st-lv5-fg: #fde047; --st-lv5-bg: rgba(161, 98, 7, 0.2);
|
||||||
|
|
||||||
|
/* el-tag 四态: 暗色下深底浅字 */
|
||||||
|
.el-tag--success {
|
||||||
|
--el-tag-bg-color: rgba(16, 185, 129, 0.16);
|
||||||
|
--el-tag-text-color: #6ee7b7;
|
||||||
|
--el-tag-border-color: rgba(16, 185, 129, 0.4);
|
||||||
|
}
|
||||||
|
.el-tag--warning {
|
||||||
|
--el-tag-bg-color: rgba(245, 158, 11, 0.16);
|
||||||
|
--el-tag-text-color: #fcd34d;
|
||||||
|
--el-tag-border-color: rgba(245, 158, 11, 0.4);
|
||||||
|
}
|
||||||
|
.el-tag--danger {
|
||||||
|
--el-tag-bg-color: rgba(239, 68, 68, 0.16);
|
||||||
|
--el-tag-text-color: #fca5a5;
|
||||||
|
--el-tag-border-color: rgba(239, 68, 68, 0.4);
|
||||||
|
}
|
||||||
|
.el-tag--info {
|
||||||
|
--el-tag-bg-color: rgba(148, 163, 184, 0.16);
|
||||||
|
--el-tag-text-color: #cbd5e1;
|
||||||
|
--el-tag-border-color: rgba(148, 163, 184, 0.4);
|
||||||
|
}
|
||||||
|
/* 老式 rr-tag-* 状态类 (浅底深字 -> 深底浅字) */
|
||||||
|
.rr-tag-warn { background: rgba(245, 158, 11, 0.16); color: #fcd34d; }
|
||||||
|
.rr-tag-ok { background: rgba(16, 185, 129, 0.16); color: #6ee7b7; }
|
||||||
|
.rr-tag-err { background: rgba(239, 68, 68, 0.16); color: #fca5a5; }
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user