Merge branch 'main' of http://39.101.188.84:7000/suzhou-jichuang-lanhai/park-shanghai
commit
d6a11710b9
Binary file not shown.
After Width: | Height: | Size: 369 B |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 294 B |
After Width: | Height: | Size: 26 KiB |
@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
<div ref="chartDom" class="echarts-container"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
const chartDom = ref(null);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const myChart = echarts.init(chartDom.value);
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
formatter: (params) => {
|
||||||
|
return `${params[0].axisValue}<br/>数值: ${params[0].value}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: ['一阶段', '二阶段', '三阶段', '四阶段'],
|
||||||
|
axisLine: {
|
||||||
|
show: false // 隐藏x轴线
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false // 隐藏刻度
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#fff' // 坐标轴文字颜色
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
min: 0,
|
||||||
|
max: 120,
|
||||||
|
interval: 20,
|
||||||
|
axisLine: {
|
||||||
|
show: false // 隐藏y轴线
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false // 隐藏刻度
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#fff'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '阶段数据',
|
||||||
|
type: 'bar',
|
||||||
|
data: [40, 60, 90, 110],
|
||||||
|
barWidth: 12,
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: 6, // 圆角柱形
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: '#3CE2FF' },
|
||||||
|
{ offset: 0.57, color: 'rgba(18,211,172,0.38)' },
|
||||||
|
{ offset: 1, color: 'rgba(18,115,211,0)' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
disabled: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
grid: {
|
||||||
|
top: 20,
|
||||||
|
bottom: 20,
|
||||||
|
left: 40,
|
||||||
|
right: 20
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
myChart.setOption(option);
|
||||||
|
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
myChart.resize();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.echarts-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div class="cell-row">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.cell-row {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(33, 39, 53, 0) 0%,
|
||||||
|
rgba(18, 116, 210, 0.3) 100%
|
||||||
|
);
|
||||||
|
border-radius: 0px 0px 10px 10px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container-bottom">
|
||||||
|
<!-- 表头 -->
|
||||||
|
<div class="table-head">
|
||||||
|
<div class="table-row header">
|
||||||
|
<span>工单描述</span>
|
||||||
|
<span>上报时间</span>
|
||||||
|
<span>区域负责人</span>
|
||||||
|
<span>负责人联系方式</span>
|
||||||
|
<span>操作</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 数据行 -->
|
||||||
|
<cellRow
|
||||||
|
v-for="(item, index) in tableData"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<div class="table-container">
|
||||||
|
<div class="table-row data">
|
||||||
|
<span>{{ item.desc }}</span>
|
||||||
|
<span>{{ item.time }}</span>
|
||||||
|
<span>{{ item.person }}</span>
|
||||||
|
<span>{{ item.contact }}</span>
|
||||||
|
<div class="status-container">
|
||||||
|
<span :class="['status-tag', getStatusClass(item.status)]">{{
|
||||||
|
item.status
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</cellRow>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import cellRow from "./cellRow.vue";
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const tableData = ref([
|
||||||
|
{
|
||||||
|
desc: "金山南路生活垃圾乱堆乱放",
|
||||||
|
time: "2021-05-05 09:05:05",
|
||||||
|
person: "王小虎",
|
||||||
|
contact: "18888888888",
|
||||||
|
status: "待处理",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "浦东新区道路积水严重",
|
||||||
|
time: "2021-06-01 14:30:00",
|
||||||
|
person: "王小虎",
|
||||||
|
contact: "17777777777",
|
||||||
|
status: "处理中",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "徐汇区路灯故障",
|
||||||
|
time: "2021-07-15 08:20:00",
|
||||||
|
person: "张三",
|
||||||
|
contact: "13333333333",
|
||||||
|
status: "已处理",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 根据状态返回对应的类名
|
||||||
|
const getStatusClass = (status) => {
|
||||||
|
switch (status) {
|
||||||
|
case "待处理":
|
||||||
|
return "status-pending";
|
||||||
|
case "处理中":
|
||||||
|
return "status-processing";
|
||||||
|
case "已处理":
|
||||||
|
return "status-done";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container-bottom {
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
.table-head {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 0 0px 40px;
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
.table-container {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 0 12px 40px;
|
||||||
|
display: grid;
|
||||||
|
gap: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row {
|
||||||
|
display: grid;
|
||||||
|
width: 100%;
|
||||||
|
grid-template-columns: 2fr 2fr 2fr 2fr 1fr;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
span:last-child {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
color: #9cbeff;
|
||||||
|
font-family: "MiSans-Regular";
|
||||||
|
}
|
||||||
|
|
||||||
|
.data {
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
font-family: "MiSans-Regular";
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-container{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
/* 状态标签通用样式 */
|
||||||
|
.status-tag {
|
||||||
|
width: 60%;
|
||||||
|
padding: 6px 0px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #ffffff;
|
||||||
|
border-radius: 18px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 待处理 - 橙色 */
|
||||||
|
.status-pending {
|
||||||
|
background-color: #CA7A2A;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 处理中 - 蓝色 */
|
||||||
|
.status-processing {
|
||||||
|
background-color: #2A95CA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 已处理 - 绿色 */
|
||||||
|
.status-done {
|
||||||
|
background-color: #5DCA2A;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<div class="main-right">
|
||||||
|
<panelBlock title="最新预警信息">
|
||||||
|
<warning></warning>
|
||||||
|
</panelBlock>
|
||||||
|
<panelBlock title="工单数量变化分析">
|
||||||
|
<lineEchart></lineEchart>
|
||||||
|
</panelBlock>
|
||||||
|
<panelBlock title="工作量统计分析">
|
||||||
|
<barEchart></barEchart>
|
||||||
|
</panelBlock>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { panelBlock } from "@/views/visualization/components/index";
|
||||||
|
import warning from "./warning.vue";
|
||||||
|
import lineEchart from "./lineEchart.vue";
|
||||||
|
import barEchart from "./barEchart.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.main-right {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
& > div {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,128 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
ref="chartDom"
|
||||||
|
class="echarts-container"
|
||||||
|
></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from "vue";
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
|
||||||
|
const chartDom = ref(null);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const myChart = echarts.init(chartDom.value);
|
||||||
|
|
||||||
|
// 原始数据
|
||||||
|
const rawData = [
|
||||||
|
{ value: 50, name: "应急工单录入" },
|
||||||
|
{ value: 30, name: "工单受理派发" },
|
||||||
|
{ value: 20, name: "工单处理完成" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 计算总数
|
||||||
|
const total = rawData.reduce((sum, item) => sum + item.value, 0);
|
||||||
|
|
||||||
|
// 百分比
|
||||||
|
const processedData = rawData.map((item) => ({
|
||||||
|
...item,
|
||||||
|
percent: Math.round((item.value / total) * 100),
|
||||||
|
itemStyle: {
|
||||||
|
color: getColor(item.name),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
animation: false,
|
||||||
|
tooltip: {
|
||||||
|
trigger: "item",
|
||||||
|
formatter: (params) => {
|
||||||
|
return `${params.name}<br/>数值: ${params.data.value}<br/>占比: ${params.data.percent}%`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "工单派发及完成率分析",
|
||||||
|
type: "funnel",
|
||||||
|
width: "50%",
|
||||||
|
height: "90%",
|
||||||
|
left: "10%",
|
||||||
|
top: "5%",
|
||||||
|
minSize: "20%", //底部变方
|
||||||
|
sort: "descending",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "inside",
|
||||||
|
formatter: "{c}%",
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontFamily: "MiSans-Regular",
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0, // 去掉边线
|
||||||
|
},
|
||||||
|
data: processedData.map((item) => ({
|
||||||
|
...item,
|
||||||
|
value: item.percent,
|
||||||
|
})),
|
||||||
|
emphasis: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "funnel",
|
||||||
|
width: "50%",
|
||||||
|
height: "90%",
|
||||||
|
left: "10%",
|
||||||
|
top: "5%",
|
||||||
|
minSize: "20%", // 底部变方
|
||||||
|
sort: "descending",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
formatter: (params) => {
|
||||||
|
return `${params.name}: ${
|
||||||
|
rawData.find((d) => d.name === params.name).value
|
||||||
|
}`;
|
||||||
|
},
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
align: "left",
|
||||||
|
padding: [0, 0, 0, 10],
|
||||||
|
verticalAlign: "middle", // 垂直居中
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0, //去掉边线
|
||||||
|
},
|
||||||
|
data: processedData,
|
||||||
|
emphasis: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
myChart.setOption(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
function getColor(name) {
|
||||||
|
const colors = {
|
||||||
|
应急工单录入: "#395EB0",
|
||||||
|
工单受理派发: "#5595F7",
|
||||||
|
工单处理完成: "#6BABF8",
|
||||||
|
};
|
||||||
|
return colors[name] || "#999";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.echarts-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,122 @@
|
|||||||
|
<template>
|
||||||
|
<div class="chart-container">
|
||||||
|
<div
|
||||||
|
id="pieChart"
|
||||||
|
class="pie-chart"
|
||||||
|
></div>
|
||||||
|
<div class="legend">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in chartData"
|
||||||
|
:key="index"
|
||||||
|
class="legend-item"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="color-box"
|
||||||
|
:style="{ backgroundColor: colors[index] }"
|
||||||
|
></span>
|
||||||
|
<span class="label">{{ item.name }}</span>
|
||||||
|
<span class="value">{{ item.percent }}%</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted } from "vue";
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
|
||||||
|
const chartData = [
|
||||||
|
{ name: "断枝", value: 35 },
|
||||||
|
{ name: "倾斜", value: 40 },
|
||||||
|
{ name: "倒伏", value: 25 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const total = chartData.reduce((sum, item) => sum + item.value, 0);
|
||||||
|
chartData.forEach((item) => {
|
||||||
|
item.percent = ((item.value / total) * 100).toFixed(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
const colors = ["#29CC82", "#FAC300", "#5765FF"];
|
||||||
|
|
||||||
|
const initChart = () => {
|
||||||
|
const chartDom = document.getElementById("pieChart");
|
||||||
|
const myChart = echarts.init(chartDom);
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
tooltip: { trigger: 'item' },
|
||||||
|
color: colors,
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: "pie",
|
||||||
|
radius: ["50%", "70%"],
|
||||||
|
avoidLabelOverlap: false,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
data: chartData.map((item) => ({
|
||||||
|
value: item.value,
|
||||||
|
name: item.name,
|
||||||
|
})),
|
||||||
|
itemStyle: (params) => {
|
||||||
|
const color = colors[params.dataIndex];
|
||||||
|
return {
|
||||||
|
color: color,
|
||||||
|
borderColor: color,
|
||||||
|
borderWidth: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
myChart.setOption(option);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
initChart();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.chart-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pie-chart {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-box {
|
||||||
|
display: inline-block;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
margin-right: 8px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
margin-right: 10px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #fff;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 台风 -->
|
||||||
|
<cellRow>
|
||||||
|
<div class="row-main">
|
||||||
|
<img
|
||||||
|
src="@/assets/images/taifeng.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<div class="row-main-right">
|
||||||
|
<div class="right-top">
|
||||||
|
<span>台风黄色预警</span>
|
||||||
|
<span>5月18日</span>
|
||||||
|
</div>
|
||||||
|
<div class="right-bottom">
|
||||||
|
<span>东北风</span>
|
||||||
|
<span>风力7~8级</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</cellRow>
|
||||||
|
<!-- 暴雨 -->
|
||||||
|
<cellRow>
|
||||||
|
<div class="row-main">
|
||||||
|
<img
|
||||||
|
src="@/assets/images/baoyu.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<div class="row-main-right">
|
||||||
|
<div class="right-top">
|
||||||
|
<span>暴雨黄色预警</span>
|
||||||
|
<span>5月19日</span>
|
||||||
|
</div>
|
||||||
|
<div class="right-bottom">
|
||||||
|
<span>大暴雨</span>
|
||||||
|
<span>小时雨量大于50毫米</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</cellRow>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import cellRow from "./cellRow.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.row-main {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 5px;
|
||||||
|
align-items: center;
|
||||||
|
height: 75px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
img {
|
||||||
|
width: 75px;
|
||||||
|
height: 65px;
|
||||||
|
}
|
||||||
|
.row-main-right {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
font-family: "MiSans-Regular";
|
||||||
|
.right-top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
color: #ffffff;
|
||||||
|
span:nth-child(1) {
|
||||||
|
color: #f4ec19;
|
||||||
|
font-family: "MiSans-Medium";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right-bottom{
|
||||||
|
display: flex;
|
||||||
|
color: #ffffff;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in new issue