|
@@ -1,88 +1,63 @@
|
|
|
<template>
|
|
|
<div class="early-statistics-container layout-padding">
|
|
|
<div class="layout-padding-auto layout-padding-view pd20">
|
|
|
- <el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent :disabled="state.loading">
|
|
|
- <el-form-item label="推送报告名称" prop="EarlyWarningPushName">
|
|
|
- <el-input
|
|
|
- v-model="state.queryParams.EarlyWarningPushName"
|
|
|
- placeholder="请填写推送报告名称"
|
|
|
- clearable
|
|
|
- @keyup.enter="handleQuery"
|
|
|
- class="keyword-input"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="推送状态" prop="EarlyPushStatus">
|
|
|
- <el-select v-model="state.queryParams.EarlyPushStatus" placeholder="请选择推送状态" @change="handleQuery">
|
|
|
- <el-option v-for="item in earlyWarningLevel" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item>
|
|
|
- <el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
|
|
|
- <el-button @click="resetQuery(ruleFormRef)" class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- <vxe-toolbar
|
|
|
- ref="toolbarRef"
|
|
|
- :loading="state.loading"
|
|
|
- custom
|
|
|
- :refresh="{
|
|
|
- queryMethod: handleQuery,
|
|
|
- }"
|
|
|
- >
|
|
|
- <template #buttons>
|
|
|
- <el-button type="primary" @click="onAdd" v-auth="'early:push:add'"> <SvgIcon name="ele-Plus" class="mr5" />新增推送 </el-button>
|
|
|
- </template>
|
|
|
- </vxe-toolbar>
|
|
|
+ <el-tabs v-model="type" @tab-change="changeTab">
|
|
|
+ <el-tab-pane name="0" label="预警统计图表" :disabled="state.loading"></el-tab-pane>
|
|
|
+ <el-tab-pane name="1" label="预警统计列表" :disabled="state.loading"></el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ <div class="flex-center-between">
|
|
|
+ <div></div>
|
|
|
+ <el-date-picker v-model="monthValue" type="month" placeholder="请选择月份" :clearable="false" @change="selectMonth" />
|
|
|
+ </div>
|
|
|
<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
|
|
|
- <vxe-table
|
|
|
- border
|
|
|
- :loading="state.loading"
|
|
|
- :data="state.tableData"
|
|
|
- :column-config="{ resizable: true, useKey: true }"
|
|
|
- :row-config="{ isCurrent: true, isHover: true, useKey: true, height: 30 }"
|
|
|
- ref="tableRef"
|
|
|
- height="auto"
|
|
|
- auto-resize
|
|
|
- show-overflow
|
|
|
- :scrollY="{ enabled: true, gt: 100 }"
|
|
|
- id="earlyStatistics"
|
|
|
- :custom-config="{ storage: true }"
|
|
|
- :sort-config="{ remote: true }"
|
|
|
- @sort-change="sortChange"
|
|
|
- >
|
|
|
- <vxe-column field="earlyWarningSetting.earlyWarningName" title="预警名称"></vxe-column>
|
|
|
- <vxe-column field="earlyWarningSetting.earlyWarningLevelName" title="预警级别"></vxe-column>
|
|
|
- <vxe-column field="earlyWarningSetting.earlyWarningTypeName" title="时间/时间段"></vxe-column>
|
|
|
- <vxe-column field="earlyWarningSetting.earlyWarningTypeName" title="预警类型"></vxe-column>
|
|
|
- <vxe-column field="earlyWarningSetting.frequencyText" title="频率"></vxe-column>
|
|
|
- <vxe-column field="fullAddress" title="预警地点"></vxe-column>
|
|
|
- <vxe-column field="isEnable" title="关联工单">
|
|
|
- <template #default="{ row }">
|
|
|
- <el-button type="primary" link @click="onDetail(row)">{{ row.earlyWarningOrderDetails.length }}</el-button>
|
|
|
- </template>
|
|
|
- </vxe-column>
|
|
|
- <vxe-column field="lastEarlyTime" title="最新预警时间" width="160">
|
|
|
- <template #default="{ row }">
|
|
|
- {{ formatDate(row.lastEarlyTime, 'YYYY-mm-dd HH:MM:SS') }}
|
|
|
- </template>
|
|
|
- </vxe-column>
|
|
|
- <vxe-column title="操作" fixed="right" width="90" align="center">
|
|
|
- <template #default="{ row }">
|
|
|
- <el-button link type="primary" @click="onDetail(row)" title="查看详情"> 详情 </el-button>
|
|
|
- </template>
|
|
|
- </vxe-column>
|
|
|
- </vxe-table>
|
|
|
+ <el-row :gutter="20" v-show="type === '0'" class="w100 h100">
|
|
|
+ <el-col :span="12">
|
|
|
+ <v-chart class="chart" :option="option" :loading="state.loading" autoresize />
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" class="w100 h100">
|
|
|
+ <div style="height: 50%" class="w100">
|
|
|
+ <v-chart class="chart" :option="option1" :loading="state.loading" autoresize />
|
|
|
+ </div>
|
|
|
+ <div style="height: 50%" class="w100">
|
|
|
+ <v-chart class="chart" :option="option2" :loading="state.loading" autoresize />
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <vxe-grid v-bind="gridOptions" v-show="type === '1'">
|
|
|
+ <template #form>
|
|
|
+ <el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent :disabled="state.loading">
|
|
|
+ <el-form-item label="预警名称" prop="EarlyWarningPushName">
|
|
|
+ <el-input
|
|
|
+ v-model="state.queryParams.EarlyWarningPushName"
|
|
|
+ placeholder="请填写预警名称"
|
|
|
+ clearable
|
|
|
+ @keyup.enter="handleQuery"
|
|
|
+ class="keyword-input"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="预警类型" prop="EarlyPushStatus">
|
|
|
+ <el-select v-model="state.queryParams.EarlyPushStatus" placeholder="请选择预警类型" @change="handleQuery">
|
|
|
+ <el-option v-for="item in earlyWarningLevel" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
|
|
|
+ <el-button @click="resetQuery(ruleFormRef)" class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </template>
|
|
|
+ <template #pager>
|
|
|
+ <pagination
|
|
|
+ @pagination="queryList"
|
|
|
+ :total="state.total"
|
|
|
+ v-model:current-page="state.queryParams.PageIndex"
|
|
|
+ v-model:page-size="state.queryParams.PageSize"
|
|
|
+ :disabled="state.loading"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </vxe-grid>
|
|
|
</div>
|
|
|
- <pagination
|
|
|
- @pagination="queryList"
|
|
|
- :total="state.total"
|
|
|
- v-model:current-page="state.queryParams.PageIndex"
|
|
|
- v-model:page-size="state.queryParams.PageSize"
|
|
|
- :disabled="state.loading"
|
|
|
- />
|
|
|
</div>
|
|
|
- <!-- 新增 -->
|
|
|
- <push-add ref="pushAddRef" @updateList="queryList"/>
|
|
|
<!-- 详情 -->
|
|
|
<push-detail ref="pushDetailRef" />
|
|
|
</div>
|
|
@@ -95,13 +70,14 @@ import { formatDate } from '@/utils/formatTime';
|
|
|
import { deleteEarlySetting, getEarlySettingBaseData, getEarlySettingList } from '@/api/early/setting';
|
|
|
import { getEarlyManageList } from '@/api/early/manage';
|
|
|
import { getEarlyPushList } from '@/api/early/push';
|
|
|
+import { statisticsOrderAcceptExport } from '@/api/statistics/order';
|
|
|
+import dayjs from 'dayjs';
|
|
|
// 引入组件
|
|
|
const PushDetail = defineAsyncComponent(() => import('@/views/early/push/components/Detail.vue')); // 详情
|
|
|
-const PushAdd = defineAsyncComponent(() => import('@/views/early/push/components/Push-add.vue')); // 新增
|
|
|
const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
|
|
|
|
|
|
// 定义变量内容
|
|
|
-const state = reactive({
|
|
|
+const state = reactive<any>({
|
|
|
loading: false, // 加载状态
|
|
|
queryParams: {
|
|
|
// 查询参数
|
|
@@ -115,7 +91,215 @@ const state = reactive({
|
|
|
total: 0, // 总条数
|
|
|
tableData: [], // 表格数据
|
|
|
});
|
|
|
-const ruleFormRef = ref<any>(null); // 表单ref
|
|
|
+const monthValue = ref<Date | null>(new Date()); // 月份 默认当月
|
|
|
+const days = dayjs(monthValue.value).daysInMonth(); // 获取当月有多少天
|
|
|
+const dataX = Array.from({ length: days }, (v, k) => k + 1 + '日');
|
|
|
+const xData = ref<EmptyArrayType>(dataX); // x轴数据
|
|
|
+xData.value = dataX;
|
|
|
+const selectMonth = (val: Date) => {
|
|
|
+ // 获取当月的天数 并组成数组
|
|
|
+ const days = dayjs(val).daysInMonth(); // 获取当月有多少天
|
|
|
+ const dataX = Array.from({ length: days }, (v, k) => k + 1 + '日');
|
|
|
+ xData.value = dataX;
|
|
|
+ queryList();
|
|
|
+ console.log(dataX, '111');
|
|
|
+};
|
|
|
+console.log(monthValue.value, '111');
|
|
|
+const type = ref<string>('0');
|
|
|
+const changeTab = () => {};
|
|
|
+const requestParams = ref<EmptyObjectType>({});
|
|
|
+const gridOptions = reactive<any>({
|
|
|
+ loading: false,
|
|
|
+ border: true,
|
|
|
+ showOverflow: true,
|
|
|
+ printConfig: {},
|
|
|
+ columnConfig: {
|
|
|
+ resizable: true,
|
|
|
+ },
|
|
|
+ toolbarConfig: {
|
|
|
+ zoom: true,
|
|
|
+ custom: true,
|
|
|
+ refresh: {
|
|
|
+ queryMethod: () => {
|
|
|
+ queryList();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ tools: [{ toolRender: { name: 'exportAll' } }],
|
|
|
+ },
|
|
|
+ customConfig: {
|
|
|
+ storage: true,
|
|
|
+ },
|
|
|
+ id: 'earlyStatistics',
|
|
|
+ rowConfig: { isHover: true, height: 30, isCurrent: true, useKey: true },
|
|
|
+ height: 'auto',
|
|
|
+ columns: [
|
|
|
+ { field: 'acceptType', title: '预警名称', minWidth: 90 },
|
|
|
+ { field: 'sumCount', title: '级别' },
|
|
|
+ { field: 'completionCount', title: '预警类型' },
|
|
|
+ { field: 'completionRate', title: '频率' },
|
|
|
+ { field: 'visitCount', title: '出现次数' },
|
|
|
+ { field: 'sumCountRate', title: '占比' },
|
|
|
+ {
|
|
|
+ title: '操作',
|
|
|
+ width: 90,
|
|
|
+ align: 'center',
|
|
|
+ slots: {
|
|
|
+ default: ({ row }) => {
|
|
|
+ return (
|
|
|
+ <el-button link type="primary" onClick={() => onDetail(row)}>
|
|
|
+ 详情
|
|
|
+ </el-button>
|
|
|
+ );
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ data: [],
|
|
|
+ params: {
|
|
|
+ exportMethod: statisticsOrderAcceptExport,
|
|
|
+ exportParams: requestParams,
|
|
|
+ },
|
|
|
+});
|
|
|
+const option = ref<any>({});
|
|
|
+// 信件来源统计
|
|
|
+const setOption = (legendData: string[], seriesData: any) => {
|
|
|
+ option.value = {
|
|
|
+ title: {},
|
|
|
+ tooltip: {
|
|
|
+ // 提示框组件
|
|
|
+ trigger: 'axis', // 触发类型
|
|
|
+ axisLabel: {
|
|
|
+ fontSize: 12, // 文字像素
|
|
|
+ },
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ top: '1%',
|
|
|
+ data: legendData,
|
|
|
+ icon: 'roundRect',
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ data: xData.value, // 数据
|
|
|
+ min: 0, // 最小值
|
|
|
+ type: 'category',
|
|
|
+ boundaryGap: true, // 开始和结尾是否隔开
|
|
|
+ axisLabel: {
|
|
|
+ color: '#808080', // 文字颜色
|
|
|
+ fontSize: 12, // 文字像素
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: false, // 是否显示坐标轴轴线
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: false, // 去除刻度线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ min: 0, // 最小值
|
|
|
+ axisLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ color: '#808080', // 文字颜色
|
|
|
+ fontSize: 12, // 文字像素
|
|
|
+ },
|
|
|
+ // y轴分割线的颜色
|
|
|
+ splitLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: 'rgba(0,0,0,0.15)', // 分割线的颜色
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ series: seriesData,
|
|
|
+ };
|
|
|
+};
|
|
|
+const option1 = ref<any>({});
|
|
|
+// 信件来源统计
|
|
|
+const setOption1 = (legendData: string[], data: any) => {
|
|
|
+ option1.value = {
|
|
|
+ title: {
|
|
|
+ text: '信件来源统计',
|
|
|
+ left: 'center',
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ formatter: '{b0}: {c0} ({d}%)',
|
|
|
+ },
|
|
|
+ legend: [
|
|
|
+ {
|
|
|
+ left: 'left',
|
|
|
+ top: '40',
|
|
|
+ orient: 'vertical',
|
|
|
+ data: legendData,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'pie',
|
|
|
+ radius: ['0%', '80%'],
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ overflow: 'none',
|
|
|
+ formatter: function (params) {
|
|
|
+ if (params.name !== '') {
|
|
|
+ return `${params.name}:${params.data.value}(${params.percent}%)`;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data: data,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+};
|
|
|
+const option2 = ref<any>({});
|
|
|
+// 信件来源统计
|
|
|
+const setOption2 = (legendData: string[], data: any) => {
|
|
|
+ option2.value = {
|
|
|
+ tooltip: {},
|
|
|
+ grid: {
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%',
|
|
|
+ containLabel: true,
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '漏斗图',
|
|
|
+ type: 'funnel',
|
|
|
+ width: '55%',
|
|
|
+ minSize: '15%',
|
|
|
+ left: '25%',
|
|
|
+ gap: 0,
|
|
|
+ labelLayout: {
|
|
|
+ verticalAlign: 'top',
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'rightTop',
|
|
|
+ color: '#4B5265',
|
|
|
+ fontSize: 12,
|
|
|
+ formatter: (params) => {
|
|
|
+ return `${params.data.name}${params.data.value} ${params.data.percent}%`;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ borderColor: '#fff',
|
|
|
+ borderWidth: 0,
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ { name: '浏览1', value: 400, percent: 100 },
|
|
|
+ { name: '浏览2', value: 320, percent: 40 },
|
|
|
+ { name: '浏览3', value: 200, percent: 20 },
|
|
|
+ { name: '浏览4', value: 50, percent: 10 },
|
|
|
+ { name: '浏览5', value: 20, percent: 8 },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+};
|
|
|
+const ruleFormRef = ref<RefType>(); // 表单ref
|
|
|
/** 搜索按钮操作 */
|
|
|
const handleQuery = () => {
|
|
|
state.queryParams.PageIndex = 1;
|
|
@@ -124,11 +308,67 @@ const handleQuery = () => {
|
|
|
// 获取列表
|
|
|
const queryList = () => {
|
|
|
state.loading = true;
|
|
|
- getEarlyPushList(state.queryParams)
|
|
|
+ const params = {
|
|
|
+ ...state.queryParams,
|
|
|
+ StartTime: dayjs(monthValue.value).startOf('month').format('YYYY-MM-DD[T]HH:mm:ss'), // 获取当月的开始时间
|
|
|
+ EndTime: dayjs(monthValue.value).endOf('month').format('YYYY-MM-DD[T]HH:mm:ss'), // 获取当月的结束时间
|
|
|
+ };
|
|
|
+ getEarlyPushList(params)
|
|
|
.then((res) => {
|
|
|
state.loading = false;
|
|
|
state.tableData = res.result.items ?? [];
|
|
|
state.total = res.result.total ?? 0;
|
|
|
+ const legendData = ['一级', '二级', '三级', '四级'];
|
|
|
+ const seriesData = [
|
|
|
+ {
|
|
|
+ name: '一级',
|
|
|
+ type: 'line',
|
|
|
+ data: [5, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 5, 3, 5, 6, 7, 2, 1, 2, 4, 4, 7, 1, 2, 2, 21, 1, 2, 4, 1, 7],
|
|
|
+ areaStyle: {
|
|
|
+ // 区域填充样式
|
|
|
+ color: '#BADEFF', // 填充颜色
|
|
|
+ },
|
|
|
+ smooth: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '二级',
|
|
|
+ type: 'line',
|
|
|
+ data: [8, 23, 3, 2, 7, 2, 6, 2, 2, 8, 0, 1, 5, 3, 5, 6, 7, 4, 1, 2, 4, 2, 7, 1, 2, 2, 21, 2, 2, 4, 1], // 随机数
|
|
|
+ areaStyle: {
|
|
|
+ // 区域填充样式
|
|
|
+ color: '#C1EDCE', // 填充颜色
|
|
|
+ },
|
|
|
+ smooth: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '三级',
|
|
|
+ type: 'line',
|
|
|
+ data: [12, 1, 5, 1, 7, 3, 6, 4, 3, 8, 0, 1, 4, 3, 5, 6, 7, 5, 1, 2, 4, 1, 7, 1, 2, 2, 3, 6, 2, 4, 1], // 随机数],
|
|
|
+ areaStyle: {
|
|
|
+ // 区域填充样式
|
|
|
+ color: '#FBECB8', // 填充颜色
|
|
|
+ },
|
|
|
+ smooth: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '四级',
|
|
|
+ type: 'line',
|
|
|
+ data: [5, 23, 3, 4, 4, 5, 6, 4, 2, 8, 0, 1, 2, 3, 5, 6, 7, 1, 1, 2, 4, 4, 7, 1, 2, 2, 21, 4, 2, 4, 3], // 随机数
|
|
|
+ areaStyle: {
|
|
|
+ // 区域填充样式
|
|
|
+ color: '#BDC2D5', // 填充颜色
|
|
|
+ },
|
|
|
+ smooth: true,
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ setOption(legendData, seriesData);
|
|
|
+ setOption1(legendData, [
|
|
|
+ { value: 335, name: '一级' },
|
|
|
+ { value: 310, name: '二级' },
|
|
|
+ { value: 234, name: '三级' },
|
|
|
+ { value: 135, name: '四级' },
|
|
|
+ ]);
|
|
|
+ setOption2();
|
|
|
})
|
|
|
.finally(() => {
|
|
|
state.loading = false;
|