feat(dashboard): 修改中间区域为纵向3字段布局

- 左侧区域:累计服刑天数、累计违规次数、累计表扬次数
- 右侧区域:剩余刑期天数、累计扣分次数、累计加分次数
- 底部模块:显示占位符 '-'
- 添加CSS样式适配纵向布局(info-field-item, field-label, field-value)
- 遵循Element Plus设计规范

参考计划: .sisyphus/plans/dashboard-center-update.md Tasks 2-5
This commit is contained in:
tangweijie 2026-01-27 10:50:21 +08:00
parent 4bff154317
commit 9a3044147b

View File

@ -10,42 +10,36 @@
<div class="dashboard-content-top-center">
<div class="gauge-container">
<div class="dashboard-content-top-center-data">
<!-- 左侧第一个卡片 -->
<div class="info-card-item">
<div class="card-number">{{ centerLeftData.top.value }}</div>
<div class="card-label">{{ centerLeftData.top.label }}</div>
<!-- 左侧区域3个字段纵向排列 -->
<div class="info-field-item">
<div class="field-label">累计服刑天数</div>
<div class="field-value">{{ servedDays }}</div>
</div>
<!-- 左侧第二个卡片 -->
<div class="card-row">
<div class="info-card-item center-right-card-item">
<div class="card-number">{{ centerLeftData.middle.left.value }}</div>
<div class="card-label">{{ centerLeftData.middle.left.label }}</div>
</div>
<div class="info-card-item center-right-card-item">
<div class="card-number">{{ centerLeftData.middle.right.value }}</div>
<div class="card-label">{{ centerLeftData.middle.right.label }}</div>
</div>
<div class="info-field-item">
<div class="field-label">累计违规次数</div>
<div class="field-value">{{ violationCount }}</div>
</div>
<div class="info-field-item">
<div class="field-label">累计表扬次数</div>
<div class="field-value">{{ praiseCount }}</div>
</div>
</div>
<div class="dashboard-content-top-center-center">
<GaugeChart :height="'240px'" :value="gaugeValue" :name="gaugeName" />
</div>
<div class="dashboard-content-top-center-data">
<!-- 右侧第一个卡片 -->
<div class="info-card-item">
<div class="card-number">{{ centerRightData.top.value }}</div>
<div class="card-label">{{ centerRightData.top.label }}</div>
<!-- 右侧区域3个字段纵向排列 -->
<div class="info-field-item">
<div class="field-label">剩余刑期天数</div>
<div class="field-value">{{ remainingDays }}</div>
</div>
<!-- 右侧第二个卡片 -->
<div class="card-row">
<div class="info-card-item center-right-card-item">
<div class="card-number">{{ centerRightData.middle.left.value }}</div>
<div class="card-label">{{ centerRightData.middle.left.label }}</div>
</div>
<div class="info-card-item center-right-card-item">
<div class="card-number">{{ centerRightData.middle.right.value }}</div>
<div class="card-label">{{ centerRightData.middle.right.label }}</div>
</div>
<div class="info-field-item">
<div class="field-label">累计扣分次数</div>
<div class="field-value">{{ penaltyCount }}</div>
</div>
<div class="info-field-item">
<div class="field-label">累计加分次数</div>
<div class="field-value">{{ rewardCount }}</div>
</div>
</div>
</div>
@ -242,6 +236,16 @@ const rewardsPunishments = ref<{
const currentTime = ref('')
const prisonerName = ref('加载中...')
//
const servedDays = ref(0)
const violationCount = ref(0)
const praiseCount = ref(0)
//
const remainingDays = ref(0)
const penaltyCount = ref(0)
const rewardCount = ref(0)
//
const formatTime = () => {
const now = new Date()
@ -275,13 +279,14 @@ const loadData = async (prisonerId: number) => {
gaugeName.value = ''
//
const servedDays = res.servedDays || 0;
let remainingDays = 0;
const servedDaysValue = res.servedDays || 0;
servedDays.value = servedDaysValue
remainingDays.value = 0;
if (res.imprisonmentDate && res.releaseDate) {
const startDate = new Date(res.imprisonmentDate);
const endDate = new Date(res.releaseDate);
const totalDays = Math.floor((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
remainingDays = Math.max(0, totalDays - servedDays);
remainingDays.value = Math.max(0, totalDays - servedDaysValue);
}
// -
@ -301,6 +306,10 @@ const loadData = async (prisonerId: number) => {
console.error('获取计分考核数据失败:', error)
}
//
penaltyCount.value = totalPenaltyCount
rewardCount.value = totalRewardCount
// -
let totalViolationCount = 0
try {
@ -315,6 +324,10 @@ const loadData = async (prisonerId: number) => {
console.error('获取狱情收集数据失败:', error)
}
//
violationCount.value = totalViolationCount
praiseCount.value = res.praiseCount || 0
//
if (res.centerLeftData) {
centerLeftData.value = {
@ -583,6 +596,49 @@ onUnmounted(() => {
justify-content: space-between;
}
//
.info-field-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 12px 16px;
background: #2d3d5f;
border: 1px solid rgba(56, 102, 141, 0.5);
border-radius: 6px;
box-shadow: inset 0 0 10px 0 rgba(43, 65, 131, 0.3);
transition: all 0.3s ease;
&:hover {
border-color: rgba(56, 102, 141, 0.8);
box-shadow: inset 0 0 15px 0 rgba(43, 65, 131, 0.5);
}
}
//
.field-label {
font-size: 14px;
color: rgba(255, 255, 255, 0.85);
line-height: 1.5;
text-align: center;
white-space: nowrap;
margin-bottom: 8px;
font-weight: 500;
}
//
.field-value {
font-size: 20px;
font-weight: bold;
color: #ffffff;
line-height: 1.3;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
.dashboard-content-top-center-center {
width: 40%;
height: 220px;