This commit is contained in:
lcw
2026-01-16 12:40:42 +08:00
parent 2ea84f248c
commit 10853312f2
120 changed files with 23881 additions and 617 deletions

View File

@ -1,5 +1,5 @@
<template>
<el-dialog v-model="modelValue" title="线索下发" width="50%" @close="closeDialog" destroy-on-close append-to-body>
<el-dialog :model-value="modelValue" title="线索下发" width="50%" @close="closeDialog" destroy-on-close append-to-body>
<div style="height: 50vh; overflow: auto;">
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules" />
</div>

View File

@ -19,7 +19,7 @@
</FormMessage>
</div>
<div v-if="title == '详情'" class="timeline-container">
<el-timeline class="timeline-wrapper" v-if="listQuery.czlcList.length > 0">
<el-timeline class="timeline-wrapper" v-if="listQuery.czlcLis&&listQuery.czlcList.length > 0">
<el-timeline-item placement="top" v-for="(activity, index) in listQuery.czlcList" :key="index"
:timestamp="activity.czsj" :color="activity.czlx == '01' ? '#409eff' : '#67c23a'" size="large">
<div class="timeline-content" :class="activity.czlx == '01' ? 'sign-type' : 'feedback-type'">

View File

@ -1,5 +1,5 @@
<template>
<el-dialog v-model="modelValue" title="线索反馈" width="50%" @close="closeDialog" destroy-on-close append-to-body>
<el-dialog :model-value="modelValue" title="线索反馈" width="50%" @close="closeDialog" destroy-on-close append-to-body>
<div style="height: 15vh; overflow: auto;">
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules" />
</div>

View File

@ -41,9 +41,9 @@
<template #controls="{ row }">
<el-link size="small" type="primary" v-if="row.sfqs == '0'" @click="signRow(row)">签收</el-link>
<el-link size="small" type="warning" @click="fkRow(row)">反馈</el-link>
<el-link size="small" type="primary" @click="addEdit('edit', row)">编辑</el-link>
<el-link size="small" type="primary" @click="addEdit('edit', row)" v-if="showBtn(row)">编辑</el-link>
<el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
<el-link size="small" type="danger" @click="deleteRow(row.id)" v-if="showBtn(row)">删除</el-link>
</template>
</MyTable>
<Pages
@ -71,6 +71,7 @@ import DetailForm from "./components/detailForm.vue";
import Fk from "./components/fk.vue";
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
import { getItem } from '@/utils/storage'
const { proxy } = getCurrentInstance();
const {D_GS_XS_SJLY,D_GS_XS_ZLLX,D_GS_ZDQT_FXDJ,D_GS_XS_CZZT} = proxy.$dict('D_GS_XS_SJLY','D_GS_XS_ZLLX','D_GS_ZDQT_FXDJ','D_GS_XS_CZZT')
const detailDiloag = ref();
@ -109,8 +110,9 @@ const pageData = reactive({
{ label: '是否签收', prop: 'sfqs', showSolt: true },
]
});
const userInfo=ref();
onMounted(() => {
userInfo.value=getItem('deptId')[0]
getList()
tabHeightFn();
});
@ -184,6 +186,17 @@ const fkRow = (row) => {
dataList.value = {...row};
}
const showBtn = (row) => {
let item = row.xfbmList.find(v => v.ssbmdm == userInfo.value.deptCode)
console.log(item);
return item?true:false
// // if (item) {
// // return item.zlzt == '01' ? 'sign' : item.zlzt == '02' ? 'feedback' : ''
// // } else {
// // return ''
// // }
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;

View File

@ -0,0 +1,282 @@
<template>
<div class="statistical-analysis">
<!-- 左侧树形菜单 -->
<div class="left-menu">
<!-- 这个部分用的是组件-后期替换 -->
<MOSTY.DepartmentTree width="310px" @change="init" placeholder="管理部门" clearable filterable :isBmId="false"
v-model="listQuery.ssbmdm" />
</div>
<!-- 右侧内容区 -->
<div class="right-content">
<!-- 顶部筛选 -->
<div class="filter-section">
<el-radio-group v-model="radio" @change="changeRadio">
<el-radio v-for="(it, idx) in timeList" :key="idx" :label="it.num">{{ it.label }}</el-radio>
</el-radio-group>
<el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期"
end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" @change="handleDateChange" />
<el-button type="primary" @click="init">查询</el-button>
<el-button type="primary" @click="handleRest">重置</el-button>
</div>
<!-- 统计图表区域 -->
<div class="charts-container">
<div class="chart-item">
<div class="chart-title">
<span>信息分组统计</span>
<!-- <el-button type="primary">导出统计表</el-button> -->
</div>
<div class="chart">
<PieEcharts echartsId="pieChart" color="#333" :data="obj.xsfzList" />
</div>
</div>
<div class="chart-item">
<div class="chart-title">
<span>预警等级统计</span>
<!-- <el-button type="primary">导出统计表</el-button> -->
</div>
<div class="chart">
<!-- {{ obj.yjdjList }} -->
<DbarEcharts echartsId="bar3DChart" :data="obj.yjdjList" />
</div>
</div>
<div class="chart-item">
<div class="chart-title">
<span>线索来源统计</span>
<!-- <el-button type="primary">导出统计表</el-button> -->
</div>
<ul class="chart mt8">
<li v-for="(it, idx) in obj.xslyList" :key="idx" class="mb6">
<div style="color: #333">{{ it.label }}</div>
<el-progress :text-inside="true" :stroke-width="20" :percentage="calculatePercentage(it.value)"
status="exception">
<span><span style="color: #e37233">{{ it.value }}</span> </span>
</el-progress>
</li>
</ul>
</div>
<div class="chart-item">
<div class="chart-title">
<span>研判统计</span>
<!-- <el-button type="primary">导出统计表</el-button> -->
</div>
<DbarEcharts echartsId="bar3DCharts" :data="obj.ypList" />
<!-- <lineEcharts color="#333" echartsId="areaChart" :data="obj.ypList" /> -->
</div>
</div>
</div>
</div>
</template>
<script setup>
import { timeValidate, timeSlotChange } from "@/utils/tools.js";
import * as MOSTY from "@/components/MyComponents/index";
import lineEcharts from "@/views/home/echarts/lineEcharts.vue";
import PieEcharts from "@/views/home/echarts/pieEcharts.vue";
import DbarEcharts from "@/views/home/echarts/3DbarEcharts.vue";
import { qcckPost, qcckGet } from "@/api/qcckApi.js";
import { reactive, ref, onMounted } from "vue";
const dateRange = ref([timeValidate(new Date(), 'ymd'), timeValidate(new Date(), 'ymd')]);// 日期范围
const radio = ref(0); //当天
const timeList = ref([
{ label: "日", num: 0 },
{ label: "月", num: 1 },
{ label: "季", num: 2 },
{ label: "年", num: 3 }
]);
const listQuery = ref({})
const obj = reactive({
xsfzList: [],// 线索采集统计
xslyList: [],// 线索专题统计
ypList: {
list: [],//线索来源统计
topColor: '#1bd6c2',
colors: ["#28EEBF", "#0DBAC5"],
},
yjdjList: {
list: [],//线索来源统计
topColor: '#1bd6c2',
colors: ["#28EEBF", "#0DBAC5"],
}
});
onMounted(() => {
init() //初始化数据
});
const init = () => {
console.log(dateRange.value);
let data = {
ssbmdm: listQuery.value.ssbmdm,
startTime: dateRange.value[0]+' 00:00:00',
endTime: dateRange.value[1] + ' 23:59:59',
}
// 线索分组统计
qcckGet(data, '/mosty-gsxt/xxcj/xxfztj').then(res => {
let arr = res || [];
obj.xsfzList = arr.map(v => {
return { label: v.label, value: v.sl }
})
})
//研判统计
qcckGet(data, '/mosty-gsxt/ypbg/sjzl/yptj').then(res => {
let arr = res || [];
obj.ypList.list = arr.map(v => {
return { label: v.label, value: v.sl }
})
})
//线索来源统计
qcckPost(data, '/mosty-gsxt/qbcj/getXscjTjByQbly').then(res => {
let arr = res || [];
obj.xslyList = arr.map(v => {
return { label: v.zdmc, value: v.count }
})
})
//预警等级
const yjdjList = [
{ label: '红色预警', key: '01', count: 0 },
{ label: '橙色预警', key: '02', count: 0 },
{ label: '黄色预警', key: '03', count: 0 },
{ label: '蓝色预警', key: '04', count: 0 },
]
// 预警等级统计
qcckGet({ssbmdm:data.ssbmdm,kssj:data.startTime,jssj:data.endTime}, '/mosty-gsxt/tbYjxx/getYjxxTj').then(res => {
let arr = res || [];
obj.yjdjList.list = yjdjList.map(items => {
const index= arr.findIndex(item=>item.yj_jb===items.key);
return {
label: items.label,
value:index==-1?0:arr[index].count
}
})
})
}
const changeRadio = (val) => {
switch (val) {
case 0: //日
dateRange.value = timeSlotChange('日')
// [timeValidate(), timeValidate()]
break;
case 1: //月
dateRange.value = timeSlotChange('本月')
break;
case 2: //季度
dateRange.value = timeSlotChange('本季度')
break;
case 3: //年
dateRange.value = timeSlotChange('本年')
break;
}
}
const handleDateChange = (val) => {
radio.value = '';
if (val[0] == timeSlotChange('天')[0] && val[1] == timeSlotChange('天')[1]) radio.value = 0;
if (val[0] == timeSlotChange('本月')[0] && val[1] == timeSlotChange('本月')[1]) radio.value = 1;
if (val[0] == timeSlotChange('本季度')[0] && val[1] == timeSlotChange('本季度')[1]) radio.value = 2;
if (val[0] == timeSlotChange('本年')[0] && val[1] == timeSlotChange('本年')[1]) radio.value = 3;
};
// 重置
const handleRest = () => {
radio.value = 0;
dateRange.value = [timeValidate(), timeValidate()];
init();
};
// 计算百分比
const calculatePercentage = (value) => {
if (!obj.xslyList || obj.xslyList.length === 0) return 0;
const total = obj.xslyList.reduce((sum, item) => sum + (item.value || 0), 0);
if (total === 0) return 0;
return Math.round((value / total) * 100);
};
</script>
<style lang="scss" scoped>
.statistical-analysis {
display: flex;
height: 100%;
.left-menu {
width: 350px;
padding: 20px;
margin-top: 20px;
border-radius: 4px;
background-color: #fff;
border-right: 1px solid #e8e8e8;
}
.right-content {
flex: 1;
padding: 20px;
.filter-section {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 20px;
background: #fff;
padding: 10px;
box-sizing: border-box;
border-radius: 4px;
}
.charts-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
height: calc(100% - 50px);
.chart-item {
width: 49.5%;
height: calc(50% - 5px);
background-color: #fff;
border-radius: 8px;
padding: 20px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.chart-title {
font-size: 16px;
font-weight: bold;
color: #333;
display: flex;
justify-content: space-between;
align-items: center;
}
.chart {
height: calc(100% - 40px);
overflow: hidden;
overflow-y: auto;
}
}
}
}
::v-deep .el-radio {
color: #333;
}
::v-deep .el-radio__inner {
border-radius: 4px;
}
::v-deep .el-progress-bar__innerText {
color: #333;
margin: 0 -40px;
}
::v-deep .el-progress.is-exception .el-progress-bar__inner {
background: linear-gradient(90deg, #fe5d00 0%, #face35 100%);
}
}
</style>

View File

@ -44,6 +44,7 @@
<el-button type="primary">导出统计表</el-button>
</div>
<div class="chart">
<!-- {{ obj.xslyList }} -->
<DbarEcharts echartsId="bar3DChart" :data="obj.xslyList" />
</div>
</div>
@ -237,7 +238,7 @@ const handleRest = () => {
}
}
}
::v-deep .el-radio {
color: #333;
}

View File

@ -1,5 +1,5 @@
<template>
<el-dialog v-model="modelValue" title="合并详情" width="1500px" @close="handleClose">
<el-dialog :model-value="modelValue" title="合并详情" width="1500px" @close="handleClose">
<div style="width:100%">
<MyTable
:tableData="pageForm.tableData"
@ -101,4 +101,4 @@ watch(()=>props.modelValue,val=>{
<style lang="scss" scoped>
</style>
</style>