更新代码

This commit is contained in:
2025-04-14 19:48:42 +08:00
parent 49cfd7e64f
commit 8b786df36a
73 changed files with 1988 additions and 4488 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
<template>
<div ref="vehicleChartRef" id="bar-main"></div>
</template>
<script setup>
import { onMounted ,onUnmounted} from 'vue';
import * as echarts from 'echarts'
let myChart = null
const getLine = async () => {
var chartDom = document.getElementById('bar-main');
var myChart = echarts.init(chartDom);
var option;
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true
}
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: 'Direct',
type: 'bar',
barWidth: '60%',
data: [10, 52, 200, 334, 390, 330, 220]
}
]
};
option && myChart.setOption(option);
}
const handleResize = () => {
myChart?.resize()
}
onMounted(() => {
getLine()
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
myChart?.dispose()
})
</script>
<style lang="scss" scoped>
#bar-main{
z-index:999;
}
</style>

View File

@ -1,99 +0,0 @@
<template>
<div class="checkpoint-list">
<div class="checkpoint-item" v-for="(item, index) in checkpoints" :key="index">
<div class="checkpoint-icon">
<img src="@/assets/images/bg_11.png" alt="检查站">
</div>
<div class="checkpoint-info">
<span class="checkpoint-name">{{ item.name }}</span>
<span class="checkpoint-count">{{ item.count }} </span>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const checkpoints = ref([
{
name: '玉普一级检查站',
count: 100
},
{
name: '京瓦龙一级检查站',
count: 100
},
{
name: '岗庙边境检查站',
count: 100
},
{
name: '察隅边境检查站',
count: 100
},
{
name: '金东边境检查站',
count: 100
},
{
name: '达木边境检查站',
count: 100
}
])
</script>
<style scoped lang="scss">
.checkpoint-list {
margin-top: 20px;
height: calc(100% - 40px);
overflow: hidden;
overflow-y: auto;
padding: 4px;
box-sizing: border-box;
}
.checkpoint-item {
display: flex;
align-items: center;
gap: 15px;
padding: 4px 10px;
}
.checkpoint-icon {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 240, 255, 0.1);
border-radius: 4px;
}
.checkpoint-icon img {
width: 24px;
height: 24px;
filter: brightness(0) invert(1);
opacity: 0.8;
}
.checkpoint-info {
flex: 1;
display: flex;
align-items: center;
}
.checkpoint-name {
color: #fff;
font-size: 16px;
display: inline-block;
width: 50%;
}
.checkpoint-count {
color: #00f0ff;
font-size: 16px;
font-weight: 500;
}
</style>

View File

@ -1,145 +0,0 @@
<template>
<div class="data-statistics">
<!-- 人员数据采集 -->
<div class="data-collection">
<h2 class="section-title">人员数据采集</h2>
<div class="statistics-cards">
<div class="stat-card">
<div class="stat-number">50</div>
<div class="f14">人证核验</div>
<div><img src="@/assets/images/bg_03.png" alt=""></div>
</div>
<div class="stat-card">
<div class="stat-number">320</div>
<div class="f14">无感通行</div>
<div><img src="@/assets/images/bg_04.png" alt=""></div>
</div>
<div class="stat-card">
<div class="stat-number">100</div>
<div class="f14">手持终端登记</div>
<div><img src="@/assets/images/bg_05.png" alt=""></div>
</div>
</div>
</div>
<!-- 流入流出统计 -->
<div class="flow-statistics">
<h2 class="section-title">流入流出统计</h2>
<div class="flow-grid">
<div class="flow-item">
<div class="flow-icon"><img width="64" src="@/assets/images/bg_06.png" alt=""></div>
<div class="flow-info">
<span class="flow-label">进林人员</span>
<span class="flow-number">2000</span>
</div>
</div>
<div class="flow-item">
<div class="flow-icon"><img width="64" src="@/assets/images/bg_06.png" alt=""></div>
<div class="flow-info">
<span class="flow-label">出林人员</span>
<span class="flow-number">300</span>
</div>
</div>
<div class="flow-item">
<div class="flow-icon"><img width="64" src="@/assets/images/bg_07.png" alt=""></div>
<div class="flow-info">
<span class="flow-label">进林车辆</span>
<span class="flow-number">500</span>
</div>
</div>
<div class="flow-item">
<div class="flow-icon"><img width="64" src="@/assets/images/bg_07.png" alt=""></div>
<div class="flow-info">
<span class="flow-label">出林车辆</span>
<span class="flow-number">666</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
// 可以在这里添加需要的响应式数据和方法
</script>
<style scoped lang="scss">
.data-statistics {
height: 100%;
overflow: hidden;
padding: 0 10px;
box-sizing: border-box;
}
.section-title {
margin-bottom: 15px;
font-size: 18px;
position: relative;
padding-left: 12px;
background: linear-gradient(0deg, #59A6F4 0%,#ffffff 90%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.section-title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 8px;
height: 16px;
background: url('~@/assets/images/bg_02.png');
background-size: 100% 100%;
}
.statistics-cards {
display: flex;
gap: 20px;
}
.stat-card {
flex: 1;
text-align: center;
position: relative;
}
.stat-number {
font-size: 32px;
color: #00f0ff;
margin-bottom: 5px;
}
.flow-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.flow-item {
display: flex;
align-items: center;
gap: 20px;
}
.flow-icon {
font-size: 24px;
color: #00f0ff;
}
.flow-info {
display: flex;
flex-direction: column;
}
.flow-label {
font-size: 14px;
color: #fff;
}
.flow-number {
font-size: 24px;
color: #00f0ff;
margin-top: 5px;
}
</style>

View File

@ -0,0 +1,57 @@
<template>
<div ref="vehicleChartRef" id="chart-container"></div>
</template>
<script setup>
import { onMounted ,onUnmounted} from 'vue';
import * as echarts from 'echarts'
let myChart = null
const getLine = async () => {
var chartDom = document.getElementById('chart-container');
console.log("chartDom")
myChart = echarts.init(chartDom);
var option;
option = {
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
areaStyle: {}
}
]
};
option && myChart.setOption(option);
console.log("option", option);
}
const handleResize = () => {
myChart?.resize()
}
onMounted(() => {
getLine()
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
myChart?.dispose()
})
</script>
<style lang="scss" scoped>
#chart-container{
z-index:999;
}
</style>

View File

@ -1,145 +0,0 @@
<template>
<div class="map-container">
<div ref="chartRef" class="chart"></div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import * as echarts from 'echarts'
import 'echarts-gl'
const chartRef = ref(null)
let chart = null
const initChart = async () => {
// 使用require方式导入静态资源
const baseImg = require('@/assets/images/map-marker.svg')
try {
// 确保图片加载完成
await new Promise((resolve, reject) => {
const img = new Image()
img.onload = resolve
img.onerror = reject
img.src = baseImg
})
let geoJson = require('./511202.json')
chart = echarts.init(chartRef.value)
echarts.registerMap('myMap', geoJson)
// 异步加载撒点数据
const markerData = [
{ name: '站点1', value: [102.651727, 30.117088, 3] },
{ name: '站点2', value: [102.527442, 30.108846, 3] },
{ name: '站点3', value: [102.801965, 30.100063, 3] },
{ name: '站点4', value: [102.711411, 30.158424, 3] },
{ name: '站点5', value: [102.579582, 30.174818, 3] }
]
const option = {
geo3D: {
map: 'myMap',
regionHeight: 6,
shading: 'realistic',
realisticMaterial: {
roughness: 0.2,
metalness: 0
},
itemStyle: {
color: 'rgba(1,59,110,0.2)',
opacity: 0.9,
borderWidth: 1,
borderColor: '#61CFF8',
},
emphasis: {
label: {
show: true,
textStyle: {
color: '#fff'
}
},
itemStyle: {
color: 'rgba(1,59,110,0.5)',
borderWidth: 10,
borderColor: 'rgba(10,148,184,1)'
}
},
light: {
main: {
color: '#fff',
intensity: 1,
shadow: true,
shadowQuality: 'high',
alpha: 25,
beta: 20
},
ambient: {
color: '#fff',
intensity: 0.6
}
},
viewControl: {
distance: 150,
alpha: 46,
beta: 30,
},
postEffect: {
enable: true,
bloom: {
enable: true,
intensity: 0.1
}
},
temporalSuperSampling: {
enable: true
}
},
series: [{
type: 'scatter3D',
coordinateSystem: 'geo3D',
symbol: 'image://' + baseImg,
symbolSize: [40, 40],
itemStyle: {
color: '#00f0ff',
opacity: 1
},
data: markerData
}]
}
// 确保DOM已经渲染完成
await nextTick()
chart.setOption(option)
} catch (error) {
console.error('地图初始化失败:', error)
}
}
const handleResize = () => {
chart?.resize()
}
onMounted(() => {
initChart()
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
chart?.dispose()
})
</script>
<style scoped>
.map-container {
width: 100%;
height: 100%;
}
.chart {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,73 @@
<template>
<div ref="vehicleChartRef" id="pei-main"></div>
</template>
<script setup>
import { onMounted ,onUnmounted} from 'vue';
import * as echarts from 'echarts'
let myChart = null
const getLine = async () => {
var chartDom = document.getElementById('pei-main');
var myChart = echarts.init(chartDom);
var option;
option = {
title: {
text: 'Referer of a Website',
subtext: 'Fake Data',
left: 'center'
},
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
name: 'Access From',
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Union Ads' },
{ value: 300, name: 'Video Ads' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
option && myChart.setOption(option);
}
const handleResize = () => {
myChart?.resize()
}
onMounted(() => {
getLine()
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
myChart?.dispose()
})
</script>
<style lang="scss" scoped>
#pei-main{
z-index:999;
}
</style>

View File

@ -0,0 +1,49 @@
<template>
<div class="top-icon-container">
<div v-for="(item, index) in list" :key="`list${index}`" class="top-icon-item">
<img :src="item.icon" alt="">
<div>
<div>{{ item.title }}</div>
<div style="font-size:10px">{{ item.desc }}</div>
</div>
</div>
<div class="yjbk"></div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const list = ref([{
icon: require("@/assets/images/databi/tianqi.png"),
title: "多云转小雨",
desc: "无持续风向微风",
},
{
icon: require("@/assets/images/databi/wendu.png"),
title: "36°",
desc: "11°~26°",
},
{
icon: require("@/assets/images/databi/time.png"),
title: "20:30:59",
desc: "星期二 2024-12-17",
}
])
</script>
<style lang="scss" scoped>
.top-icon-container{
gap: 10px;
display: flex;
.top-icon-item{
display: flex;
}
.yjbk{
background: url("~@/assets/images/databi/head-1.png") no-repeat center center;
}
}
</style>

View File

@ -1,242 +0,0 @@
<template>
<div class="warning-analysis">
<div class="chart-section">
<h2 class="section-title">车辆预警分析</h2>
<div ref="vehicleChartRef" class="chart-container"></div>
</div>
<div class="chart-section">
<h2 class="section-title">人员预警分析</h2>
<div ref="personChartRef" class="chart-container"></div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
const vehicleChartRef = ref(null)
const personChartRef = ref(null)
let vehicleChart = null
let personChart = null
const createChartOption = (data, colors) => {
return {
title: {
text: '100',
subtext: '总数',
left: '20%',
top: 'center',
textStyle: {
color: '#fff',
fontSize: 24,
fontWeight: 'normal'
},
subtextStyle: {
color: '#fff',
fontSize: 14
}
},
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: '45%',
top: 'center',
textStyle: {
color: '#fff',
rich: {
value: {
color: '#fff'
},
percentage: {
padding: [0, 0, 0, 10]
},
blue: {
color: colors[0]
},
lightBlue: {
color: colors[1]
},
orange: {
color: colors[2]
},
green: {
color: colors[3]
}
}
},
formatter: (name) => {
const item = data.find(d => d.name === name)
return `${name} ${item.value} {${item.colorType}|(${item.value}%)}`
}
},
series: [
{
type: 'pie',
radius: ['55%', '70%'],
center: ['25%', '50%'],
data: data.map(item => ({
...item,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: item.color[0] },
{ offset: 1, color: item.color[1] }
])
}
})),
label: {
show: false
},
emphasis: {
scale: false,
focus: 'none'
},
z: 2
},
{
type: 'pie',
radius: ['65%', '85%'],
center: ['50%', '50%'],
data: data.map(item => ({
...item,
itemStyle: {
color: 'rgba(0, 0, 0, 0.3)'
}
})),
label: {
show: false
},
emphasis: {
scale: false,
focus: 'none'
},
z: 1,
silent: true
}
]
}
}
const initCharts = () => {
const colors = ['#00f0ff', '#0066ff', '#ff9900', '#00cc66']
// 车辆预警数据
const vehicleData = [
{
value: 25,
name: '盗窃车辆',
colorType: 'blue',
color: ['#00f0ff', '#00a0cc']
},
{
value: 30,
name: '车牌与车辆不符',
colorType: 'lightBlue',
color: ['#0066ff', '#0044cc']
},
{
value: 17,
name: '车辆超高',
colorType: 'orange',
color: ['#ff9900', '#cc7a00']
},
{
value: 28,
name: '车辆超限',
colorType: 'green',
color: ['#00cc66', '#009944']
}
]
// 人员预警数据
const personData = [
{
value: 25,
name: '涉稳人员',
colorType: 'blue',
color: ['#00f0ff', '#00a0cc']
},
{
value: 30,
name: '涉毒人员',
colorType: 'lightBlue',
color: ['#0066ff', '#0044cc']
},
{
value: 17,
name: '涉黄人员',
colorType: 'orange',
color: ['#ff9900', '#cc7a00']
},
{
value: 28,
name: '前科人员',
colorType: 'green',
color: ['#00cc66', '#009944']
}
]
vehicleChart = echarts.init(vehicleChartRef.value)
personChart = echarts.init(personChartRef.value)
vehicleChart.setOption(createChartOption(vehicleData, colors))
personChart.setOption(createChartOption(personData, colors))
}
const handleResize = () => {
vehicleChart?.resize()
personChart?.resize()
}
onMounted(() => {
initCharts()
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
vehicleChart?.dispose()
personChart?.dispose()
})
</script>
<style scoped lang="scss">
.warning-analysis {
padding: 20px;
background-color: #001529;
height: 100%;
}
.chart-section {
height: 50%;
}
.section-title {
font-size: 18px;
margin-bottom: 20px;
position: relative;
padding-left: 12px;
background: linear-gradient(0deg, #59A6F4 0%,#ffffff 90%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.section-title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 8px;
height: 16px;
background: url('~@/assets/images/bg_02.png');
background-size: 100% 100%;
}
.chart-container {
height: calc(100% - 40px);
width: 100%;
}
</style>

View File

@ -1,180 +0,0 @@
<template>
<div class="warning-container">
<!-- 标签切换 -->
<div class="tab-container">
<div class="tab-item active">
<div class="tab-content">车辆预警</div>
</div>
<div class="tab-item">
<div class="tab-content">人员预警</div>
</div>
</div>
<!-- 预警列表 -->
<div class="warning-list">
<div class="warning-card" v-for="(item, index) in warningList" :key="index">
<div class="warning-image">
<img :src="item.image" alt="预警图片">
</div>
<div class="warning-info">
<div class="info-item">
<span class="label">姓名</span>
<span>{{ item.name }}</span>
<span class="tag">涉警人员</span>
</div>
<div class="info-item">
<span class="label">性别</span>
<span>{{ item.gender }}</span>
</div>
<div class="info-item">
<span class="label">相似度</span>
<span class="highlight">{{ item.similarity }}%</span>
</div>
<div class="info-item">
<span class="label">预警时间</span>
<span>{{ item.warningTime }}</span>
</div>
<div class="info-item flex align-center">
<span class="label nowrap">抓拍地址</span>
<span class="one_text_detail">{{ item.location }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const warningList = ref([
{
image: require('@/assets/images/person.png'),
name: '张三',
gender: '男',
similarity: 85,
warningTime: '2025-02-15 13: 00',
location: '林艺市八宫区天山路宫区天山路宫区天山路'
},
{
image: require('@/assets/images/person.png'),
name: '张三',
gender: '男',
similarity: 85,
warningTime: '2025-02-15 13: 00',
location: '林艺市八宫区天山路宫区天山路宫区天山路'
},
{
image: require('@/assets/images/person.png'),
name: '张三',
gender: '男',
similarity: 85,
warningTime: '2025-02-15 13: 00',
location: '林艺市八宫区天山路...'
}
])
</script>
<style scoped lang="scss">
.warning-container {
height: 100%;
}
.tab-container {
display: flex;
justify-content: space-around;
margin-bottom: 10px;
}
.tab-item {
width: 159px;
height: 43px;
text-align: center;
line-height: 24px;
position: relative;
cursor: pointer;
}
.tab-content {
padding: 8px 30px;
color: #fff;
font-size: 16px;
position: relative;
z-index: 1;
}
.tab-item::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url("~@/assets/images/bg_08.png") no-repeat center center;
background-size: 100% 100%;
}
.tab-item.active::before {
background: url("~@/assets/images/bg_09.png") no-repeat center center;
background-size: 100% 100%;
}
.warning-list {
height: calc(100% - 64px);
overflow: hidden;
overflow-y: auto;
}
.warning-card {
background: url("~@/assets/images/bg_10.png") no-repeat center center;
background-size: 100% 100%;
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 4px;
padding: 4px 4px 4px 10px;
box-sizing: border-box;
}
.warning-image {
width: 100px;
height: 80px;
img {
width: 100%;
height: 100%;
}
}
.warning-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.warning-info {
flex: 1;
}
.info-item {
margin-bottom: 4px;
color: #fff;
font-size: 14px;
}
.label {
color: rgba(255, 255, 255, 0.7);
}
.highlight {
color: #00f0ff;
}
.tag {
background: rgba(250, 177, 21, 0.9);
color: #fff;
padding: 2px 8px;
border-radius: 2px;
font-size: 12px;
margin-left: 10px;
}
</style>