style: 优化数据分析页面 UI
- 表格:移除边框,使用悬浮效果,表头透明化,优化内边距 - 徽章:使用 CSS 渐变色圆环代替 Emoji - 卡片:移除描边,加深背景,柔化阴影 - 排版:优化对齐方式,增强呼吸感
This commit is contained in:
parent
55921af840
commit
2a91ffd908
@ -566,41 +566,41 @@ const efficiencyTableData = computed(() => [
|
||||
|
||||
// 表格列定义
|
||||
const userColumns = [
|
||||
{ title: '排名', key: 'rank', width: 60 },
|
||||
{ title: '排名', key: 'rank', width: 80, align: 'center' },
|
||||
{ title: '用户名', dataIndex: 'userName', key: 'userName' },
|
||||
{ title: '部门', dataIndex: 'deptName', key: 'deptName' },
|
||||
{ title: '发起数', dataIndex: 'totalDemands', key: 'totalDemands', sorter: (a: any, b: any) => a.totalDemands - b.totalDemands },
|
||||
{ title: '完成数', dataIndex: 'completedDemands', key: 'completedDemands' },
|
||||
{ title: '总积分', dataIndex: 'totalScore', key: 'totalScore' },
|
||||
{ title: '完成率', key: 'completionRate', width: 150 }
|
||||
{ title: '发起数', dataIndex: 'totalDemands', key: 'totalDemands', sorter: (a: any, b: any) => a.totalDemands - b.totalDemands, align: 'center' },
|
||||
{ title: '完成数', dataIndex: 'completedDemands', key: 'completedDemands', align: 'center' },
|
||||
{ title: '总积分', dataIndex: 'totalScore', key: 'totalScore', align: 'center' },
|
||||
{ title: '完成率', key: 'completionRate', width: 150, align: 'center' }
|
||||
]
|
||||
|
||||
const designerColumns = [
|
||||
{ title: '排名', key: 'rank', width: 60 },
|
||||
{ title: '排名', key: 'rank', width: 80, align: 'center' },
|
||||
{ title: '设计师', dataIndex: 'realName', key: 'realName' },
|
||||
{ title: '部门', dataIndex: 'deptName', key: 'deptName' },
|
||||
{ title: '接单量', dataIndex: 'receivedCount', key: 'receivedCount', sorter: (a: any, b: any) => a.receivedCount - b.receivedCount },
|
||||
{ title: '完成量', dataIndex: 'completedCount', key: 'completedCount' },
|
||||
{ title: '完成率', dataIndex: 'completionRate', key: 'completionRate', customRender: ({ text }: any) => text + '%' },
|
||||
{ title: '准时率', key: 'onTimeRate' },
|
||||
{ title: '评分', key: 'avgRating', width: 140 }
|
||||
{ title: '接单量', dataIndex: 'receivedCount', key: 'receivedCount', sorter: (a: any, b: any) => a.receivedCount - b.receivedCount, align: 'center' },
|
||||
{ title: '完成量', dataIndex: 'completedCount', key: 'completedCount', align: 'center' },
|
||||
{ title: '完成率', dataIndex: 'completionRate', key: 'completionRate', customRender: ({ text }: any) => text + '%', align: 'center' },
|
||||
{ title: '准时率', key: 'onTimeRate', align: 'center' },
|
||||
{ title: '评分', key: 'avgRating', width: 140, align: 'center' }
|
||||
]
|
||||
|
||||
const efficiencyColumns = [
|
||||
{ title: '指标', dataIndex: 'metric', key: 'metric' },
|
||||
{ title: '本周', dataIndex: 'week', key: 'week' },
|
||||
{ title: '上周', dataIndex: 'lastWeek', key: 'lastWeek' },
|
||||
{ title: '环比', key: 'change' },
|
||||
{ title: '本月', dataIndex: 'month', key: 'month' },
|
||||
{ title: '目标', dataIndex: 'target', key: 'target' }
|
||||
{ title: '本周', dataIndex: 'week', key: 'week', align: 'right' },
|
||||
{ title: '上周', dataIndex: 'lastWeek', key: 'lastWeek', align: 'right' },
|
||||
{ title: '环比', key: 'change', align: 'right' },
|
||||
{ title: '本月', dataIndex: 'month', key: 'month', align: 'right' },
|
||||
{ title: '目标', dataIndex: 'target', key: 'target', align: 'right' }
|
||||
]
|
||||
|
||||
const warningColumns = [
|
||||
{ title: '级别', key: 'level', width: 80 },
|
||||
{ title: '级别', key: 'level', width: 100, align: 'center' },
|
||||
{ title: '任务名称', dataIndex: 'taskTitle', key: 'taskTitle', ellipsis: true },
|
||||
{ title: '处理人', dataIndex: 'receiverName', key: 'receiverName' },
|
||||
{ title: '处理人', dataIndex: 'receiverName', key: 'receiverName', align: 'center' },
|
||||
{ title: '预警原因', dataIndex: 'warningReason', key: 'warningReason' },
|
||||
{ title: '操作', key: 'action', width: 140 }
|
||||
{ title: '操作', key: 'action', width: 140, align: 'center' }
|
||||
]
|
||||
|
||||
// 方法
|
||||
@ -867,16 +867,18 @@ onMounted(() => {
|
||||
|
||||
.stat-card {
|
||||
background: $bg-card;
|
||||
border: 1px solid $border-primary;
|
||||
border-radius: $radius-lg;
|
||||
padding: $space-md;
|
||||
padding: $space-lg;
|
||||
display: flex;
|
||||
gap: $space-md;
|
||||
transition: all $transition-base $ease-out;
|
||||
border: 1px solid rgba(255, 255, 255, 0.03);
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
|
||||
&:hover {
|
||||
border-color: $brand-primary;
|
||||
box-shadow: $shadow-base;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
border-color: rgba($brand-primary, 0.3);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
@ -886,6 +888,8 @@ onMounted(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
background: rgba($brand-primary, 0.1);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
@ -895,35 +899,41 @@ onMounted(() => {
|
||||
.stat-label {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-secondary;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: $font-size-xl;
|
||||
font-weight: $font-weight-bold;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: $text-primary;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabs-section {
|
||||
:deep(.ant-tabs-nav) {
|
||||
margin-bottom: $space-lg;
|
||||
margin-bottom: $space-xl;
|
||||
|
||||
.ant-tabs-tab {
|
||||
color: $text-secondary;
|
||||
padding: 12px 0;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: $brand-primary;
|
||||
color: $text-primary;
|
||||
}
|
||||
|
||||
&.ant-tabs-tab-active .ant-tabs-tab-btn {
|
||||
color: $brand-primary;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-tabs-ink-bar {
|
||||
background: $brand-primary;
|
||||
height: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -934,42 +944,53 @@ onMounted(() => {
|
||||
|
||||
.chart-card, .table-card {
|
||||
background: $bg-card;
|
||||
border: 1px solid $border-primary;
|
||||
border-radius: $radius-lg;
|
||||
padding: $space-lg;
|
||||
padding: $space-xl;
|
||||
border: 1px solid rgba(255, 255, 255, 0.03);
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 24px;
|
||||
|
||||
.chart-title {
|
||||
font-size: $font-size-base;
|
||||
font-weight: $font-weight-semibold;
|
||||
font-size: $font-size-lg;
|
||||
font-weight: 600;
|
||||
color: $text-primary;
|
||||
margin-bottom: $space-md;
|
||||
margin-bottom: $space-lg;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.count-badge {
|
||||
font-size: $font-size-sm;
|
||||
font-weight: normal;
|
||||
color: $text-secondary;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mini-stat-card {
|
||||
background: $bg-tertiary;
|
||||
background: $bg-card;
|
||||
border-radius: $radius-md;
|
||||
padding: $space-md;
|
||||
padding: $space-lg;
|
||||
text-align: center;
|
||||
border: 1px solid rgba(255, 255, 255, 0.03);
|
||||
|
||||
&.warning {
|
||||
border: 1px solid $color-warning;
|
||||
border: 1px solid rgba($color-warning, 0.3);
|
||||
background: rgba($color-warning, 0.05);
|
||||
}
|
||||
|
||||
.mini-stat-label {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-secondary;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.mini-stat-value {
|
||||
font-size: $font-size-xl;
|
||||
font-weight: $font-weight-bold;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: $text-primary;
|
||||
}
|
||||
}
|
||||
@ -978,27 +999,34 @@ onMounted(() => {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
font-weight: $font-weight-bold;
|
||||
font-size: $font-size-sm;
|
||||
background: $bg-tertiary;
|
||||
font-weight: 700;
|
||||
font-size: 12px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
color: $text-secondary;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
|
||||
&.rank-1 {
|
||||
background: rgba(#FFD700, 0.2);
|
||||
color: #FFD700;
|
||||
background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%);
|
||||
color: #fff;
|
||||
border: none;
|
||||
box-shadow: 0 2px 4px rgba(255, 215, 0, 0.3);
|
||||
}
|
||||
|
||||
&.rank-2 {
|
||||
background: rgba(#C0C0C0, 0.2);
|
||||
color: #C0C0C0;
|
||||
background: linear-gradient(135deg, #E0E0E0 0%, #A0A0A0 100%);
|
||||
color: #fff;
|
||||
border: none;
|
||||
box-shadow: 0 2px 4px rgba(192, 192, 192, 0.3);
|
||||
}
|
||||
|
||||
&.rank-3 {
|
||||
background: rgba(#CD7F32, 0.2);
|
||||
color: #CD7F32;
|
||||
background: linear-gradient(135deg, #CD7F32 0%, #8B4513 100%);
|
||||
color: #fff;
|
||||
border: none;
|
||||
box-shadow: 0 2px 4px rgba(205, 127, 50, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1009,9 +1037,9 @@ onMounted(() => {
|
||||
// 流程图样式
|
||||
.process-flow-card {
|
||||
background: $bg-card;
|
||||
border: 1px solid $border-primary;
|
||||
border-radius: $radius-lg;
|
||||
padding: $space-xl;
|
||||
border: 1px solid rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.process-flow {
|
||||
@ -1019,39 +1047,50 @@ onMounted(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: $space-sm;
|
||||
margin: $space-xl 0;
|
||||
gap: $space-lg;
|
||||
margin: 40px 0;
|
||||
}
|
||||
|
||||
.process-step {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
gap: 8px;
|
||||
position: relative;
|
||||
|
||||
.step-name {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-primary;
|
||||
padding: $space-sm $space-md;
|
||||
background: $bg-tertiary;
|
||||
border-radius: $radius-md;
|
||||
padding: 8px 16px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.step-time {
|
||||
font-size: $font-size-xs;
|
||||
font-size: 13px;
|
||||
color: $brand-primary;
|
||||
font-weight: $font-weight-bold;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.step-arrow {
|
||||
color: $text-tertiary;
|
||||
font-size: $font-size-lg;
|
||||
color: rgba(255, 255, 255, 0.2);
|
||||
font-size: 20px;
|
||||
position: absolute;
|
||||
right: -24px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
&:last-child .step-arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.bottleneck {
|
||||
.step-name {
|
||||
background: rgba($color-warning, 0.2);
|
||||
border: 1px solid $color-warning;
|
||||
background: rgba($color-warning, 0.1);
|
||||
border-color: rgba($color-warning, 0.3);
|
||||
color: $color-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1059,9 +1098,13 @@ onMounted(() => {
|
||||
.process-summary {
|
||||
text-align: center;
|
||||
color: $text-secondary;
|
||||
margin-top: $space-lg;
|
||||
padding-top: $space-lg;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
||||
|
||||
strong {
|
||||
color: $text-primary;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.bottleneck-info {
|
||||
@ -1072,76 +1115,110 @@ onMounted(() => {
|
||||
|
||||
// 预警卡片样式
|
||||
.warning-stat-card {
|
||||
background: $bg-tertiary;
|
||||
border-radius: $radius-md;
|
||||
background: $bg-card;
|
||||
border-radius: $radius-lg;
|
||||
padding: $space-lg;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all $transition-base;
|
||||
border: 1px solid rgba(255, 255, 255, 0.03);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-base;
|
||||
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
&.urgent { border: 1px solid $color-error; }
|
||||
&.warning { border: 1px solid $color-warning; }
|
||||
&.normal { border: 1px solid $color-success; }
|
||||
&.all { border: 1px solid $brand-primary; }
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.urgent::before { background: $color-error; }
|
||||
&.warning::before { background: $color-warning; }
|
||||
&.normal::before { background: $color-success; }
|
||||
&.all::before { background: $brand-primary; }
|
||||
|
||||
.warning-icon {
|
||||
font-size: 24px;
|
||||
margin-bottom: $space-xs;
|
||||
font-size: 28px;
|
||||
margin-bottom: 12px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.warning-label {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-secondary;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.warning-count {
|
||||
font-size: $font-size-2xl;
|
||||
font-weight: $font-weight-bold;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: $text-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.level-badge {
|
||||
padding: 2px 8px;
|
||||
border-radius: $radius-sm;
|
||||
font-size: $font-size-xs;
|
||||
padding: 4px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
|
||||
&.urgent {
|
||||
background: rgba($color-error, 0.1);
|
||||
color: $color-error;
|
||||
background: rgba($color-error, 0.15);
|
||||
color: lighten($color-error, 10%);
|
||||
border: 1px solid rgba($color-error, 0.2);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background: rgba($color-warning, 0.1);
|
||||
color: $color-warning;
|
||||
background: rgba($color-warning, 0.15);
|
||||
color: lighten($color-warning, 10%);
|
||||
border: 1px solid rgba($color-warning, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
// Ant Design 深色主题覆盖
|
||||
:deep(.ant-table) {
|
||||
background: transparent !important;
|
||||
color: $text-primary;
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background: $bg-tertiary !important;
|
||||
border-color: $border-color !important;
|
||||
color: $text-primary !important;
|
||||
// 移除边框
|
||||
.ant-table-container {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr {
|
||||
&:hover > td {
|
||||
background: $bg-tertiary !important;
|
||||
}
|
||||
.ant-table-thead > tr > th {
|
||||
background: transparent !important;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05) !important;
|
||||
color: $text-secondary !important;
|
||||
font-weight: 500;
|
||||
padding: 16px;
|
||||
|
||||
> td {
|
||||
border-color: $border-color !important;
|
||||
color: $text-primary !important;
|
||||
&::before {
|
||||
display: none !important; // 移除表头分割线
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.02) !important;
|
||||
padding: 16px;
|
||||
color: $text-primary;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background: rgba(255, 255, 255, 0.03) !important;
|
||||
}
|
||||
|
||||
// 移除所有垂直边框
|
||||
.ant-table-cell {
|
||||
border-right: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-tabs) {
|
||||
@ -1151,14 +1228,20 @@ onMounted(() => {
|
||||
:deep(.ant-select) {
|
||||
.ant-select-selector {
|
||||
background: $bg-tertiary !important;
|
||||
border-color: $border-color !important;
|
||||
border-color: rgba(255, 255, 255, 0.1) !important;
|
||||
color: $text-primary !important;
|
||||
border-radius: 6px !important;
|
||||
}
|
||||
|
||||
.ant-select-arrow {
|
||||
color: $text-secondary !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-picker) {
|
||||
background: $bg-tertiary !important;
|
||||
border-color: $border-color !important;
|
||||
border-color: rgba(255, 255, 255, 0.1) !important;
|
||||
border-radius: 6px !important;
|
||||
|
||||
.ant-picker-input > input {
|
||||
color: $text-primary !important;
|
||||
@ -1169,7 +1252,14 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-btn) {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
:deep(.ant-rate) {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.1);
|
||||
|
||||
.ant-rate-star-full .ant-rate-star-second {
|
||||
color: #FFD700 !important;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user