全景画像入口页面
This commit is contained in:
parent
29c8f7f562
commit
bb95119354
@ -184,6 +184,26 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
|||||||
noTagsView: true
|
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',
|
path: '/login',
|
||||||
component: () => import('@/views/Login/Login.vue'),
|
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