全景画像入口页面
This commit is contained in:
parent
29c8f7f562
commit
bb95119354
@ -184,6 +184,26 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/dashentry',
|
||||
component: Layout,
|
||||
name: 'DashEntryL',
|
||||
meta: {
|
||||
hidden: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/DashEntry/DashEntry.vue'),
|
||||
name: 'DashEntry',
|
||||
meta: {
|
||||
hidden: true,
|
||||
title: 'DashEntry',
|
||||
noTagsView: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/views/Login/Login.vue'),
|
||||
|
||||
513
src/views/DashEntry/DashEntry.vue
Normal file
513
src/views/DashEntry/DashEntry.vue
Normal file
@ -0,0 +1,513 @@
|
||||
<template>
|
||||
<div class="dash-entry-container">
|
||||
<!-- 顶部四个数据卡片 -->
|
||||
<div class="stats-cards">
|
||||
<div v-for="(card, index) in statsCards" :key="index" class="stat-card">
|
||||
<div class="stat-card-icon" :class="`icon-${card.type}`">
|
||||
<Icon :icon="card.icon" :size="20" />
|
||||
</div>
|
||||
<div class="stat-card-content">
|
||||
<div class="stat-card-title">{{ card.title }}</div>
|
||||
<div class="stat-card-value">{{ card.value }}</div>
|
||||
<div class="stat-card-subtitle">
|
||||
{{ card.subtitle }}
|
||||
<span class="trend-icon" :class="card.trend === 'up' ? 'trend-up' : 'trend-down'">{{
|
||||
card.trend === 'up' ? '↑' : '↓'
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中间图表区域 -->
|
||||
<div class="charts-section">
|
||||
<!-- 左侧:风险等级分布(环形图) -->
|
||||
<div class="chart-card">
|
||||
<div class="chart-title">风险等级分布</div>
|
||||
<div class="chart-content">
|
||||
<EChart :options="riskDistributionOptions" :width="'100%'" :height="'300px'" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:风险趋势图(折线图) -->
|
||||
<div class="chart-card">
|
||||
<div class="chart-title">风险趋势图</div>
|
||||
<div class="chart-content">
|
||||
<EChart :options="riskTrendOptions" :height="'300px'" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-title">重点关注对象列表</div>
|
||||
<el-table :data="paginatedResults" style="width: 100%" stripe>
|
||||
<el-table-column prop="name" label="姓名" width="130" class-name="name-column">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.isNew" class="new-tag">新增</span>
|
||||
{{ row.name }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="gender" label="性别" width="80" />
|
||||
<el-table-column prop="age" label="年龄" width="80" />
|
||||
<el-table-column prop="riskLevel" label="风险等级" width="120">
|
||||
<template #default="{ row }">
|
||||
<span :class="`risk-level risk-${row.riskLevelType}`">
|
||||
{{ row.riskLevel }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="supervisionArea" label="监区" width="120" />
|
||||
<el-table-column prop="psychologicalRiskLevel" label="心理风险等级" width="150" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-link type="primary" @click="handleView(row)">全景画像</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="table-pagination">
|
||||
<span class="total-count">共{{ tableData.total }}条</span>
|
||||
<el-pagination
|
||||
v-model:current-page="tableData.current"
|
||||
v-model:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="tableData.total"
|
||||
layout="sizes, prev, pager, next"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import type { EChartsOption } from 'echarts'
|
||||
// @ts-ignore
|
||||
import EChart from '@/components/Echart/src/Echart.vue'
|
||||
import { Icon } from '@/components/Icon'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
defineOptions({ name: 'DashEntry' })
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 统计数据卡片
|
||||
const statsCards = ref([
|
||||
{
|
||||
title: '全部人员',
|
||||
value: '59人',
|
||||
subtitle: '本月45人 +15',
|
||||
trend: 'up',
|
||||
type: 'all',
|
||||
icon: 'ep:user'
|
||||
},
|
||||
{
|
||||
title: '高危人员',
|
||||
value: '12人',
|
||||
subtitle: '本月3人 -3',
|
||||
trend: 'down',
|
||||
type: 'high',
|
||||
icon: 'ep:warning-filled'
|
||||
},
|
||||
{
|
||||
title: '预警人员',
|
||||
value: '23人',
|
||||
subtitle: '本月4人 +2',
|
||||
trend: 'up',
|
||||
type: 'warning',
|
||||
icon: 'ep:bell'
|
||||
},
|
||||
{
|
||||
title: '普通人员',
|
||||
value: '32人',
|
||||
subtitle: '本月5人 +1',
|
||||
trend: 'up',
|
||||
type: 'normal',
|
||||
icon: 'ep:user-filled'
|
||||
}
|
||||
])
|
||||
|
||||
// 风险等级分布图表配置(环形图)
|
||||
const riskDistributionOptions = computed<EChartsOption>(() => ({
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b}: {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
bottom: 0,
|
||||
left: 'center',
|
||||
itemGap: 20,
|
||||
icon: 'circle',
|
||||
textStyle: {
|
||||
fontSize: 12
|
||||
},
|
||||
data: ['普通 (80%)', '预警 (15%)', '高危 (5%)']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '风险等级分布',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 10,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b}\n{d}%'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
data: [
|
||||
{ value: 978, name: '普通 (80%)', itemStyle: { color: '#5470c6' } },
|
||||
{ value: 189, name: '预警 (15%)', itemStyle: { color: '#fac858' } },
|
||||
{ value: 67, name: '高危 (5%)', itemStyle: { color: '#ee6666' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}))
|
||||
|
||||
// 风险趋势图配置(折线图)
|
||||
const riskTrendOptions = computed<EChartsOption>(() => ({
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ['高危', '预警', '普通'],
|
||||
bottom: 10
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '15%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: ['2024-10', '2024-11', '2024-12', '2025-01', '2025-02', '2025-03', '2025-04']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 300,
|
||||
interval: 50
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '高危',
|
||||
type: 'line',
|
||||
data: [50, 52, 48, 51, 49, 50, 48],
|
||||
itemStyle: { color: '#ee6666' },
|
||||
lineStyle: { color: '#ee6666' },
|
||||
symbol: 'circle',
|
||||
symbolSize: 6
|
||||
},
|
||||
{
|
||||
name: '预警',
|
||||
type: 'line',
|
||||
data: [150, 180, 170, 190, 185, 175, 180],
|
||||
itemStyle: { color: '#fac858' },
|
||||
lineStyle: { color: '#fac858', type: 'dashed' },
|
||||
symbol: 'circle',
|
||||
symbolSize: 6
|
||||
},
|
||||
{
|
||||
name: '普通',
|
||||
type: 'line',
|
||||
data: [250, 280, 270, 290, 285, 275, 280],
|
||||
itemStyle: { color: '#666' },
|
||||
lineStyle: { color: '#666' },
|
||||
symbol: 'circle',
|
||||
symbolSize: 6
|
||||
}
|
||||
]
|
||||
}))
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref({
|
||||
current: 1,
|
||||
total: 3,
|
||||
results: [
|
||||
{
|
||||
name: '王建国',
|
||||
isNew: true,
|
||||
gender: '男',
|
||||
age: 34,
|
||||
riskLevel: '高危',
|
||||
riskLevelType: 'high',
|
||||
supervisionArea: '第一监区',
|
||||
psychologicalRiskLevel: '一级风险'
|
||||
},
|
||||
{
|
||||
name: '李秀英',
|
||||
isNew: true,
|
||||
gender: '女',
|
||||
age: 29,
|
||||
riskLevel: '预警',
|
||||
riskLevelType: 'warning',
|
||||
supervisionArea: '第二监区',
|
||||
psychologicalRiskLevel: '二级风险'
|
||||
},
|
||||
{
|
||||
name: '张伟',
|
||||
isNew: false,
|
||||
gender: '男',
|
||||
age: 41,
|
||||
riskLevel: '普通',
|
||||
riskLevelType: 'normal',
|
||||
supervisionArea: '第一监区',
|
||||
psychologicalRiskLevel: '三级风险'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 分页
|
||||
const pageSize = ref(10)
|
||||
|
||||
// 分页后的数据
|
||||
const paginatedResults = computed(() => {
|
||||
const start = (tableData.value.current - 1) * pageSize.value
|
||||
const end = start + pageSize.value
|
||||
return tableData.value.results.slice(start, end)
|
||||
})
|
||||
|
||||
// 处理每页大小变化
|
||||
const handleSizeChange = (val: number) => {
|
||||
pageSize.value = val
|
||||
tableData.value.current = 1 // 重置到第一页
|
||||
}
|
||||
|
||||
// 处理当前页变化
|
||||
const handleCurrentChange = (val: number) => {
|
||||
tableData.value.current = val
|
||||
}
|
||||
|
||||
const handleView = (row: any) => {
|
||||
router.push({
|
||||
name: 'Dashboard',
|
||||
query: {
|
||||
id: row.id || row.name
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dash-entry-container {
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 统计卡片区域
|
||||
.stats-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
padding: 10px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.2s;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
position: relative;
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
.stat-card-icon {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 16px;
|
||||
font-size: 28px;
|
||||
|
||||
&.icon-all {
|
||||
background: #e6f4ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
&.icon-high {
|
||||
background: #fff1f0;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
&.icon-warning {
|
||||
background: #fff7e6;
|
||||
color: #faad14;
|
||||
}
|
||||
|
||||
&.icon-normal {
|
||||
background: #f6ffed;
|
||||
color: #52c41a;
|
||||
}
|
||||
}
|
||||
|
||||
.stat-card-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.stat-card-title {
|
||||
font-size: 9px;
|
||||
color: #666;
|
||||
margin-bottom: 8px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.stat-card-value {
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.stat-card-subtitle {
|
||||
font-size: 8px;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
.trend-icon {
|
||||
margin-left: 4px;
|
||||
&.trend-up {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.trend-down {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 图表区域
|
||||
.charts-section {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.chart-card {
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.chart-content {
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.table-title {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
:deep(.name-column) {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.new-tag {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
left: 0;
|
||||
padding: 1px 3px;
|
||||
background: #1890ff;
|
||||
color: #ffffff;
|
||||
font-size: 9px;
|
||||
border-radius: 2px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.risk-level {
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 9px;
|
||||
|
||||
&.risk-high {
|
||||
color: #ff4d4f;
|
||||
background: #fff1f0;
|
||||
}
|
||||
|
||||
&.risk-warning {
|
||||
color: #faad14;
|
||||
background: #fff7e6;
|
||||
}
|
||||
|
||||
&.risk-normal {
|
||||
color: #666;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
||||
.table-pagination {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 16px;
|
||||
|
||||
.total-count {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user