修改回访统计和预警统计
This commit is contained in:
parent
4be453f04a
commit
a70671c16d
@ -54,4 +54,8 @@ export const RecordApi = {
|
||||
getRecordStatistics: async (params: any) => {
|
||||
return await request.get({ url: `/system/record/statistics`, params })
|
||||
},
|
||||
//获取会员回访记录统计
|
||||
getStatistics: async (orgid: number,startDate:string,endDate:string) => {
|
||||
return await request.get({ url: `/system/record/getstatistics?orgid=` + orgid + `&startDate=` + startDate + `&endDate=` + endDate })
|
||||
},
|
||||
}
|
||||
|
||||
@ -27,13 +27,22 @@
|
||||
</el-card>
|
||||
<!-- 统计图表卡片,下方主内容区域 -->
|
||||
<el-card class="member-stat-card stat-card" shadow="hover">
|
||||
<div id="main" style="width:100%;height:580px;"></div>
|
||||
<!-- 无数据提示 -->
|
||||
<div v-if="chartData.length === 0" class="no-data-container">
|
||||
<el-empty
|
||||
description="当前时间段无数据"
|
||||
:image-size="120"
|
||||
class="no-data-empty"
|
||||
/>
|
||||
</div>
|
||||
<!-- 图表容器 -->
|
||||
<div v-else id="main" style="width:100%;height:580px;"></div>
|
||||
</el-card>
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import { ref, onMounted, watch, nextTick } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import ShortcutDateRangePicker from '@/components/ShortcutDateRangePicker/index.vue'
|
||||
import ContentWrap from '@/components/ContentWrap/src/ContentWrap.vue'
|
||||
@ -49,12 +58,29 @@ const dateRange = ref<[string, string]>([
|
||||
dayjs().endOf('day').format('YYYY-MM-DD 23:59:59')
|
||||
])
|
||||
|
||||
// 图表实例
|
||||
let myChart: echarts.ECharts | null = null
|
||||
|
||||
// 渲染echarts图表
|
||||
const renderChart = () => {
|
||||
// 如果没有数据,销毁图表实例
|
||||
if (chartData.value.length === 0) {
|
||||
if (myChart) {
|
||||
myChart.dispose()
|
||||
myChart = null
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const dom = document.getElementById('main')
|
||||
if (!dom) return
|
||||
const myChart = echarts.init(dom)
|
||||
|
||||
// 如果图表实例已存在,先销毁
|
||||
if (myChart) {
|
||||
myChart.dispose()
|
||||
}
|
||||
|
||||
myChart = echarts.init(dom)
|
||||
myChart.setOption({
|
||||
tooltip: { trigger: 'axis' },
|
||||
grid: { left: 40, right: 20, top: 40, bottom: 40 },
|
||||
@ -106,15 +132,17 @@ const onDateChange = (range: [string, string]) => {
|
||||
|
||||
// 监听数据和图表类型变化,自动渲染图表
|
||||
watch([chartData, chartType], () => {
|
||||
renderChart()
|
||||
nextTick(() => {
|
||||
renderChart()
|
||||
})
|
||||
})
|
||||
|
||||
// 默认一周,首次渲染
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
setTimeout(() => {
|
||||
nextTick(() => {
|
||||
renderChart()
|
||||
}, 300)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -145,4 +173,23 @@ onMounted(() => {
|
||||
.stat-card {
|
||||
min-height: 320px; /* 统计图卡片主内容区高度,可根据实际需求调整 */
|
||||
}
|
||||
|
||||
/* 无数据提示样式 */
|
||||
.no-data-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 580px; /* 与图表容器保持一致的高度 */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.no-data-empty {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-data-empty :deep(.el-empty__description) {
|
||||
color: #909399;
|
||||
font-size: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
@change="onDateChange"
|
||||
style="width: 300px;"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="图表类型">
|
||||
@ -22,6 +23,9 @@
|
||||
<el-button :type="chartType === 'bar' ? 'primary' : 'default'" @click="chartType = 'bar'">
|
||||
柱状图
|
||||
</el-button>
|
||||
<el-button :type="chartType === 'stack' ? 'primary' : 'default'" @click="chartType = 'stack'">
|
||||
堆叠图
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
@ -43,10 +47,18 @@ import { RecordApi } from '@/api/record'
|
||||
import dayjs from 'dayjs'
|
||||
import { getUserProfile } from '@/api/system/user/profile'
|
||||
|
||||
// 图表类型:'line' 折线图,'bar' 柱状图
|
||||
const chartType = ref<'line' | 'bar'>('line')
|
||||
// 预警统计数据
|
||||
const chartData = ref<{ date: string; totalCount: number; readCount: number; unreadCount: number }[]>([])
|
||||
// 图表类型:'line' 折线图,'bar' 柱状图,'stack' 堆叠图
|
||||
const chartType = ref<'line' | 'bar' | 'stack'>('bar')
|
||||
// 回访统计数据
|
||||
const chartData = ref<{
|
||||
date: string;
|
||||
totalCount: number;
|
||||
visitedCount: number;
|
||||
unvisitedCount: number;
|
||||
satisfiedCount: number;
|
||||
normalCount: number;
|
||||
unsatisfiedCount: number;
|
||||
}[]>([])
|
||||
// 时间范围,默认一周
|
||||
const dateRange = ref<[string, string]>([
|
||||
dayjs().subtract(6, 'day').startOf('day').format('YYYY-MM-DD 00:00:00'),
|
||||
@ -58,17 +70,55 @@ const renderChart = () => {
|
||||
const dom = document.getElementById('main')
|
||||
if (!dom) return
|
||||
const myChart = echarts.init(dom)
|
||||
myChart.setOption({
|
||||
|
||||
// 当没有数据时显示提示
|
||||
if (!chartData.value || chartData.value.length === 0) {
|
||||
myChart.setOption(
|
||||
{
|
||||
title: {
|
||||
text: '当前时间段无数据',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
textStyle: { color: '#909399', fontSize: 16 }
|
||||
},
|
||||
// 清空系列的和轴线,避免旧内容残留
|
||||
xAxis: { show: false },
|
||||
yAxis: { show: false },
|
||||
series: []
|
||||
},
|
||||
true
|
||||
) // true表示不跟之前的option合并
|
||||
return
|
||||
}
|
||||
|
||||
const option: any = {
|
||||
title: {
|
||||
text: '电话回访统计',
|
||||
left: 'center',
|
||||
top: 0,
|
||||
textStyle: {
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function(params: any) {
|
||||
const data = params[0]
|
||||
const date = data.name
|
||||
const value = data.value
|
||||
return `${date}<br/>预警信息数量: ${value}`
|
||||
const date = params[0].name
|
||||
let result = `${date}<br/>`
|
||||
|
||||
params.forEach((param: any) => {
|
||||
result += `${param.seriesName}: ${param.value}<br/>`
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
},
|
||||
grid: { left: 40, right: 20, top: 60, bottom: 40 },
|
||||
legend: {
|
||||
data: ['总回访数', '已回访', '未回访', '满意', '一般', '不满意'],
|
||||
top: 30
|
||||
},
|
||||
grid: { left: 40, right: 20, top: 80, bottom: 40 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: chartData.value.map(item => item.date),
|
||||
@ -81,15 +131,59 @@ const renderChart = () => {
|
||||
axisLine: { lineStyle: { color: '#dcdfe6' } },
|
||||
axisLabel: { color: '#666', fontSize: 14 }
|
||||
},
|
||||
series: [
|
||||
series: []
|
||||
}
|
||||
|
||||
if (chartType.value === 'stack') {
|
||||
// 堆叠图:显示回访状态和满意度
|
||||
option.series = [
|
||||
{
|
||||
name: '预警信息数量',
|
||||
name: '已回访',
|
||||
type: 'bar',
|
||||
stack: 'status',
|
||||
data: chartData.value.map(item => item.visitedCount),
|
||||
itemStyle: { color: '#67C23A' }
|
||||
},
|
||||
{
|
||||
name: '未回访',
|
||||
type: 'bar',
|
||||
stack: 'status',
|
||||
data: chartData.value.map(item => item.unvisitedCount),
|
||||
itemStyle: { color: '#909399' }
|
||||
},
|
||||
{
|
||||
name: '满意',
|
||||
type: 'bar',
|
||||
stack: 'result',
|
||||
data: chartData.value.map(item => item.satisfiedCount),
|
||||
itemStyle: { color: '#409EFF' }
|
||||
},
|
||||
{
|
||||
name: '一般',
|
||||
type: 'bar',
|
||||
stack: 'result',
|
||||
data: chartData.value.map(item => item.normalCount),
|
||||
itemStyle: { color: '#E6A23C' }
|
||||
},
|
||||
{
|
||||
name: '不满意',
|
||||
type: 'bar',
|
||||
stack: 'result',
|
||||
data: chartData.value.map(item => item.unsatisfiedCount),
|
||||
itemStyle: { color: '#F56C6C' }
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 普通柱状图或折线图
|
||||
option.series = [
|
||||
{
|
||||
name: '总回访数',
|
||||
type: chartType.value,
|
||||
data: chartData.value.map(item => item.totalCount),
|
||||
smooth: chartType.value === 'line',
|
||||
barWidth: chartType.value === 'bar' ? '40%' : undefined,
|
||||
itemStyle: {
|
||||
color: chartType.value === 'line' ? '#409EFF' : '#67C23A',
|
||||
color: '#409EFF',
|
||||
borderRadius: chartType.value === 'bar' ? [6, 6, 0, 0] : 0
|
||||
},
|
||||
lineStyle: {
|
||||
@ -97,22 +191,83 @@ const renderChart = () => {
|
||||
color: '#409EFF'
|
||||
},
|
||||
areaStyle: chartType.value === 'line' ? { color: 'rgba(64,158,255,0.15)' } : undefined
|
||||
},
|
||||
{
|
||||
name: '已回访',
|
||||
type: chartType.value,
|
||||
data: chartData.value.map(item => item.visitedCount),
|
||||
smooth: chartType.value === 'line',
|
||||
barWidth: chartType.value === 'bar' ? '40%' : undefined,
|
||||
itemStyle: {
|
||||
color: '#67C23A',
|
||||
borderRadius: chartType.value === 'bar' ? [6, 6, 0, 0] : 0
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: '#67C23A'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '未回访',
|
||||
type: chartType.value,
|
||||
data: chartData.value.map(item => item.unvisitedCount),
|
||||
smooth: chartType.value === 'line',
|
||||
barWidth: chartType.value === 'bar' ? '40%' : undefined,
|
||||
itemStyle: {
|
||||
color: '#909399',
|
||||
borderRadius: chartType.value === 'bar' ? [6, 6, 0, 0] : 0
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: '#909399'
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
myChart.setOption(option)
|
||||
}
|
||||
|
||||
// 渲染饼图
|
||||
const renderPieChart = () => {
|
||||
const dom = document.getElementById('pieChart')
|
||||
if (!dom) return
|
||||
|
||||
// 计算已读数量、未读数量
|
||||
const readCount = chartData.value.reduce((sum, item) => sum + item.readCount, 0)
|
||||
const unreadCount = chartData.value.reduce((sum, item) => sum + item.unreadCount, 0)
|
||||
|
||||
const pieChart = echarts.init(dom)
|
||||
|
||||
// 当没有数据时显示提示
|
||||
if (!chartData.value || chartData.value.length === 0) {
|
||||
pieChart.setOption(
|
||||
{
|
||||
title: {
|
||||
text: '当前时间段无数据',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
textStyle: { color: '#909399', fontSize: 16 }
|
||||
},
|
||||
series: []
|
||||
},
|
||||
true
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// 计算总数
|
||||
const totalVisited = chartData.value.reduce((sum, item) => sum + item.visitedCount, 0)
|
||||
const totalUnvisited = chartData.value.reduce((sum, item) => sum + item.unvisitedCount, 0)
|
||||
const totalSatisfied = chartData.value.reduce((sum, item) => sum + item.satisfiedCount, 0)
|
||||
const totalNormal = chartData.value.reduce((sum, item) => sum + item.normalCount, 0)
|
||||
const totalUnsatisfied = chartData.value.reduce((sum, item) => sum + item.unsatisfiedCount, 0)
|
||||
|
||||
pieChart.setOption({
|
||||
title: {
|
||||
text: '回访状态分布',
|
||||
left: 'center',
|
||||
top: 0,
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||
@ -124,10 +279,10 @@ const renderPieChart = () => {
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '预警信息',
|
||||
name: '回访状态',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
center: ['60%', '60%'],
|
||||
center: ['65%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
@ -144,8 +299,8 @@ const renderPieChart = () => {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: readCount, name: '已读', itemStyle: { color: '#67C23A' } },
|
||||
{ value: unreadCount, name: '未读', itemStyle: { color: '#E6A23C' } }
|
||||
{ value: totalVisited, name: '已回访', itemStyle: { color: '#67C23A' } },
|
||||
{ value: totalUnvisited, name: '未回访', itemStyle: { color: '#909399' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -158,30 +313,46 @@ const params = ref({
|
||||
orgid: 0,
|
||||
})
|
||||
|
||||
// 获取预警统计数据
|
||||
// 获取回访统计数据
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const userProfile = await getUserProfile()
|
||||
params.value.orgid = userProfile.dept.id
|
||||
const res = await RecordApi.getRecordStatistics(params.value)
|
||||
|
||||
// 调用回访统计的API
|
||||
const res = await RecordApi.getStatistics(
|
||||
params.value.orgid,
|
||||
params.value.startTime,
|
||||
params.value.endTime
|
||||
)
|
||||
console.log(res)
|
||||
// 处理返回的数据格式
|
||||
if (res && res.dailyData && Array.isArray(res.dailyData)) {
|
||||
chartData.value = res.dailyData.map((item: any) => {
|
||||
// 处理date字段,如果是数组格式 [year, month, day],转换为日期字符串
|
||||
let dateStr = item.date
|
||||
if (Array.isArray(item.date) && item.date.length >= 3) {
|
||||
if (res && Array.isArray(res)) {
|
||||
chartData.value = res.map((item: any) => {
|
||||
// 处理date字段
|
||||
let dateStr = ''
|
||||
if (typeof item.date === 'number') {
|
||||
// 时间戳格式
|
||||
dateStr = dayjs(item.date).format('YYYY-MM-DD')
|
||||
} else if (Array.isArray(item.date) && item.date.length >= 3) {
|
||||
// 数组格式 [year, month, day]
|
||||
const [year, month, day] = item.date
|
||||
// 月份需要减1,因为JavaScript的Date构造函数中月份是从0开始的
|
||||
const date = new Date(year, month - 1, day)
|
||||
dateStr = dayjs(date).format('YYYY-MM-DD')
|
||||
} else {
|
||||
// 默认是字符串格式
|
||||
dateStr = item.date
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
date: dateStr,
|
||||
totalCount: item.totalCount || 0,
|
||||
readCount: item.readCount || 0,
|
||||
unreadCount: item.unreadCount || 0
|
||||
visitedCount: item.visitedCount || 0,
|
||||
unvisitedCount: item.unvisitedCount || 0,
|
||||
satisfiedCount: item.satisfiedCount || 0,
|
||||
normalCount: item.normalCount || 0,
|
||||
unsatisfiedCount: item.unsatisfiedCount || 0
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -190,15 +361,23 @@ const fetchData = async () => {
|
||||
|
||||
console.log('处理后的图表数据:', chartData.value)
|
||||
} catch (error) {
|
||||
console.error('获取预警统计数据失败:', error)
|
||||
console.error('获取回访统计数据失败:', error)
|
||||
chartData.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 时间范围变化时
|
||||
const onDateChange = (range: [string, string]) => {
|
||||
dateRange.value = range
|
||||
fetchData()
|
||||
const onDateChange = (range: [string, string] | null) => {
|
||||
// 当range不为空时,更新参数并获取数据
|
||||
if (range && range.length === 2) {
|
||||
dateRange.value = range
|
||||
params.value.startTime = range[0]
|
||||
params.value.endTime = range[1]
|
||||
fetchData()
|
||||
} else {
|
||||
// 当日期被清空时,清空图表数据
|
||||
chartData.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 监听数据和图表类型变化,自动渲染图表
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
@change="onDateChange"
|
||||
style="width: 300px;"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="图表类型">
|
||||
@ -22,6 +23,9 @@
|
||||
<el-button :type="chartType === 'bar' ? 'primary' : 'default'" @click="chartType = 'bar'">
|
||||
柱状图
|
||||
</el-button>
|
||||
<el-button :type="chartType === 'stack' ? 'primary' : 'default'" @click="chartType = 'stack'">
|
||||
堆叠图
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
@ -43,10 +47,18 @@ import { AlertMessageApi } from '@/api/alertmessage'
|
||||
import dayjs from 'dayjs'
|
||||
import { getUserProfile } from '@/api/system/user/profile'
|
||||
|
||||
// 图表类型:'line' 折线图,'bar' 柱状图
|
||||
const chartType = ref<'line' | 'bar'>('line')
|
||||
// 图表类型:'line' 折线图,'bar' 柱状图,'stack' 堆叠图
|
||||
const chartType = ref<'line' | 'bar' | 'stack'>('bar')
|
||||
// 预警统计数据
|
||||
const chartData = ref<{ date: string; totalCount: number; readCount: number; unreadCount: number }[]>([])
|
||||
const chartData = ref<{
|
||||
date: string;
|
||||
sosCount: number;
|
||||
analysisCount: number;
|
||||
sosReadCount: number;
|
||||
analysisReadCount: number;
|
||||
sosUnreadCount: number;
|
||||
analysisUnreadCount: number;
|
||||
}[]>([])
|
||||
// 时间范围,默认一周
|
||||
const dateRange = ref<[string, string]>([
|
||||
dayjs().subtract(6, 'day').startOf('day').format('YYYY-MM-DD 00:00:00'),
|
||||
@ -58,17 +70,55 @@ const renderChart = () => {
|
||||
const dom = document.getElementById('main')
|
||||
if (!dom) return
|
||||
const myChart = echarts.init(dom)
|
||||
myChart.setOption({
|
||||
|
||||
// 当没有数据时显示提示
|
||||
if (!chartData.value || chartData.value.length === 0) {
|
||||
myChart.setOption(
|
||||
{
|
||||
title: {
|
||||
text: '当前时间段无数据',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
textStyle: { color: '#909399', fontSize: 16 }
|
||||
},
|
||||
// 清空系列的和轴线,避免旧内容残留
|
||||
xAxis: { show: false },
|
||||
yAxis: { show: false },
|
||||
series: []
|
||||
},
|
||||
true
|
||||
) // true表示不跟之前的option合并
|
||||
return
|
||||
}
|
||||
|
||||
const option: any = {
|
||||
title: {
|
||||
text: '预警信息统计',
|
||||
left: 'center',
|
||||
top: 0,
|
||||
textStyle: {
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function(params: any) {
|
||||
const data = params[0]
|
||||
const date = data.name
|
||||
const value = data.value
|
||||
return `${date}<br/>预警信息数量: ${value}`
|
||||
const date = params[0].name
|
||||
let result = `${date}<br/>`
|
||||
|
||||
params.forEach((param: any) => {
|
||||
result += `${param.seriesName}: ${param.value}<br/>`
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
},
|
||||
grid: { left: 40, right: 20, top: 60, bottom: 40 },
|
||||
legend: {
|
||||
data: ['总预警数', 'SOS预警', '分析预警', '已读', '未读'],
|
||||
top: 30
|
||||
},
|
||||
grid: { left: 40, right: 20, top: 80, bottom: 40 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: chartData.value.map(item => item.date),
|
||||
@ -81,15 +131,52 @@ const renderChart = () => {
|
||||
axisLine: { lineStyle: { color: '#dcdfe6' } },
|
||||
axisLabel: { color: '#666', fontSize: 14 }
|
||||
},
|
||||
series: [
|
||||
series: []
|
||||
}
|
||||
|
||||
if (chartType.value === 'stack') {
|
||||
// 堆叠图:显示预警类型和状态
|
||||
option.series = [
|
||||
{
|
||||
name: '预警信息数量',
|
||||
name: 'SOS预警',
|
||||
type: 'bar',
|
||||
stack: 'type',
|
||||
data: chartData.value.map(item => item.sosCount),
|
||||
itemStyle: { color: '#F56C6C' }
|
||||
},
|
||||
{
|
||||
name: '分析预警',
|
||||
type: 'bar',
|
||||
stack: 'type',
|
||||
data: chartData.value.map(item => item.analysisCount),
|
||||
itemStyle: { color: '#E6A23C' }
|
||||
},
|
||||
{
|
||||
name: '已读',
|
||||
type: 'bar',
|
||||
stack: 'status',
|
||||
data: chartData.value.map(item => item.sosReadCount + item.analysisReadCount),
|
||||
itemStyle: { color: '#67C23A' }
|
||||
},
|
||||
{
|
||||
name: '未读',
|
||||
type: 'bar',
|
||||
stack: 'status',
|
||||
data: chartData.value.map(item => item.sosUnreadCount + item.analysisUnreadCount),
|
||||
itemStyle: { color: '#909399' }
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 普通柱状图或折线图
|
||||
option.series = [
|
||||
{
|
||||
name: '总预警数',
|
||||
type: chartType.value,
|
||||
data: chartData.value.map(item => item.totalCount),
|
||||
data: chartData.value.map(item => item.sosCount + item.analysisCount),
|
||||
smooth: chartType.value === 'line',
|
||||
barWidth: chartType.value === 'bar' ? '40%' : undefined,
|
||||
itemStyle: {
|
||||
color: chartType.value === 'line' ? '#409EFF' : '#67C23A',
|
||||
color: '#409EFF',
|
||||
borderRadius: chartType.value === 'bar' ? [6, 6, 0, 0] : 0
|
||||
},
|
||||
lineStyle: {
|
||||
@ -97,22 +184,112 @@ const renderChart = () => {
|
||||
color: '#409EFF'
|
||||
},
|
||||
areaStyle: chartType.value === 'line' ? { color: 'rgba(64,158,255,0.15)' } : undefined
|
||||
},
|
||||
{
|
||||
name: 'SOS预警',
|
||||
type: chartType.value,
|
||||
data: chartData.value.map(item => item.sosCount),
|
||||
smooth: chartType.value === 'line',
|
||||
barWidth: chartType.value === 'bar' ? '40%' : undefined,
|
||||
itemStyle: {
|
||||
color: '#F56C6C',
|
||||
borderRadius: chartType.value === 'bar' ? [6, 6, 0, 0] : 0
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: '#F56C6C'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '分析预警',
|
||||
type: chartType.value,
|
||||
data: chartData.value.map(item => item.analysisCount),
|
||||
smooth: chartType.value === 'line',
|
||||
barWidth: chartType.value === 'bar' ? '40%' : undefined,
|
||||
itemStyle: {
|
||||
color: '#E6A23C',
|
||||
borderRadius: chartType.value === 'bar' ? [6, 6, 0, 0] : 0
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: '#E6A23C'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '已读',
|
||||
type: chartType.value,
|
||||
data: chartData.value.map(item => item.sosReadCount + item.analysisReadCount),
|
||||
smooth: chartType.value === 'line',
|
||||
barWidth: chartType.value === 'bar' ? '40%' : undefined,
|
||||
itemStyle: {
|
||||
color: '#67C23A',
|
||||
borderRadius: chartType.value === 'bar' ? [6, 6, 0, 0] : 0
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: '#67C23A'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '未读',
|
||||
type: chartType.value,
|
||||
data: chartData.value.map(item => item.sosUnreadCount + item.analysisUnreadCount),
|
||||
smooth: chartType.value === 'line',
|
||||
barWidth: chartType.value === 'bar' ? '40%' : undefined,
|
||||
itemStyle: {
|
||||
color: '#909399',
|
||||
borderRadius: chartType.value === 'bar' ? [6, 6, 0, 0] : 0
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: '#909399'
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
myChart.setOption(option)
|
||||
}
|
||||
|
||||
// 渲染饼图
|
||||
const renderPieChart = () => {
|
||||
const dom = document.getElementById('pieChart')
|
||||
if (!dom) return
|
||||
|
||||
// 计算已读数量、未读数量
|
||||
const readCount = chartData.value.reduce((sum, item) => sum + item.readCount, 0)
|
||||
const unreadCount = chartData.value.reduce((sum, item) => sum + item.unreadCount, 0)
|
||||
|
||||
const pieChart = echarts.init(dom)
|
||||
|
||||
// 当没有数据时显示提示
|
||||
if (!chartData.value || chartData.value.length === 0) {
|
||||
pieChart.setOption(
|
||||
{
|
||||
title: {
|
||||
text: '当前时间段无数据',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
textStyle: { color: '#909399', fontSize: 16 }
|
||||
},
|
||||
series: []
|
||||
},
|
||||
true
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// 计算总数
|
||||
const totalSos = chartData.value.reduce((sum, item) => sum + item.sosCount, 0)
|
||||
const totalAnalysis = chartData.value.reduce((sum, item) => sum + item.analysisCount, 0)
|
||||
const totalRead = chartData.value.reduce((sum, item) => sum + item.sosReadCount + item.analysisReadCount, 0)
|
||||
const totalUnread = chartData.value.reduce((sum, item) => sum + item.sosUnreadCount + item.analysisUnreadCount, 0)
|
||||
|
||||
pieChart.setOption({
|
||||
title: {
|
||||
text: '预警状态分布',
|
||||
left: 'center',
|
||||
top: 0,
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||
@ -124,10 +301,10 @@ const renderPieChart = () => {
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '预警信息',
|
||||
name: '预警状态',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
center: ['60%', '60%'],
|
||||
center: ['65%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
@ -144,8 +321,8 @@ const renderPieChart = () => {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: readCount, name: '已读', itemStyle: { color: '#67C23A' } },
|
||||
{ value: unreadCount, name: '未读', itemStyle: { color: '#E6A23C' } }
|
||||
{ value: totalRead, name: '已读', itemStyle: { color: '#67C23A' } },
|
||||
{ value: totalUnread, name: '未读', itemStyle: { color: '#909399' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -160,10 +337,12 @@ const params = ref({
|
||||
|
||||
// 获取预警统计数据
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const userProfile = await getUserProfile()
|
||||
params.value.orgid = userProfile.dept.id
|
||||
try {
|
||||
|
||||
const res = await AlertMessageApi.getAlertMessageStatistics(params.value)
|
||||
console.log(res)
|
||||
// 处理返回的数据格式
|
||||
if (res && res.dailyData && Array.isArray(res.dailyData)) {
|
||||
chartData.value = res.dailyData.map((item: any) => {
|
||||
@ -178,14 +357,19 @@ const fetchData = async () => {
|
||||
|
||||
return {
|
||||
date: dateStr,
|
||||
totalCount: item.totalCount || 0,
|
||||
readCount: item.readCount || 0,
|
||||
unreadCount: item.unreadCount || 0
|
||||
sosCount: item.sosCount || 0,
|
||||
analysisCount: item.analysisCount || 0,
|
||||
sosReadCount: item.sosReadCount || 0,
|
||||
analysisReadCount: item.analysisReadCount || 0,
|
||||
sosUnreadCount: item.sosUnreadCount || 0,
|
||||
analysisUnreadCount: item.analysisUnreadCount || 0
|
||||
}
|
||||
})
|
||||
} else {
|
||||
chartData.value = []
|
||||
}
|
||||
|
||||
console.log('处理后的图表数据:', chartData.value)
|
||||
} catch (error) {
|
||||
console.error('获取预警统计数据失败:', error)
|
||||
chartData.value = []
|
||||
@ -193,9 +377,17 @@ const fetchData = async () => {
|
||||
}
|
||||
|
||||
// 时间范围变化时
|
||||
const onDateChange = (range: [string, string]) => {
|
||||
dateRange.value = range
|
||||
fetchData()
|
||||
const onDateChange = (range: [string, string] | null) => {
|
||||
// 当range不为空时,更新参数并获取数据
|
||||
if (range && range.length === 2) {
|
||||
dateRange.value = range
|
||||
params.value.startTime = range[0]
|
||||
params.value.endTime = range[1]
|
||||
fetchData()
|
||||
} else {
|
||||
// 当日期被清空时,清空图表数据
|
||||
chartData.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 监听数据和图表类型变化,自动渲染图表
|
||||
|
||||
Loading…
Reference in New Issue
Block a user