Compare commits
2 Commits
3272bbd888
...
1c6bbffc3b
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c6bbffc3b | |||
| 1a16344cf4 |
21198
package-lock.json
generated
21198
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -30,9 +30,7 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"fzui-fengqun-vue": "^1.0.1",
|
||||
"gifler": "^0.1.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"image-compressor.js": "^1.1.4",
|
||||
"jspdf": "^2.5.1",
|
||||
"lodash": "^4.17.21",
|
||||
"mitt": "^3.0.0",
|
||||
"moment": "^2.30.1",
|
||||
|
||||
@ -133,3 +133,69 @@ export const fxgbCzlfx = (params) => {
|
||||
});
|
||||
}
|
||||
|
||||
// 分析报告-地域维度统计
|
||||
export const jqypDywdtj = (params) => {
|
||||
return request({
|
||||
url: api + "/jjdbYp/fxbgDywdtj",
|
||||
method: "GET",
|
||||
params
|
||||
});
|
||||
};
|
||||
|
||||
// 分析报告 - 警情类型统计
|
||||
export const jqypfxbgJqlxtj = (params) => {
|
||||
return request({
|
||||
url: api + "/lzJcjPjdb/fxbgJqlxtj",
|
||||
method: "GET",
|
||||
params
|
||||
});
|
||||
}
|
||||
// 警情来源统计
|
||||
|
||||
export const jqypfxbgJqlytj = (params) => {
|
||||
return request({
|
||||
url: api + "/jjdbYp/fxbgJqlytj",
|
||||
method: "GET",
|
||||
params
|
||||
});
|
||||
}
|
||||
// 分析报告
|
||||
export const jqypfxbgTj = (params) => {
|
||||
return request({
|
||||
url: api + "/jjdbYp/fxbgTj",
|
||||
method: "GET",
|
||||
params
|
||||
});
|
||||
}
|
||||
// 分析报告-时间维度-月分析
|
||||
export const jqypfxbgYdfx = (params) => {
|
||||
return request({
|
||||
url: api + "/jjdbYp/fxbgYdfx",
|
||||
method: "GET",
|
||||
params
|
||||
});
|
||||
}
|
||||
// 分析报告-时间维度-24小时分析
|
||||
export const jqypfxbgXsfx = (params) => {
|
||||
return request({
|
||||
url: api + "/jjdbYp/fxbgXsfx",
|
||||
method: "GET",
|
||||
params
|
||||
});
|
||||
}
|
||||
// 分析报告 - 处理结果分析
|
||||
export const jqypfxbgCljgf = (params) => {
|
||||
return request({
|
||||
url: api + "/jjdbYp/fxgbCljgfx",
|
||||
method: "GET",
|
||||
params
|
||||
});
|
||||
}
|
||||
// 分析报告-处置率分析
|
||||
export const jqypfxbgCzlfx = (params) => {
|
||||
return request({
|
||||
url: api + "/jjdbYp/fxgbCzlfx",
|
||||
method: "GET",
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
18
src/main.js
18
src/main.js
@ -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");
|
||||
|
||||
@ -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"
|
||||
// }
|
||||
// },
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@ -125,8 +125,6 @@
|
||||
<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'
|
||||
@ -203,17 +201,14 @@ 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
|
||||
}
|
||||
// 地域统计
|
||||
|
||||
@ -390,4 +390,19 @@ watch(()=>D_BZ_SSZT.value, (val) => {
|
||||
color: red;
|
||||
}
|
||||
|
||||
|
||||
// .bts >>>p{
|
||||
// font-size: 16px; font-family: 黑体;
|
||||
// color: rgb(255, 0, 140);
|
||||
// }
|
||||
// .psj >>>p{
|
||||
// text-indent: 2em;
|
||||
// }
|
||||
// .minbt >>>p{
|
||||
// font-size: 16px; font-family: 楷体;
|
||||
// }
|
||||
// .nr >>>p{
|
||||
// font-size: 16px; font-family: 仿宋;
|
||||
// }
|
||||
|
||||
</style>
|
||||
|
||||
@ -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: 标楷体;"> ${data.orgName}编 第${data.serialNumber}号 ${data.time} </span></p ><hr/>`
|
||||
}
|
||||
export const report = (data) => {
|
||||
return `<p><br></p ><p style="text-indent: 2em;">报抄:西藏公安厅</p ><hr/><p> `
|
||||
}
|
||||
export const signature = () => {
|
||||
return `<p> 承办人: 核稿人 : 签发人:</p >`
|
||||
}
|
||||
|
||||
@ -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,51 +103,50 @@ const changeSize = (val) => {
|
||||
getList();
|
||||
};
|
||||
|
||||
const getList = () =>{
|
||||
let params = {
|
||||
id:item.value.id,
|
||||
sjLx:sjlx.value,
|
||||
pageCurrent:pageData.pageConfiger.pageCurrent,
|
||||
pageSize:pageData.pageConfiger.pageSize,
|
||||
}
|
||||
pageData.tableConfiger.loading = true;
|
||||
qcckPost(params,'/mosty-gsxt/tsyp/getRyPage').then(res=>{
|
||||
pageData.tableConfiger.loading = false;
|
||||
console.log(res,'===');
|
||||
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>
|
||||
|
||||
@ -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,11 +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('');
|
||||
@ -89,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)
|
||||
@ -141,7 +148,6 @@ const getLits = () => {
|
||||
...formData.value
|
||||
}
|
||||
loading.value = true;
|
||||
console.log(params);
|
||||
|
||||
qcckPost(params, '/mosty-gsxt/tsyp/selectPage').then(res => {
|
||||
let arr = res.records || [];
|
||||
@ -153,20 +159,6 @@ const getLits = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleYp = (val) => {
|
||||
let params = { tsypid: val.id, }
|
||||
qcckPost(params, '/mosty-gsxt/wshs/getDcypbg').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 handleHs = (val) => {
|
||||
router.push({ path: '/MeetingRoom', query: { tsypid: val.id } })
|
||||
}
|
||||
@ -187,6 +179,195 @@ const tabHeightFn = () => {
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
const dataList = reactive({
|
||||
dyTj: {
|
||||
xAxisData: [],
|
||||
seriesData: [],
|
||||
},
|
||||
jqlxTj: [],
|
||||
jqlyTj: [],
|
||||
CljgfTj: [],
|
||||
XsfxTj: [],
|
||||
})
|
||||
const sortingRatioValue = ref({
|
||||
jqlx: "",
|
||||
jqly: "",
|
||||
dywd: "",
|
||||
ydfx: "",
|
||||
xlwdfx: "",
|
||||
czjgfx: "",
|
||||
})
|
||||
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 pageData = reactive({
|
||||
parameter: { bjlbList: '' }
|
||||
})
|
||||
|
||||
|
||||
const getDictItemList = () => {
|
||||
const promes = {
|
||||
dictCode: "00000000"
|
||||
}
|
||||
getDictItem(promes).then(res => {
|
||||
pageData.parameter.bjlbList = res.map(item => item.dm).join(',')
|
||||
console.log(pageData.parameter.bjlbList);
|
||||
|
||||
})
|
||||
}
|
||||
getDictItemList()
|
||||
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 => {
|
||||
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
|
||||
}
|
||||
const model = sortingRatio(res)
|
||||
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 => {
|
||||
const model = sortingRatio(res)
|
||||
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 => {
|
||||
// sortingRatioValue.Cljgf =
|
||||
const model = sortingRatio(res)
|
||||
|
||||
let czjgfx = `从警情处置结果来看,`
|
||||
model.forEach(item => {
|
||||
czjgfx += `${item.name},占到${item.ratio};`
|
||||
})
|
||||
sortingRatioValue.value.xlwdfx = BiheadlinegTitle('1.2警情处置') + Firstlevelheading('1.2.1结果维度') + textStyle(czjgfx)
|
||||
})
|
||||
}
|
||||
// 分析报告-处置率分析
|
||||
const getfxgbCzlfx = (val) => {
|
||||
|
||||
jqypfxbgCzlfx({ ypid: val }).then(res => {
|
||||
dataList.withinTj = [{
|
||||
name: "超时分流(超过24小时)",
|
||||
value: res.within24h ? res.within24h : 0
|
||||
}, {
|
||||
name: "按时分流(24小时内)",
|
||||
value: res.over24h ? res.over24h : 0
|
||||
}]
|
||||
const data = `从处警效率来看,24小时以内处警的,占到${res.over24h}%。表明我区公安机关在接警之后能够在第一时间处警。`
|
||||
sortingRatioValue.value.czjgfx = Subheading('1.2.2效率维度') + textStyle(data)
|
||||
})
|
||||
}
|
||||
|
||||
const timeDate = ref()
|
||||
const endYears=ref()
|
||||
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');
|
||||
timeDate.value=`${endYear}年${endMonth}月${endDay}日`
|
||||
endYears.value=year
|
||||
return `${year}年${month}月${day}日 至${endYear}年${endMonth}月${endDay}日`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -236,7 +417,8 @@ const tabHeightFn = () => {
|
||||
|
||||
.right-content {
|
||||
float: left;
|
||||
width: calc(100% - 290px);
|
||||
// width: calc(100% - 290px);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 20px;
|
||||
margin-left: 10px;
|
||||
@ -254,7 +436,7 @@ const tabHeightFn = () => {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: start;
|
||||
gap: 22px;
|
||||
gap: 18px;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
background: #fff;
|
||||
|
||||
@ -37,7 +37,9 @@ const changeValue = (value) => {
|
||||
showPopup.value = true
|
||||
}
|
||||
const classIndex=ref(0)
|
||||
const handleChange = (val,index) => {
|
||||
const handleChange = (val, index) => {
|
||||
console.log(val.tqjg);
|
||||
|
||||
classIndex.value=index
|
||||
|
||||
emitter.emit('getlistData', val.tqjg)
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, toRaw, computed, watch, nextTick, onMounted,getCurrentInstance } from "vue";
|
||||
import { ref, reactive, toRaw, computed, watch, nextTick, onMounted, getCurrentInstance } from "vue";
|
||||
import formNewModel from "./formNewModel.vue"
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
const { proxy } = getCurrentInstance()
|
||||
@ -40,37 +40,57 @@ const data = {
|
||||
40: "特征识别分析",
|
||||
}
|
||||
const model = ref()
|
||||
const numberData = 0
|
||||
const jx = (val) => {
|
||||
if (val) {
|
||||
const jsonObject = val;
|
||||
if (Array.isArray(jsonObject)) {
|
||||
model.value = jsonObject.reduce((acc, cur) => {
|
||||
const key = Object.keys(cur)[0];
|
||||
const prefix = key.substring(0, 2);
|
||||
if (!acc[prefix] && prefix !== '50' && prefix !== '60') {
|
||||
acc[prefix] = {
|
||||
inputs: [],
|
||||
model: {},
|
||||
value: prefix
|
||||
};
|
||||
}
|
||||
if (prefix === '50' || prefix === '60') {
|
||||
acc[10].inputs.push({ label: cur[key].name, prop: key, type: "input", width: "33%" });
|
||||
acc[10].model[key] = cur[key].content ? cur[key].content : '-';
|
||||
} else {
|
||||
acc[prefix].inputs.push({ label: cur[key].name, prop: key, type: "input", width: "33%" });
|
||||
acc[prefix].model[key] = cur[key].content == '-' || cur[key].content == '' || cur[key].content == '无' ? '/' : cur[key].content;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
} else {
|
||||
const str = JSON.parse(jsonObject);
|
||||
jx(str)
|
||||
numberData++
|
||||
if (numberData == 3) {
|
||||
numberData=0
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const json =props.listData ;
|
||||
const jsonString = JSON.parse(json);
|
||||
if (jsonString) {
|
||||
const jsonObject = jsonString;
|
||||
console.log(jsonObject);
|
||||
model.value = jsonObject.reduce((acc, cur) => {
|
||||
const key = Object.keys(cur)[0];
|
||||
const prefix = key.substring(0, 2);
|
||||
if (!acc[prefix] && prefix !== '50' && prefix !== '60') {
|
||||
acc[prefix] = {
|
||||
inputs: [],
|
||||
model: {},
|
||||
value: prefix
|
||||
};
|
||||
}
|
||||
if (prefix === '50' || prefix === '60') {
|
||||
acc[10].inputs.push({ label: cur[key].name, prop: key, type: "input", width: "33%" });
|
||||
acc[10].model[key] = cur[key].content? cur[key].content : '-';
|
||||
} else {
|
||||
acc[prefix].inputs.push({ label: cur[key].name, prop: key, type: "input", width: "33%" });
|
||||
acc[prefix].model[key] = cur[key].content=='-'||cur[key].content==''||cur[key].content=='无'? '/':cur[key].content ;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
} else {
|
||||
model.value = []
|
||||
proxy.$message({ type: "error", message: "解析失败" });
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
const json = props.listData;
|
||||
const jsonString = JSON.parse(json);
|
||||
jx(jsonString)
|
||||
})
|
||||
watch(() => props.listData, (val) => {
|
||||
if (val) {
|
||||
const json = val;
|
||||
const jsonString = JSON.parse(json);
|
||||
jx(jsonString)
|
||||
}
|
||||
},{deep:true})
|
||||
const handleClose = () => {
|
||||
emitter.emit('showDetails', true)
|
||||
}
|
||||
|
||||
@ -317,26 +317,26 @@ const getText = async (val) => {
|
||||
handleFx(obj)
|
||||
}
|
||||
function simpleExtractJSON(text) {
|
||||
// 找到第一个 [
|
||||
const startIndex = text.indexOf('[');
|
||||
if (startIndex === -1) return null;
|
||||
// 找到第一个 [
|
||||
const startIndex = text.indexOf('[');
|
||||
if (startIndex === -1) return null;
|
||||
|
||||
// 找到最后一个完整的 }
|
||||
let lastBraceIndex = text.lastIndexOf('}');
|
||||
if (lastBraceIndex === -1) return null;
|
||||
// 找到最后一个完整的 }
|
||||
let lastBraceIndex = text.lastIndexOf('}');
|
||||
if (lastBraceIndex === -1) return null;
|
||||
|
||||
// 确保 } 后面没有其他字符(除了空格和换行)
|
||||
let endIndex = lastBraceIndex + 1;
|
||||
// 确保 } 后面没有其他字符(除了空格和换行)
|
||||
let endIndex = lastBraceIndex + 1;
|
||||
|
||||
// 截取从 [ 到最后一个 } 的内容,然后加上 ]
|
||||
let jsonString = text.substring(startIndex, endIndex) + ']';
|
||||
// 截取从 [ 到最后一个 } 的内容,然后加上 ]
|
||||
let jsonString = text.substring(startIndex, endIndex) + ']';
|
||||
|
||||
try {
|
||||
return JSON.parse(jsonString);
|
||||
} catch (error) {
|
||||
console.error("简单修复失败:", error);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return JSON.parse(jsonString);
|
||||
} catch (error) {
|
||||
console.error("简单修复失败:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
const handleFx = (val) => {
|
||||
ElMessageBox.prompt('请输入名称', '提示', {
|
||||
@ -349,44 +349,44 @@ const handleFx = (val) => {
|
||||
.then(({ value }) => {
|
||||
loading.value = true
|
||||
completions(val).then(res => {
|
||||
console.log(res,"分析报告数据");
|
||||
let jsonString
|
||||
let jsonMatch = res.choices[0].text.match(/\[[\s\S]*?\]/g);
|
||||
if (!jsonMatch) {
|
||||
jsonMatch = simpleExtractJSON(res.choices[0].text)
|
||||
jsonString = jsonMatch;
|
||||
} else {
|
||||
jsonString = jsonMatch[0];
|
||||
}
|
||||
if (jsonMatch) {
|
||||
const promes = {
|
||||
fxlb: selectType.value,
|
||||
fxmc: value,
|
||||
tqjg:JSON.stringify(jsonString),//提取结果
|
||||
xyjg: res.choices[0].text,
|
||||
...saveData.value
|
||||
// console.log(res,"分析报告数据");
|
||||
let jsonString
|
||||
let jsonMatch = res.choices[0].text.match(/\[[\s\S]*?\]/g);
|
||||
if (!jsonMatch) {
|
||||
jsonMatch = simpleExtractJSON(res.choices[0].text)
|
||||
jsonString = jsonMatch;
|
||||
} else {
|
||||
jsonString = jsonMatch[0];
|
||||
}
|
||||
yyfxAdd(promes).then(res => {
|
||||
proxy.$message({ type: "success", message: "添加成功" });
|
||||
emitter.emit('getYyfxSelectPage')
|
||||
emitter.emit('getlistData',JSON.stringify(jsonString))
|
||||
emitter.emit('showDetails', false)
|
||||
}).catch(err => {
|
||||
console.log(err, "xxxxx");
|
||||
proxy.$message({ type: "error", message: "添加失败" });
|
||||
})
|
||||
} else {
|
||||
proxy.$message({ type: "error", message: "解析失败,请重新上传分析" });
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err, 'vvvv');
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
if (jsonMatch) {
|
||||
const promes = {
|
||||
fxlb: selectType.value,
|
||||
fxmc: value,
|
||||
tqjg: JSON.stringify(jsonString),//提取结果
|
||||
xyjg: res.choices[0].text,
|
||||
...saveData.value
|
||||
}
|
||||
yyfxAdd(promes).then(res => {
|
||||
proxy.$message({ type: "success", message: "添加成功" });
|
||||
emitter.emit('getYyfxSelectPage')
|
||||
emitter.emit('getlistData', JSON.stringify(jsonString))
|
||||
emitter.emit('showDetails', false)
|
||||
}).catch(err => {
|
||||
console.log(err, "xxxxx");
|
||||
proxy.$message({ type: "error", message: "添加失败" });
|
||||
})
|
||||
} else {
|
||||
proxy.$message({ type: "error", message: "解析失败,请重新上传分析" });
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err, 'vvvv');
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ onUnmounted(() => {
|
||||
})
|
||||
// 自动滚动
|
||||
const autoScroll = () => {
|
||||
if(personList.value.length==0){return}
|
||||
intervalId.value = setInterval(() => {
|
||||
if (!isAutoScrolling) return
|
||||
const scrollTableEl = scrollTableRef.value
|
||||
|
||||
@ -47,6 +47,8 @@ onUnmounted(() => {
|
||||
})
|
||||
// 自动滚动
|
||||
const autoScroll = () => {
|
||||
|
||||
if(personList.value.length==0){return}
|
||||
intervalId.value = setInterval(() => {
|
||||
if (!isAutoScrolling) return
|
||||
const scrollTableEl = scrollCgTableRef.value
|
||||
|
||||
@ -4,8 +4,8 @@ function resolve(dir) {
|
||||
return path.join(__dirname, dir);
|
||||
}
|
||||
|
||||
const serverHost = "http://192.168.1.32:8006"//波哥
|
||||
// const serverHost = "http://192.168.0.231:8006"//线上
|
||||
// const serverHost = "http://192.168.1.32:8006"//波哥
|
||||
const serverHost = "http://192.168.0.231:8006"//线上
|
||||
// const serverHost = "http://192.168.1.117:8006"//周
|
||||
// const serverHost = "http://192.168.1.98:8006"//毛毛
|
||||
|
||||
|
||||
Reference in New Issue
Block a user