lcw
This commit is contained in:
@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<!-- 直接使用box作为根元素,减少嵌套层级 -->
|
||||
<div class="box" ref="chartDom" style="width: 100%; margin: 0; padding: 0;"></div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, watch } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
let chartDom = ref(null); //注意变量名 和 ref名字要对应
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: '2023年1月1日至2023年12月31日'
|
||||
},
|
||||
xAxisData: {
|
||||
type: Array,
|
||||
default: () => ['A', 'B', 'C', 'D', 'E', 'F']
|
||||
},
|
||||
seriesData: {
|
||||
type: Array,
|
||||
default: () => [[2549], [12421], [2637],[ 3146],[ 15189], [9562]]
|
||||
},
|
||||
// yAxisData: {
|
||||
// type: Array,
|
||||
// default: () => [2549, 12421, 2637, 3146, 15189, 9562]
|
||||
// },
|
||||
});
|
||||
|
||||
// 保存图表实例的引用
|
||||
const myChart = ref(null);
|
||||
let resizeTimer = null;
|
||||
const chartInstance = ref(null);
|
||||
onMounted(() => {
|
||||
// 确保DOM渲染完成后再初始化图表
|
||||
setTimeout(() => {
|
||||
initChart();
|
||||
}, 0);
|
||||
|
||||
// 监听窗口大小变化,确保图表能正确调整大小
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
// 组件卸载时清理监听器
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
if (resizeTimer) {
|
||||
clearTimeout(resizeTimer);
|
||||
}
|
||||
// 销毁图表实例
|
||||
if (myChart.value) {
|
||||
myChart.value.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
// 处理窗口大小变化的函数
|
||||
const handleResize = () => {
|
||||
// 防抖处理,避免频繁调用
|
||||
if (resizeTimer) {
|
||||
clearTimeout(resizeTimer);
|
||||
}
|
||||
resizeTimer = setTimeout(() => {
|
||||
// 如果图表实例存在,调用resize方法
|
||||
if (myChart.value) {
|
||||
myChart.value.resize();
|
||||
}
|
||||
}, 200);
|
||||
};
|
||||
watch([
|
||||
() => props.seriesData,
|
||||
() => props.xAxisData,
|
||||
], () => {
|
||||
initChart();
|
||||
},{deep:true});
|
||||
const initChart = () => {
|
||||
chartInstance.value = props.seriesData.map((item, index) => {
|
||||
return {
|
||||
name: props.xAxisData[index],
|
||||
data: item,
|
||||
type: "bar",
|
||||
barWidth: "20",
|
||||
// barGap: 20, // 系列之间的间距
|
||||
barCategoryGap: '20%', // 使用百分比更适应不同宽度
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: function (params) {
|
||||
// 值为0或null时不显示
|
||||
if (params.value === 0 || params.value === null) {
|
||||
return '';
|
||||
}
|
||||
// 格式化数值显示
|
||||
return params.value.toLocaleString();
|
||||
},
|
||||
color: '#2c3e50',
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
distance: 10 // 标签与柱子的距离
|
||||
},
|
||||
}
|
||||
})
|
||||
// 保存图表实例以便后续调用resize
|
||||
myChart.value = echarts.init(chartDom.value);
|
||||
// 重置容器大小确保占满
|
||||
chartDom.value.style.width = '100%';
|
||||
|
||||
var option = {
|
||||
title: {
|
||||
text: props.title,
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
// 鼠标悬浮提示数据
|
||||
trigger: "axis",
|
||||
backgroundColor: "rgba(32, 33, 36,.7)",
|
||||
borderColor: "rgba(32, 33, 36,0.20)",
|
||||
borderWidth: 15,
|
||||
textStyle: {
|
||||
// 文字提示样式
|
||||
color: "#fff",
|
||||
fontSize: "12",
|
||||
},
|
||||
axisPointer: {
|
||||
// 坐标轴虚线
|
||||
type: "cross",
|
||||
label: {
|
||||
backgroundColor: "#6a7985",
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
right: 0
|
||||
},
|
||||
// },
|
||||
grid: {
|
||||
// 控制图表的位置,设置为最紧凑以占满整个容器
|
||||
left: "2%",
|
||||
right: "2%",
|
||||
top: "15%",
|
||||
bottom: "3%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
data: props.xAxisData,
|
||||
},
|
||||
yAxis: {
|
||||
// axisLabel: {
|
||||
// // y轴线 标签修改
|
||||
// textStyle: {
|
||||
// color: "white", //坐标值得具体的颜色
|
||||
// },
|
||||
// },
|
||||
// data: props.xAxisData,
|
||||
},
|
||||
series: chartInstance.value
|
||||
};
|
||||
myChart.value.setOption(option);
|
||||
|
||||
// 初始时强制调整大小,确保完全适应容器
|
||||
setTimeout(() => {
|
||||
if (myChart.value) {
|
||||
myChart.value.resize();
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 根容器样式,确保完全占满父容器 */
|
||||
.box {
|
||||
width: 100% !important;
|
||||
height: 60vh;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
display: block !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
/* 确保ECharts实例占满容器 */
|
||||
:deep(.echarts) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
min-width: 0 !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
/* 为父级元素设置样式,确保没有额外的内边距 */
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* 防止任何默认的边距或内边距影响 */
|
||||
* {
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<!-- 将固定id改为ref引用 -->
|
||||
<div ref="chartContainer" style="height: 100%;"></div>
|
||||
</template>
|
||||
<script setup>
|
||||
import * as echarts from 'echarts';
|
||||
import { onMounted, onUnmounted, ref, watch, defineProps } from 'vue';
|
||||
|
||||
// 定义组件的属性,使其可复用
|
||||
const props = defineProps({
|
||||
// 图表数据
|
||||
chartData: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
{ value: 40, name: 'rose 1' },
|
||||
{ value: 38, name: 'rose 2' },
|
||||
{ value: 32, name: 'rose 3' },
|
||||
{ value: 30, name: 'rose 4' },
|
||||
{ value: 28, name: 'rose 5' },
|
||||
{ value: 26, name: 'rose 6' },
|
||||
{ value: 22, name: 'rose 7' },
|
||||
{ value: 18, name: 'rose 8' }
|
||||
]
|
||||
},
|
||||
// 图表标题
|
||||
chartName: {
|
||||
type: String,
|
||||
default: 'Nightingale Chart'
|
||||
},
|
||||
// 是否显示工具箱
|
||||
showToolbox: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否显示图例
|
||||
showLegend: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 内半径
|
||||
innerRadius: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 外半径
|
||||
outerRadius: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
// 扇形间距
|
||||
padAngle: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
title: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
text: 'Nightingale Chart',
|
||||
left: 'center'
|
||||
})
|
||||
},
|
||||
roseType: {
|
||||
type: String,
|
||||
default: 'radius'
|
||||
}
|
||||
});
|
||||
|
||||
// 图表容器引用
|
||||
const chartContainer = ref(null);
|
||||
// 图表实例引用
|
||||
const chartInstance = ref(null);
|
||||
|
||||
// 初始化图表
|
||||
const initChart = () => {
|
||||
const chartDom = chartContainer.value;
|
||||
if (!chartDom) return;
|
||||
|
||||
// 如果已经存在实例,先销毁
|
||||
if (chartInstance.value) {
|
||||
chartInstance.value.dispose();
|
||||
}
|
||||
|
||||
// 创建新实例
|
||||
chartInstance.value = echarts.init(chartDom);
|
||||
|
||||
// 设置图表选项
|
||||
const option = {
|
||||
title: props.title,
|
||||
legend: props.showLegend ? {
|
||||
top: 'bottom'
|
||||
} : false,
|
||||
toolbox: props.showToolbox ? {
|
||||
show: true,
|
||||
feature: {
|
||||
mark: { show: true },
|
||||
dataView: { show: true, readOnly: false },
|
||||
restore: { show: true },
|
||||
saveAsImage: { show: true }
|
||||
}
|
||||
} : false,
|
||||
series: [
|
||||
{
|
||||
name: props.chartName,
|
||||
type: 'pie',
|
||||
radius: [props.innerRadius, props.outerRadius],
|
||||
center: ['50%', '50%'],
|
||||
roseType: props.roseType,
|
||||
// 在 ECharts 5.3.3 中,当 roseType 为 'area' 时,padAngle 需要特殊处理
|
||||
// 为了确保间距生效,我们需要添加一个小的非零值来替代0
|
||||
// padAngle: props.padAngle === 0 ? 0.1 : props.padAngle,
|
||||
itemStyle: {
|
||||
borderColor: '#fff',
|
||||
borderWidth:props.padAngle
|
||||
},
|
||||
// 显示百分比
|
||||
label: {
|
||||
show: true,
|
||||
formatter: function(params) {
|
||||
// 对于值为0的项,显示0%而不是极小值计算出的百分比
|
||||
if (props.chartData.find(d => d.name === params.name && d.value === 0)) {
|
||||
return params.name + ': 0%';
|
||||
}
|
||||
return params.name + ': ' + params.percent + '%';
|
||||
}
|
||||
},
|
||||
// 鼠标悬停时的样式
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '16',
|
||||
fontWeight: 'bold',
|
||||
formatter: function(params) {
|
||||
// 对于值为0的项,显示0%而不是极小值计算出的百分比
|
||||
if (props.chartData.find(d => d.name === params.name && d.value === 0)) {
|
||||
return params.name + ': 0%';
|
||||
}
|
||||
return params.name + ': ' + params.percent + '%';
|
||||
}
|
||||
}
|
||||
},
|
||||
// 处理数据,确保值为0的项也能显示
|
||||
data: props.chartData.map(item => ({
|
||||
...item,
|
||||
// 对于值为0的数据,设置一个极小值来确保它在饼图中显示
|
||||
value: item.value === 0 ? 0.0000001 : item.value
|
||||
}))
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// 应用选项
|
||||
chartInstance.value.setOption(option);
|
||||
};
|
||||
|
||||
// 处理窗口大小变化,自动调整图表大小
|
||||
const handleResize = () => {
|
||||
if (chartInstance.value) {
|
||||
chartInstance.value.resize();
|
||||
}
|
||||
};
|
||||
|
||||
// 组件挂载时初始化图表
|
||||
onMounted(() => {
|
||||
initChart();
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
// 组件卸载时销毁图表实例并移除事件监听
|
||||
onUnmounted(() => {
|
||||
if (chartInstance.value) {
|
||||
chartInstance.value.dispose();
|
||||
}
|
||||
window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
// 监听数据变化,更新图表
|
||||
watch(() => props.chartData, () => {
|
||||
initChart();
|
||||
}, { deep: true });
|
||||
|
||||
// 监听其他配置变化,更新图表
|
||||
watch([
|
||||
() => props.chartName,
|
||||
() => props.showToolbox,
|
||||
() => props.showLegend,
|
||||
() => props.innerRadius,
|
||||
() => props.outerRadius,
|
||||
() => props.padAngle,
|
||||
()=> props.roseType,
|
||||
], () => {
|
||||
initChart();
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
:deep(div) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* min-height: 400px; */
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,441 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <div class="titleBox">
|
||||
<PageTitle title="警情分析报告">
|
||||
<el-button type="primary" @click="generatePDF()">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">导出</span>
|
||||
</el-button>
|
||||
</PageTitle>
|
||||
</div> -->
|
||||
<!-- 搜索 -->
|
||||
<!-- <div ref="searchBox">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch">
|
||||
<template #defaultSlot>
|
||||
<el-select v-model="bjlbList" placeholder="请选择情报类型" multiple collapse-tags>
|
||||
<el-option v-for="item in dictItemList" :key="item.dm" :label="item.zdmc" :value="item.dm" />
|
||||
</el-select>
|
||||
</template>
|
||||
</Search>
|
||||
</div> -->
|
||||
<div style="background-color: #fff;color: black;padding: 15px;overflow: auto;" :style="{ height: tabHeight + 'px' }"
|
||||
ref="tableBox">
|
||||
<div style="border-bottom: 1px #ccc solid;padding-bottom: 30px;">
|
||||
<h1 class="headline">{{ nd }}年度西藏公安战术研判报告</h1>
|
||||
<div style="display: flex;align-items: center;justify-content: space-between; color: red;margin-top: 30px;padding: 0 30px;font-size: 18px;font-weight: 700;">
|
||||
<div>{{ deptId.name }}</div>
|
||||
<div>{{ deptId?.ord }}</div>
|
||||
<div>{{ deptId?.time }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>为全面、客观、准确掌握全区公安机关的执法状况,自治区
|
||||
公安厅基于数据统计,对全区公安机关{{ nd }}年度的执法状况作
|
||||
了客观分析。</p>
|
||||
<h2>一、执法状况总体分析</h2>
|
||||
<h2>1.接处警情况</h2>
|
||||
<h2>1.1接报警情</h2>
|
||||
<p>
|
||||
{{ timeValidate(TimeValue.startTime, 'td') }}至{{ timeValidate(TimeValue.endTime, 'td') }}
|
||||
,全区公安机关共
|
||||
接报各类警情{{ dataList.XsfxTj.total }}起,同比{{ `${dataList.XsfxTj.tbbsb > 0 ? "下降" : "上升"}
|
||||
${dataList.XsfxTj.tbbsb}%,同比${dataList.XsfxTj.tbbsb > 0 ? "下降" : "上升"}${dataList.XsfxTj.tbbsb}%` }}。</p>
|
||||
<h2>1.1.1类型维度</h2>
|
||||
<p>
|
||||
从警情类型来看,{{ sortingRatioValue.Ydfx[0]?.name }}警情最多,占到{{ sortingRatioValue.Ydfx[0]?.ratio }};其次为{{
|
||||
sortingRatioValue.Ydfx[1]?.name }}警情,占到{{ sortingRatioValue.Ydfx[1]?.ratio }}。
|
||||
</p>
|
||||
<MaleNightingalePicture roseType="area" style="height: 550px;" :title="{ text: '接警情类型', left: 'center' }"
|
||||
:chartData="dataList.jqlxTj" :chartName="'接警情类型'" :innerRadius="0" :padAngle="4" />
|
||||
<h2>1.1.2来源维度</h2>
|
||||
<p>
|
||||
从警情来源来看,{{ sortingRatioValue.Jqlx[0]?.name }}警情最多,占到{{ sortingRatioValue.Jqlx[0]?.ratio }};其次为{{
|
||||
sortingRatioValue.Jqlx[1]?.name }}警情,占到{{ sortingRatioValue.Jqlx[1]?.ratio }}。
|
||||
</p>
|
||||
<MaleNightingalePicture roseType="area" :title="{ text: '警情来源', left: 'center' }" style="height: 550px;"
|
||||
:chartData="dataList.jqlyTj" :innerRadius="50" :outerRadius="150" :padAngle="4" />
|
||||
|
||||
<h2>1.1.3地域维度</h2>
|
||||
<p>从地市分布地市来看,{{ sortingRatioValue.Dywdtj[0]?.ssbm }}警情量最大,占到全区警情总
|
||||
量的{{ sortingRatioValue.Dywdtj[0]?.ratio }}。
|
||||
<span v-if="sortingRatioValue.Dywdtj.length > 1">
|
||||
其次为{{ sortingRatioValue.Dywdtj[1]?.ssbm }}
|
||||
<span v-if="sortingRatioValue.Dywdtj.length > 2">
|
||||
<span v-if="sortingRatioValue.Dywdtj.length > 3">
|
||||
和{{ sortingRatioValue.Dywdtj[3]?.ssbm }},两市警情量较为接近。
|
||||
</span>
|
||||
<span>
|
||||
警情量最少的为{{ sortingRatioValue.Dywdtj[sortingRatioValue.Dywdtj.length - 1]?.ssbm }}。
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
<Histogram title="地市分布" :xAxisData="dataList.dyTj.xAxisData" :seriesData="dataList.dyTj.seriesData" />
|
||||
<h2>1.1.4时间维度</h2>
|
||||
<p>
|
||||
我们将所有警情按照月份划分进行统计发现,每月警情分布
|
||||
较为平均。最高月份为
|
||||
{{ sortingRatioValue.Ydfx[0]?.month }}月,占到{{ sortingRatioValue.Ydfx[0]?.ratio }};
|
||||
<span v-if="sortingRatioValue.Ydfx.length > 1">
|
||||
最低月份为{{ sortingRatioValue.Ydfx[sortingRatioValue.Ydfx.length - 1]?.month }}月,
|
||||
占到{{ sortingRatioValue.Ydfx[sortingRatioValue.Ydfx.length - 1]?.ratio }}。
|
||||
考虑是因为{{ sortingRatioValue.Ydfx[0]?.month }}月为我区传统旅游旺季,进藏人员较多。
|
||||
<!-- {{sortingRatioValue.Ydfx[sortingRatioValue.Ydfx.length-1]?.month}}月一般春节及藏历新年期间,在藏人员较少。 -->
|
||||
</span>
|
||||
</p>
|
||||
<MaleNightingalePicture :title="{ text: '警情分布', left: 'center' }" style="height: 550px;"
|
||||
:chartData="dataList.ydTj" :innerRadius="10" :outerRadius="150" :padAngle="2" />
|
||||
<!-- <p>
|
||||
按照24小时每小时时段进行划分后发现,警情多发时段集
|
||||
中在9时至20时,每小时均在1000起以上。
|
||||
</p> -->
|
||||
<h2>1.2警情处置</h2>
|
||||
<h2>1.2.1结果维度</h2>
|
||||
<p>
|
||||
从警情处置结果来看,
|
||||
<span v-for="(item, index) in sortingRatioValue.Cljgf">
|
||||
{{ `${item.name}占到${item.ratio},` }}
|
||||
</span>
|
||||
</p>
|
||||
<MaleNightingalePicture :title="{ text: '警情处置', left: 'center' }" style="height: 550px;"
|
||||
:chartData="dataList.CljgfTj" :innerRadius="0" :outerRadius="150" :padAngle="2" />
|
||||
<h2>1.2.2效率维度</h2>
|
||||
<p>从处警效率来看,{{ sortingRatioValue.Czlfx[1]?.name }}处警的,占到{{ sortingRatioValue.Czlfx[0]?.ratio
|
||||
}}。表明我区公安机关在接警之后能够在第一时间处警。
|
||||
</p>
|
||||
<MaleNightingalePicture :title="{ text: '效率维度', left: 'center' }" style="height: 550px;"
|
||||
:chartData="dataList.withinTj" :innerRadius="0" :outerRadius="150" :padAngle="0" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<AddForm ref="addForm" :dict="{ D_GS_XS_LX }" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import Search from "@/components/aboutTable/Search.vue";
|
||||
import MaleNightingalePicture from './components/maleNightingalePicture.vue'
|
||||
import Histogram from './components/histogram.vue'
|
||||
import { timeValidate } from '@/utils/tools.js'
|
||||
import { getItem, setItem } from '@/utils/storage'
|
||||
import { fxbgDywdtj, getDictItem, fxbgJqlxtj, fxbgJqlytj, fxbgYdfx, fxbgXsfx, fxgbCljgf, fxgbCzlfx, fxbgTj } from '@/api/semanticAnalysis'
|
||||
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick, computed, watch } from "vue";
|
||||
const props = defineProps({
|
||||
// 数据
|
||||
search: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
})
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_XS_LX } = proxy.$dict("D_GS_XS_LX"); //获取字典数据
|
||||
const dictItemList = ref([])
|
||||
const searchConfiger = reactive([
|
||||
{
|
||||
label: "时间",
|
||||
showType: "daterange",
|
||||
prop: "startTime",
|
||||
placeholder: "请输入警情名称",
|
||||
},
|
||||
{
|
||||
showType: "defaultSlot",
|
||||
// prop: "bjlbList",
|
||||
placeholder: "请选择情报类型",
|
||||
label: "警情类别"
|
||||
},
|
||||
])
|
||||
const bjlbList = ref([])
|
||||
onMounted(() => {
|
||||
tabHeightFn()
|
||||
})
|
||||
const tabHeight = ref(0)
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
tabHeight.value = window.innerHeight - 300
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
};
|
||||
const pageData = reactive({
|
||||
parameter: {},
|
||||
total: 0,
|
||||
loading: false,
|
||||
tableData: []
|
||||
})
|
||||
const onSearch = (val) => {
|
||||
const promes = {
|
||||
startTime: val.startTime ? val.startTime[0] : '',
|
||||
endTime: val.startTime ? val.startTime[1] : '',
|
||||
}
|
||||
const bjlbLists = bjlbList.value ? bjlbList.value.join(',') : ""
|
||||
pageData.parameter = { bjlbList: bjlbLists, ...promes }
|
||||
funAll()
|
||||
}
|
||||
|
||||
// 数据处理
|
||||
|
||||
const dataList = reactive({
|
||||
dyTj: {
|
||||
xAxisData: [],
|
||||
seriesData: [],
|
||||
},
|
||||
jqlxTj: [],
|
||||
jqlyTj: [],
|
||||
CljgfTj: [],
|
||||
XsfxTj: [],
|
||||
})
|
||||
const sortingRatioValue = reactive({
|
||||
Dywdtj: [],
|
||||
Ydfx: [],
|
||||
Cljgf: [],
|
||||
Czlfx: [],
|
||||
Lyfx: [],
|
||||
Jqlx: []
|
||||
})
|
||||
const sortingRatio = (data) => {
|
||||
// 提取所有number值
|
||||
// 计算总数
|
||||
const total = data.reduce((sum, item) => sum + item.number, 0);
|
||||
// 找出第一大和第二大的值及其对应的name
|
||||
const sortedData = [...data].sort((a, b) => b.number - a.number);
|
||||
const dataValue = sortedData.map(item => {
|
||||
return {
|
||||
...item,
|
||||
ratio: total > 0 ? (item.number / total * 100).toFixed(2) + '%' : '0%',
|
||||
}
|
||||
})
|
||||
return dataValue
|
||||
}
|
||||
// 地域统计
|
||||
const getfxbgDywdtj = () => {
|
||||
let params = {
|
||||
...pageData.parameter,
|
||||
}
|
||||
fxbgDywdtj(params).then(res => {
|
||||
dataList.dyTj.xAxisData = res.map(it => it.ssbm)
|
||||
dataList.dyTj.seriesData = [];
|
||||
for (let i = 0; i < res.length; i++) {
|
||||
dataList.dyTj.seriesData[i] = [];
|
||||
for (let j = 0; j < res.length; j++) {
|
||||
dataList.dyTj.seriesData[i][j] = 0;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < dataList.dyTj.seriesData.length; i++) {
|
||||
dataList.dyTj.seriesData[i][i] = res[i].number
|
||||
}
|
||||
sortingRatioValue.Dywdtj = sortingRatio(res)
|
||||
})
|
||||
}
|
||||
// 警情类型统计
|
||||
const getfxbgJqlxtj = () => {
|
||||
let params
|
||||
if (pageData.parameter.bjlbList) {
|
||||
params = {
|
||||
...pageData.parameter,
|
||||
}
|
||||
} else {
|
||||
params = {
|
||||
...pageData.parameter,
|
||||
bjlbList: dictItemList.value.map(item => item.dm).join(',')
|
||||
}
|
||||
}
|
||||
fxbgJqlxtj(params).then(res => {
|
||||
sortingRatioValue.Jqlx = sortingRatio(res)
|
||||
dataList.jqlxTj = res.map(item => {
|
||||
return {
|
||||
name: item.name,
|
||||
value: item.number
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
// 警情来源统计
|
||||
const getfxbgJqlytj = () => {
|
||||
let params = {
|
||||
...pageData.parameter,
|
||||
}
|
||||
fxbgJqlytj(params).then(res => {
|
||||
sortingRatioValue.Lyfx = sortingRatio(res)
|
||||
dataList.jqlyTj = res.map(item => {
|
||||
return {
|
||||
name: item.name,
|
||||
value: item.number
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//分析报告-时间维度-月分析
|
||||
const getfxbgYdfx = () => {
|
||||
let params = {
|
||||
...pageData.parameter,
|
||||
}
|
||||
fxbgYdfx(params).then(res => {
|
||||
sortingRatioValue.Ydfx = sortingRatio(res)
|
||||
dataList.ydTj = res.map(item => {
|
||||
return {
|
||||
name: item.month,
|
||||
value: item.number
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
// 分析报告-处理结果分析
|
||||
const getfxgbCljgf = () => {
|
||||
let params = {
|
||||
...pageData.parameter,
|
||||
}
|
||||
|
||||
fxgbCljgf(params).then(res => {
|
||||
sortingRatioValue.Cljgf = sortingRatio(res)
|
||||
dataList.CljgfTj = res.map(item => {
|
||||
return {
|
||||
name: item.name,
|
||||
value: item.number
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
// 分析报告-处置率分析
|
||||
const getfxgbCzlfx = () => {
|
||||
let params = {
|
||||
...pageData.parameter,
|
||||
}
|
||||
fxgbCzlfx(params).then(res => {
|
||||
dataList.withinTj = [{
|
||||
name: "超时分流(超过24小时)",
|
||||
value: res.within24h ? res.within24h : 0
|
||||
}, {
|
||||
name: "按时分流(24小时内)",
|
||||
value: res.over24h ? res.over24h : 0
|
||||
}]
|
||||
sortingRatioValue.Czlfx = sortingRatio(dataList.withinTj)
|
||||
})
|
||||
}
|
||||
|
||||
const getfxbgTj = () => {
|
||||
let params = {
|
||||
...pageData.parameter,
|
||||
}
|
||||
fxbgTj(params).then(res => {
|
||||
console.log(res, "xxx");
|
||||
dataList.XsfxTj = res
|
||||
})
|
||||
}
|
||||
const TimeValue = ref({
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const nd = ref()
|
||||
|
||||
watch(() => pageData.parameter, (newVal) => {
|
||||
if (newVal.startTime) {
|
||||
TimeValue.value.startTime = newVal.startTime
|
||||
TimeValue.value.endTime = newVal.endTime
|
||||
if (timeValidate(newVal.startTime, 'yd') == timeValidate(newVal.endTime, 'yd')) {
|
||||
nd.value = timeValidate(newVal.startTime, 'yd')
|
||||
} else {
|
||||
nd.value = `${timeValidate(newVal.startTime, 'yd')}至${timeValidate(newVal.endTime, 'yd')}`
|
||||
}
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
const deptId = ref({
|
||||
name: ''
|
||||
})
|
||||
const Time = () => {
|
||||
const currentYear = new Date().getFullYear();
|
||||
const startOfYear = new Date(currentYear, 0, 1); // 今年1月1日
|
||||
const endOfYear = new Date(currentYear, 11, 31, 23); // 今年12月31日23:59:59.999
|
||||
const year = startOfYear.getFullYear();
|
||||
const month = String(startOfYear.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(startOfYear.getDate()).padStart(2, '0');
|
||||
const endYear = endOfYear.getFullYear();
|
||||
const endMonth = String(endOfYear.getMonth() + 1).padStart(2, '0');
|
||||
const endDay = String(endOfYear.getDate()).padStart(2, '0');
|
||||
const devt = getItem('deptId')
|
||||
deptId.value.name = devt[0].deptName
|
||||
nd.value = timeValidate('', 'yd')
|
||||
deptId.value.time = timeValidate('', 'ydm')
|
||||
deptId.value.ord=timeValidate('', 'mm')
|
||||
TimeValue.value.startTime = `${year}-${month}-${day}`
|
||||
TimeValue.value.endTime = `${endYear}-${endMonth}-${endDay}`
|
||||
|
||||
}
|
||||
Time()
|
||||
const funAll = () => {
|
||||
getfxbgDywdtj()
|
||||
getfxbgJqlxtj()
|
||||
getfxbgJqlytj()
|
||||
getfxgbCljgf()
|
||||
getfxbgYdfx()
|
||||
getfxgbCzlfx()
|
||||
getfxbgTj()
|
||||
}
|
||||
|
||||
const getDictItemList = () => {
|
||||
const promes = {
|
||||
startTime: props.search.startTime ,
|
||||
endTime: props.search.endTime,
|
||||
}
|
||||
if (props.search.lx) {
|
||||
const bjlbLists = props.search.lx ? props.search.lx.join(',') : ""
|
||||
pageData.parameter = { bjlbList: bjlbLists, ...promes }
|
||||
funAll()
|
||||
} else {
|
||||
const promesing = {
|
||||
dictCode: "00000000"
|
||||
}
|
||||
getDictItem(promesing).then(res => {
|
||||
const bjlbLists = res.map(item=>item.dm).join(',')?res.map(item=>item.dm).join(','):""
|
||||
pageData.parameter = { bjlbList: bjlbLists, ...promes }
|
||||
funAll()
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const data = ref()
|
||||
watch(() => dictItemList.value, (val) => {
|
||||
data.value = val
|
||||
}, { deep: true })
|
||||
getDictItemList()
|
||||
const tableBox = ref(null);
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.headline {
|
||||
text-align: center;
|
||||
color: red;
|
||||
}
|
||||
|
||||
p {
|
||||
text-indent: 2em;
|
||||
/* 首行缩进2个汉字 */
|
||||
margin: 1em 0;
|
||||
/* 段落间距 */
|
||||
line-height: 1.6;
|
||||
/* 行高 */
|
||||
font-size: 16px;
|
||||
/* 字体大小 */
|
||||
text-align: justify;
|
||||
/* 两端对齐 */
|
||||
}
|
||||
|
||||
/* 特殊情况处理 */
|
||||
p.no-indent {
|
||||
text-indent: 0;
|
||||
/* 不需要缩进的段落 */
|
||||
}
|
||||
|
||||
p.first-no-indent:first-of-type {
|
||||
text-indent: 0;
|
||||
/* 第一个段落不缩进 */
|
||||
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<el-dialog :title="title" v-model="visible" width="80%" destroy-on-close>
|
||||
<JudgmentReport :search="search"/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ref, reactive ,watch} from 'vue'
|
||||
import JudgmentReport from './AnalysisReport/index.vue'
|
||||
const title = ref('详情')
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
search: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
const opebg = ref(false)
|
||||
watch(() => props.visible, (val) => {
|
||||
opebg.value = val
|
||||
},{immediate:true})
|
||||
const emit=defineEmits(['update:visible'])
|
||||
</script>
|
||||
@ -14,7 +14,6 @@
|
||||
<MoreBarEcharts echartsId="cztjEcharts" :data="obj.data_lxtj"></MoreBarEcharts>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hh50">
|
||||
<div class="comm-title">会商统计</div>
|
||||
<div class="echartsBox">
|
||||
@ -35,10 +34,10 @@
|
||||
<div ref="searchBox">
|
||||
<el-form :model="searchList" ref="searchFormRef" :inline="true">
|
||||
<el-form-item label="类型">
|
||||
<el-cascader ref="cascaRef" @change="changeCascader" :disabled="readonly_lx" v-model="searchList.lx" clearable
|
||||
:options="cascaderList" :props="{ checkStrictly: true,multiple: true }" placeholder="请选择类型" />
|
||||
<el-cascader ref="cascaRef" v-model="searchList.lx" @change="changeCascader" collapse-tags
|
||||
:disabled="readonly_lx" :options="cascaderList" :props="{ multiple: true }" placeholder="请选择类型" />
|
||||
</el-form-item>
|
||||
<el-form-item label="人员">
|
||||
<!-- <el-form-item label="人员">
|
||||
<el-input @change="changeRy" v-model="searchList.ry" :disabled="readonly_ry" clearable
|
||||
placeholder="请输入姓名或身份证"></el-input>
|
||||
</el-form-item>
|
||||
@ -52,10 +51,11 @@
|
||||
<el-input @change="changeRy" :disabled="readonly_dd" v-model="searchList.xxdz" clearable
|
||||
placeholder="请输入详细地址"></el-input>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="时间">
|
||||
<el-date-picker v-model="searchList.datetimes" type="datetimerange" unlink-panels :range-separator="'至'"
|
||||
start-placeholder="开始日期时间" end-placeholder="结束日期时间" value-format="YYYY-MM-DD HH:mm:ss" />
|
||||
<el-date-picker v-model="searchList.datetimes" type="daterange" unlink-panels :range-separator="'至'"
|
||||
start-placeholder="开始日期时间" end-placeholder="结束日期时间" format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSearch">查询</el-button>
|
||||
@ -67,9 +67,9 @@
|
||||
<li class="list-item" ref="listBoxRef" v-for="(it, idx) in list" :key="idx">
|
||||
<div class="comm-title title-s">{{ it.title }}</div>
|
||||
<div class="list-table">
|
||||
<MyTable :tableData="it.tableList" :tableColumn="it.tableColumn" :key="idx + '' + it.keyCount" :fixed="false"
|
||||
:tableHeight="pageData.tableHeight" :tabelModel="it.title" :tableConfiger="pageData.tableConfiger"
|
||||
:controlsWidth="pageData.controlsWidth">
|
||||
<MyTable :tableData="it.tableList" :tableColumn="it.tableColumn" :key="idx + '' + it.keyCount"
|
||||
:fixed="false" :tableHeight="pageData.tableHeight" :tabelModel="it.title"
|
||||
:tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
|
||||
<template #jqlbdm="{ row }">
|
||||
<DictTag :tag="false" :value="row.jqlbdm" :options="JQLB" />
|
||||
</template>
|
||||
@ -85,22 +85,26 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<YpModel v-model="showModel" :textContent="textContent"></YpModel>
|
||||
<!-- <YpModel v-model="showModel" :textContent="textContent"></YpModel> -->
|
||||
<!-- 弹窗 -->
|
||||
<DetailDialog ref="detaileRef"></DetailDialog>
|
||||
<!-- <DetailDialog ref="detaileRef"></DetailDialog> -->
|
||||
<!-- 研判报告弹窗 -->
|
||||
<JudgmentReport v-model="visible" :search="search"></JudgmentReport>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { lzJcjPjdbSelectPage } from '@/api/semanticAnalysis.js'
|
||||
import { ElMessage } from "element-plus";
|
||||
import DetailDialog from './components/detailDialog.vue'
|
||||
import YpModel from '@/components/ypModel/index.vue'
|
||||
// import DetailDialog from './components/detailDialog.vue'
|
||||
import JudgmentReport from './components/judgmentReport.vue'
|
||||
// import YpModel from '@/components/ypModel/index.vue'
|
||||
import { qcckPost, qcckGet } from "@/api/qcckApi.js";
|
||||
import MoreBarEcharts from "@/views/home/echarts/moreBarEcharts.vue";
|
||||
import LineEcharts from "@/views/home/echarts/moreLineEcharts.vue";
|
||||
import MyTable from "@/components/aboutTable/DarkTable.vue";
|
||||
import Pages from "@/components/aboutTable/Pages.vue";
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import {tbJqGetPageList } from '@/api/yj.js'
|
||||
const router = useRouter();
|
||||
import { nextTick, onMounted, reactive, getCurrentInstance, ref, watch } from 'vue';
|
||||
const { proxy } = getCurrentInstance();
|
||||
@ -108,9 +112,9 @@ const { JQLB } = proxy.$dict("JQLB"); //获取字典数据
|
||||
const readonly_lx = ref(false)
|
||||
const readonly_ry = ref(false)
|
||||
const readonly_dd = ref(false)
|
||||
const cascaRef=ref()
|
||||
const cascaRef = ref()
|
||||
const showModel = ref(false);
|
||||
const detaileRef = ref();
|
||||
// const detaileRef = ref();
|
||||
const searchBox = ref();
|
||||
const listBoxRef = ref();
|
||||
const textContent = ref('');
|
||||
@ -319,34 +323,50 @@ const getJqList = () => {
|
||||
const handleHs = (val) => {
|
||||
router.push({ path: '/MeetingRoom', query: { tsypid: val.id } })
|
||||
}
|
||||
|
||||
const visible = ref(false)
|
||||
const search = ref({})
|
||||
const handleYP = () => {
|
||||
let arr=cascaRef.value.getCheckedNodes()
|
||||
searchForm.value.jqlbdms=arr.map((el)=>{
|
||||
return el.value
|
||||
})
|
||||
let params = {
|
||||
hskssj: searchForm.value.kssj,
|
||||
hsjssj: searchForm.value.jssj,
|
||||
jqlbdms:searchForm.value.jqlbdms
|
||||
console.log(searchList.value);
|
||||
visible.value = true
|
||||
let data = []
|
||||
if (searchList.value.lx) {
|
||||
data = searchList.value.lx.map(item => {
|
||||
return item[item.length - 1]
|
||||
})
|
||||
|
||||
}
|
||||
qcckPost(params, '/mosty-gsxt/lzJcjPjdb/getJqDcypbg').then(res => {
|
||||
let data = res || {};
|
||||
let html = `<p class="html_bt">${data.bt}</p>`
|
||||
html += `<p>${data.head}</p>`
|
||||
html += `<p>${data.nr}</p>`
|
||||
html += `<p>${data.bc}</p>`
|
||||
html += `<p>${data.end}</p>`
|
||||
textContent.value = html;
|
||||
showModel.value = true;
|
||||
})
|
||||
search.value = {
|
||||
lx: searchList.value.lx ? data : '',
|
||||
startTime: searchList.value.datetimes ? searchList.value.datetimes[0] : '',
|
||||
endTime: searchList.value.datetimes ? searchList.value.datetimes[1] : '',
|
||||
}
|
||||
|
||||
// let arr=cascaRef.value.getCheckedNodes()
|
||||
// searchForm.value.jqlbdms=arr.map((el)=>{
|
||||
// return el.value
|
||||
// })
|
||||
// let params = {
|
||||
// hskssj: searchForm.value.kssj,
|
||||
// hsjssj: searchForm.value.jssj,
|
||||
// jqlbdms:searchForm.value.jqlbdms
|
||||
// }
|
||||
// qcckPost(params, '/mosty-gsxt/lzJcjPjdb/getJqDcypbg').then(res => {
|
||||
// let data = res || {};
|
||||
// let html = `<p class="html_bt">${data.bt}</p>`
|
||||
// html += `<p>${data.head}</p>`
|
||||
// html += `<p>${data.nr}</p>`
|
||||
// html += `<p>${data.bc}</p>`
|
||||
// html += `<p>${data.end}</p>`
|
||||
// textContent.value = html;
|
||||
// showModel.value = true;
|
||||
// })
|
||||
}
|
||||
|
||||
// 选择类型
|
||||
const changeCascader = (val) => {
|
||||
console.log(val,'val');
|
||||
console.log(cascaRef.value.getCheckedNodes(),'++++++++');
|
||||
|
||||
console.log(val, 'val');
|
||||
console.log(cascaRef.value.getCheckedNodes(), '++++++++');
|
||||
|
||||
readonly_lx.value = false;
|
||||
readonly_ry.value = val ? true : false
|
||||
readonly_dd.value = val ? true : false
|
||||
@ -372,6 +392,7 @@ const changeBm = (val) => {
|
||||
}
|
||||
// 重置
|
||||
const resetForm = () => {
|
||||
searchList.value = {}
|
||||
searchForm.value = {}
|
||||
readonly_lx.value = false
|
||||
readonly_ry.value = false
|
||||
@ -381,7 +402,25 @@ const resetForm = () => {
|
||||
// 搜索
|
||||
const onSearch = () => {
|
||||
if (searchList.value.lx || searchList.value.ry || searchList.value.dd) {
|
||||
detaileRef.value.init(searchList.value)
|
||||
const data= searchList.value.lx.map(item => {
|
||||
return item[item.length - 1]
|
||||
})
|
||||
console.log(searchList.value);
|
||||
|
||||
const promes = {
|
||||
startTime: searchList.value.datetimes ? searchList.value.datetimes[0] : '',
|
||||
endTime: searchList.value.datetimes ? searchList.value.datetimes[1] : '',
|
||||
bjlbs: searchList.value.lx ? data.join(',') : '',
|
||||
}
|
||||
console.log(promes);
|
||||
|
||||
tbJqGetPageList(promes).then(res => {
|
||||
list[1].tableList = res.records || [];
|
||||
list[1].pageConfiger.total = res.total;
|
||||
})
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
ElMessage.warning('请选择查询条件')
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="modelValue" center width="1000px" :destroy-on-close="true" title="网上会商" @close="close"
|
||||
<el-dialog v-model="props.modelValue" center width="1000px" :destroy-on-close="true" title="网上会商" @close="close"
|
||||
:close-on-click-modal="false">
|
||||
<div class="cntBox">
|
||||
<div class="form_item flex">
|
||||
|
||||
@ -79,11 +79,11 @@ const pageData = reactive({
|
||||
tableColumn: [
|
||||
{
|
||||
label: "研判标题",
|
||||
prop: "ypbt"
|
||||
prop: "jymc"
|
||||
},
|
||||
{
|
||||
label: "研判时间",
|
||||
prop: "ypsj"
|
||||
prop: "fbsj"
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
@ -1,107 +0,0 @@
|
||||
<template>
|
||||
<div class="dialog" v-if="dialogForm">
|
||||
<div class="head_box">
|
||||
<span class="title">{{ title }}模型 </span>
|
||||
<div>
|
||||
<el-button type="primary" size="small" :loading="loading" @click="submit" v-show="title != '详情'">保存</el-button>
|
||||
<el-button size="small" @click="close">关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form_cnt">
|
||||
<FormMessage :formList="formData" v-model="listQuery" ref="elform" :rules="rules" :disabled="editAdd">
|
||||
</FormMessage>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, getCurrentInstance } from 'vue'
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import { addEntity,editEntity } from '@/api/model.js'
|
||||
import { ElMessage } from "element-plus";
|
||||
const proxy = getCurrentInstance()
|
||||
const props = defineProps({
|
||||
dict: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
}
|
||||
})
|
||||
const dialogForm = ref(false)
|
||||
const emit = defineEmits(['getLits'])
|
||||
// 判断是否增删改
|
||||
const editAdd = ref(false)
|
||||
const title = ref("新增")
|
||||
const formData = ref()
|
||||
const listQuery = ref({})
|
||||
const elform = ref()
|
||||
const rules = ref({
|
||||
mxmc: [
|
||||
{ required: true, message: '请输入模型名称', trigger: 'blur' },
|
||||
],
|
||||
mxlx: [
|
||||
{ required: true, message: '请选择模型类型', trigger: 'change' },
|
||||
],
|
||||
})
|
||||
const init = (type, row) => {
|
||||
dialogForm.value = true
|
||||
editAdd.value = false
|
||||
formData.value = [
|
||||
{ label: "模型名称", prop: "mxmc", type: "input", width: "40%" },
|
||||
{
|
||||
label: "模型类型", prop: "mxlx", type: "select",
|
||||
width: "40%", options: props.dict.D_MXGL_MXLX
|
||||
},
|
||||
]
|
||||
listQuery.value = { ...row }
|
||||
if (type == 'edit') {
|
||||
title.value = "编辑"
|
||||
} else if (type == 'add') {
|
||||
title.value = "新增"
|
||||
} else {
|
||||
editAdd.value = true
|
||||
title.value = "详情"
|
||||
}
|
||||
}
|
||||
|
||||
// 表单内容
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
// 新增
|
||||
const submit = () => {
|
||||
elform.value.submit((data) => {
|
||||
loading.value = true
|
||||
if (title.value == '新增') {
|
||||
addEntity(listQuery.value).then((res) => {
|
||||
ElMessage.success("新增成功");
|
||||
emit('getLits')
|
||||
dialogForm.value = false
|
||||
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
});
|
||||
} else {
|
||||
editEntity(listQuery.value).then((res) => {
|
||||
ElMessage.success("修改成功");
|
||||
emit('getLits')
|
||||
dialogForm.value = false
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭
|
||||
const close = () => {
|
||||
dialogForm.value = false
|
||||
}
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@ -1,290 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="titleBox">
|
||||
<PageTitle title="预警规则">
|
||||
<el-button type="primary" size="small" @click="openAddRule('add', item)">新增</el-button>
|
||||
<el-button type="primary" size="small" :disabled="ids.length == 0" @click="deleteRule(ids)">批量删除</el-button>
|
||||
<el-button size="small" @click="retenHome()">返回</el-button>
|
||||
</PageTitle>
|
||||
</div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData">
|
||||
<template #tjName="{ row }">
|
||||
<div class="flex one_text_detail" v-if="row.tj">{{ ` ${row.tj} ${row.cs}` }} </div>
|
||||
</template>
|
||||
<template #zz="{ row }">
|
||||
<template v-if="row.zz">
|
||||
<span v-for="(item, index) in jsonParse(row.zz)" :key="index">{{ item.zzmc }}
|
||||
<span v-if="index < jsonParse(row.zz).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #sfbq="{ row }">
|
||||
<template v-if="row.sfbq">
|
||||
<span v-for="(item, index) in jsonParse(row.sfbq)" :key="index">{{ item.bqmc }}
|
||||
<span v-if="index < jsonParse(row.sfbq).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #xwbq="{ row }">
|
||||
<template v-if="row.xwbq">
|
||||
<span v-for="(item, index) in jsonParse(row.xwbq)" :key="index">{{ item.bqmc }}
|
||||
<span v-if="index < jsonParse(row.xwbq).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #dd="{ row }">
|
||||
<template v-if="row.dd">
|
||||
<span v-for="(item, index) in jsonParse(row.dd)" :key="index">{{ item.dz }}
|
||||
<span v-if="index < jsonParse(row.dd).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #ryxx="{ row }">
|
||||
<template v-if="row.ryxx">
|
||||
<span v-for="(item, index) in jsonParse(row.ryxx)" :key="index">{{ item.xm }}
|
||||
<span v-if="index < jsonParse(row.ryxx).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #jqlx="{ row }">
|
||||
<template v-if="row.jqlx">
|
||||
<span v-for="(item, index) in jsonParse(row.jqlx)" :key="index">{{ item.lxmc }}
|
||||
<span v-if="index < jsonParse(row.jqlx).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #sjlx="{ row }">
|
||||
<template v-if="row.sjlx">
|
||||
<span v-for="(item, index) in jsonParse(row.sjlx)" :key="index">{{ item.lxmc }}
|
||||
<span v-if="index < jsonParse(row.sjlx).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #wp="{ row }">
|
||||
<template v-if="row.wp">
|
||||
<span v-for="(item, index) in jsonParse(row.wp)" :key="index">{{ item.wpmc }}
|
||||
<span v-if="index < jsonParse(row.wp).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #controls="{ row }">
|
||||
<el-link type="primary" size="small" @click="yzSsyjpzMxgzxl( row.id)">运行规则</el-link>
|
||||
<el-link type="primary" size="small" @click="openAddRule('edit',item, row)">修改</el-link>
|
||||
<el-link type="primary" size="small" @click="openAddRule('detail',item, row)">详情</el-link>
|
||||
<!-- <el-link type="primary" size="small" @click="openAddRule('detail',item, row)">预警列表</el-link> -->
|
||||
<el-link type="danger" size="small" @click="deleteRule(row.id)">删除</el-link>
|
||||
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"></Pages>
|
||||
</div>
|
||||
</div>
|
||||
<List ref="regulation" :dict="{ D_BB_AJLB,D_BZ_WPLX }" @getList="getList" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessage } from "element-plus";
|
||||
import List from "../list";
|
||||
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import { deleteYjgzpz,getYjgzpzMxgzxl,getYjgzpzPageList } from "@/api/model";
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import Pages from "@/components/aboutTable/Pages.vue";
|
||||
import Search from "@/components/aboutTable/Search.vue";
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
import { template } from "lodash";
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BB_AJLB,D_BZ_WPLX} = proxy.$dict("D_BB_AJLB","D_BZ_WPLX")
|
||||
const regulation = ref(null)
|
||||
const queryFrom = ref({})
|
||||
const searchBox = ref(); //搜索框
|
||||
|
||||
const searchConfiger = ref([
|
||||
{
|
||||
label: "规则名称",
|
||||
prop: "gzmc",
|
||||
placeholder: "请输入规则名称",
|
||||
showType: "input"
|
||||
},
|
||||
{
|
||||
label: "时间",
|
||||
prop: "startTime",
|
||||
placeholder: "请选择时间",
|
||||
showType: "daterange"
|
||||
},
|
||||
]);
|
||||
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
keyCount: 0,
|
||||
tableConfiger: {
|
||||
rowHieght: 61,
|
||||
showSelectType: "null",
|
||||
loading: false
|
||||
},
|
||||
total: 0,
|
||||
pageConfiger: {
|
||||
pageSize: 20,
|
||||
pageCurrent: 1
|
||||
},
|
||||
controlsWidth: 300,
|
||||
tableColumn: [
|
||||
{ label: "规则名称", prop: "gzmc", showOverflowTooltip: true },
|
||||
{ label: "开始时间", prop: "jssj", showOverflowTooltip: true },
|
||||
{ label: "结束时间", prop: "kssj", showOverflowTooltip: true },
|
||||
{ label: "条件", prop: "tjName", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "组织", prop: "zz", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "人员信息", prop: "ryxx", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "警情类型", prop: "jqlx", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "事件类型", prop: "sjlx", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "物品", prop: "wp", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "地址", prop: "dd", showOverflowTooltip: true, showSolt: true },
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
tabHeightFn();
|
||||
});
|
||||
|
||||
// 搜索
|
||||
const onSearch = (val) => {
|
||||
queryFrom.value = { ...val };
|
||||
queryFrom.value.startTime = val.startTime&&val.startTime.length > 0 ? val.startTime[0] : '';
|
||||
queryFrom.value.endTime = val.startTime&&val.startTime.length > 0 ? val.startTime[1] : '';
|
||||
pageData.pageConfiger.pageCurrent = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
const changeNo = (val) => {
|
||||
pageData.pageConfiger.pageCurrent = val;
|
||||
getList();
|
||||
};
|
||||
|
||||
const changeSize = (val) => {
|
||||
pageData.pageConfiger.pageSize = val;
|
||||
getList();
|
||||
};
|
||||
//
|
||||
// 获取列表
|
||||
const getList = () => {
|
||||
const promes = {
|
||||
...pageData.pageConfiger,
|
||||
...queryFrom.value,
|
||||
mxid:props.item.id,
|
||||
}
|
||||
getYjgzpzPageList(promes).then((res) => {
|
||||
pageData.tableData = res.records
|
||||
pageData.total = res.total
|
||||
});
|
||||
};
|
||||
const retenHome = () => {
|
||||
emitter.emit('changeModel', { name: '研判首页', row: {} });
|
||||
}
|
||||
const openAddRule = (type, item, row) => {
|
||||
regulation.value.init(type, item, row)
|
||||
}
|
||||
const ids = ref([])
|
||||
|
||||
const chooseData = (val) => {
|
||||
ids.value = val.map(item => item.id)
|
||||
}
|
||||
const deleteRule = (row) => {
|
||||
proxy.$confirm('是否删除该规则, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let list
|
||||
if (Array.isArray(row)) {
|
||||
list = ids.value
|
||||
} else {
|
||||
list =[row]
|
||||
}
|
||||
deleteYjgzpz({ids:list}).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
getList()
|
||||
})
|
||||
}).catch((err) => {
|
||||
proxy.$message({
|
||||
type: 'info',
|
||||
message: '已取消删除'
|
||||
});
|
||||
});
|
||||
}
|
||||
const yzSsyjpzMxgzxl = (params) => {
|
||||
getYjgzpzMxgzxl({id:params}).then((res) => {
|
||||
console.log(res);
|
||||
})
|
||||
}
|
||||
const jsonParse = (val) => {
|
||||
if (val) {
|
||||
return JSON.parse(val)
|
||||
}
|
||||
}
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.basic-info {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
|
||||
.avatar {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.info-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.control-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -1,696 +0,0 @@
|
||||
<template>
|
||||
<!-- 可用条件类型列表 -->
|
||||
<div class="regulation-wrapper">
|
||||
<div class="rule-name-section flex align-center">
|
||||
<div class="rule-name-label">规则名称:</div>
|
||||
<el-input v-model="gzmc" :disabled="disabled" placeholder="请输入规则名称" class="search-input" clearable></el-input>
|
||||
</div>
|
||||
<!-- 可用条件区域 -->
|
||||
<div class="condition-section">
|
||||
<div class="available-conditions">
|
||||
<VueDraggable class="flex-wrap" v-model="dataList" ghostClass="ghost"
|
||||
:group="{ name: 'people', pull: 'clone', put: false }" :clone="clone">
|
||||
<el-button v-for="item in dataList" :key="item.name" class="condition-button" size="small">
|
||||
<i class="el-icon-document-add"></i>
|
||||
{{ item.name }}
|
||||
</el-button>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 拖拽提示 -->
|
||||
<div class="drag-hint">
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
<span>拖拽条件到下方区域</span>
|
||||
</div>
|
||||
|
||||
<!-- 已选条件区域 -->
|
||||
<div class="selected-section">
|
||||
<div class="section-title">
|
||||
<i class="el-icon-check-square"></i>
|
||||
<span>已选条件</span>
|
||||
<span class="selected-count">{{ copyList.length }}</span>
|
||||
</div>
|
||||
<div class="selected-container">
|
||||
<VueDraggable v-model="copyList" :group="{ name: 'people', pull: !disabled, put: !disabled }" ghostClass="ghost"
|
||||
class="selected-list" itemKey="name">
|
||||
<div v-for="(item, indexs) in copyList" :key="item" class="draggable-item">
|
||||
<div class="item-content">
|
||||
<div v-if="!disabled" class="item-remove-btn" @click="romes(item)"><el-icon :size="16">
|
||||
<Close />
|
||||
</el-icon></div>
|
||||
<span class="item-text">{{ item.name }}{{}}</span>
|
||||
</div>
|
||||
<div v-if="item[item['key']]">
|
||||
<template v-if="item.key == 'dd'">
|
||||
<div class="condition-input-container flex just-between" v-for="(value, index) in item[item['key']]">
|
||||
<div>
|
||||
<el-input v-model="item[item['key']][index]" :placeholder="`请输入${item.name}`" clearable></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-button class="btn-margin-right" v-if="index == item[item['key']].length - 1"
|
||||
@click="addInput(item['key'], indexs)" type="danger" size="mini">+</el-button>
|
||||
<el-button class="btn-margin-right" v-if="index != item[item['key']].length - 1"
|
||||
@click="removeItem(item['key'], index)" type="danger" size="mini">-</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.key == 'cs'">
|
||||
<div class="count-condition-container">
|
||||
<el-select v-model="item[item['key']].tj" placeholder="请选择条件" class="condition-select">
|
||||
<el-option :label="item" :value="item" v-for="(item, index) in dataConst" :key="index"></el-option>
|
||||
</el-select>
|
||||
<el-input-number v-model="item[item['key']].cs" :min="1" :max="1000" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.key == 'zz'">
|
||||
<div class="condition-input-container flex just-between" v-for="(value, index) in item[item['key']]">
|
||||
<div>
|
||||
<el-input v-model="item[item['key']][index]" :placeholder="`请输入${item.name}`" clearable></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-button class="btn-margin-right" v-if="index == item[item['key']].length - 1"
|
||||
@click="addInput(item['key'], indexs)" type="danger" size="mini">+</el-button>
|
||||
<el-button class="btn-margin-right" v-if="index != item[item['key']].length - 1"
|
||||
@click="removeItem(item['key'], index)" type="danger" size="mini">-</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.key == 'kssj'">
|
||||
<div class="condition-input-container flex just-between">
|
||||
<div>
|
||||
<el-date-picker value-format="YYYY-MM-DD" format="YYYY-MM-DD" v-model="item[item['key']]"
|
||||
type="date" :placeholder="`请选择${item.name}`" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.key == 'jssj'">
|
||||
<div class="condition-input-container flex just-between">
|
||||
<div>
|
||||
<el-date-picker value-format="YYYY-MM-DD" format="YYYY-MM-DD" v-model="item[item['key']]"
|
||||
type="date" :placeholder="`请选择${item.name}`" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="item.key == 'sjlx'">
|
||||
<div class="condition-input-container flex just-between">
|
||||
<el-select v-model="item[item['key']]" multiple :placeholder="`请选择${item.name}`">
|
||||
<el-option v-for="item in dict.D_BB_AJLB" :key="item.dm" :label="item.zdmc" :value="item.dm" />
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.key == 'wp'">
|
||||
<div class="condition-input-container flex just-between">
|
||||
<el-select v-model="item[item['key']]" multiple :placeholder="`请选择${item.name}`" style="width: 240px">
|
||||
<el-option v-for="item in dict.D_BZ_WPLX" :key="item.dm" :label="item.zdmc" :value="item.dm" />
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.key == 'ryxx'">
|
||||
<div class="condition-input-container flex just-between" v-for="(value, index) in item[item['key']]">
|
||||
<div>
|
||||
<el-input v-model="item[item['key']][index].xm" :placeholder="`请输入姓名`" clearable></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-input v-model="item[item['key']][index].sfzh" :placeholder="`请输入身份证号`" clearable></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-button class="btn-margin-right" v-if="index == item[item['key']].length - 1"
|
||||
@click="addInput(item['key'], indexs)" type="danger" size="mini">+</el-button>
|
||||
<el-button class="btn-margin-right" v-if="index != item[item['key']].length - 1"
|
||||
@click="removeItem(item['key'], index)" type="danger" size="mini">-</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="item.key == 'jqlx'">
|
||||
<div class="condition-input-container flex just-between" v-for="(value, index) in item[item['key']]">
|
||||
<div>
|
||||
<el-input @click="chooseMarksVisible = true" v-model="item[item['key']][index].lxmc"
|
||||
:placeholder="`请输入${item.name}`" clearable></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-button class="btn-margin-right" @click="removeItem(item['key'], index)" type="danger"
|
||||
size="mini">-</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</VueDraggable>
|
||||
|
||||
<!-- 空状态提示 -->
|
||||
<div v-if="copyList.length === 0" class="empty-state">
|
||||
<i class="el-icon-tickets"></i>
|
||||
<p>暂无已选条件</p>
|
||||
<p class="empty-tip">从上方拖拽条件到此处</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ChooseIdeJqlb v-model="chooseMarksVisible" @choosed="choosed" :roleIds="roleIds" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { ElMessage } from "element-plus";
|
||||
import ChooseIdeJqlb from '@/components/ChooseList/ChooseIdeJqlb/index.vue'
|
||||
import { VueDraggable } from 'vue-draggable-plus'//npm install vue-draggable-plus
|
||||
const props = defineProps({
|
||||
dict: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
'Joao',
|
||||
'Jean',
|
||||
'Johanna',
|
||||
'Juan',
|
||||
],
|
||||
}, defaultData: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
}, disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const dataConst = reactive([
|
||||
">",
|
||||
"<",
|
||||
"="
|
||||
])
|
||||
const gzmc = ref('')
|
||||
const dataList = ref(props.list)
|
||||
const copyList = ref([])
|
||||
const clone = (val) => {
|
||||
if (val.key == 'jqlx') {
|
||||
dataList.value = dataList.value.filter(item => item.key != 'sjlx')
|
||||
}
|
||||
if (val.key == 'sjlx') {
|
||||
dataList.value = dataList.value.filter(item => item.key != 'jqlx')
|
||||
}
|
||||
const data = copyList.value.find(item => item.name == val.name)
|
||||
if (data) {
|
||||
console.log("已存在")
|
||||
} else {
|
||||
switch (val.key) {
|
||||
case 'cs':
|
||||
return {
|
||||
name: val.name,
|
||||
key: val.key,
|
||||
[val["key"]]: {}
|
||||
}
|
||||
case "wp":
|
||||
return {
|
||||
name: val.name,
|
||||
key: val.key,
|
||||
[val["key"]]: []
|
||||
}
|
||||
case 'ryxx':
|
||||
return {
|
||||
name: val.name,
|
||||
key: val.key,
|
||||
[val["key"]]: [{
|
||||
xm: "",
|
||||
sfzh: ""
|
||||
}]
|
||||
}
|
||||
case 'kssj':
|
||||
case 'jssj':
|
||||
return {
|
||||
name: val.name,
|
||||
key: val.key,
|
||||
[val["key"]]: []
|
||||
}
|
||||
case 'sjlx':
|
||||
return {
|
||||
name: val.name,
|
||||
key: val.key,
|
||||
[val["key"]]: []
|
||||
}
|
||||
default:
|
||||
return {
|
||||
name: val.name,
|
||||
key: val.key,
|
||||
[val["key"]]: [""]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
watch(() => props.defaultData, (val) => {
|
||||
if (val) {
|
||||
gzmc.value = val.gzmc
|
||||
const data = props.list.map(item => {
|
||||
switch (item.key) {
|
||||
case 'cs':
|
||||
return {
|
||||
name: item.name,
|
||||
key: item.key,
|
||||
[item["key"]]: val.cs && val.tj ? {
|
||||
cs: val.cs,
|
||||
tj: val.tj
|
||||
} : null
|
||||
}
|
||||
case 'jssj':
|
||||
case 'kssj':
|
||||
return {
|
||||
name: item.name,
|
||||
key: item.key,
|
||||
[item["key"]]: val[item.key] ? val[item.key] : null,
|
||||
}
|
||||
case 'zz':
|
||||
return {
|
||||
name: item.name,
|
||||
key: item.key,
|
||||
[item["key"]]: val[item.key] ? JSON.parse(val[item.key]).map(item => item.zzmc) : null,
|
||||
}
|
||||
case 'dd':
|
||||
return {
|
||||
name: item.name,
|
||||
key: item.key,
|
||||
[item["key"]]: val[item.key] ? JSON.parse(val[item.key]).map(item => item.dz) : null,
|
||||
}
|
||||
default:
|
||||
return {
|
||||
name: item.name,
|
||||
key: item.key,
|
||||
[item["key"]]: val[item.key] ? JSON.parse(val[item.key]) : null
|
||||
}
|
||||
}
|
||||
})
|
||||
copyList.value = data.filter(item => item[item.key] != null)
|
||||
}
|
||||
}, { deep: true, immediate: true })
|
||||
const addInput = (key, index) => {
|
||||
if (key == 'ryxx') {
|
||||
copyList.value[index][key].push({
|
||||
xm: "",
|
||||
sfzh: ""
|
||||
})
|
||||
} else {
|
||||
copyList.value[index][key].push("")
|
||||
}
|
||||
}
|
||||
|
||||
// 移除项目
|
||||
const removeItem = (key, index) => {
|
||||
const data = copyList.value.findIndex(item => item.key == key)
|
||||
if (copyList.value[data][key].length == 1) {
|
||||
return
|
||||
}
|
||||
copyList.value[data][key].splice(index, 1)
|
||||
}
|
||||
const chooseMarksVisible = ref(false)
|
||||
const roleIds = ref([])
|
||||
const choosed = (val) => {
|
||||
roleIds.value = val.map(item => item.id)
|
||||
copyList.value.find(item => item.key == 'jqlx')['jqlx'] = val.map(item => {
|
||||
return {
|
||||
lxmc: item.zdmc,
|
||||
lxdm: item.dm
|
||||
}
|
||||
})
|
||||
}
|
||||
const romes = (val) => {
|
||||
copyList.value = copyList.value.filter(item => item.key !== val.key)
|
||||
if (val.key == 'jqlx' || val.key == 'sjlx') {
|
||||
dataList.value = props.list
|
||||
}
|
||||
}
|
||||
|
||||
const promes = ref({})
|
||||
// 新增
|
||||
const retValue = () => {
|
||||
if (gzmc.value == '') {
|
||||
return
|
||||
}
|
||||
const data = copyList.value.map(item => {
|
||||
return {
|
||||
[item.key]: item[item.key]
|
||||
}
|
||||
})
|
||||
promes.value = data.reduce((acc, cur) => {
|
||||
return { ...acc, ...cur }
|
||||
}, {})
|
||||
promes.value = { ...promes.value, ...promes.value.cs, gzmc: gzmc.value }
|
||||
if (promes.value.dd && promes.value.dd.length > 0) {
|
||||
const dd = promes.value.dd.map(item => {
|
||||
return { dz: item }
|
||||
})
|
||||
promes.value.dd = JSON.stringify(dd)
|
||||
}
|
||||
if (promes.value.zz && promes.value.zz.length > 0) {
|
||||
const zz = promes.value.zz.map(item => {
|
||||
return { zzmc: item }
|
||||
})
|
||||
promes.value.zz = JSON.stringify(zz)
|
||||
}
|
||||
const sjlx = copyList.value.find(item => item.key == 'sjlx')
|
||||
if (sjlx) {
|
||||
const data = props.dict.D_BB_AJLB.filter(item => {
|
||||
if (sjlx['sjlx'].includes(item.dm)) {
|
||||
return item
|
||||
}
|
||||
}).map(item => {
|
||||
return {
|
||||
lxmc: item.zdmc,
|
||||
lxdm: item.dm
|
||||
}
|
||||
})
|
||||
promes.value.sjlx = JSON.stringify(data)
|
||||
}
|
||||
const wplx = copyList.value.find(item => item.key == 'wp')
|
||||
if (wplx) {
|
||||
const data = props.dict.D_BZ_WPLX.filter(item => {
|
||||
if (wplx['wp'].includes(item.dm)) {
|
||||
return item
|
||||
}
|
||||
}).map(item => {
|
||||
return {
|
||||
wpmc: item.zdmc,
|
||||
wpdm: item.dm
|
||||
}
|
||||
})
|
||||
promes.value.wp = JSON.stringify(data)
|
||||
}
|
||||
if (promes.value.ryxx && promes.value.ryxx.length > 0) {
|
||||
promes.value.ryxx = JSON.stringify(promes.value.ryxx)
|
||||
}
|
||||
if (promes.value.jqlx && promes.value.jqlx.length > 0) {
|
||||
promes.value.jqlx = JSON.stringify(promes.value.jqlx)
|
||||
}
|
||||
return promes.value
|
||||
}
|
||||
defineExpose({
|
||||
retValue
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.regulation-wrapper {
|
||||
padding: 20px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
// 条件区域通用样式
|
||||
.condition-section,
|
||||
.selected-section {
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
// margin-bottom: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.condition-section:hover,
|
||||
.selected-section:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
// 区域标题
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 2px solid #e6f7ff;
|
||||
|
||||
i {
|
||||
color: #409eff;
|
||||
margin-right: 8px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.selected-count {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: #606266;
|
||||
background: #f0f9ff;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
min-width: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
// 可用条件区域
|
||||
.available-conditions {
|
||||
// min-height: 100px;
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.condition-button {
|
||||
background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
|
||||
color: white !important;
|
||||
border: none !important;
|
||||
border-radius: 8px !important;
|
||||
padding: 8px 16px !important;
|
||||
font-size: 14px !important;
|
||||
transition: all 0.3s ease !important;
|
||||
min-width: 120px;
|
||||
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #66b1ff 0%, #409eff 100%) !important;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
|
||||
}
|
||||
|
||||
i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
// 拖拽提示
|
||||
.drag-hint {
|
||||
display: flex;
|
||||
align-content: flex-start;
|
||||
// align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
|
||||
i {
|
||||
margin-right: 8px;
|
||||
font-size: 16px;
|
||||
animation: bounce 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
|
||||
0%,
|
||||
20%,
|
||||
50%,
|
||||
80%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
40% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 已选条件区域
|
||||
.selected-container {
|
||||
min-height: 120px;
|
||||
border: 2px dashed #dcdfe6;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
transition: all 0.3s ease;
|
||||
background-color: #dcdfe670;
|
||||
|
||||
&:hover {
|
||||
border-color: #409eff;
|
||||
background: #f0f9ff;
|
||||
}
|
||||
}
|
||||
|
||||
.selected-list {
|
||||
display: flex;
|
||||
min-height: 100px;
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
// 拖拽项样式
|
||||
.draggable-item {
|
||||
position: relative;
|
||||
padding: 3px;
|
||||
margin: 8px;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
display: table-cell;
|
||||
justify-content: space-between;
|
||||
text-align: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px) scale(1.02);
|
||||
box-shadow: 0 6px 16px rgba(103, 194, 58, 0.4);
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
opacity: 0.6;
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
}
|
||||
|
||||
.item-content {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px 12px 12px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-width: 140px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.item-text {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.item-remove {
|
||||
color: #c0c4cc;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
padding: 4px;
|
||||
border-radius: 50%;
|
||||
|
||||
&:hover {
|
||||
color: #f56c6c;
|
||||
background: #fef0f0;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* 规则名称区域 */
|
||||
.rule-name-section {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.rule-name-label {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
/* 项目删除按钮 */
|
||||
.item-remove-btn {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
/* 条件输入容器 */
|
||||
.condition-input-container {
|
||||
flex-wrap: nowrap;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* 计数条件容器 */
|
||||
.count-condition-container {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* 条件选择框 */
|
||||
.condition-select {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
/* 按钮右侧边距 */
|
||||
.btn-margin-right {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
// 空状态样式
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
color: #909399;
|
||||
|
||||
i {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
color: #dcdfe6;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
font-size: 12px;
|
||||
color: #c0c4cc;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
&:hover i {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
// 拖拽效果
|
||||
.ghost {
|
||||
opacity: 0.6;
|
||||
background-color: #e6f7ff;
|
||||
border: 2px dashed #409eff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 768px) {
|
||||
.regulation-wrapper {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.condition-section,
|
||||
.selected-section {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.condition-button {
|
||||
min-width: 100px;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
min-width: 120px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
:v-deep .el-select {
|
||||
width: 59%;
|
||||
}
|
||||
</style>
|
||||
@ -1,257 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="titleBox">
|
||||
<PageTitle title="四色预警规则">
|
||||
<el-button type="primary" size="small" @click="openAddRule('add', item)">新增</el-button>
|
||||
<el-button type="primary" size="small" :disabled="ids.length == 0" @click="deleteRule(ids)">批量删除</el-button>
|
||||
<el-button size="small" @click="retenHome()">返回</el-button>
|
||||
</PageTitle>
|
||||
</div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData">
|
||||
<!-- <template #tjName="{ row }">
|
||||
<div class="flex one_text_detail">{{ ` ${row.tj} ${row.cs}` }} </div>
|
||||
</template> -->
|
||||
<!-- <template #fxDj="{ row }">
|
||||
<DictTag :tag="false" :value="row.fxDj" :options="D_GS_RQFJ_FXDJ"/>
|
||||
</template> -->
|
||||
<template #zz="{ row }">
|
||||
<template v-if="row.zz">
|
||||
<span v-for="(item, index) in jsonParse(row.zz)" :key="index">{{ item.zzmc }}
|
||||
<span v-if="index < jsonParse(row.zz).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #sfbq="{ row }">
|
||||
<template v-if="row.sfbq">
|
||||
<span v-for="(item, index) in jsonParse(row.sfbq)" :key="index">{{ item.bqmc }}
|
||||
<span v-if="index < jsonParse(row.sfbq).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #xwbq="{ row }">
|
||||
<template v-if="row.xwbq">
|
||||
<span v-for="(item, index) in jsonParse(row.xwbq)" :key="index">{{ item.bqmc }}
|
||||
<span v-if="index < jsonParse(row.xwbq).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #dd="{ row }">
|
||||
<template v-if="row.dd">
|
||||
<span v-for="(item, index) in jsonParse(row.dd)" :key="index">{{ item.dz }}
|
||||
<span v-if="index < jsonParse(row.dd).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #controls="{ row }">
|
||||
<el-link type="primary" size="small" @click="yzSsyjpzMxgzxl( row.id)">运行规则</el-link>
|
||||
<el-link type="primary" size="small" @click="openAddRule('edit',item, row)">修改</el-link>
|
||||
<el-link type="primary" size="small" @click="openAddRule('detail',item, row)">详情</el-link>
|
||||
<!-- <el-link type="primary" size="small" @click="openAddRule('detail',item, row)">预警列表</el-link> -->
|
||||
<el-link type="danger" size="small" @click="deleteRule(row.id)">删除</el-link>
|
||||
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"></Pages>
|
||||
</div>
|
||||
</div>
|
||||
<List ref="regulation" :dict="{ D_BZ_RYBQ }" @getList="getList" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessage } from "element-plus";
|
||||
import List from "../list";
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import { getSsyjpzPageList, deleteSsyjpz,getSsyjpzMxgzxl } from "@/api/model";
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import Pages from "@/components/aboutTable/Pages.vue";
|
||||
import Search from "@/components/aboutTable/Search.vue";
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
import { template } from "lodash";
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_RYBQ } = proxy.$dict("D_BZ_RYBQ")
|
||||
const regulation = ref(null)
|
||||
const queryFrom = ref({})
|
||||
const searchBox = ref(); //搜索框
|
||||
|
||||
const searchConfiger = ref([
|
||||
{
|
||||
label: "规则名称",
|
||||
prop: "gzmc",
|
||||
placeholder: "请输入规则名称",
|
||||
showType: "input"
|
||||
},
|
||||
{
|
||||
label: "时间",
|
||||
prop: "startTime",
|
||||
placeholder: "请选择时间",
|
||||
showType: "daterange"
|
||||
},
|
||||
]);
|
||||
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
keyCount: 0,
|
||||
tableConfiger: {
|
||||
rowHieght: 61,
|
||||
showSelectType: "null",
|
||||
loading: false
|
||||
},
|
||||
total: 0,
|
||||
pageConfiger: {
|
||||
pageSize: 20,
|
||||
pageCurrent: 1
|
||||
},
|
||||
controlsWidth: 300,
|
||||
tableColumn: [
|
||||
{ label: "规则名称", prop: "gzmc", showOverflowTooltip: true },
|
||||
{ label: "开始时间", prop: "jssj", showOverflowTooltip: true },
|
||||
{ label: "结束时间", prop: "kssj", showOverflowTooltip: true },
|
||||
// { label: "条件", prop: "tjName", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "组织", prop: "zz", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "身份标签", prop: "sfbq", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "行为标签", prop: "xwbq", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "地址", prop: "dd", showOverflowTooltip: true, showSolt: true },
|
||||
]
|
||||
});
|
||||
onMounted(() => {
|
||||
getList();
|
||||
tabHeightFn();
|
||||
});
|
||||
|
||||
// 搜索
|
||||
const onSearch = (val) => {
|
||||
queryFrom.value.startTime = val.startTime&&val.startTime.length > 0 ? val.startTime[0] : '';
|
||||
queryFrom.value.endTime = val.startTime&&val.startTime.length > 0 ? val.startTime[1] : '';
|
||||
pageData.pageConfiger.pageCurrent = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
const changeNo = (val) => {
|
||||
pageData.pageConfiger.pageCurrent = val;
|
||||
getList();
|
||||
};
|
||||
|
||||
const changeSize = (val) => {
|
||||
pageData.pageConfiger.pageSize = val;
|
||||
getList();
|
||||
};
|
||||
//
|
||||
// 获取列表
|
||||
const getList = () => {
|
||||
|
||||
const promes = {
|
||||
...pageData.pageConfiger,
|
||||
...queryFrom.value,
|
||||
mxid:props.item.id
|
||||
}
|
||||
getSsyjpzPageList(promes).then((res) => {
|
||||
pageData.tableData = res.records
|
||||
pageData.total = res.total
|
||||
});
|
||||
};
|
||||
const retenHome = () => {
|
||||
emitter.emit('changeModel', { name: '研判首页', row: {} });
|
||||
}
|
||||
const openAddRule = (type, item, row) => {
|
||||
regulation.value.init(type, item, row)
|
||||
}
|
||||
const ids = ref([])
|
||||
|
||||
const chooseData = (val) => {
|
||||
ids.value = val.map(item => item.id)
|
||||
}
|
||||
const deleteRule = (row) => {
|
||||
proxy.$confirm('是否删除该规则, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let list
|
||||
if (Array.isArray(row)) {
|
||||
list = ids.value
|
||||
} else {
|
||||
list =[row]
|
||||
}
|
||||
deleteSsyjpz({ids:list}).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
getList()
|
||||
})
|
||||
}).catch((err) => {
|
||||
proxy.$message({
|
||||
type: 'info',
|
||||
message: '已取消删除'
|
||||
});
|
||||
});
|
||||
}
|
||||
const yzSsyjpzMxgzxl = (params) => {
|
||||
getSsyjpzMxgzxl({id:params}).then((res) => {
|
||||
console.log(res);
|
||||
})
|
||||
}
|
||||
const jsonParse = (val) => {
|
||||
if (val) {
|
||||
return JSON.parse(val)
|
||||
}
|
||||
}
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.basic-info {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
|
||||
.avatar {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.info-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.control-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -1,638 +0,0 @@
|
||||
<template>
|
||||
<!-- 可用条件类型列表 -->
|
||||
<div class="regulation-wrapper">
|
||||
<div class="rule-name-section flex align-center">
|
||||
<div class="rule-name-label">规则名称:</div>
|
||||
<el-input v-model="gzmc" :disabled="disabled" placeholder="请输入规则名称" class="search-input" clearable></el-input>
|
||||
</div>
|
||||
<!-- 可用条件区域 -->
|
||||
<div class="condition-section">
|
||||
<div class="available-conditions">
|
||||
<VueDraggable class="flex-wrap" v-model="dataList" ghostClass="ghost"
|
||||
:group="{ name: 'people', pull: 'clone', put: false }" :clone="clone">
|
||||
<el-button v-for="item in dataList" :key="item.name" class="condition-button" size="small">
|
||||
<i class="el-icon-document-add"></i>
|
||||
{{ item.name }}
|
||||
</el-button>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 拖拽提示 -->
|
||||
<div class="drag-hint">
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
<span>拖拽条件到下方区域</span>
|
||||
</div>
|
||||
|
||||
<!-- 已选条件区域 -->
|
||||
<div class="selected-section">
|
||||
<div class="section-title">
|
||||
<i class="el-icon-check-square"></i>
|
||||
<span>已选条件</span>
|
||||
<span class="selected-count">{{ copyList.length }}</span>
|
||||
</div>
|
||||
<div class="selected-container">
|
||||
<VueDraggable v-model="copyList" :group="{ name: 'people', pull: !disabled, put: !disabled }" ghostClass="ghost"
|
||||
class="selected-list" itemKey="name">
|
||||
<div v-for="(item, indexs) in copyList" :key="item" class="draggable-item">
|
||||
|
||||
<div class="item-content">
|
||||
<div v-if="!disabled" class="item-remove-btn" @click="romes(item)"><el-icon :size="16">
|
||||
<Close />
|
||||
</el-icon></div>
|
||||
<span class="item-text">{{ item.name }}</span>
|
||||
</div>
|
||||
<div v-if="item[item['key']]">
|
||||
<template v-if="item.key == 'dd'">
|
||||
<div class="condition-input-container flex just-between" v-for="(value, index) in item[item['key']]">
|
||||
<div>
|
||||
<el-input v-model="item[item['key']][index]" :placeholder="`请输入${item.name}`" clearable></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-button class="btn-margin-right" v-if="index == item[item['key']].length - 1"
|
||||
@click="addInput(item['key'], indexs)" type="danger" size="mini">+</el-button>
|
||||
<el-button class="btn-margin-right" v-if="index != item[item['key']].length - 1"
|
||||
@click="removeItem(item['key'], index)" type="danger" size="mini">-</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="item.key == 'sfbq'">
|
||||
<div class="condition-input-container flex just-between" v-for="(value, index) in item[item['key']]">
|
||||
<div>
|
||||
<el-input @click="chooseIdentityVisible = true" v-model="item[item['key']][index].bqmc"
|
||||
:placeholder="`请输入${item.name}`" clearable></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-button class="btn-margin-right" @click="removeItem(item['key'], index)" type="danger"
|
||||
size="mini">-</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- <template v-if="item.key == 'cs'">
|
||||
<div class="count-condition-container">
|
||||
<el-select v-model="item[item['key']].tj" placeholder="请选择条件" class="condition-select">
|
||||
<el-option :label="item" :value="item" v-for="(item, index) in dataConst" :key="index"></el-option>
|
||||
</el-select>
|
||||
<el-input-number v-model="item[item['key']].cs" :min="1" :max="1000" />
|
||||
</div>
|
||||
</template> -->
|
||||
<template v-if="item.key == 'xwbq'">
|
||||
<div class="condition-input-container flex just-between" v-for="(value, index) in item[item['key']]">
|
||||
<div>
|
||||
<el-input @click="chooseMarksVisible = true" v-model="item[item['key']][index].bqmc"
|
||||
:placeholder="`请输入${item.name}`" clearable></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-button class="btn-margin-right" @click="removeItem(item['key'], index)" type="danger"
|
||||
size="mini">-</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.key == 'zz'">
|
||||
<div class="condition-input-container flex just-between" v-for="(value, index) in item[item['key']]">
|
||||
<div>
|
||||
<el-input v-model="item[item['key']][index]" :placeholder="`请输入${item.name}`" clearable></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-button class="btn-margin-right" v-if="index == item[item['key']].length - 1"
|
||||
@click="addInput(item['key'], indexs)" type="danger" size="mini">+</el-button>
|
||||
<el-button class="btn-margin-right" v-if="index != item[item['key']].length - 1"
|
||||
@click="removeItem(item['key'], index)" type="danger" size="mini">-</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.key == 'kssj'">
|
||||
<div class="condition-input-container flex just-between">
|
||||
<div>
|
||||
<el-date-picker value-format="YYYY-MM-DD" format="YYYY-MM-DD" v-model="item[item['key']]"
|
||||
type="date" :placeholder="`请选择${item.name}`" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.key == 'jssj'">
|
||||
<div class="condition-input-container flex just-between">
|
||||
<div>
|
||||
<el-date-picker value-format="YYYY-MM-DD" format="YYYY-MM-DD" v-model="item[item['key']]"
|
||||
type="date" :placeholder="`请选择${item.name}`" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</VueDraggable>
|
||||
|
||||
<!-- 空状态提示 -->
|
||||
<div v-if="copyList.length === 0" class="empty-state">
|
||||
<i class="el-icon-tickets"></i>
|
||||
<p>暂无已选条件</p>
|
||||
<p class="empty-tip">从上方拖拽条件到此处</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ChooseMarks v-model="chooseMarksVisible" @choosed="choosed" :roleIds="roleIds" />
|
||||
<ChooseIdentity v-model="chooseIdentityVisible" @choosed="choosedIdentity" :roleIds="roleIdsIdentity" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import ChooseMarks from "@/components/ChooseList/ChooseMarks/index.vue";
|
||||
import ChooseIdentity from "@/components/ChooseList/ChooseIdentity/index.vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { VueDraggable } from 'vue-draggable-plus'//npm install vue-draggable-plus
|
||||
const props = defineProps({
|
||||
dict: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
'Joao',
|
||||
'Jean',
|
||||
'Johanna',
|
||||
'Juan',
|
||||
],
|
||||
}, defaultData: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
}, disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const dataConst = reactive([
|
||||
">",
|
||||
"<",
|
||||
"="
|
||||
])
|
||||
const gzmc = ref('')
|
||||
const dataList = ref(props.list)
|
||||
const copyList = ref([])
|
||||
const clone = (val) => {
|
||||
const data = copyList.value.find(item => item.name == val.name)
|
||||
if (data) {
|
||||
console.log("已存在")
|
||||
} else {
|
||||
// if (val.key == 'cs') {
|
||||
// return {
|
||||
// name: val.name,
|
||||
// key: val.key,
|
||||
// [val["key"]]: {}
|
||||
// }
|
||||
// } else {
|
||||
if (val.key == 'cs') {
|
||||
return {
|
||||
name: val.name,
|
||||
key: val.key,
|
||||
[val["key"]]: []
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
name: val.name,
|
||||
key: val.key,
|
||||
[val["key"]]: [""]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
watch(() => props.defaultData, (val) => {
|
||||
if (val) {
|
||||
gzmc.value = val.gzmc
|
||||
const data = props.list.map(item => {
|
||||
|
||||
switch (item.key) {
|
||||
// case 'cs':
|
||||
// return {
|
||||
// name: item.name,
|
||||
// key: item.key,
|
||||
// [item["key"]]: {
|
||||
// cs: val.cs,
|
||||
// tj: val.tj
|
||||
// }
|
||||
// }
|
||||
case 'jssj':
|
||||
case 'kssj':
|
||||
return {
|
||||
name: item.name,
|
||||
key: item.key,
|
||||
[item["key"]]: val[item.key] ? val[item.key] : null,
|
||||
}
|
||||
case 'zz':
|
||||
return {
|
||||
name: item.name,
|
||||
key: item.key,
|
||||
[item["key"]]: val[item.key] ? JSON.parse(val[item.key]).map(item => item.zzmc) : null,
|
||||
}
|
||||
case 'dd':
|
||||
return {
|
||||
name: item.name,
|
||||
key: item.key,
|
||||
[item["key"]]: val[item.key] ? JSON.parse(val[item.key]).map(item => item.dz) : null,
|
||||
}
|
||||
default:
|
||||
return {
|
||||
name: item.name,
|
||||
key: item.key,
|
||||
[item["key"]]: val[item.key] ? JSON.parse(val[item.key]) : null
|
||||
}
|
||||
}
|
||||
})
|
||||
copyList.value = data.filter(item => {
|
||||
return item[item.key] != null
|
||||
})
|
||||
|
||||
}
|
||||
}, { deep: true, immediate: true })
|
||||
const addInput = (key, index) => {
|
||||
copyList.value[index][key].push("")
|
||||
}
|
||||
|
||||
// 移除项目
|
||||
const removeItem = (key, index) => {
|
||||
const data = copyList.value.findIndex(item => item.key == key)
|
||||
if (copyList.value[data][key].length == 1) {
|
||||
return
|
||||
}
|
||||
copyList.value[data][key].splice(index, 1)
|
||||
}
|
||||
|
||||
// 选择预警标签
|
||||
const roleIds = ref([])
|
||||
const chooseMarksVisible = ref()
|
||||
const choosed = (val) => {
|
||||
roleIds.value = val.map(item => item.id)
|
||||
copyList.value.find(item => item.key == 'xwbq')['xwbq'] = val.map(item => {
|
||||
return {
|
||||
bqdm: item.bqDm,
|
||||
bqmc: item.bqMc
|
||||
}
|
||||
})
|
||||
}
|
||||
// 选择身份标签
|
||||
const chooseIdentityVisible = ref()
|
||||
const roleIdsIdentity = ref([])
|
||||
const choosedIdentity = (val) => {
|
||||
roleIdsIdentity.value = val.map(item => item.id)
|
||||
copyList.value.find(item => item.key == 'sfbq')['sfbq'] = val.map(item => {
|
||||
return {
|
||||
bqdm: item.bqDm,
|
||||
bqmc: item.bqMc
|
||||
}
|
||||
})
|
||||
}
|
||||
const romes = (val) => {
|
||||
copyList.value = copyList.value.filter(item => item.key !== val.key)
|
||||
}
|
||||
|
||||
const promes = ref({})
|
||||
// 新增
|
||||
const retValue = () => {
|
||||
if (gzmc.value == '') {
|
||||
return
|
||||
}
|
||||
const data = copyList.value.map(item => {
|
||||
return {
|
||||
[item.key]: item[item.key]
|
||||
}
|
||||
})
|
||||
promes.value = data.reduce((acc, cur) => {
|
||||
console.log(cur);
|
||||
|
||||
return { ...acc, ...cur }
|
||||
}, {})
|
||||
promes.value = { ...promes.value, gzmc: gzmc.value }
|
||||
if (promes.value.dd && promes.value.dd.length > 0) {
|
||||
promes.value.dd = promes.value.dd.map(item => {
|
||||
return { dz: item }
|
||||
})
|
||||
}
|
||||
if (promes.value.zz && promes.value.zz.length > 0) {
|
||||
promes.value.zz = promes.value.zz.map(item => {
|
||||
return { zzmc: item }
|
||||
})
|
||||
}
|
||||
promes.value.kssj = promes.value.kssj ? promes.value.kssj.toString() : null
|
||||
promes.value.jssj = promes.value.jssj ? promes.value.jssj.toString() : null
|
||||
const retData = {
|
||||
...promes.value,
|
||||
dd: promes.value.dd ? JSON.stringify(promes.value.dd) : null,
|
||||
sfbq: promes.value.sfbq ? JSON.stringify(promes.value.sfbq) :null,
|
||||
xwbq: promes.value.xwbq ? JSON.stringify(promes.value.xwbq) :null,
|
||||
zz: promes.value.zz ? JSON.stringify(promes.value.zz) :null,
|
||||
}
|
||||
return retData
|
||||
}
|
||||
defineExpose({
|
||||
retValue
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.regulation-wrapper {
|
||||
padding: 20px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
// 条件区域通用样式
|
||||
.condition-section,
|
||||
.selected-section {
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
// margin-bottom: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.condition-section:hover,
|
||||
.selected-section:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
// 区域标题
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 2px solid #e6f7ff;
|
||||
|
||||
i {
|
||||
color: #409eff;
|
||||
margin-right: 8px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.selected-count {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: #606266;
|
||||
background: #f0f9ff;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
min-width: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
// 可用条件区域
|
||||
.available-conditions {
|
||||
// min-height: 100px;
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.condition-button {
|
||||
background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
|
||||
color: white !important;
|
||||
border: none !important;
|
||||
border-radius: 8px !important;
|
||||
padding: 8px 16px !important;
|
||||
font-size: 14px !important;
|
||||
transition: all 0.3s ease !important;
|
||||
min-width: 120px;
|
||||
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #66b1ff 0%, #409eff 100%) !important;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
|
||||
}
|
||||
|
||||
i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
// 拖拽提示
|
||||
.drag-hint {
|
||||
display: flex;
|
||||
align-content: flex-start;
|
||||
// align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
|
||||
i {
|
||||
margin-right: 8px;
|
||||
font-size: 16px;
|
||||
animation: bounce 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
|
||||
0%,
|
||||
20%,
|
||||
50%,
|
||||
80%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
40% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 已选条件区域
|
||||
.selected-container {
|
||||
min-height: 120px;
|
||||
border: 2px dashed #dcdfe6;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
transition: all 0.3s ease;
|
||||
background-color: #dcdfe670;
|
||||
|
||||
&:hover {
|
||||
border-color: #409eff;
|
||||
background: #f0f9ff;
|
||||
}
|
||||
}
|
||||
|
||||
.selected-list {
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
// 拖拽项样式
|
||||
.draggable-item {
|
||||
position: relative;
|
||||
// background: rgba(103, 194, 58, 0.3);
|
||||
padding: 3px;
|
||||
margin: 8px;
|
||||
// box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
display: table-cell;
|
||||
justify-content: space-between;
|
||||
// cursor: move;
|
||||
text-align: center;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px) scale(1.02);
|
||||
box-shadow: 0 6px 16px rgba(103, 194, 58, 0.4);
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
opacity: 0.6;
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
}
|
||||
|
||||
.item-content {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px 12px 12px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-width: 140px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.item-text {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.item-remove {
|
||||
color: #c0c4cc;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
padding: 4px;
|
||||
border-radius: 50%;
|
||||
|
||||
&:hover {
|
||||
color: #f56c6c;
|
||||
background: #fef0f0;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* 规则名称区域 */
|
||||
.rule-name-section {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.rule-name-label {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
/* 项目删除按钮 */
|
||||
.item-remove-btn {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
/* 条件输入容器 */
|
||||
.condition-input-container {
|
||||
flex-wrap: nowrap;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* 计数条件容器 */
|
||||
.count-condition-container {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* 条件选择框 */
|
||||
.condition-select {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
/* 按钮右侧边距 */
|
||||
.btn-margin-right {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
// 空状态样式
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
color: #909399;
|
||||
|
||||
i {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
color: #dcdfe6;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
font-size: 12px;
|
||||
color: #c0c4cc;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
&:hover i {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
// 拖拽效果
|
||||
.ghost {
|
||||
opacity: 0.6;
|
||||
background-color: #e6f7ff;
|
||||
border: 2px dashed #409eff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 768px) {
|
||||
.regulation-wrapper {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.condition-section,
|
||||
.selected-section {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.condition-button {
|
||||
min-width: 100px;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
min-width: 120px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
:v-deep .el-select {
|
||||
width: 59%;
|
||||
}
|
||||
</style>
|
||||
@ -1,234 +0,0 @@
|
||||
<template>
|
||||
<div class="dialog" v-if="dialogForm">
|
||||
<div class="head_box">
|
||||
<span class="title">{{ title }}规则 </span>
|
||||
<div>
|
||||
<el-button type="primary" size="small" :loading="loading" @click="submit" v-show="title != '详情'">保存</el-button>
|
||||
<el-button size="small" @click="close">关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form_cnt">
|
||||
<EarlyWarning :list="listData" v-if=" listQuery.mxlx=='01'" ref="regulationRef" :dict="props.dict" :defaultData="defaultData"
|
||||
:disabled="title == '详情'" />
|
||||
<Regulation :list="listData" v-if=" listQuery.mxlx=='02'" ref="regulationRef" :dict="props.dict" :defaultData="defaultData"
|
||||
:disabled="title == '详情'" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { ElMessage } from "element-plus";
|
||||
import { addSsyjpz, editSsyjpz,addYjgzpz,editYjgzpz } from '@/api/model'
|
||||
import Regulation from "../components/FourColor/regulation.vue";
|
||||
import EarlyWarning from "../components/EarlyWarning/regulation.vue";
|
||||
const props = defineProps({
|
||||
dict: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
}
|
||||
})
|
||||
const dialogForm = ref(false)
|
||||
const title = ref("新增")
|
||||
const emit = defineEmits(['getList'])
|
||||
const typeData = {
|
||||
'02': [{
|
||||
name: "地点",
|
||||
key: "dd",
|
||||
id: 1
|
||||
}, {
|
||||
name: "身份标签",
|
||||
key: "sfbq",
|
||||
id: 2
|
||||
},
|
||||
// {
|
||||
// name: "次数",
|
||||
// key: "cs",
|
||||
// id: 3
|
||||
// },
|
||||
{
|
||||
name: "行为标签",
|
||||
key: "xwbq",
|
||||
id: 4
|
||||
}, {
|
||||
name: "组织",
|
||||
key: "zz",
|
||||
id: 5
|
||||
}, {
|
||||
name: "开始时间",
|
||||
key: "kssj",
|
||||
id: 6
|
||||
}, {
|
||||
name: "结束时间",
|
||||
key: "jssj",
|
||||
id: 7
|
||||
}],
|
||||
'01': [{
|
||||
name: "地点",
|
||||
key: "dd",
|
||||
}, {
|
||||
name: '警情类型',
|
||||
key: 'jqlx',
|
||||
}, {
|
||||
name: '人员信息',
|
||||
key: 'ryxx',
|
||||
}, {
|
||||
name: '事件类型',
|
||||
key: 'sjlx',
|
||||
}, {
|
||||
name: '物品',
|
||||
key: 'wp',
|
||||
}, {
|
||||
name: '组织',
|
||||
key: 'zz',
|
||||
}, {
|
||||
name: '开始时间',
|
||||
key: 'kssj',
|
||||
}, {
|
||||
name: '结束时间',
|
||||
key: 'jssj',
|
||||
}, {
|
||||
name: '次数',
|
||||
key: 'cs',
|
||||
}],
|
||||
|
||||
}
|
||||
const listData = ref([])
|
||||
const listQuery = ref()
|
||||
const defaultData = ref({})
|
||||
const mxlx=ref()
|
||||
const init = (type, item, row) => {
|
||||
dialogForm.value = true
|
||||
listQuery.value = item
|
||||
listData.value = typeData[item.mxlx]
|
||||
|
||||
if (type == 'edit') {
|
||||
defaultData.value = row
|
||||
title.value = "编辑"
|
||||
} else if (type == 'add') {
|
||||
defaultData.value={}
|
||||
title.value = "新增"
|
||||
} else {
|
||||
title.value = "详情"
|
||||
defaultData.value = row
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const regulationRef = ref(null)
|
||||
const loading = ref(false)
|
||||
// 新增
|
||||
const submit = () => {
|
||||
|
||||
switch (listQuery.value.mxlx) {
|
||||
case '01':
|
||||
addYjgzpzs()
|
||||
break;
|
||||
case '02':
|
||||
addSsyj()
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
const addSsyj = () => {
|
||||
const data = regulationRef.value.retValue()
|
||||
if (!data||!data.gzmc) {
|
||||
ElMessage.warning('请填写规则名称')
|
||||
return
|
||||
}
|
||||
if (title.value == "新增") {
|
||||
const promes = {
|
||||
mxid: listQuery.value.id,
|
||||
...data
|
||||
}
|
||||
addSsyjpz(promes).then((result) => {
|
||||
ElMessage.success('新增成功')
|
||||
emit('getList')
|
||||
close()
|
||||
}).catch((err) => {
|
||||
ElMessage.error(err.message)
|
||||
});
|
||||
} else {
|
||||
editSsyjpz({
|
||||
id: defaultData.value.id,
|
||||
...data
|
||||
}).then((result) => {
|
||||
ElMessage.success('编辑成功')
|
||||
emit('getList')
|
||||
close()
|
||||
}).catch((err) => {
|
||||
ElMessage.error(err.message)
|
||||
});
|
||||
}
|
||||
}
|
||||
const addYjgzpzs = () => {
|
||||
const data = regulationRef.value.retValue()
|
||||
if (!data||!data.gzmc) {
|
||||
ElMessage.warning('请填写规则名称')
|
||||
return
|
||||
}
|
||||
if (title.value == "新增") {
|
||||
const promes = {
|
||||
mxid: listQuery.value.id,
|
||||
...data
|
||||
}
|
||||
addYjgzpz(promes).then((result) => {
|
||||
ElMessage.success('新增成功')
|
||||
emit('getList')
|
||||
close()
|
||||
}).catch((err) => {
|
||||
ElMessage.error(err.message)
|
||||
});
|
||||
} else {
|
||||
editYjgzpz({
|
||||
id: defaultData.value.id,
|
||||
...data
|
||||
}).then((result) => {
|
||||
ElMessage.success('编辑成功')
|
||||
emit('getList')
|
||||
close()
|
||||
}).catch((err) => {
|
||||
ElMessage.error(err.message)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const close = () => {
|
||||
dialogForm.value = false
|
||||
}
|
||||
defineExpose({
|
||||
init,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .el-button+.el-button {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.just-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.mb-10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.mr-10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -1,273 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="titleBox">
|
||||
<PageTitle title="预警列表">
|
||||
<el-button type="primary" size="small" @click="openAddRule('add', item)">新增</el-button>
|
||||
<el-button type="primary" size="small" :disabled="ids.length == 0" @click="deleteRule(ids)">批量删除</el-button>
|
||||
<el-button size="small" @click="retenHome()">返回</el-button>
|
||||
</PageTitle>
|
||||
</div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData">
|
||||
<template #tjName="{ row }">
|
||||
<div class="flex one_text_detail" v-if="row.tj">{{ ` ${row.tj} ${row.cs}` }} </div>
|
||||
</template>
|
||||
<template #zz="{ row }">
|
||||
<template v-if="row.zz">
|
||||
<span v-for="(item, index) in jsonParse(row.zz)" :key="index">{{ item.zzmc }}
|
||||
<span v-if="index < jsonParse(row.zz).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #sfbq="{ row }">
|
||||
<template v-if="row.sfbq">
|
||||
<span v-for="(item, index) in jsonParse(row.sfbq)" :key="index">{{ item.bqmc }}
|
||||
<span v-if="index < jsonParse(row.sfbq).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #xwbq="{ row }">
|
||||
<template v-if="row.xwbq">
|
||||
<span v-for="(item, index) in jsonParse(row.xwbq)" :key="index">{{ item.bqmc }}
|
||||
<span v-if="index < jsonParse(row.xwbq).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #dd="{ row }">
|
||||
<template v-if="row.dd">
|
||||
<span v-for="(item, index) in jsonParse(row.dd)" :key="index">{{ item.dz }}
|
||||
<span v-if="index < jsonParse(row.dd).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #ryxx="{ row }">
|
||||
<template v-if="row.ryxx">
|
||||
<span v-for="(item, index) in jsonParse(row.ryxx)" :key="index">{{ item.xm }}
|
||||
<span v-if="index < jsonParse(row.ryxx).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #jqlx="{ row }">
|
||||
<template v-if="row.jqlx">
|
||||
<span v-for="(item, index) in jsonParse(row.jqlx)" :key="index">{{ item.lxmc }}
|
||||
<span v-if="index < jsonParse(row.jqlx).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #sjlx="{ row }">
|
||||
<template v-if="row.sjlx">
|
||||
<span v-for="(item, index) in jsonParse(row.sjlx)" :key="index">{{ item.lxmc }}
|
||||
<span v-if="index < jsonParse(row.sjlx).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #wp="{ row }">
|
||||
<template v-if="row.wp">
|
||||
<span v-for="(item, index) in jsonParse(row.wp)" :key="index">{{ item.wpmc }}
|
||||
<span v-if="index < jsonParse(row.wp).length - 1">、</span>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #controls="{ row }">
|
||||
<el-link type="primary" size="small" @click="yzSsyjpzMxgzxl( row.id)">运行规则</el-link>
|
||||
<el-link type="primary" size="small" @click="openAddRule('edit',item, row)">修改</el-link>
|
||||
<el-link type="primary" size="small" @click="openAddRule('detail',item, row)">详情</el-link>
|
||||
<!-- <el-link type="primary" size="small" @click="openAddRule('detail',item, row)">预警列表</el-link> -->
|
||||
<el-link type="danger" size="small" @click="deleteRule(row.id)">删除</el-link>
|
||||
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"></Pages>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessage } from "element-plus";
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import { deleteYjgzpz,getYjgzpzMxgzxl,getYjxxPageList } from "@/api/model";
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import Pages from "@/components/aboutTable/Pages.vue";
|
||||
import Search from "@/components/aboutTable/Search.vue";
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
import { template } from "lodash";
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BB_AJLB,D_BZ_WPLX} = proxy.$dict("D_BB_AJLB","D_BZ_WPLX")
|
||||
const regulation = ref(null)
|
||||
const queryFrom = ref({})
|
||||
const searchBox = ref(); //搜索框
|
||||
|
||||
const searchConfiger = ref([
|
||||
|
||||
{
|
||||
label: "时间",
|
||||
prop: "startTime",
|
||||
placeholder: "请选择时间",
|
||||
showType: "daterange"
|
||||
},
|
||||
]);
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
keyCount: 0,
|
||||
tableConfiger: {
|
||||
rowHieght: 61,
|
||||
showSelectType: "null",
|
||||
loading: false
|
||||
},
|
||||
total: 0,
|
||||
pageConfiger: {
|
||||
pageSize: 20,
|
||||
pageCurrent: 1
|
||||
},
|
||||
controlsWidth: 300,
|
||||
tableColumn: [
|
||||
{ label: "预警时间", prop: "gzmc", showOverflowTooltip: true },
|
||||
{ label: "类型", prop: "jssj", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "内容", prop: "kssj", showOverflowTooltip: true, showSolt: true },
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
tabHeightFn();
|
||||
});
|
||||
|
||||
// 搜索
|
||||
const onSearch = (val) => {
|
||||
queryFrom.value.startTime = val.startTime&&val.startTime.length > 0 ? val.startTime[0] : '';
|
||||
queryFrom.value.endTime = val.startTime&&val.startTime.length > 0 ? val.startTime[1] : '';
|
||||
pageData.pageConfiger.pageCurrent = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
const changeNo = (val) => {
|
||||
pageData.pageConfiger.pageCurrent = val;
|
||||
getList();
|
||||
};
|
||||
|
||||
const changeSize = (val) => {
|
||||
pageData.pageConfiger.pageSize = val;
|
||||
getList();
|
||||
};
|
||||
//
|
||||
// 获取列表
|
||||
const getList = () => {
|
||||
const promes = {
|
||||
...pageData.pageConfiger,
|
||||
...queryFrom.value,
|
||||
mxid:props.item.id,
|
||||
}
|
||||
getYjxxPageList(promes).then((res) => {
|
||||
pageData.tableData = res.records
|
||||
pageData.total = res.total
|
||||
});
|
||||
};
|
||||
const retenHome = () => {
|
||||
emitter.emit('changeModel', { name: '研判首页', row: {} });
|
||||
}
|
||||
const openAddRule = (type, item, row) => {
|
||||
regulation.value.init(type, item, row)
|
||||
}
|
||||
const ids = ref([])
|
||||
|
||||
const chooseData = (val) => {
|
||||
ids.value = val.map(item => item.id)
|
||||
}
|
||||
const deleteRule = (row) => {
|
||||
proxy.$confirm('是否删除该规则, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let list
|
||||
if (Array.isArray(row)) {
|
||||
list = ids.value
|
||||
} else {
|
||||
list =[row]
|
||||
}
|
||||
deleteYjgzpz({ids:list}).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
getList()
|
||||
})
|
||||
}).catch((err) => {
|
||||
proxy.$message({
|
||||
type: 'info',
|
||||
message: '已取消删除'
|
||||
});
|
||||
});
|
||||
}
|
||||
const yzSsyjpzMxgzxl = (params) => {
|
||||
getYjgzpzMxgzxl({id:params}).then((res) => {
|
||||
console.log(res);
|
||||
})
|
||||
}
|
||||
const jsonParse = (val) => {
|
||||
if (val) {
|
||||
return JSON.parse(val)
|
||||
}
|
||||
}
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.basic-info {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
|
||||
.avatar {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.info-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.control-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -1,321 +0,0 @@
|
||||
<template>
|
||||
<!-- 研判类型 -->
|
||||
<div class="content">
|
||||
<div class="titleBox">
|
||||
<PageTitle title="模型平台">
|
||||
<el-button type="primary" @click="openAddModel('add')" :icon="CirclePlus">
|
||||
新增模型
|
||||
</el-button>
|
||||
</PageTitle>
|
||||
</div>
|
||||
<div ref="searchBox">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch"> </Search>
|
||||
</div>
|
||||
<ul class="cntlsit mb10" v-if="show" v-infinite-scroll="load" :style="{ height: listHeight + 'px' }"
|
||||
v-loading="loading">
|
||||
<li class="model-card" v-for="(it, idx) in list" :key="idx">
|
||||
<div class="model-info">
|
||||
<div class="model-name">
|
||||
<strong>模型名称:</strong>{{ it.mxmc }}
|
||||
</div>
|
||||
<div class="model-type flex">
|
||||
<strong>模型类型:</strong> <DictTag :tag="false" :value="it.mxlx" :options="D_MXGL_MXLX" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="model-image-container" @click="openYjList">
|
||||
<img class="model-image"
|
||||
src="@/assets/images/mxbg.jpg" alt="">
|
||||
</div>
|
||||
<div class="model-actions">
|
||||
<span class="action-btn action-btn-view" @click.stop="openAddRule('', it)">
|
||||
<el-icon class="action-icon"><Document /></el-icon>查看规则
|
||||
</span>
|
||||
<span class="action-btn action-btn-edit" @click.stop="openAddModel('edit', it)">
|
||||
<el-icon class="action-icon"><ChatDotSquare /></el-icon>编辑
|
||||
</span>
|
||||
<span class="action-btn action-btn-edit" @click.stop="openAddModel('detail', it)">
|
||||
<el-icon class="action-icon"><Edit /></el-icon>详情
|
||||
</span>
|
||||
<span class="action-btn action-btn-delete" @click.stop="delDictItem(it.id)">
|
||||
<el-icon class="action-icon"><Files /></el-icon>删除
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<div class="empty-container">
|
||||
<MOSTY.Empty :show="!loading && list.length <= 0"></MOSTY.Empty>
|
||||
</div>
|
||||
<div class="no-more-data" v-if="total == list.length && total > 0">暂时没有数据了!</div>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- <AddModel ref="addModel" :dict="{ D_MXGL_MXLX }" @getLits="getLits" /> -->
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import { getPageList, deleteEntity } from '@/api/model.js'
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import { CirclePlus } from '@element-plus/icons-vue'
|
||||
import * as MOSTY from "@/components/MyComponents/index";
|
||||
import Search from "@/components/aboutTable/Search.vue";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, watch, defineEmits } from "vue";
|
||||
// import AddModel from "../components/AddModel/addModel";
|
||||
const emit = defineEmits(['change'])
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_MXGL_MXLX ,D_BZ_RYBQ} = proxy.$dict("D_MXGL_MXLX","D_BZ_RYBQ")
|
||||
const searchBox = ref(); //搜索框
|
||||
const show = ref(false)
|
||||
const listHeight = ref()
|
||||
const searchConfiger = ref([
|
||||
{ label: "模型名称", prop: "mxmc", placeholder: "请输入模型名称", showType: "input" },
|
||||
{
|
||||
label: "模型类型",
|
||||
prop: "mxlx",
|
||||
placeholder: "请选择模型类型",
|
||||
showType: "select",
|
||||
options: D_MXGL_MXLX
|
||||
},
|
||||
]);
|
||||
const PaginationConfig = reactive({
|
||||
pageCurrent: 1,
|
||||
pageSize: 8,
|
||||
});
|
||||
const total = ref(0)
|
||||
const list = ref([])
|
||||
const loading = ref(false);
|
||||
const formData = ref({})
|
||||
onMounted(() => {
|
||||
show.value = true;
|
||||
tabHeightFn();
|
||||
getLits()
|
||||
})
|
||||
|
||||
|
||||
const onSearch = (val) => {
|
||||
formData.value = { ...formData.value, ...val, };
|
||||
PaginationConfig.pageCurrent = 1;
|
||||
getLits();
|
||||
}
|
||||
const load = () => {
|
||||
if (total.value == list.value.length) return;
|
||||
PaginationConfig.pageCurrent++;
|
||||
// getLits();
|
||||
}
|
||||
const getLits = () => {
|
||||
let params = {
|
||||
...PaginationConfig,
|
||||
...formData.value
|
||||
}
|
||||
loading.value = true;
|
||||
|
||||
getPageList(params).then(res => {
|
||||
let arr = res.records || [];
|
||||
list.value = PaginationConfig.pageCurrent == 1 ? arr : list.value.concat(arr);
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
listHeight.value = window.innerHeight - searchBox.value.offsetHeight - 230;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
};
|
||||
const delDictItem = (id) => {
|
||||
proxy.$confirm('是否删除该模型, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteEntity({ ids: [id] }).then(res => {
|
||||
proxy.$message.success("删除成功!")
|
||||
getLits()
|
||||
})
|
||||
}).catch(() => {
|
||||
proxy.$message({
|
||||
type: 'info',
|
||||
message: '已取消删除'
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
// 打开弹窗
|
||||
const addModel = ref(null)
|
||||
const openAddModel = (type, row) => {
|
||||
addModel.value.init(type, row)
|
||||
}
|
||||
// 打开规则弹窗
|
||||
const openAddRule = (type, row) => {
|
||||
switch (row.mxlx) {
|
||||
case '02':
|
||||
emitter.emit('changeModel', {row,name:'四色预警规则'})
|
||||
break;
|
||||
case '01':
|
||||
emitter.emit('changeModel', {row,name:'预警规则'})
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
const openYjList = (row) => {
|
||||
emitter.emit('changeModel', {row,name:'预警列表'})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 20px;
|
||||
margin-left: 10px;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.btnsBox {
|
||||
background: #fff;
|
||||
padding: 10px 5px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.cntlsit {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: start;
|
||||
gap: 20px;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
// 模型卡片样式
|
||||
.model-card {
|
||||
width: 300px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
// 模型信息区域
|
||||
.model-info {
|
||||
padding: 16px;
|
||||
background-color: #fafafa;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
.model-name,
|
||||
.model-type {
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
|
||||
strong {
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.model-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 模型图片区域
|
||||
.model-image-container {
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
.model-image {
|
||||
width: 100%;
|
||||
height: 168px;
|
||||
object-fit: cover;
|
||||
transition: transform 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作按钮区域
|
||||
.model-actions {
|
||||
text-align: right;
|
||||
padding: 12px 0px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
background-color: #fafafa;
|
||||
|
||||
.action-btn {
|
||||
// margin-left: 12px;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
|
||||
.action-icon {
|
||||
margin-right: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn-view,
|
||||
.action-btn-edit {
|
||||
color: #409eff;
|
||||
|
||||
&:hover {
|
||||
background-color: #ecf5ff;
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn-delete {
|
||||
color: #f4ac47;
|
||||
|
||||
&:hover {
|
||||
background-color: #fff7e6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 空状态和无更多数据样式
|
||||
.empty-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 40px 0;
|
||||
}
|
||||
|
||||
.no-more-data {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-bottom: 16px;
|
||||
color: #a29f9f;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="dialog" v-if="dialogForm">
|
||||
<div class="head_box">
|
||||
<div>详情</div>
|
||||
<div><el-button @click="close">关闭</el-button></div>
|
||||
</div>
|
||||
<div class="form_cnt">
|
||||
<FormMessage v-model="listQuery" disabled :formList="formData" ref="elform">
|
||||
<template #yjTp="{ row }">
|
||||
<template v-if="!listQuery.yjTp || listQuery.yjTp.includes('baidu')">
|
||||
<img src="@/assets/images/car.png" width="65" height="70" v-if="listQuery.yjlx == 2" />
|
||||
<img src="@/assets/images/default_male.png" width="65" height="70" v-else />
|
||||
</template>
|
||||
<el-image v-else style="width: 80px; height:120px" :src="listQuery.yjTp" :preview-src-list="[row.yjTp]"
|
||||
show-progress>
|
||||
<template #error>
|
||||
<div class="image-slot error">
|
||||
<img src="@/assets/images/car.png" width="65" height="70" v-if="listQuery.yjlx == 2" />
|
||||
<img src="@/assets/images/default_male.png" width="65" height="70" v-else />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</template>
|
||||
</FormMessage>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import { ref, defineExpose } from "vue";
|
||||
const props = defineProps({
|
||||
dict: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
});
|
||||
const dialogForm = ref(false); //弹窗
|
||||
const formData = ref([
|
||||
{ label: "预警照片", prop: "yjTp", type: "slot", width: '100%' },
|
||||
{ label: "预警名称", prop: "yjBt", type: "input" },
|
||||
{ label: "预警人员姓名", prop: "yjRyxm", type: "input" },
|
||||
{ label: "车牌号", prop: "yjClcph", type: "input" },
|
||||
{ label: "身份证号", prop: "yjRysfzh", type: "input" },
|
||||
{ label: "预警地址", prop: "yjDz", type: "input" },
|
||||
{ label: "预警时间", prop: "yjsj", type: "date" },
|
||||
{ label: "预警类型", prop: "yjlx", type: "select", options: props.dict.D_BZ_YJLX },
|
||||
{ label: "预警内容", prop: "yjnr", type: "textarea", width: '100%' },
|
||||
]);
|
||||
const listQuery = ref({}); //表单
|
||||
const elform = ref();
|
||||
// 初始化数据
|
||||
const init = (row) => {
|
||||
dialogForm.value = true;
|
||||
listQuery.value = row;
|
||||
};
|
||||
|
||||
// 关闭
|
||||
const close = () => {
|
||||
listQuery.value = {};
|
||||
dialogForm.value = false;
|
||||
};
|
||||
|
||||
defineExpose({ init });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/assets/css/layout.scss";
|
||||
@import "~@/assets/css/element-plus.scss";
|
||||
|
||||
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
|
||||
color: #0072ff;
|
||||
background: rgba(0, 114, 255, 0.3);
|
||||
}
|
||||
|
||||
.boxlist {
|
||||
width: 99%;
|
||||
height: 225px;
|
||||
margin-top: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
::v-deep .avatar-uploader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
::v-deep .el-upload-list {
|
||||
margin-left: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
::v-deep .el-upload-list__item-name .el-icon {
|
||||
top: 3px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="titleBox">
|
||||
<PageTitle title="预警详情">
|
||||
<!-- <el-button type="primary" size="small" @click="yzSsyjpzMxgzxl()">测试</el-button> -->
|
||||
<el-button size="small" @click="retenHome()">返回</el-button>
|
||||
</PageTitle>
|
||||
</div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
|
||||
<template #yjTp="{ row }">
|
||||
<template v-if="!row.yjTp || row.yjTp.includes('baidu')">
|
||||
<img src="@/assets/images/car.png" width="65" height="70" v-if="row.yjlx == 2" />
|
||||
<img src="@/assets/images/default_male.png" width="65" height="70" v-else />
|
||||
</template>
|
||||
<el-image v-else style="width: 80px; height:120px" :src="row.yjTp" :preview-src-list="[row.yjTp]"
|
||||
show-progress>
|
||||
<template #error>
|
||||
<div class="image-slot error">
|
||||
<img src="@/assets/images/car.png" width="65" height="70" v-if="row.yjlx == 2" />
|
||||
<img src="@/assets/images/default_male.png" width="65" height="70" v-else />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</template>
|
||||
<template #yjlx="{ row }">
|
||||
<DictTag :tag="false" :value="row.yjlx" :options="dict.D_BZ_YJLX" />
|
||||
</template>
|
||||
<template #controls="{ row }">
|
||||
<el-link type="primary" size="small" @click="openYjdict(row)">详情</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"></Pages>
|
||||
</div>
|
||||
</div>
|
||||
<DetailsFollows ref="yjdict" :dict="dict" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import { mxglJqxqPageList } from "@/api/model";
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import Pages from "@/components/aboutTable/Pages.vue";
|
||||
import Search from "@/components/aboutTable/Search.vue";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, watch } from "vue";
|
||||
import DetailsFollows from './detailsFollows.vue'
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}, dict: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const queryFrom = ref({})
|
||||
const searchBox = ref(); //搜索框
|
||||
const yjdict = ref(null)//详情弹窗
|
||||
const ItemData = ref()//模型数据
|
||||
const searchConfiger = ref([
|
||||
{
|
||||
label: "时间",
|
||||
prop: "startTime",
|
||||
placeholder: "请选择时间",
|
||||
showType: "daterange"
|
||||
},
|
||||
]);
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
keyCount: 0,
|
||||
tableConfiger: {
|
||||
rowHieght: 61,
|
||||
showSelectType: "null",
|
||||
loading: false
|
||||
},
|
||||
total: 0,
|
||||
pageConfiger: {
|
||||
pageSize: 20,
|
||||
pageCurrent: 1
|
||||
},
|
||||
controlsWidth: 150,
|
||||
tableColumn: [
|
||||
// { label: "预警名称", prop: "", showOverflowTooltip: true },
|
||||
// { label: "预警图片", prop: "yjTp", showOverflowTooltip: true, showSolt: true },
|
||||
{ label: "报警人", prop: "bjrmc", showOverflowTooltip: true },
|
||||
{ label: "接警单号", prop: "bjh", showOverflowTooltip: true },
|
||||
// { label: "车牌号", prop: "yjClcph", showOverflowTooltip: true },
|
||||
// { label: "身份证号", prop: "yjRysfzh", showOverflowTooltip: true },
|
||||
{ label: "报警时间", prop: "bjsj", showOverflowTooltip: true },
|
||||
{ label: "报警地址", prop: "bjdz", showOverflowTooltip: true },
|
||||
{ label: "类型", prop: "yjlx", showSolt: true },
|
||||
{ label: "报警内容", prop: "bjnr", showOverflowTooltip: true },
|
||||
]
|
||||
});
|
||||
onMounted(() => {
|
||||
getList();
|
||||
tabHeightFn();
|
||||
|
||||
});
|
||||
const openYjdict = (val) => {
|
||||
yjdict.value.init(val)
|
||||
}
|
||||
watch(() => props.item, (val) => {
|
||||
ItemData.value = val
|
||||
}, { deep: true })
|
||||
|
||||
// 获取列表
|
||||
const getList = () => {
|
||||
const promes = {
|
||||
...pageData.pageConfiger,
|
||||
...queryFrom.value,
|
||||
yjid: props.item.id,
|
||||
}
|
||||
mxglJqxqPageList(promes).then((res) => {
|
||||
pageData.tableData = res.records || []
|
||||
pageData.total = res.total
|
||||
});
|
||||
};
|
||||
// 搜索
|
||||
const onSearch = (val) => {
|
||||
queryFrom.value.startTime = val.startTime && val.startTime.length > 0 ? val.startTime[0] : '';
|
||||
queryFrom.value.endTime = val.startTime && val.startTime.length > 0 ? val.startTime[1] : '';
|
||||
pageData.pageConfiger.pageCurrent = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
const changeNo = (val) => {
|
||||
pageData.pageConfiger.pageCurrent = val;
|
||||
getList();
|
||||
};
|
||||
|
||||
const changeSize = (val) => {
|
||||
pageData.pageConfiger.pageSize = val;
|
||||
getList();
|
||||
};
|
||||
//返回
|
||||
const retenHome = () => {
|
||||
emitter.emit('changeModel', { name: '预警列表', row: {} });
|
||||
}
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.basic-info {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
|
||||
.avatar {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.info-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.control-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -19,7 +19,8 @@
|
||||
<DictTag :tag="false" :value="row.yjlx" :options="dict.D_BZ_TPYJLX" />
|
||||
</template>
|
||||
<template #controls="{ row }">
|
||||
<el-link type="primary" size="small" @click="opneModel">打开研判报告</el-link>
|
||||
<el-link type="primary" size="small" @click="opneModel(row)">打开研判报告</el-link>
|
||||
<el-link type="primary" size="small" @click="warningDetails(row)">预警详情</el-link>
|
||||
<el-link type="primary" size="small" @click="openYjdict(row)">详情</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
@ -36,12 +37,13 @@
|
||||
<script setup>
|
||||
import YpModel from '@/components/ypModel/index.vue'
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import { getYjxxPageList,getSsyjpzMxgzxl } from "@/api/model";
|
||||
import { getYjxxPageList,getSsyjpzMxgzxl,mxglYjxqSelectList } from "@/api/model";
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import Pages from "@/components/aboutTable/Pages.vue";
|
||||
import Search from "@/components/aboutTable/Search.vue";
|
||||
import {timeValidate} from '@/utils/tools'
|
||||
import { timeValidate } from '@/utils/tools'
|
||||
import { completions } from '@/api/semanticAnalysis'
|
||||
import { reactive, ref, onMounted, getCurrentInstance, watch } from "vue";
|
||||
import { textStyle, Firstlevelheading, Subheading, BiheadlinegTitle, newTotitle,BigTitle,fbtool, headTitle, report, signature } from '../content.js'
|
||||
import Yjdict from './yjdict.vue'
|
||||
@ -62,14 +64,41 @@ const showModel = ref(false)
|
||||
const textContent=ref('')//报告数据
|
||||
const SaveReport = () => {
|
||||
}
|
||||
const opneModel = () => {
|
||||
const opneModel = (row) => {
|
||||
showModel.value = true
|
||||
textContent.value=''
|
||||
textContent.value += BigTitle("林芝市公安局情指中心") + BigTitle("研判专刊(初稿)") + newTotitle({
|
||||
textContent.value = ''
|
||||
mxglYjxqSelectList({
|
||||
yjid: row.id,
|
||||
}).then((res) => {
|
||||
let str = {
|
||||
model: "deepseek-32b",
|
||||
prompt: `# 角色定位\n你是一名资深警务人员,尤其擅长对警情、案件、线索等非结构化文本数据进行阅读理解,并从中提取各种对象特征信息进行结构化,并总结各种对象之间的关联关系。\n`,
|
||||
max_tokens: 1000,
|
||||
}
|
||||
res.forEach(item => {
|
||||
const lx = props.dict.D_BZ_YJLX.find(items => {
|
||||
return items.value == item.yjlx
|
||||
}).zdmc
|
||||
str.prompt+=`预警名称:${item.yjBt},预警人员姓名:${item.yjRyxm},身份证号:${item.yjRysfzh},车牌号:${item.yjClcph},预警地址:${item.yjDz},预警类型:${lx},预警内容:${item.yjnr},预警时间:${item.yjsj}\n`
|
||||
})
|
||||
str.prompt += `根据以上预警信息,总结出一个解决方案`
|
||||
let jsonMatch
|
||||
completions(str).then(reslve => {
|
||||
jsonMatch = reslve.choices[0].text
|
||||
textContent.value += BigTitle("林芝市公安局情指中心") + BigTitle("研判专刊(初稿)") + newTotitle({
|
||||
org: "市公安局情指中心编",
|
||||
time: timeValidate()
|
||||
})+fbtool('同类事件发生3次以上预警')+textStyle("2025年9月2日164525,产生同类事件3次以上预警,刑事案件中的置充身份诈美发生3起,同七上升30%、环比比下健5%")
|
||||
+ Subheading('1.警情内容') + Subheading('2.警情内容') + Subheading('3.警情内容')
|
||||
}) + fbtool(`同类事件发生${res.length}次以上预警`)
|
||||
res.forEach((item,index) => {
|
||||
const lx = props.dict.D_BZ_YJLX.find((items) => {
|
||||
return items.value == item.yjlx
|
||||
}).zdmc
|
||||
textContent.value +=Subheading(`${index+1}.警情内容`)+textStyle(`预警名称:${item.yjBt},预警人员姓名:${item.yjRyxm},身份证号:${item.yjRysfzh},车牌号:${item.yjClcph},预警地址:${item.yjDz},预警类型:${lx},预警内容:${item.yjnr},预警时间:${item.yjsj}\n`)
|
||||
})
|
||||
textContent.value+=Subheading(`解决方案`)+textStyle(jsonMatch?jsonMatch:'暂无解决方案')
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
const searchConfiger = ref([
|
||||
@ -86,7 +115,7 @@ const pageData = reactive({
|
||||
tableConfiger: {
|
||||
rowHieght: 61,
|
||||
showSelectType: "null",
|
||||
loading: false
|
||||
// loading: false
|
||||
},
|
||||
total: 0,
|
||||
pageConfiger: {
|
||||
@ -159,9 +188,10 @@ const yzSsyjpzMxgzxl = (params) => {
|
||||
// })
|
||||
getSsyjpzMxgzxl({id:'88c166e670da48e59324906648794b05'}).then((res) => {
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const warningDetails = (row) => {
|
||||
emitter.emit('changeModel', { row, name: '预警详情' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -1,25 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
<YpHome v-if="showModel == '研判首页'"></YpHome>
|
||||
<!-- <ModeList v-if="showModel == '四色预警规则'" :item="itemData" ></ModeList>
|
||||
<EarlyWarning v-if="showModel == '预警规则'" :item="itemData" ></EarlyWarning> -->
|
||||
<!-- <YjList v-if="showModel == '预警列表'" :item="itemData" ></YjList> -->
|
||||
<List v-if="showModel == '四色预警规则' || showModel == '预警规则'" :item="itemData"></List>
|
||||
<YjDetail v-if="showModel == '预警列表'" :item="itemData" :dict="{D_BZ_TPYJLX}"></YjDetail>
|
||||
<YjDetail v-if="showModel == '预警列表'" :item="itemData" :dict="{ D_BZ_TPYJLX,D_BZ_YJLX }"></YjDetail>
|
||||
<WarningList v-if="showModel == '预警详情'" :item="itemData" :dict="{ D_BZ_YJLX }"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import YpHome from "./components/ypHome.vue";
|
||||
// import YjList from "./components/yjList.vue";
|
||||
import YjDetail from './components/AddModel/yjList.vue'
|
||||
import List from "./components/list.vue";
|
||||
// import ModeList from "./components/FourColor/modeList.vue";
|
||||
// import EarlyWarning from "./components/EarlyWarning/modeList.vue";
|
||||
import WarningList from "./components/AddModel/warningList.vue"
|
||||
const { proxy } = getCurrentInstance();
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import { onMounted, ref, getCurrentInstance } from "vue";
|
||||
const { D_BZ_TPYJLX} = proxy.$dict("D_BZ_TPYJLX")
|
||||
const { D_BZ_TPYJLX,D_BZ_YJLX } = proxy.$dict("D_BZ_TPYJLX","D_BZ_YJLX")
|
||||
|
||||
const showModel = ref('研判首页')
|
||||
const itemData = ref({})
|
||||
|
||||
Reference in New Issue
Block a user