This commit is contained in:
lcw
2025-08-31 22:42:03 +08:00
15 changed files with 418 additions and 574 deletions

View File

@ -258,7 +258,7 @@
left: 50%;
bottom: 2px;
transform: translateX(-50%);
width: calc(100% - 920px);
width: calc(100% - 890px);
height: calc((100% - 141px)/3 - 32px);
min-width: 560px;
overflow: hidden;

View File

@ -7,8 +7,8 @@
<Editor :style="`height: ${props.heightNumber}px; overflow-y: hidden`" v-model="textContent" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" @onChange="handChange" />
</div>
<template #footer>
<el-button type="primary">暂存</el-button>
<el-button type="primary">下载</el-button>
<!-- <el-button type="primary">暂存</el-button> -->
<el-button type="primary" @click="downloadWithStyles">下载</el-button>
<el-button type="primary" @click="close">取消</el-button>
</template>
</el-dialog>
@ -19,6 +19,7 @@ import { compressImage } from "@/utils/tools.js";
import "@wangeditor/editor/dist/css/style.css";
import { qcckPost } from "@/api/qcckApi.js";
import { ElMessage } from "element-plus";
import { saveAs } from 'file-saver';
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { ref, shallowRef, onBeforeUnmount, defineEmits, defineProps, watch } from "vue";
const props = defineProps({
@ -46,7 +47,7 @@ const mode = "default";
const toolbarConfig = {
excludeKeys: ["blockquote", "codeBlock"] //清除不必要的工具,引用和代码块
};
const emits = defineEmits(["update:textContent", "changeFn"]);
const emits = defineEmits(["update:textContent", "changeFn","update:modelValue"]);
//编辑器配置
const editorConfig = {
withCredentials: true, //允许跨域
@ -86,7 +87,6 @@ const handleCreated = (editor) => {
};
//内容发生变化
const handChange = (editor) => {
console.log(editor.getHtml(),'====editor.getHtml()');
// 判断是否是一个空段落,是空就传空文本
if (editor.isEmpty()) {
emits("changeFn", editor.getText());
@ -94,11 +94,34 @@ const handChange = (editor) => {
emits("changeFn", editor.getHtml());
}
};
const close = () => {
emits("update:modelValue", false)
}
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor) editor.destroy();
});
// 带样式的下载方法
const downloadWithStyles = () => {
const wordDocument = `
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>富文本导出</title>
</head>
<body>
${props.textContent}
</body>
</html>
`;
const blob = new Blob([wordDocument], {
type: 'application/msword'
});
saveAs(blob, 'styled-document.doc');
};
</script>
<style lang="scss" scoped>

View File

@ -52,7 +52,7 @@ import mitt from "mitt";
import { resetForm } from "@/utils/validate";
import { getDict, setCascader } from '@/utils/dict';
import axios from "axios";
import fzui from 'fzui-fengqun-vue'
// import fzui from 'fzui-fengqun-vue'
//挂载全局方法
app.config.globalProperties.resetForm = resetForm;
@ -66,12 +66,12 @@ installElementPlus(app);
installIcons(app);
installFilter(app);
installDirective(app);
app.use(fzui, {
getOwnHostLabel: () => {
return '/fd_api';
},
translateHostLabel: () => {
return '/fd_api';
}
})
// app.use(fzui, {
// getOwnHostLabel: () => {
// return '/fd_api';
// },
// translateHostLabel: () => {
// return '/fd_api';
// }
// })
app.use(store).use(ELMessage).use(router).use(plugins).mount("#app");

View File

@ -616,15 +616,16 @@ export const publicRoutes = [
title: "语义分析",
icon: "article"
}
}, {
path: "/analysisReport",
name: "AnalysisReport",
component: () => import("@/views/backOfficeSystem/AnalysisReport/index"),
meta: {
title: "分析报告",
icon: "article"
}
},
// {
// path: "/analysisReport",
// name: "AnalysisReport",
// component: () => import("@/views/backOfficeSystem/AnalysisReport/index"),
// meta: {
// title: "分析报告",
// icon: "article"
// }
// },
]
}
]

View File

@ -1,78 +0,0 @@
// import jsPDF from 'jspdf';
// import html2canvas from 'html2canvas';
// export function useExportToPDF() {
// const exportToImage = async (element, filename = 'screenshot.png') => {
// const canvas = await html2canvas(element, {
// scale: 2,
// useCORS: true,
// });
// // 转换为图片并下载
// const link = document.createElement('a');
// link.download = filename;
// link.href = canvas.toDataURL('image/png');
// link.click();
// };
// // 将div导出为PDF的方法
// const exportDivToPDF = async (element, filename = 'document.pdf') => {
// try {
// // 使用html2canvas将div转换为canvas
// const canvas = await html2canvas(element, {
// scale: 2, // 提高清晰度
// useCORS: true, // 允许跨域图片
// logging: false, // 关闭日志
// width: element.offsetWidth,
// height: element.offsetHeight,
// windowWidth: element.scrollWidth,
// windowHeight: element.scrollHeight,
// backgroundColor: '#ffffff' // 设置背景色为白色
// });
// // 获取canvas的宽高
// const imgWidth = 210; // A4纸宽度(mm)
// const pageHeight = 297; // A4纸高度(mm)
// const imgHeight = canvas.height * imgWidth / canvas.width;
// let heightLeft = imgHeight;
// let position = 0;
// // 创建PDF文档
// const pdf = new jsPDF({
// orientation: 'portrait',
// unit: 'mm',
// format: 'a4'
// });
// // 将canvas转换为图片并添加到PDF
// const imgData = canvas.toDataURL('image/png');
// pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
// heightLeft -= pageHeight;
// // 如果内容超出一页,添加新页面
// while (heightLeft > 0) {
// position = heightLeft - imgHeight;
// pdf.addPage();
// pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
// heightLeft -= pageHeight;
// }
// // 下载PDF
// pdf.save(filename);
// } catch (error) {
// console.error('导出PDF失败:', error);
// alert('导出PDF失败请稍后重试');
// }
// };
// return {
// exportToImage,
// exportDivToPDF
// };
// }
// exportToImage
// };
// }
export function exportDivToPDF(divId, filename) {
}

View File

@ -124,17 +124,13 @@
<script setup>
import PageTitle from "@/components/aboutTable/PageTitle.vue";
// import { useExportToPDF } from './components/a.js';
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 AddForm from './components/a/addForm.vue'
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
// import ItemXs from './components/itemXs/itemXs.vue'
import { reactive, ref, onMounted, getCurrentInstance, nextTick, computed, watch } from "vue";
const { proxy } = getCurrentInstance();
const { D_GS_XS_LX } = proxy.$dict("D_GS_XS_LX"); //获取字典数据
@ -398,68 +394,9 @@ watch(() => dictItemList.value, (val) => {
}, { deep: true })
getDictItemList()
const tableBox = ref(null);
async function generatePDF(filename = 'document.pdf') {
// try {
const element = tableBox.value;
console.log();
// // 保存原始滚动位置和样式
// const originalScrollTop = element.scrollTop;
// const originalOverflow = element.style.overflow;
// // 临时允许元素滚动并获取完整高度
// element.style.overflow = 'visible';
// const canvas = await html2canvas(element, {
// scale: 2, // 提高清晰度
// useCORS: true, // 允许跨域图片
// logging: false, // 关闭日志
// scrollY: 0, // 禁止窗口滚动
// scrollX: 0,
// windowWidth: element.scrollWidth, // 设置窗口大小为元素大小
// windowHeight: element.scrollHeight,
// width: element.scrollWidth, // 设置canvas大小为元素大小
// height: element.scrollHeight
// });
// // 恢复原始样式和滚动位置
// element.style.overflow = originalOverflow;
// element.scrollTop = originalScrollTop;
// const imgData = canvas.toDataURL('image/png');
// const pdf = new jsPDF('p', 'mm', 'a4');
// const imgProps = pdf.getImageProperties(imgData);
// const pdfWidth = pdf.internal.pageSize.getWidth();
// const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
// // 计算需要多少页
// const pageHeight = pdf.internal.pageSize.getHeight();
// let heightLeft = pdfHeight;
// let position = 0;
// // 添加第一页
// pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, pdfHeight);
// heightLeft -= pageHeight;
// // 添加更多页(如果需要)
// while (heightLeft > 0) {
// position = -heightLeft;
// pdf.addPage();
// pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, pdfHeight);
// heightLeft -= pageHeight;
// }
// pdf.save(filename);
// } catch (error) {
// console.error('生成PDF时出错:', error);
// alert('生成PDF时出错请查看控制台获取详细信息');
// }
}
</script>
<style lang="scss" scoped>

View File

@ -22,7 +22,7 @@
<div class="infoItem flex nowrap">
<span class="smllbtn" @click.stop="handleQsFk(props.item,'签收')" v-if="props.item.yjJb != 10 && props.item.czzt == '01' && deptLevel=='40' ">签收</span>
<span class="smllbtn" @click.stop="handleQsFk(props.item,'反馈')" v-if="props.item.yjJb != 10 && props.item.czzt == '02' && deptLevel=='40'"> 反馈 </span>
<span class="smllbtn" @click.stop="handleQsFk(props.item,'查看反馈')" v-if="props.item.yjJb != 10 && props.item.czzt == '03' && deptLevel=='40' "> 查看反馈 </span>
<span class="smllbtn" @click.stop="handleQsFk(props.item,'查看反馈')" v-if="props.item.yjJb != 10 && props.item.czzt == '03'"> 查看反馈 </span>
</div>
</div>
<div class="items">
@ -82,7 +82,7 @@ const rules = reactive({
fknr: [{ required: true, message: "请输入反馈内容", trigger: "blur" }],
})
onMounted(() => {
deptLevel.value = localStorage.getItem("deptId") ? JSON.parse(localStorage.getItem("deptId"))[0].deptLevel : null;
// deptLevel.value = localStorage.getItem("deptId") ? JSON.parse(localStorage.getItem("deptId"))[0].deptLevel : null;
});

View File

@ -0,0 +1,30 @@
// 正文
export const textStyle = (data) => {
return `<p style="text-indent: 2em;"><span style="font-size: 16px; font-family: 仿宋;">${data}</span></p>`
}
//一级标题
export const Firstlevelheading = (data) => {
return `<p style="text-indent: 2em;"><span style="font-size: 16px; font-family: 黑体;">${data}</span></p>`
}
//二级标题
export const Subheading = (data) => {
return `<p style="text-indent: 2em;"><span style="font-size: 16px; font-family: 仿宋;">${data}</span></p>`
}
export const BiheadlinegTitle = (data) => {
return `<p style="text-indent: 2em;"><span style="font-size: 16px; font-family: 楷体;"><strong>${data}</strong></span></p>`
}
// 大标题
export const BigTitle = (data) => {
return `<h4 style="text-align: center;"><span style="color: rgb(225, 60, 57); font-size: 32px; font-family: 标楷体;">${data}</span></h4>`
}
export const headTitle = (data) => {
return `<p style="text-align: left;"><span style="color: rgb(225, 60, 57); font-size: 16px; font-family: 标楷体;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;${data.orgName}编 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;第${data.serialNumber}号&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;${data.time}&nbsp; </span></p ><hr/>`
}
export const report = (data) => {
return `<p><br></p ><p style="text-indent: 2em;">报抄:西藏公安厅</p ><hr/><p> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;`
}
export const signature = () => {
return `<p> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 承办人: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 核稿人 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;签发人:</p >`
}

View File

@ -7,36 +7,23 @@
</div>
</div>
<div class="listBox">
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount"></Search>
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
<template #zdrRyjb="{ row }">
<DictTag :value="row.zdrRyjb" :tag="false" :options="D_GS_ZDR_RYJB" />
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount"></Search>
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #jqlbdm="{ row }">
<DictTag :tag="false" :value="row.jqlbdm" :options="dict.JQLB" />
</template>
<template #zdrYjdj="{ row }">
<DictTag :value="row.zdrYjdj" :tag="false" :options="D_GS_ZDR_YJDJ" />
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="{
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"
></Pages>
</div>
}"></Pages>
</div>
</div>
</div>
@ -48,19 +35,28 @@ import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import { qcckPost } from "@/api/qcckApi.js";
import { ref, reactive, nextTick, getCurrentInstance } from 'vue';
import { useRouter,useRoute } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
const { proxy } = getCurrentInstance();
const { D_GS_ZDR_RYJB,D_GS_ZDR_YJDJ} = proxy.$dict("D_GS_ZDR_RYJB","D_GS_ZDR_YJDJ"); //获取字典数据
const showDialog = ref(false)
const searchBox = ref(); //搜索框
const searchConfiger = ref(
[
{ label: "姓名", prop: 'ryXm', placeholder: "请输入姓名", showType: "input"},
{ label: "身份证号", prop: 'rySfzh', placeholder: "请输入身份证号", showType: "input"},
]);
const emit=defineEmits(['getData'])
{ label: "研判名称", prop: 'ypmc', placeholder: "请输入研判名称", showType: "input" },
]);
const props=defineProps({
dict: {
type: Object,
default: ()=>{}
}
})
const emit = defineEmits(['getData'])
const ypPremsess = ref()
const onSearch = (val) => {
ypPremsess.value = val
getList()
}
const router = useRouter()
const route=useRoute()
const route = useRoute()
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
@ -77,13 +73,14 @@ const pageData = reactive({
}, //分页
controlsWidth: 160, //操作栏宽度
tableColumn: [
{ label: "姓名", prop: "ryXm" },
{ label: "身份证号", prop: "rySfzh" },
{ label: "联系电话", prop: "ryLxdh" },
{ label: "重点人员级别", prop: "zdrRyjb",showSolt:true },
{ label: "预警等级", prop: "zdrYjdj",showSolt:true },
{ label: "关联民警", prop: "gkMjXm" },
{ label: "民警警号", prop: "gkMjJh" },
{ label: "研判名称", prop: "ypmc" },
{ label: "报警时间", prop: "bjsj" },
{ label: "报警地址", prop: "bjdz" },
{ label: "警情类型", prop: "jqlbdm",showSolt:true },
{ label: "报警内容", prop: "bjnr", showOverflowTooltip: true },
{ label: "报警电话", prop: "bjdh" },
{ label: "报警时间", prop: "bjsj" },
]
});
const item = ref({})
@ -106,50 +103,50 @@ const changeSize = (val) => {
getList();
};
const getList = () =>{
let params = {
ypid:item.value.id,
// sjLx:sjlx.value,
pageCurrent:pageData.pageConfiger.pageCurrent,
pageSize:pageData.pageConfiger.pageSize,
}
pageData.tableConfiger.loading = true;
qcckPost(params,'/jjdbYp/getPageList').then(res=>{
pageData.tableConfiger.loading = false;
pageData.tableData = res.records || []
pageData.total = res.total;
}).catch(()=>{
pageData.tableConfiger.loading = false;
})
const getList = () => {
let params = {
ypid: item.value.id,
ypmc:ypPremsess.value,
pageCurrent: pageData.pageConfiger.pageCurrent,
pageSize: pageData.pageConfiger.pageSize,
}
pageData.tableConfiger.loading = true;
qcckPost(params, '/mosty-gsxt/jjdbYp/getPageList').then(res => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records || []
pageData.total = res.total;
}).catch(() => {
pageData.tableConfiger.loading = false;
})
}
const close = () =>{
pageData.tableData = [];
const close = () => {
pageData.tableData = [];
showDialog.value = false;
router.replace(route.query)
emit("getData")
// emit("getData")
}
const init = (val,lxs) =>{
showDialog.value = true;
item.value = val;
sjlx.value = lxs;
getList()
nextTick(()=>{
tabHeightFn()
})
const init = (val, lxs) => {
showDialog.value = true;
item.value = val;
sjlx.value = lxs;
getList()
nextTick(() => {
tabHeightFn()
})
}
defineExpose({init})
defineExpose({ init })
</script>
<style lang="scss" scoped>
.listBox{
height: calc(100% - 50px);
::v-deep .searchBox{
margin-bottom: 0 !important;
}
}
.listBox {
height: calc(100% - 50px);
::v-deep .searchBox {
margin-bottom: 0 !important;
}
}
</style>

View File

@ -1,14 +1,15 @@
<template>
<div class="statistical-analysis">
<!-- 左侧树形菜单 -->
<div class="left-menu">
<!-- 数据类型 -->
<!-- 左侧树形菜单 -->
<!-- <div class="left-menu">
<CheckBox :data="checkData.sjlxBtn" customClass="all" @changeData="changeData_sjly"></CheckBox>
</div>
</div> -->
<!-- 右侧内容区 -->
<!-- 研判类型 -->
<div class="right-content">
<div class="btnsBox" ref="refBtn">
<!-- 研判类型 -->
<CheckBox :data="checkData.yplxBtn" @changeData="changeData_yplx"></CheckBox>
</div>
<div ref="searchBox">
@ -24,7 +25,7 @@
</div>
<div class="f14 lh24 pl4 pr4 one_text_detail">数量{{ it.num }}</div>
<div class="foot">
<span class="ml10 pointer" @click.stop="handleYp(it)" style="color:#027ff0 ;"><el-icon style="top: 2px;">
<span class="ml10 pointer" @click.stop="funAll(it.id)" style="color:#027ff0 ;"><el-icon style="top: 2px;">
<Document />
</el-icon>报告</span>
<span class="ml10 pointer" @click="handleHs(it)" style="color:#f4ac47 ;"><el-icon style="top: 2px;">
@ -40,8 +41,8 @@
</div>
</div>
<!-- 详情 -->
<Detail ref="detailForm" @getData="getLits"></Detail>
<YpModel v-model="showModel" :textContent="textContent"></YpModel>
<Detail ref="detailForm" @getData="getLits" :dict="JQLB"></Detail>
<YpModel v-model="showModel" :heightNumber="650" v-model:textContent="textContent"></YpModel>
</template>
<script setup>
@ -51,12 +52,16 @@ import * as MOSTY from "@/components/MyComponents/index";
import CheckBox from "@/components/checkBox/index.vue";
import Search from "@/components/aboutTable/Search.vue";
import { qcckPost } from "@/api/qcckApi.js";
import { timeValidate } from '@/utils/tools.js'
import {getItem} from '@/utils/storage.js'
import { useRoute, useRouter } from 'vue-router';
import { reactive, ref, onMounted, getCurrentInstance, watch, nextTick } from "vue";
import { jqypDywdtj, jqypfxbgJqlxtj, jqypfxbgYdfx, jqypfxbgJqlytj, jqypfxbgTj, jqypfxbgCljgf, jqypfxbgCzlfx, getDictItem } from '@/api/semanticAnalysis'
import { textStyle, Firstlevelheading, Subheading, BiheadlinegTitle, BigTitle, headTitle, report, signature } from './components/content.js'
const router = useRouter();
const { proxy } = getCurrentInstance();
const { D_SG_SJLY, D_SG_TSYPGZ } = proxy.$dict("D_SG_SJLY", "D_SG_TSYPGZ"); //获取字典数据
const { D_SG_SJLY, D_SG_TSYPGZ,JQLB } = proxy.$dict("D_SG_SJLY", "D_SG_TSYPGZ","JQLB"); //获取字典数据
const searchBox = ref(); //搜索框
const showModel = ref(false);
const textContent = ref('');
@ -90,6 +95,7 @@ watch(() => [D_SG_SJLY.value, D_SG_TSYPGZ.value], val => {
const route = useRoute();
onMounted(() => {
show.value = true;
Time()
tabHeightFn();
if (route.query.id) {
lookDeatl(route.query)
@ -153,38 +159,6 @@ const getLits = () => {
})
}
const handleYp = async (val) => {
await funAll(val.id)
let params = { tsypid: val.id, }
await qcckPost(params, '/mosty-gsxt/wshs/getDcypbg').then(res => {
let data = res || {};
const content = `
<p>为全面、客观、准确掌握全区公安机关的执法状况自治区公安厅基于数据统计对全区公安机关2021年度的执法状况作了客观分析。</p>
<p>一、执法状况总体分析</p>
<p>1.接处警情况</p>
<p>1.1接报警情</p>
`
// let html = `<p class="html_bt">${data.bt}</p>`
html += `<p>${data.head}</p>`
// html += `<p>${data.nr}</p>`
html += `<p class="html_bt">${content}
${sortingRatioValue.fxbg}
${sortingRatioValue.jqlx}
${sortingRatioValue.jqly}
${sortingRatioValue.dywd}
${sortingRatioValue.ydfx}
${sortingRatioValue.czjgfx}
${sortingRatioValue.xlwdfx}
</p>`;
html += `<p>${data.bc}</p>`
html += `<p>${data.end}</p>`
console.log(html);
textContent.value = html
showModel.value = true;
})
}
const handleHs = (val) => {
router.push({ path: '/MeetingRoom', query: { tsypid: val.id } })
}
@ -217,14 +191,13 @@ const dataList = reactive({
CljgfTj: [],
XsfxTj: [],
})
const sortingRatioValue = reactive({
const sortingRatioValue = ref({
jqlx: "",
jqly: "",
dywd: "",
ydfx: "",
xlwdfx: "",
czjgfx: "",
fxbg: ""
})
const sortingRatio = (data) => {
// 提取所有number值
@ -256,19 +229,64 @@ const getDictItemList = () => {
})
}
getDictItemList()
const funAll =async (val) => {
// await getfxbgDywdtj(val)
// await getfxbgJqlxtj(val)
// await getfxbgJqlytj(val)
// await getfxbgYdfx(val)
// await getfxgbCljgf(val)
// await getfxgbCzlfx(val)
// await getfxbgTj(val)
const funAll = (val) => {
const dev=getItem('deptId')[0]
textContent.value = BigTitle(`${endYears.value}年度西藏公安执法数据分析`) + headTitle({
orgName:dev.deptName,
serialNumber: timeValidate("","mm"),
time: timeValidate(),
})
const data = `为全面、客观、准确掌握全区公安机关的执法状况,自治区公安厅基于数据统计,对全区公安机关${endYears.value}年度的执法状况作了客观分析。`
textContent.value += BiheadlinegTitle('1.接处警情况') + textStyle(data) + Firstlevelheading('一、执法状况总体分析')
getfxbgYdfx(val)
getfxbgTj()
getfxbgJqlxtj(val)
getfxbgJqlytj(val)
getfxbgDywdtj(val)
getfxgbCljgf(val)
getfxgbCzlfx(val)
console.log(sortingRatioValue.value);
showModel.value = true;
}
watch(() => sortingRatioValue.value, (val) => {
if (val.jqlx&&val.jqly&&val.dywd&&val.ydfx&&val.xlwdfx&&val.czjgfx) {
textContent.value +=val.jqlx +val.jqly +val.dywd +val.ydfx + val.xlwdfx +val.czjgfx+report()+signature()
}
},{deep:true})
const getfxbgTj = (val) => {
jqypfxbgTj({ ypid: val }).then(res => {
const data = `${Time()} ,全区公安机关共接报各类警情${res.total}起,同比上升 ${res.tbbsb}%,同比上升${res.hbbsb}%`
textContent.value += BiheadlinegTitle('1.1接报警情') + textStyle(data)
dataList.XsfxTj = res
})
}
// 警情类型统计
const getfxbgJqlxtj = (val) => {
let params = {
...pageData.parameter,
ypid: val
}
jqypfxbgJqlxtj(params).then(res => {
const model = sortingRatio(res)
const data = `按警情类型来看,${model[0].name}最多,占到${model[0].ratio};其次为${model[1].name}最多,占到${model[1].ratio}`
sortingRatioValue.value.jqlx = Subheading('1.1.1类型维度') + textStyle(data)
})
}
// 警情来源统计
const getfxbgJqlytj = (val) => {
jqypfxbgJqlytj({ ypid: val }).then(res => {
const model = sortingRatio(res)
const data = `按警情来源来看,${model[0].name}最多,占到${model[0].ratio};其次为${model[1].name}最多,占到${model[1].ratio}`
sortingRatioValue.value.jqly = Subheading('1.1.2来源维度') + textStyle(data)
})
}
// 地域统计
const getfxbgDywdtj = (val) => {
jqypDywdtj({ypid:val}).then(res => {
jqypDywdtj({ ypid: val }).then(res => {
dataList.dyTj.xAxisData = res.map(it => it.ssbm)
dataList.dyTj.seriesData = [];
for (let i = 0; i < res.length; i++) {
@ -281,81 +299,42 @@ const getfxbgDywdtj = (val) => {
dataList.dyTj.seriesData[i][i] = res[i].number
}
const model = sortingRatio(res)
sortingRatioValue.dywd = `<p>1.1.3地域维度</p><p>从地市分布地市来看,${model[0].ssbm}警情量最大,占到全区警情总量的${model[0].number}。其次为${model[1].ssbm}${model[2].ssbm},两市警情量较为接近。警情量最少的为${model[model.length - 1].ssbm} </p>`
// sortingRatioValue.Dywdtj = sortingRatio(res)
})
}
// 警情类型统计
const getfxbgJqlxtj = (val) => {
let params = {
...pageData.parameter,
ypid:val
}
jqypfxbgJqlxtj(params).then(res => {
// sortingRatioValue.Jqlx =
const model = sortingRatio(res)
sortingRatioValue.jqlx = `<p>1.1.1类型维度</p><p>按警情类型来看,${model[0].name}最多,占到${model[0].ratio};其次为${model[1].name}最多,占到${model[1].ratio}。</p>`
dataList.jqlxTj = res.map(item => {
return {
name: item.name,
value: item.number
}
})
})
}
// 警情来源统计
const getfxbgJqlytj = (val) => {
jqypfxbgJqlytj({ypid:val}).then(res => {
// sortingRatioValue.Lyfx =
const model = sortingRatio(res)
sortingRatioValue.jqly = `<p>1.1.2来源维度</p><p>按警情来源来看,${model[0].name}最多,占到${model[0].ratio};其次为${model[1].name}最多,占到${model[1].ratio}。</p>`
dataList.jqlyTj = res.map(item => {
return {
name: item.name,
value: item.number
}
})
let data
if (model.length>1) {
data = `从地市分布地市来看,${model[0].ssbm}警情量最大,占到全区警情总量的${model[0].number}。其次为${model[1].ssbm}${model[2].ssbm},两市警情量较为接近。警情量最少的为${model[model.length - 1].ssbm}`
} else {
data = `从地市分布地市来看,${model[0].ssbm}警情量最大,占到全区警情总量的${model[0].number}`
}
sortingRatioValue.value.dywd = Subheading('1.1.3地域维度') + textStyle(data)
})
}
//分析报告-时间维度-月分析
const getfxbgYdfx = (val) => {
jqypfxbgYdfx({ypid:val}).then(res => {
// sortingRatioValue.Ydfx =
jqypfxbgYdfx({ ypid: val }).then(res => {
const model = sortingRatio(res)
sortingRatioValue.ydfx = `<p >1.1.4时间维度</p> <p>我们将所有警情按照月份划分进行统计发现,每月警情分布较为平均。最高月份为${model[0].month}月,占到${model[0].number};最低月份为${model[res.length - 1].month}月,占到${model[res.length - 1].number}。考虑是因为${model[0].month}月为我区传统旅游旺季,进藏人员较多。 ${model[res.length - 1].month}月一般春节及藏历新年期间,在藏人员较少。</p>
`
// dataList.ydTj = res.map(item => {
// return {
// name: item.month,
// value: item.number
// }
// })
const data = `我们将所有警情按照月份划分进行统计发现,每月警情分布较为平均。最高月份为${model[0].month}月,占到${model[0].number};最低月份为${model[res.length - 1].month}月,占到${model[res.length - 1].number}。考虑是因为${model[0].month}月为我区传统旅游旺季,进藏人员较多。 ${model[res.length - 1].month}月一般春节及藏历新年期间,在藏人员较少。`
sortingRatioValue.value.ydfx = Subheading('1.1.4时间维度') + textStyle(data)
})
}
// 分析报告-处理结果分析
const getfxgbCljgf = (val) => {
jqypfxbgCljgf({ypid:val}).then(res => {
jqypfxbgCljgf({ ypid: val }).then(res => {
// sortingRatioValue.Cljgf =
const model = sortingRatio(res)
dataList.CljgfTj = res.map(item => {
return {
name: item.name,
value: item.number
}
})
let czjgfx = `从警情处置结果来看,`
model.forEach(item => {
czjgfx += `${item.name},占到${item.ratio};`
})
sortingRatioValue.czjgfx = `<p>1.2警情处置</p><p>1.2.1结果维度</p><p>${czjgfx}</p>`
sortingRatioValue.value.xlwdfx = BiheadlinegTitle('1.2警情处置') + Firstlevelheading('1.2.1结果维度') + textStyle(czjgfx)
})
}
// 分析报告-处置率分析
const getfxgbCzlfx = (val) => {
jqypfxbgCzlfx({ypid:val}).then(res => {
jqypfxbgCzlfx({ ypid: val }).then(res => {
dataList.withinTj = [{
name: "超时分流(超过24小时)",
value: res.within24h ? res.within24h : 0
@ -363,18 +342,13 @@ const getfxgbCzlfx = (val) => {
name: "按时分流(24小时内)",
value: res.over24h ? res.over24h : 0
}]
sortingRatioValue.xlwdfx = `<p>1.2.2效率维度</p><p>从处警效率来看24小时以内处警的占到${res.over24h}%。表明我区公安机关在接警之后能够在第一时间处警。</p>
`
// sortingRatioValue.Czlfx = sortingRatio(dataList.withinTj)
const data = `从处警效率来看24小时以内处警的占到${res.over24h}%。表明我区公安机关在接警之后能够在第一时间处警。`
sortingRatioValue.value.czjgfx = Subheading('1.2.2效率维度') + textStyle(data)
})
}
const getfxbgTj = (val) => {
jqypfxbgTj({ypid:val}).then(res => {
sortingRatioValue.fxbg = `<p>${Time()} ,全区公安机关共 接报各类警情${res.total}起,同比上升 ${res.tbbsb}%,同比上升${res.hbbsb}%</p>`
dataList.XsfxTj = res
})
}
const timeDate = ref()
const endYears=ref()
const Time = () => {
const currentYear = new Date().getFullYear();
const startOfYear = new Date(currentYear, 0, 1); // 今年1月1日
@ -385,19 +359,15 @@ const Time = () => {
const endYear = endOfYear.getFullYear();
const endMonth = String(endOfYear.getMonth() + 1).padStart(2, '0');
const endDay = String(endOfYear.getDate()).padStart(2, '0');
timeDate.value=`${endYear}${endMonth}${endDay}`
endYears.value=year
return `${year}${month}${day}日 至${endYear}${endMonth}${endDay}`
}
</script>
<style lang="scss" scoped>
@ -447,7 +417,8 @@ const Time = () => {
.right-content {
float: left;
width: calc(100% - 290px);
// width: calc(100% - 290px);
width: 100%;
height: 100%;
margin-top: 20px;
margin-left: 10px;
@ -465,7 +436,7 @@ const Time = () => {
display: flex;
flex-wrap: wrap;
align-content: start;
gap: 22px;
gap: 18px;
overflow: hidden;
overflow-y: auto;
background: #fff;
@ -484,7 +455,7 @@ const Time = () => {
margin-top: 4px;
border-top: 1px solid #ccc;
padding: 4px;
box-sizing: border-box ;
box-sizing: border-box;
}
}

View File

@ -2,9 +2,7 @@
<div class="homeBox">
<!-- <GdMap></GdMap> -->
<!-- 头部 -->
<Head></Head>
<!-- 内容 -->
<!-- 左边 -->
<div class="home-aside asideL">
<div class="asideL-top">
@ -36,16 +34,10 @@
</div>
<!-- 中间 -->
<div class="home-center">
<div class="middle-top">
<Yszs />
</div>
<div class="middle-top"><Yszs /></div>
<div class="flex middle-bottom mt10">
<div class="mr10" style="width: 50%;">
<DeployControl />
</div>
<div class="flex-1" style="flex: 1;">
<ZdryWarning />
</div>
<div class="mr10" style="width: 50%;"><DeployControl /></div>
<div class="flex-1" style="flex: 1;"><ZdryWarning /></div>
</div>
</div>

View File

@ -6,7 +6,7 @@
<div style="height:33px;">
<CheckBox :data="checkData" @changeData="changeData"></CheckBox>
</div>
<ul class="ryBox" v-loading="loading" v-infinite-scroll="loadList" style="overflow: auto">
<ul class="ryBox" ref="scrollTableRef" @mouseenter="stopAutoScroll" @mouseleave="startAutoScroll" v-loading="loading" v-infinite-scroll="loadList" >
<li v-for="item in personList" :key="item.id" @click="chooseItem(item)">
<DeployControlItem :item="item" :dict="{D_BZ_HPZL}"/>
</li>
@ -21,7 +21,7 @@ import { qcckPost } from "@/api/qcckApi.js";
import DeployControlItem from "@/views/home/components/deployControlItem.vue";
import * as MOSTY from "@/components/MyComponents/index";
import CheckBox from "@/components/checkBox/index.vue";
import { ref ,reactive, onMounted,getCurrentInstance} from 'vue';
import { ref ,reactive, onMounted,onUnmounted,getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();
const {D_BZ_HPZL} =proxy.$dict('D_BZ_HPZL')
const checkData = reactive({
@ -33,9 +33,51 @@ const yjJb = ref('10,20,30,40');
const pageNum = ref(1);
const loading = ref(false); // 加载中
const personList = ref([]);
const scrollTableRef = ref(null) // 滚动元素区域
let isAutoScrolling = true // 是否自动滚动
const intervalId = ref(null) //定时器
onMounted(()=>{
getList()
autoScroll()
})
onUnmounted(() => {
if (intervalId.value) clearInterval(intervalId.value)// 清理定时器
})
// 自动滚动
const autoScroll = () => {
if(personList.value.length==0){return}
intervalId.value = setInterval(() => {
if (!isAutoScrolling) return
const scrollTableEl = scrollTableRef.value
scrollTableEl.scrollTop += 1 // 垂直滚动距离
let scrollTop = scrollTableEl.scrollTop;
let scrollHeight = scrollTableEl.scrollHeight;
let offsetHeight = Math.ceil(scrollTableEl.getBoundingClientRect().height);
let currentHeight = scrollTop + offsetHeight;
if (currentHeight >= scrollHeight) { // 到底部
if(personList.value.length == total.value){
scrollTableEl.scrollTop = 0;
}else{
pageNum.value++;
getList('load')
}
}
}, 100)
}
// 停止滚动
const stopAutoScroll = () => {
isAutoScrolling = false
}
// 开始滚动
const startAutoScroll = () => {
isAutoScrolling = true
autoScroll()
}
// 复选框切换
function changeData(val){
pageNum.value = 1;
@ -60,9 +102,9 @@ const loadList = () =>{
getList()
}
const getList = () =>{
const getList = (type) =>{
let data = { pageSize:10, pageNum:pageNum.value,yjJb:yjJb.value ,bkyj:1};
loading.value = true;
loading.value = !type ? true : false;
qcckPost(data,'/mosty-gsxt/tbYjxx/getPageList').then(res=>{
loading.value = false;
let arr = res.records || [];

View File

@ -6,7 +6,7 @@
<div style="height:33px;">
<CheckBox :data="checkData" @changeData="changeData"></CheckBox>
</div>
<ul class="ryBox" v-loading="loading" v-infinite-scroll="loadList" style="overflow: auto">
<ul class="ryBox" ref="scrollCgTableRef" @mouseenter="stopAutoScroll" @mouseleave="startAutoScroll" v-loading="loading" v-infinite-scroll="loadList">
<li v-for="item in personList" :key="item.id" @click="chooseItem(item)">
<YjItem :item="item" :dict="{D_BZ_HPZL}"></YjItem>
</li>
@ -21,7 +21,7 @@ import { qcckPost } from "@/api/qcckApi.js";
import YjItem from "@/views/home/components/yjItem.vue";
import * as MOSTY from "@/components/MyComponents/index";
import CheckBox from "@/components/checkBox/index.vue";
import { ref ,reactive, onMounted,getCurrentInstance} from 'vue';
import { ref ,reactive, onMounted,getCurrentInstance , onUnmounted} from 'vue';
const { proxy } = getCurrentInstance();
const {D_BZ_HPZL} =proxy.$dict('D_BZ_HPZL')
const checkData = reactive({
@ -33,9 +33,51 @@ const yjJb = ref('1,2');
const pageNum = ref(1);
const loading = ref(false); // 加载中
const personList = ref([]);
const scrollCgTableRef = ref(null) // 滚动元素区域
let isAutoScrolling = true // 是否自动滚动
const intervalId = ref(null) //定时器
onMounted(()=>{
getList()
autoScroll()
})
onUnmounted(() => {
if (intervalId.value) clearInterval(intervalId.value)// 清理定时器
})
// 自动滚动
const autoScroll = () => {
if(personList.value.length==0){return}
intervalId.value = setInterval(() => {
if (!isAutoScrolling) return
const scrollTableEl = scrollCgTableRef.value
scrollTableEl.scrollTop += 1 // 垂直滚动距离
let scrollTop = scrollTableEl.scrollTop;
let scrollHeight = scrollTableEl.scrollHeight;
let offsetHeight = Math.ceil(scrollTableEl.getBoundingClientRect().height);
let currentHeight = scrollTop + offsetHeight;
if (currentHeight >= scrollHeight) { // 到底部
if(personList.value.length == total.value){
scrollTableEl.scrollTop = 0;
}else{
pageNum.value++;
getList('load')
}
}
}, 100)
}
// 停止滚动
const stopAutoScroll = () => {
isAutoScrolling = false
}
// 开始滚动
const startAutoScroll = () => {
isAutoScrolling = true
autoScroll()
}
// 复选框切换
function changeData(val){
pageNum.value = 1;
@ -58,9 +100,9 @@ const loadList = () =>{
getList()
}
const getList = () =>{
const getList = (type) =>{
let data = { pageSize:10, pageNum:pageNum.value,yjLx:yjJb.value };
loading.value = true;
loading.value = !type ? true : false;
qcckPost(data,'/mosty-gsxt/tbYjxx/getPageList').then(res=>{
loading.value = false;
let arr = res.records || [];