fix(F006): UI 打磨 P1-4 banner 着色 + P2 Statistics/Dashboard PageHeader + 全局规范注释
- P1-4: 企业详情页 audit-banner 修状态→class 映射 bug (banner-1/2/3 → banner-warning/success/danger)
颜色 token 改用 --st-warn/ok/err-bg/fg 自动适配暗色
- P2: StatisticsView / DashboardView 自定义 rr-page-header 改用 PageHeader 组件
删除 2 个文件里残留的 rr-page-title / rr-page-sub / rr-api-badge 死样式
- global-ui.scss: 顶部加组件使用约定注释 (状态呈现 / 表格列对齐 / Dialog 宽度 4 档)
- 验证: 浏览器亮色截图 banner 已认证=绿色、Statistics 首页 PageHeader 正常
This commit is contained in:
parent
f8b7e72e82
commit
1ca87d8ec2
@ -13,6 +13,7 @@
|
|||||||
import { ref, onMounted, watch, nextTick } from 'vue'
|
import { ref, onMounted, watch, nextTick } 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 PageHeader from '@/components/PageHeader/PageHeader.vue'
|
||||||
|
|
||||||
interface Stat {
|
interface Stat {
|
||||||
label: string
|
label: string
|
||||||
@ -343,23 +344,14 @@ window.addEventListener('resize', () => { trendChart?.resize(); statusChart?.res
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="rr-dashboard">
|
<div class="rr-dashboard">
|
||||||
<div class="rr-page-header">
|
<PageHeader title="数据看板" :sub="`2026 年 6 月 17 日 · 实时数据`">
|
||||||
<div>
|
|
||||||
<h2 class="rr-page-title">数据看板</h2>
|
|
||||||
<p class="rr-page-sub">
|
|
||||||
2026 年 6 月 17 日 · 实时数据
|
|
||||||
<el-tag
|
<el-tag
|
||||||
v-if="apiStatus !== 'loading'"
|
v-if="apiStatus !== 'loading'"
|
||||||
size="small"
|
size="small"
|
||||||
:type="apiStatus === 'live' ? 'success' : 'info'"
|
:type="apiStatus === 'live' ? 'success' : 'info'"
|
||||||
effect="light"
|
effect="light"
|
||||||
class="rr-api-badge"
|
>{{ apiStatus === 'live' ? '实时' : '示例数据' }}</el-tag>
|
||||||
>
|
</PageHeader>
|
||||||
{{ apiStatus === 'live' ? '实时' : '示例数据' }}
|
|
||||||
</el-tag>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 4 个统计卡 -->
|
<!-- 4 个统计卡 -->
|
||||||
<div class="rr-stats-grid">
|
<div class="rr-stats-grid">
|
||||||
@ -412,13 +404,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; }
|
/* header 已抽到 PageHeader 组件, 此处不再维护 */
|
||||||
.rr-page-title {
|
|
||||||
font-size: 20px; font-weight: 700;
|
|
||||||
color: var(--ink); margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
.rr-page-sub { color: var(--ink-3); font-size: 13px; }
|
|
||||||
.rr-api-badge { margin-left: 8px; }
|
|
||||||
|
|
||||||
.rr-stats-grid {
|
.rr-stats-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
import { ref, onMounted, defineAsyncComponent } 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 PageHeader from '@/components/PageHeader/PageHeader.vue'
|
||||||
|
|
||||||
// 图表组件: echarts 在组件内动态 import, 独立 chunk 懒加载 (2026-08-18)
|
// 图表组件: echarts 在组件内动态 import, 独立 chunk 懒加载 (2026-08-18)
|
||||||
const TrendChart = defineAsyncComponent(() => import('./charts/EchartsTrendChart.vue'))
|
const TrendChart = defineAsyncComponent(() => import('./charts/EchartsTrendChart.vue'))
|
||||||
@ -210,17 +211,9 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="rr-dashboard">
|
<div class="rr-dashboard">
|
||||||
<div class="rr-page-header">
|
<PageHeader title="数据统计" :sub="`2026 年 7 月 4 日 · 实时数据`">
|
||||||
<div>
|
<el-tag v-if="apiStatus !== 'loading'" size="small" :type="apiStatus === 'live' ? 'success' : 'info'" effect="light">{{ apiStatus === 'live' ? '实时' : '示例数据' }}</el-tag>
|
||||||
<h2 class="rr-page-title">数据统计</h2>
|
</PageHeader>
|
||||||
<p class="rr-page-sub">
|
|
||||||
2026 年 7 月 4 日 · 实时数据
|
|
||||||
<el-tag v-if="apiStatus !== 'loading'" size="small" :type="apiStatus === 'live' ? 'success' : 'info'" effect="light" class="rr-api-badge">
|
|
||||||
{{ apiStatus === 'live' ? '实时' : '示例数据' }}
|
|
||||||
</el-tag>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="rr-stats-grid">
|
<div class="rr-stats-grid">
|
||||||
<div v-for="(s, i) in stats" :key="i" class="rr-stat">
|
<div v-for="(s, i) in stats" :key="i" class="rr-stat">
|
||||||
@ -263,10 +256,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.rr-dashboard { max-width: 1400px; }
|
.rr-dashboard { max-width: 1400px; }
|
||||||
.rr-page-header { margin-bottom: 20px; }
|
/* header 已抽到 PageHeader 组件, 此处不再维护 */
|
||||||
.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-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; }
|
||||||
.rr-stat { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 18px 20px; transition: all 0.15s; &:hover { border-color: var(--border-strong); box-shadow: var(--shadow); } }
|
.rr-stat { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 18px 20px; transition: all 0.15s; &:hover { border-color: var(--border-strong); box-shadow: var(--shadow); } }
|
||||||
.rr-stat-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
|
.rr-stat-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
|
||||||
|
|||||||
@ -53,6 +53,8 @@ const isCertified = computed(() => status.value === 2)
|
|||||||
const isPending = computed(() => status.value === 1)
|
const isPending = computed(() => status.value === 1)
|
||||||
const isRejected = computed(() => status.value === 3)
|
const isRejected = computed(() => status.value === 3)
|
||||||
const statusMeta = computed(() => STATUS_META[status.value])
|
const statusMeta = computed(() => STATUS_META[status.value])
|
||||||
|
// 状态 → banner 修饰类 (CSS 里 banner-warning/success/danger 对应 warning/success/danger)
|
||||||
|
const bannerClass = computed(() => `banner-${statusMeta.value?.type || 'unknown'}`)
|
||||||
|
|
||||||
const logoText = computed(() => (detail.value.enterpriseName || '企').trim().charAt(0))
|
const logoText = computed(() => (detail.value.enterpriseName || '企').trim().charAt(0))
|
||||||
const registerYear = computed(() => {
|
const registerYear = computed(() => {
|
||||||
@ -231,7 +233,7 @@ onMounted(load)
|
|||||||
</PageHeader>
|
</PageHeader>
|
||||||
|
|
||||||
<!-- ===== ① 状态横幅 (审核操作区) ===== -->
|
<!-- ===== ① 状态横幅 (审核操作区) ===== -->
|
||||||
<div class="audit-banner" :class="`banner-${status || 'unknown'}`" v-if="status">
|
<div class="audit-banner" :class="bannerClass" v-if="status">
|
||||||
<div class="banner-icon">
|
<div class="banner-icon">
|
||||||
<el-icon v-if="statusMeta" :size="26"><component :is="statusMeta.icon" /></el-icon>
|
<el-icon v-if="statusMeta" :size="26"><component :is="statusMeta.icon" /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
@ -582,19 +584,19 @@ onMounted(load)
|
|||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
.banner-warning {
|
.banner-warning {
|
||||||
background: linear-gradient(90deg, rgba(245,158,11,.14), rgba(245,158,11,.04));
|
background: linear-gradient(90deg, color-mix(in srgb, var(--st-warn-bg) 70%, transparent), transparent);
|
||||||
border-color: rgba(245,158,11,.35);
|
border-color: color-mix(in srgb, var(--st-warn-fg) 35%, transparent);
|
||||||
.banner-icon { background: rgba(245,158,11,.18); color: #b45309; }
|
.banner-icon { background: var(--st-warn-bg); color: var(--st-warn-fg); }
|
||||||
}
|
}
|
||||||
.banner-success {
|
.banner-success {
|
||||||
background: linear-gradient(90deg, rgba(34,197,94,.12), rgba(34,197,94,.03));
|
background: linear-gradient(90deg, color-mix(in srgb, var(--st-ok-bg) 70%, transparent), transparent);
|
||||||
border-color: rgba(34,197,94,.3);
|
border-color: color-mix(in srgb, var(--st-ok-fg) 30%, transparent);
|
||||||
.banner-icon { background: rgba(34,197,94,.18); color: #15803d; }
|
.banner-icon { background: var(--st-ok-bg); color: var(--st-ok-fg); }
|
||||||
}
|
}
|
||||||
.banner-danger {
|
.banner-danger {
|
||||||
background: linear-gradient(90deg, rgba(239,68,68,.12), rgba(239,68,68,.03));
|
background: linear-gradient(90deg, color-mix(in srgb, var(--st-err-bg) 70%, transparent), transparent);
|
||||||
border-color: rgba(239,68,68,.32);
|
border-color: color-mix(in srgb, var(--st-err-fg) 32%, transparent);
|
||||||
.banner-icon { background: rgba(239,68,68,.16); color: #b91c1c; }
|
.banner-icon { background: var(--st-err-bg); color: var(--st-err-fg); }
|
||||||
}
|
}
|
||||||
.banner-unknown {
|
.banner-unknown {
|
||||||
background: var(--bg, #f6f8fb); border-color: var(--border);
|
background: var(--bg, #f6f8fb); border-color: var(--border);
|
||||||
|
|||||||
@ -1,11 +1,26 @@
|
|||||||
/* ============================================================
|
/* ============================================================
|
||||||
* 后台全局 UI 统一规范 (2026-08-18 建立)
|
* 后台全局 UI 统一规范 (2026-08-18 建立, 2026-08-21 补约定注释)
|
||||||
* 由 UI 审查驱动, 解决跨页视觉一致性缺口:
|
* 由 UI 审查驱动, 解决跨页视觉一致性缺口:
|
||||||
* 1. 页面骨架统一 (rr-page 默认内边距)
|
* 1. 页面骨架统一 (rr-page 默认内边距)
|
||||||
* 2. 表格视觉统一 (表头底色/圆角/消除老页面 border 竖线)
|
* 2. 表格视觉统一 (表头底色/圆角/消除老页面 border 竖线)
|
||||||
* 3. 卡片圆角统一
|
* 3. 卡片圆角统一
|
||||||
* 4. 状态标签/el-tag 暗色主题适配
|
* 4. 状态标签/el-tag 暗色主题适配
|
||||||
* 设计原则: 只做"兜底默认", 页面 scoped 样式优先覆盖
|
* 设计原则: 只做"兜底默认", 页面 scoped 样式优先覆盖
|
||||||
|
*
|
||||||
|
* ────────── 组件使用约定 (审计后定) ──────────
|
||||||
|
* ◆ 状态呈现:
|
||||||
|
* - 列表页表格的状态/标志列: 统一用 `.st-pill` (圆点+胶囊, --st-* token)
|
||||||
|
* 例: <span class="st-pill" :style="{color,background}"><span class="st-dot"/>正常</span>
|
||||||
|
* - 详情页/向导/标签: 用原生 <el-tag type="success|warning|danger|info">
|
||||||
|
* (global-ui.scss 已写 el-tag 四态暗色适配)
|
||||||
|
* - 不要混用: 同一项目里两种风格并存会出现"有没有圆点"的视觉差
|
||||||
|
*
|
||||||
|
* ◆ 表格列对齐:
|
||||||
|
* - 识别性内容 (名称/手机/编号/地址) 左对齐, header 也左对齐
|
||||||
|
* - 纯数据 (时间/金额/数量/状态) 居中, header 也居中
|
||||||
|
* - 操作列固定居中且 fixed="right"
|
||||||
|
*
|
||||||
|
* ◆ Dialog 宽度: 仅允许 4 档 — 500px(small) / 640px(medium) / 800px(large) / 960px(xlarge)
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
|
|
||||||
/* ---------- 1. 页面骨架: 默认 16px 内边距 (页面未定义时生效) ---------- */
|
/* ---------- 1. 页面骨架: 默认 16px 内边距 (页面未定义时生效) ---------- */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user