Browse Source

fix: 个人风险库/单位风险库

master
wxc 1 month ago
parent
commit
b9f0acc942
  1. 7
      src/components/comfort/dialog.vue
  2. 2
      src/components/datav/chart-bar.vue
  3. 31
      src/components/file/list.vue
  4. 265
      src/components/negativeInfo/depart-dialog.vue
  5. 38
      src/components/negativeInfo/police-dialog.vue
  6. 634
      src/views/mobileSupervise/TaskProblem.vue
  7. 393
      src/views/sensitivePerception/PoliceNegative.vue

7
src/components/comfort/dialog.vue

@ -72,12 +72,7 @@
<el-divider /> <el-divider />
<template v-if="comfort.apply.isSelf === '0'"> <template v-if="comfort.apply.isSelf === '0'">
<div class="row"> <div class="row">
<div class="col col-6">
<label>代理人关系</label>
<span>{{
comfort.apply.relation === "1" ? "同事" : "亲属"
}}</span>
</div>
<div class="col col-6"> <div class="col col-6">
<label>代理人姓名</label> <label>代理人姓名</label>
<span>{{ comfort.apply.agentName }}</span> <span>{{ comfort.apply.agentName }}</span>

2
src/components/datav/chart-bar.vue

@ -3,7 +3,7 @@
<span class="bar-title">{{ title }}</span> <span class="bar-title">{{ title }}</span>
<span class="bar-sub-title">{{ subTitle }}</span> <span class="bar-sub-title">{{ subTitle }}</span>
</div> </div>
<div> <div style="width:100%">
<div <div
class="flex v-center bar-item wrap between" class="flex v-center bar-item wrap between"
v-for="item in data" v-for="item in data"

31
src/components/file/list.vue

@ -15,7 +15,7 @@
:style="{ :style="{
backgroundImage: `url(${BASE_PATH}/file/stream/${item.filePath})`, backgroundImage: `url(${BASE_PATH}/file/stream/${item.filePath})`,
}" }"
@click="filePreview(item)" @click="filePreview(item, index)"
></div> ></div>
<a <a
class="remove-btn" class="remove-btn"
@ -29,7 +29,7 @@
<div <div
class="item flex end v-center column text-center" class="item flex end v-center column text-center"
:title="item.fileName" :title="item.fileName"
@click="filePreview(item)" @click="filePreview(item, index)"
v-else v-else
> >
<icon :name="getIconName(item.fileName)" :size="40" /> <icon :name="getIconName(item.fileName)" :size="40" />
@ -54,8 +54,8 @@
v-for="(item, index) in files" v-for="(item, index) in files"
:key="index" :key="index"
class="flex gap v-center pointer" class="flex gap v-center pointer"
:active="files.indexOf(activeFile) === index" :active="activeIndex === index"
@click="filePreview(item)" @click="filePreview(item, index)"
> >
<icon :name="getIconName(item.fileName)" :size="24" /> <icon :name="getIconName(item.fileName)" :size="24" />
<span>{{ item.fileName }}</span> <span>{{ item.fileName }}</span>
@ -249,10 +249,13 @@ let moveFlag = false;
let initialX = 0; let initialX = 0;
let initialY = 0; let initialY = 0;
const fileRrror = ref(false); const fileRrror = ref(false);
const activeIndex = ref(0);
function filePreview(file) { function filePreview(file, index) {
preview.value = true; activeIndex.value = index;
activeFile.value = file; activeFile.value = file;
console.log(activeFile.value)
preview.value = true;
rotate.value = 0; rotate.value = 0;
scale.value = 1; scale.value = 1;
translateX.value = 0; translateX.value = 0;
@ -271,20 +274,20 @@ function download() {
} }
function prev() { function prev() {
const index = props.files.indexOf(activeFile.value); if (activeIndex.value === 0) {
if (index === 0) { activeIndex.value = props.files.length - 1
filePreview(props.files[props.files.length - 1]);
} else { } else {
filePreview(props.files[index - 1]); activeIndex.value = activeIndex.value - 1;
} }
filePreview(props.files[activeIndex.value], activeIndex.value);
} }
function next() { function next() {
const index = props.files.indexOf(activeFile.value); if (activeIndex.value === props.files.length - 1) {
if (index === props.files.length - 1) { activeIndex.value = 0;
filePreview(props.files[0]);
} else { } else {
filePreview(props.files[index + 1]); activeIndex.value = activeIndex.value + 1
} }
filePreview(props.files[activeIndex.value], activeIndex.value);
} }
function wheel(event) { function wheel(event) {

265
src/components/negativeInfo/depart-dialog.vue

@ -1,10 +1,5 @@
<template> <template>
<el-dialog <el-dialog title="单位问题详情" width="85vw" top="1vh" style="margin: 1vh auto">
title="单位问题详情"
width="85vw"
top="1vh"
style="margin: 1vh auto"
>
<header class="flex center v-center gap"> <header class="flex center v-center gap">
<label>统计范围</label> <label>统计范围</label>
<div style="width: 320px"> <div style="width: 320px">
@ -22,11 +17,12 @@
element-loading-text="单位问题详情加载中..." element-loading-text="单位问题详情加载中..."
> >
<main> <main>
<el-row class="mb-20"> <el-row class="mb-20" :gutter="20">
<el-col :span="8"> <el-col :span="8">
<h5>单位情况</h5> <h5>单位情况</h5>
<el-row> <div class="card-item">
<el-col :span="12"> <el-row class="mb-10">
<el-col :span="16">
<div class="row"> <div class="row">
<div class="col col-24"> <div class="col col-24">
<label>单位名称</label> <label>单位名称</label>
@ -49,11 +45,14 @@
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :span="12" v-if="departInfo.departImg"> <el-col :span="8" >
<div class="flex center v-center">
<img <img
:src="`${BASE_PATH}/file/stream/${departInfo.departImg}`" :src="`${BASE_PATH}/file/stream/${departInfo.departImg}`"
style="max-height: 96px" style="max-height: 96px"
v-if="departInfo.departImg1"
/> />
</div>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
@ -61,7 +60,7 @@
<description-pair <description-pair
label1="民警总人数" label1="民警总人数"
label2="问题涉及民警数" label2="问题涉及民警数"
:value1="departInfo.negativePoliceSize" :value1="departInfo.policeSize"
:value2="departInfo.negativePoliceSize" :value2="departInfo.negativePoliceSize"
size="large" size="large"
/> />
@ -70,24 +69,20 @@
<description-pair <description-pair
label1="协辅警人数" label1="协辅警人数"
label2="问题涉及协辅警数" label2="问题涉及协辅警数"
:value1="departInfo.negativeAuxSize" :value1="departInfo.auxSize"
:value2="departInfo.negativeAuxSize" :value2="departInfo.negativeAuxSize"
size="large" size="large"
/> />
</el-col> </el-col>
</el-row> </el-row>
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<h5>问题情况</h5> <h5>问题情况</h5>
<el-row <div class="card-item">
class="flex v-center" <el-row class="flex v-center" style="height: calc(100% - 76px)">
style="height: calc(100% - 76px)"
>
<el-col :span="6" class="text-center"> <el-col :span="6" class="text-center">
<div <div class="text-primary" style="font-size: 34px">
class="text-primary"
style="font-size: 34px"
>
{{ negativeInfo.size }} {{ negativeInfo.size }}
</div> </div>
<div>问题总数</div> <div>问题总数</div>
@ -95,140 +90,122 @@
<el-col :span="18"> <el-col :span="18">
<el-row> <el-row>
<el-col <el-col
:span="12" :span="24"
class="mb-20" class="mb-20"
v-if=" v-if="negativeInfo.jcj110BusinessSize || negativeInfo.jcj110Size"
negativeInfo.jcj110BusinessSize ||
negativeInfo.jcj110Size
"
> >
<description-pair <description-pair
label1="110接处警量" label1="110接处警量"
label2="110接处警问题数" label2="110接处警问题数"
:value1=" :value1="negativeInfo.jcj110BusinessSize"
negativeInfo.jcj110BusinessSize
"
:value2="negativeInfo.jcj110Size" :value2="negativeInfo.jcj110Size"
/> />
</el-col> </el-col>
<el-col <el-col
:span="12" :span="24"
v-if=" v-if="negativeInfo.jcj122BusinessSize || negativeInfo.jcj122Size"
negativeInfo.jcj122BusinessSize || class="mb-20"
negativeInfo.jcj122Size
"
> >
<description-pair <description-pair
label1="122接处警量" label1="122接处警量"
label2="122接处警问题数" label2="122接处警问题数"
:value1=" :value1="negativeInfo.jcj122BusinessSize"
negativeInfo.jcj122BusinessSize
"
:value2="negativeInfo.jcj122Size" :value2="negativeInfo.jcj122Size"
/> />
</el-col> </el-col>
<el-col :span="12"> <el-col :span="24">
<description-pair <description-pair
label1="执法办案" label1="执法办案"
label2="执法办案问题数" label2="执法办案问题数"
:value1=" :value1="negativeInfo.zfbaBusinessSize"
negativeInfo.zfbaBusinessSize
"
:value2="negativeInfo.zfbaSize" :value2="negativeInfo.zfbaSize"
/> />
</el-col> </el-col>
</el-row> </el-row>
</el-col> </el-col>
</el-row> </el-row>
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<h5 style="margin-bottom: 0">风险</h5> <h5>问题累计分</h5>
<div class="flex center"> <div class="flex center card-item wrap">
<el-progress <el-progress
type="dashboard" type="dashboard"
:percentage="100" :percentage="100"
:stroke-width="16" :stroke-width="16"
:width="220" :width="200"
:color="colors2" color="#5B8FF9"
> >
<div class="score-progress-body"> <div class="score-progress-body">
<div v-if="score"> <div>
<div style="font-size: 16px">分数</div>
<div> <div>
<span <span
class="score-progress_score score-theme text-bold" class="score-progress_score score-theme text-bold"
:type="getType(score)" style="color: #19257d"
>{{ score }}</span >{{ score }}</span>
>
<span></span>
</div> </div>
<!-- <div
style="font-size: 14px"
class="mb-16"
>
分险指标值
</div> -->
</div>
<div
v-else
style="
font-size: 60px;
line-height: 84px;
color: #999;
"
>
-
</div> </div>
<!-- <div
class="score-progress_title score-theme"
:type="getType(score)"
>
{{ getScoreLabel() }}
</div> -->
</div> </div>
</el-progress> </el-progress>
<div style="width: 100%" class="text-center">累计{{ days }}天分值</div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<el-row class="mb-20"> <el-row class="mb-20" :gutter="20">
<el-col :span="8"> <el-col :span="8">
<h5>问题来源占比</h5> <h5>问题来源占比</h5>
<div class="card-item">
<v-charts <v-charts
style="height: 320px" style="height: 320px"
:option="problemSourcesPieOptions" :option="problemSourcesPieOptions"
autoresize autoresize
/> />
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<h5>业务类型占比</h5> <h5>业务类型占比</h5>
<div class="card-item">
<v-charts <v-charts
style="height: 320px" style="height: 320px"
:option="businessTypePieOptions" :option="businessTypePieOptions"
autoresize autoresize
/> />
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<h5>风险问题构成</h5> <h5>问题涉及方面</h5>
<div class="card-item">
<v-charts <v-charts
style="height: 320px" style="height: 320px"
:option="radarOption" :option="problemTypePieOptions"
autoresize autoresize
/> />
</div>
</el-col> </el-col>
</el-row> </el-row>
<el-row class="mb-20" :gutter="20"> <el-row class="mb-20" :gutter="20">
<el-col :span="8"> <el-col :span="8">
<h5>个人问题排名</h5> <h5>个人问题排名</h5>
<div class="card-item">
<el-scrollbar max-height="300px"> <el-scrollbar max-height="300px">
<datav-chart-bar <datav-chart-bar size="small" :data="policeBarList" :color="colors" />
size="small" <el-empty v-if="policeBarList.length === 0" />
:data="policeBarList"
:color="colors"
/>
<el-empty v-if="policeBarList.length === 0"/>
</el-scrollbar> </el-scrollbar>
</div>
</el-col>
<el-col :span="8">
<h5>问题涉及领导</h5>
<div class="card-item">
<el-scrollbar max-height="300px">
<datav-chart-bar size="small" :data="policeLeadBarList" :color="colors" />
<el-empty v-if="policeLeadBarList.length === 0" />
</el-scrollbar>
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<h5>突出问题排名</h5> <h5>突出问题排名</h5>
<div class="card-item">
<el-scrollbar max-height="300px"> <el-scrollbar max-height="300px">
<datav-chart-bar <datav-chart-bar
size="small" size="small"
@ -236,52 +213,51 @@
:color="colors" :color="colors"
labelPosition="top" labelPosition="top"
/> />
<el-empty v-if="problemTypeBarList.length === 0"/> <el-empty v-if="problemTypeBarList.length === 0" />
</el-scrollbar> </el-scrollbar>
</div>
</el-col> </el-col>
</el-row> </el-row>
<div style="margin-top: 60px"> <div>
<h5>问题变化趋势</h5> <h5>问题变化趋势</h5>
<v-charts <div class="card-item">
style="height: 320px" <v-charts style="height: 320px" :option="barOption" autoresize />
:option="barOption" </div>
autoresize
/>
<div></div>
</div> </div>
<h5>问题清单</h5> <h5>问题清单</h5>
<el-table :data="negativeList"> <el-table :data="negativeList" height="500">
<el-table-column label="发现时间" prop="discoveryTime"/> <el-table-column label="发现时间" prop="discoveryTime" width="160" />
<el-table-column label="问题来源" prop="problemSources"/> <el-table-column label="问题来源" prop="problemSources" width="150" />
<el-table-column label="业务类别" prop="businessTypeName"/> <el-table-column label="业务类别" prop="businessTypeName" width="150" />
<el-table-column <el-table-column
label="问题详情" label="问题详情"
prop="thingDesc" prop="thingDesc"
show-overflow-tooltip
/>
<el-table-column
label="核查情况"
prop="checkStatusDesc"
show-overflow-tooltip
/>
<el-table-column
label="问题类型"
prop="problemType"
show-overflow-tooltip
/>
<el-table-column
label="分值"
prop="score"
width="100"
align="center"
/> />
<el-table-column label="操作" width="160"> <el-table-column label="操作" width="160">
<template #default="{ row }"> <template #default="{ row }">
<el-button <el-button type="primary" link @click="handleAction(row)"
type="primary"
link
@click="handleAction(row)"
>查看详情 >查看详情
</el-button </el-button>
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="flex end mt-8 mb-20">
<el-pagination
@size-change="getNegativeList"
@current-change="getNegativeList"
:page-sizes="[10, 20, 50, 100]"
v-model:page-size="negativeQuery.size"
v-model:current-page="negativeQuery.current"
layout="total, sizes, prev, pager, next"
:total="negativeTotal"
>
</el-pagination>
</div>
</main> </main>
</el-scrollbar> </el-scrollbar>
@ -290,18 +266,17 @@
:id="activeNegativeId" :id="activeNegativeId"
@close="negativeShow = false" @close="negativeShow = false"
/> />
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import vCharts from "vue-echarts"; import vCharts from "vue-echarts";
import {BASE_PATH} from "@/api/request"; import { BASE_PATH } from "@/api/request";
import {InspectCase} from "@/enums/dictEnums"; import { InspectCase } from "@/enums/dictEnums";
import { import {
getDepartProfile, getDepartProfile,
listNegativeMonthly, listNegativeMonthly,
} from "@/api/sensitivePerception/profileDepart"; } from "@/api/sensitivePerception/profileDepart";
import {listNegative} from "@/api/work/negative"; import { listNegative } from "@/api/work/negative";
import moment from "moment"; import moment from "moment";
const props = defineProps({ const props = defineProps({
@ -311,50 +286,50 @@ const props = defineProps({
}); });
const time = ref([ const time = ref([
moment().subtract(12, "month").format("YYYY-MM-DD HH:mm:ss"), moment().startOf('year').format("YYYY-MM-DD HH:mm:ss"),
moment().format("YYYY-MM-DD HH:mm:ss"), moment().format("YYYY-MM-DD HH:mm:ss"),
]); ]);
const colors = [ const colors = [
{color: "#5AD8A6", percentage: 40}, { color: "#5AD8A6", percentage: 40 },
{color: "#F6BD16", percentage: 60}, { color: "#F6BD16", percentage: 60 },
{color: "#E8684A ", percentage: 80}, { color: "#E8684A ", percentage: 80 },
]; ];
const colors2 = [ const colors2 = [
{color: "var(--success-color)", percentage: 60}, { color: "var(--success-color)", percentage: 60 },
{color: "#DC6231", percentage: 80}, { color: "#DC6231", percentage: 80 },
{color: "var(--danger-color)", percentage: 100}, { color: "var(--danger-color)", percentage: 100 },
]; ];
const loading = ref(false); const loading = ref(false);
const departInfo = ref({}); const departInfo = ref({});
const negativeInfo = ref({}); const negativeInfo = ref({});
const negativeQuery = ref({
checkStatusList: [InspectCase.TRUE, InspectCase.TRUE],
});
const negativeList = ref([]); const negativeList = ref([]);
const negativeTotal = ref(0); const negativeTotal = ref(0);
const problemTypeBarList = ref([]); const problemTypeBarList = ref([]);
const score = ref(0); const score = ref(0);
const days = ref(0)
async function getProfileData() { async function getProfileData() {
loading.value = true; loading.value = true;
negativeQuery.value.involveDepartId = props.departId;
getNegativeList();
const data = await getDepartProfile(props.departId, { const data = await getDepartProfile(props.departId, {
beginTime: time.value.length ? time.value[0] : "", beginTime: time.value.length ? time.value[0] : "",
endTime: time.value.length ? time.value[1] : "", endTime: time.value.length ? time.value[1] : "",
}); });
score.value = Math.round(data.score); score.value = data.score;
console.log(data.expression); days.value = data.days
console.log(data.remarks); negativeList.value = data.negatives;
departInfo.value = data.departInfo; departInfo.value = data.departInfo;
negativeInfo.value = data.negativeInfo; negativeInfo.value = data.negativeInfo;
problemSourcesPieOptions.value.series[0].data = data.problemSourcesList; problemSourcesPieOptions.value.series[0].data = data.problemSourcesList;
businessTypePieOptions.value.series[0].data = data.businessTypeList; businessTypePieOptions.value.series[0].data = data.businessTypeList;
problemTypePieOptions.value.series[0].data = data.problemTypeList;
policeBarList.value = data.policeBarList; policeBarList.value = data.policeBarList;
policeLeadBarList.value = data.policeLeadBarList;
radarOption.value.radar.indicator = data.problemTypeRadarIndicator; radarOption.value.radar.indicator = data.problemTypeRadarIndicator;
radarOption.value.series[0].data[0].value = data.problemTypeRadarData; radarOption.value.series[0].data[0].value = data.problemTypeRadarData;
@ -391,13 +366,6 @@ watch(
} }
); );
function getNegativeList() {
listNegative(negativeQuery.value).then((data) => {
negativeList.value = data.records;
negativeTotal.value = data.total;
});
}
const radarOption = ref({ const radarOption = ref({
radar: { radar: {
indicator: [], indicator: [],
@ -409,8 +377,8 @@ const radarOption = ref({
{ {
value: [], value: [],
areaStyle: { areaStyle: {
color: 'rgba(255, 145, 124, 0.9)' color: "rgba(255, 145, 124, 0.9)",
} },
}, },
], ],
label: { label: {
@ -443,8 +411,21 @@ const businessTypePieOptions = ref({
}, },
], ],
}); });
const problemTypePieOptions = ref({
tooltip: {
trigger: "item",
},
series: [
{
type: "pie",
radius: ["40%", "70%"],
data: [],
},
],
});
const policeBarList = ref([]); const policeBarList = ref([]);
const policeLeadBarList = ref([])
function getType(val) { function getType(val) {
if (val < 60) { if (val < 60) {
@ -514,4 +495,12 @@ main {
color: var(--danger-color); color: var(--danger-color);
} }
} }
h5 {
margin-bottom: 12px;
}
.card-item {
background: #f9faff;
padding: 16px;
min-height: 200px;
}
</style> </style>

38
src/components/negativeInfo/police-dialog.vue

@ -26,7 +26,7 @@
<el-row class="mb-20"> <el-row class="mb-20">
<el-col :span="8"> <el-col :span="8">
<h5>民警基本情况</h5> <h5>民警基本情况</h5>
<el-row> <el-row >
<el-col :span="6"> <el-col :span="6">
<img v-if="policeInfo.avatarUrl" :src="`${BASE_PATH}/file/stream/${policeInfo.avatarUrl}`" <img v-if="policeInfo.avatarUrl" :src="`${BASE_PATH}/file/stream/${policeInfo.avatarUrl}`"
class="police-avatar" style="width: 94px"/> class="police-avatar" style="width: 94px"/>
@ -61,21 +61,21 @@
> >
</span> </span>
</div> </div>
<div class="col col-12"> <div class="col col-24">
<label>警号</label> <label>警号</label>
<span>{{ policeInfo.empNo }}</span> <span>{{ policeInfo.empNo }}</span>
</div> </div>
<div class="col col-12"> <div class="col col-24">
<label>身份证号</label> <label>身份证号</label>
<span>{{ policeInfo.idCode }}</span> <span>{{ policeInfo.idCode }}</span>
</div> </div>
<div class="col col-12"> <div class="col col-24">
<label>入职时间</label> <label>入职时间</label>
<span>{{ <span>{{
policeInfo.employmentDate || "/" policeInfo.employmentDate || "/"
}}</span> }}</span>
</div> </div>
<div class="col col-12"> <div class="col col-24">
<label>手机号</label> <label>手机号</label>
<span>{{ <span>{{
policeInfo.mobile || "/" policeInfo.mobile || "/"
@ -99,13 +99,6 @@
{{ negativeInfo.size }} {{ negativeInfo.size }}
</div> </div>
<div class="mb-10">问题总数</div> <div class="mb-10">问题总数</div>
<div
class="text-danger"
style="font-size: 34px"
>
{{ negativeInfo.score }}
</div>
<div>风险值</div>
</el-col> </el-col>
<el-col :span="18"> <el-col :span="18">
<el-row> <el-row>
@ -166,14 +159,14 @@
:percentage="100" :percentage="100"
:stroke-width="16" :stroke-width="16"
:width="220" :width="220"
:color="colors" color="#DC6231"
> >
<div class="score-progress-body"> <div class="score-progress-body">
<div v-if="score"> <div v-if="score">
<div> <div>
<span <span
class="score-progress_score score-theme text-bold" class="score-progress_score score-theme text-bold"
:type="getType(score)"
>{{ score }}</span >{{ score }}</span
> >
<span></span> <span></span>
@ -243,18 +236,18 @@
<div></div> <div></div>
<h5>问题清单</h5> <h5>问题清单</h5>
<el-table :data="negativeList"> <el-table :data="negativeList">
<el-table-column label="发现时间" prop="discoveryTime"/> <el-table-column label="发现时间" prop="discoveryTime" width="160" />
<el-table-column label="问题来源" prop="problemSources"/> <el-table-column label="问题来源" prop="problemSources" width="150" />
<el-table-column label="业务类别" prop="businessTypeName"/> <el-table-column label="业务类别" prop="businessTypeName" width="150" />
<el-table-column <el-table-column
label="涉及单位" label="问题详情"
prop="involveDepartName" prop="thingDesc"
show-overflow-tooltip
/> />
<el-table-column <el-table-column
label="核查情况" label="核查情况"
prop="checkStatusName" prop="checkStatusDesc"
width="140" show-overflow-tooltip
align="center"
/> />
<el-table-column label="操作" width="160"> <el-table-column label="操作" width="160">
<template #default="{ row }"> <template #default="{ row }">
@ -521,4 +514,5 @@ main {
color: var(--danger-color); color: var(--danger-color);
} }
} }
</style> </style>

634
src/views/mobileSupervise/TaskProblem.vue

@ -10,10 +10,7 @@
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="问题来源"> <el-form-item label="问题来源">
<el-select <el-select clearable v-model="query.taskType">
clearable
v-model="query.taskType"
>
<el-option <el-option
v-for="item in dict.taskType" v-for="item in dict.taskType"
:key="item.id" :key="item.id"
@ -30,10 +27,7 @@
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="分发状态"> <el-form-item label="分发状态">
<el-select <el-select v-model="query.distributionState" clearable>
v-model="query.distributionState"
clearable
>
<el-option <el-option
v-for="item in dict.distributionState" v-for="item in dict.distributionState"
:label="item.dictLabel" :label="item.dictLabel"
@ -45,8 +39,10 @@
</el-row> </el-row>
</el-form> </el-form>
<div class="flex between"> <div class="flex between">
<el-button type="primary" @click=""> <el-button type="primary" @click="handleShowGenReport">
生成督察通报</el-button> 生成督察通报
<span v-if="selectRows.length">{{ selectRows.length }}</span></el-button
>
<div> <div>
<el-button type="primary" @click="getList"> <el-button type="primary" @click="getList">
<template #icon> <template #icon>
@ -59,67 +55,52 @@
</div> </div>
</header> </header>
<el-tabs <el-tabs class="demo-tabs" @tab-click="handleTabClick">
class="demo-tabs"
@tab-click="handleTabClick"
>
<el-tab-pane label="全部" name="0"></el-tab-pane> <el-tab-pane label="全部" name="0"></el-tab-pane>
<el-tab-pane label="待下发" name="1"></el-tab-pane> <el-tab-pane label="待下发" name="1"></el-tab-pane>
<el-tab-pane label="回收站" name="2"></el-tab-pane> <el-tab-pane label="回收站" name="2"></el-tab-pane>
</el-tabs> </el-tabs>
<div class="table-container"> <div class="table-container">
<el-table :data="list" v-loading="loading"> <el-table :data="list" v-loading="loading" @selection-change="handleTableSelect">
<el-table-column label="发现时间" prop="createTime" width="120" /> <el-table-column type="selection" width="55" />
<el-table-column label="问题录入时间" prop="supTime" width="120"></el-table-column> <el-table-column label="发现时间" prop="createTime" width="150" />
<el-table-column label="问题来源" width="100"> <el-table-column label="录入时间" prop="supTime" width="150" />
<el-table-column label="是否存在问题" width="80" align="center">
<template #default="{ row }">
<span>{{ row.hasProblem ? "是" : "否" }}</span>
</template>
</el-table-column>
<el-table-column label="问题来源" width="120">
<template #default="{ row }"> <template #default="{ row }">
<span>{{ getDictLable(dict.taskType, row.taskType) }}</span> <span>{{ getDictLable(dict.taskType, row.taskType) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column
label="涉及单位"
prop="departName"
width="120"
/>
<el-table-column <el-table-column
label="涉及人员" label="涉及人员"
prop="peoples" prop="peoples"
width="80" width="90"
show-overflow-tooltip
/>
<el-table-column
label="问题类型"
prop="problemType"
width="100"
align="center"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column <el-table-column label="涉及单位" prop="departName" show-overflow-tooltip />
label="问题描述" <el-table-column label="问题类型" prop="problemType" show-overflow-tooltip />
prop="thingDesc" <el-table-column label="问题描述" prop="thingDesc" show-overflow-tooltip />
show-overflow-tooltip <el-table-column label="分发状态" width="90">
/>
<el-table-column label="分发状态" width="100">
<template #default="{ row }"> <template #default="{ row }">
<span v-if="row.distributionState === '0'">未分发</span> <span v-if="row.distributionState === '0'">未分发</span>
<span v-if="row.distributionState === '1'">已分发</span> <span v-if="row.distributionState === '1'">已分发</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="240"> <el-table-column label="操作" width="260">
<template #default="{ row }"> <template #default="{ row }">
<el-button <el-button type="primary" link @click="showDeatil(row)">问题详情</el-button>
type="primary"
link
@click="showDeatil(row)"
>问题详情</el-button
>
<el-button <el-button
@click="upProblemFun(row)" @click="upProblemFun(row)"
type="primary" type="primary"
link link
v-if="row.distributionState === '0'"> v-if="row.distributionState === '0'"
>
编辑 编辑
</el-button> </el-button>
<el-button <el-button
@ -129,18 +110,18 @@
@click="issueMatterFun(row)" @click="issueMatterFun(row)"
>问题下发</el-button >问题下发</el-button
> >
<!-- <el-button--> <!-- <el-button-->
<!-- type="danger"--> <!-- type="danger"-->
<!-- link--> <!-- link-->
<!-- @click="delProblemsFun(row)"--> <!-- @click="delProblemsFun(row)"-->
<!-- >删除</el-button--> <!-- >删除</el-button-->
<!-- >--> <!-- >-->
<el-button <el-button
:type="row.problemState == '1'?'danger':'primary' " :type="row.problemState == '1' ? 'danger' : 'primary'"
link link
@click="upProblemStateFun(row)" @click="upProblemStateFun(row)"
> >
{{row.problemState == '1'?'删除':'恢复'}} {{ row.problemState == "1" ? "删除" : "恢复" }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -178,22 +159,22 @@
<div class="col col-12"> <div class="col col-12">
<label>涉及人员</label> <label>涉及人员</label>
<span v-if="activeRow.peoples"> <span v-if="activeRow.peoples">
<el-tag v-for="(item,index) in JSON.parse(activeRow.peoples)" :key="index"> <el-tag v-for="(item, index) in JSON.parse(activeRow.peoples)" :key="index">
{{item.name}} {{ item.name }}
</el-tag> </el-tag>
</span> </span>
</div> </div>
<div class="col col-12"> <div class="col col-12">
<label>创建人</label> <label>创建人</label>
<span>{{ activeRow.createName || '/' }}</span> <span>{{ activeRow.createName || "/" }}</span>
</div> </div>
<div class="col col-12"> <div class="col col-12">
<label>下发人</label> <label>下发人</label>
<span>{{ activeRow.issueUserName || '/' }}</span> <span>{{ activeRow.issueUserName || "/" }}</span>
</div> </div>
<div class="col col-24"> <div class="col col-24">
<label>问题类型</label> <label>问题类型</label>
<span>{{ activeRow.problemType || '/' }}</span> <span>{{ activeRow.problemType || "/" }}</span>
</div> </div>
<div class="col col-24"> <div class="col col-24">
<label>问题描述</label> <label>问题描述</label>
@ -201,17 +182,31 @@
</div> </div>
<div class="col col-24"> <div class="col col-24">
<label>分发状态</label> <label>分发状态</label>
<span>{{ getDictLable(dict.distributionState, activeRow.distributionState) }}</span> <span>{{
getDictLable(dict.distributionState, activeRow.distributionState)
}}</span>
</div> </div>
</div> </div>
<div> <div>
<file-list :files="activeRow.files? JSON.parse(activeRow.files) : []" /> <file-list :files="activeRow.files ? JSON.parse(activeRow.files) : []" />
</div> </div>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog @close="addClose" title="任务分发" v-model="distributeShow" width="50vw" top="2vh" style="margin-bottom: 0"> <el-dialog
<el-form :label-width="120" ref="formRefs" :model="issueForm" v-loading="issueLoading"> @close="addClose"
title="任务分发"
v-model="distributeShow"
width="50vw"
top="2vh"
style="margin-bottom: 0"
>
<el-form
:label-width="120"
ref="formRefs"
:model="issueForm"
v-loading="issueLoading"
>
<el-form-item <el-form-item
label="任务名称" label="任务名称"
prop="taskName" prop="taskName"
@ -278,11 +273,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="涉及警种" prop="policeType"> <el-form-item label="涉及警种" prop="policeType">
<el-select <el-select v-model="issueForm.policeType" clearable style="width: 280px">
v-model="issueForm.policeType"
clearable
style="width: 280px"
>
<el-option <el-option
v-for="item in dict.policeType" v-for="item in dict.policeType"
:key="item.id" :key="item.id"
@ -321,7 +312,8 @@
v-for="item in dict.distributionFlow" v-for="item in dict.distributionFlow"
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ item.dictLabel }}</el-radio> >{{ item.dictLabel }}</el-radio
>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
@ -337,8 +329,7 @@
v-for="item in dict.approvalFlow" v-for="item in dict.approvalFlow"
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ item.dictLabel >{{ item.dictLabel }}{{ item.remark ? `(${item.remark})` : "" }}</el-radio
}}{{ item.remark ? `(${item.remark})` : "" }}</el-radio
> >
</el-radio-group> </el-radio-group>
<div class="tips mt-10"> <div class="tips mt-10">
@ -366,7 +357,12 @@
</el-dialog> </el-dialog>
<el-dialog @close="upClose" title="编辑问题" v-model="upShow" width="50vw" top="2vh"> <el-dialog @close="upClose" title="编辑问题" v-model="upShow" width="50vw" top="2vh">
<el-form :label-width="120" ref="upFormRefs" :model="upFormData" v-loading="upLoading"> <el-form
:label-width="120"
ref="upFormRefs"
:model="upFormData"
v-loading="upLoading"
>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="发现时间"> <el-form-item label="发现时间">
@ -382,11 +378,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="问题来源"> <el-form-item label="问题来源">
<el-select <el-select clearable v-model="upFormData.taskType" style="width: 100%">
clearable
v-model="upFormData.taskType"
style="width:100%"
>
<el-option <el-option
v-for="item in dict.taskType" v-for="item in dict.taskType"
:key="item.id" :key="item.id"
@ -408,18 +400,26 @@
:loading="peoplesloading" :loading="peoplesloading"
filterable filterable
multiple multiple
v-model="upFormData.peopleIds"> v-model="upFormData.peopleIds"
<el-option v-for="(item,index) in polices" :key="index" :value="item.idCode" :label="item.name"></el-option> >
<el-option
v-for="(item, index) in polices"
:key="index"
:value="item.idCode"
:label="item.name"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="问题类型"> <el-form-item label="问题类型">
<problem-type-select v-model="upFormData.problemTypeCode"></problem-type-select> <problem-type-select
v-model="upFormData.problemTypeCode"
></problem-type-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"></el-col> <el-col :span="12"></el-col>
<el-col :span="12" > <el-col :span="24">
<el-form-item label="问题描述"> <el-form-item label="问题描述">
<el-input type="textarea" v-model="upFormData.thingDesc"></el-input> <el-input type="textarea" v-model="upFormData.thingDesc"></el-input>
</el-form-item> </el-form-item>
@ -428,215 +428,365 @@
<file-upload <file-upload
style="width: 100%" style="width: 100%"
:uploadDrag="true" :uploadDrag="true"
v-model:files="upFormData.files"></file-upload> v-model:files="upFormData.files"
></file-upload>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
<footer class="flex end mt-20"> <footer class="flex end mt-20">
<el-button <el-button type="primary" size="large" @click="handleUpData" v-loading="upLoading"
type="primary"
size="large"
@click="handleUpData"
v-loading="upLoading"
>确认</el-button >确认</el-button
> >
</footer> </footer>
</el-dialog> </el-dialog>
<el-dialog title="生成督察通报" v-model="showGenReport" width="1100" top="1vh" style="margin-bottom: 0">
<el-scrollbar height="81vh" style="padding: 10px">
<el-form label-width="148" :model="formData" ref="formRef">
<el-form-item
label="督察通报文件名"
prop=""
:rules="{
required: true,
message: '请输入督察通报文件名',
trigger: ['blur'],
}"
>
<el-input v-model="formData.fileName" />
</el-form-item>
<el-divider />
<h3 style="font-size: 16px">通报内容</h3>
<div class="mb-32">
<div class="flex gap">
<el-input v-model="formData.contents1.title" />
<el-button @click="formData.contents1.list.push({})">
<icon name="el-icon-Plus" />
</el-button>
</div>
<ul style="list-style: circle">
<li v-for="(item, index) in formData.contents1.list" class="mb-16">
<div class="flex gap">
<el-input v-model="item.content" type="textarea" />
<el-button @click="formData.contents1.list.splice(index, 1)">
<icon name="el-icon-Minus" />
</el-button>
</div>
</li>
</ul>
</div>
<div>
<div class="flex gap">
<el-input v-model="formData.contents2.title" />
<el-button @click="formData.contents2.list.push({})">
<icon name="el-icon-Plus" />
</el-button>
</div>
<ul style="list-style: circle">
<li v-for="item in formData.contents2.list" class="mb-16">
<div class="flex gap mb-10">
<el-input v-model="item.title" />
<el-button @click="formData.contents2.list.splice(index, 1)">
<icon name="el-icon-Minus" />
</el-button>
</div>
<div class="flex gap">
<el-input v-model="item.content" type="textarea" />
<div style="width: 46px"></div>
</div>
</li>
</ul>
</div>
</el-form>
</el-scrollbar>
<footer class="flex end">
<!-- <el-button @click="showGenReport = false" size="large">通报预览</el-button> -->
<el-button type="primary" @click="handleGenReport" size="large">生成通报</el-button>
</footer>
</el-dialog>
</template> </template>
<script setup> <script setup>
import { getDictLable } from "@/utils/util"; import { getToken } from '@/utils/token'
import { listTaskProblem, getTaskProblem,delTaskProblem,upProblemState,upTaskProblem } from '@/api/mobileSupervision/taskProblem' import { BASE_PATH } from "@/api/request";
import useCatchStore from "@/stores/modules/catch"; import { getDictLable } from "@/utils/util";
import {TestingAlcoholIssueMatterFun} from "@/api/mobileSupervision/testingAlcohol"; import {
import feedback from "@/utils/feedback"; listTaskProblem,
import {listPoliceData} from "@/api/system/police"; getTaskProblem,
const catchStore = useCatchStore(); delTaskProblem,
const dict = catchStore.getDicts(["taskType","policeType","approvalFlow","suspectProblem","businessType","distributionFlow", "distributionState"]); upProblemState,
const loading = ref(false); upTaskProblem,
const upLoading = ref(false); } from "@/api/mobileSupervision/taskProblem";
const peoplesloading = ref(false); import useCatchStore from "@/stores/modules/catch";
const upShow = ref(false); import { TestingAlcoholIssueMatterFun } from "@/api/mobileSupervision/testingAlcohol";
const upFormData = ref({}) import feedback from "@/utils/feedback";
import { listPoliceData } from "@/api/system/police";
// const catchStore = useCatchStore();
const distributeShow = ref(false) const dict = catchStore.getDicts([
const issueForm = ref({}) "taskType",
const issueLoading = ref(false) "policeType",
const formRefs =ref(); "approvalFlow",
// "suspectProblem",
const issueMatterFun = async (row)=>{ "businessType",
const data = await getTaskProblem(row.id) "distributionFlow",
switch (row.taskType){ "distributionState",
]);
const loading = ref(false);
const upLoading = ref(false);
const peoplesloading = ref(false);
const upShow = ref(false);
const upFormData = ref({});
//
const distributeShow = ref(false);
const issueForm = ref({});
const issueLoading = ref(false);
const formRefs = ref();
//
const issueMatterFun = async (row) => {
const data = await getTaskProblem(row.id);
switch (row.taskType) {
case "selfexamination": case "selfexamination":
issueForm.value.problemVo = data issueForm.value.problemVo = data;
break; break;
case "inspection": case "inspection":
issueForm.value.problemVo = data issueForm.value.problemVo = data;
break; break;
case "testing_alcohol": case "testing_alcohol":
issueForm.value.taskId = data.taskId; issueForm.value.taskId = data.taskId;
issueForm.value.empNo =data.empNo; issueForm.value.empNo = data.empNo;
break; break;
case "risk_personal": case "risk_personal":
issueForm.value.supRecordId =row.id issueForm.value.supRecordId = row.id;
break; break;
default: default:
issueForm.value.problemVo = data; issueForm.value.problemVo = data;
break break;
}
issueForm.value.tableKey=row.taskType;
distributeShow.value=true;
}
const upQuery = ref({
departBranch:true
})
const polices = ref()
const getPeoplesFun =async ()=>{
peoplesloading.value=true;
if(upQuery.value.idCodes){
delete upQuery.value.idCodes
} }
const res = await listPoliceData(upQuery.value) issueForm.value.tableKey = row.taskType;
polices.value = res.records.map(s=> { distributeShow.value = true;
return{ };
"name":s.name,
"idCode":s.idCode, const upQuery = ref({
"empNo":s.empNo departBranch: true,
});
const polices = ref();
const getPeoplesFun = async () => {
peoplesloading.value = true;
if (upQuery.value.idCodes) {
delete upQuery.value.idCodes;
} }
const res = await listPoliceData(upQuery.value);
polices.value = res.records.map((s) => {
return {
name: s.name,
idCode: s.idCode,
empNo: s.empNo,
};
}); });
delete upQuery.value.idCodes delete upQuery.value.idCodes;
console.log('polices',upFormData.value.peoples) console.log("polices", upFormData.value.peoples);
peoplesloading.value=false; peoplesloading.value = false;
} };
// //
function inputPeopleFun(val){ function inputPeopleFun(val) {
upQuery.value.name = val; upQuery.value.name = val;
getPeoplesFun(); getPeoplesFun();
} }
inputPeopleFun(); inputPeopleFun();
const handleUpData = async()=>{ const handleUpData = async () => {
upLoading.value=true upLoading.value = true;
const res = await upTaskProblem(upFormData.value)
upShow.value=false;
getList()
upLoading.value=false
}
const addClose =()=>{
issueForm.value={
}
}
const upClose = ()=>{
upFormData.value={
}
}
// const res = await upTaskProblem(upFormData.value);
const handleSubmitTask =async ()=>{ upShow.value = false;
getList();
upLoading.value = false;
};
const addClose = () => {
issueForm.value = {};
};
const upClose = () => {
upFormData.value = {};
};
//
const handleSubmitTask = async () => {
await formRefs.value.validate(); await formRefs.value.validate();
issueLoading.value = true issueLoading.value = true;
try { try {
await TestingAlcoholIssueMatterFun(issueForm.value) await TestingAlcoholIssueMatterFun(issueForm.value);
} catch(e) { } catch (e) {
issueLoading.value = false issueLoading.value = false;
return return;
} }
issueLoading.value = false issueLoading.value = false;
feedback.msgSuccess("下发成功"); feedback.msgSuccess("下发成功");
distributeShow.value = false; distributeShow.value = false;
getList() getList();
} };
const handleTabClick= (tab)=>{ const handleTabClick = (tab) => {
query.value.actionType=tab.props.name query.value.actionType = tab.props.name;
console.log('tab',tab.props.name) console.log("tab", tab.props.name);
getList(); getList();
} };
const delProblemsFun =async (row)=>{ const delProblemsFun = async (row) => {
await feedback.confirm("确定要删除该数据?"); await feedback.confirm("确定要删除该数据?");
delTaskProblem(row.id).then(res=>{ delTaskProblem(row.id).then((res) => {
getList() getList();
}) });
feedback.msgSuccess("删除成功"); feedback.msgSuccess("删除成功");
} };
async function upProblemStateFun(row){ async function upProblemStateFun(row) {
await feedback.confirm(`确定要${row.problemState == '1'?'删除':'恢复'}该问题项(可在回收站中查看已删除的问题项)?`); await feedback.confirm(
upProblemState(row.id).then(res=>{ `确定要${
getList() row.problemState == "1" ? "删除" : "恢复"
}) }该问题项可在回收站中查看已删除的问题项`
);
upProblemState(row.id).then((res) => {
getList();
});
feedback.msgSuccess("操作成功"); feedback.msgSuccess("操作成功");
} }
const query = ref({ const query = ref({
actionType:"0" actionType: "0",
}) });
const list = ref([]) const list = ref([]);
const total = ref(0) const total = ref(0);
function getList() { function getList() {
loading.value=true loading.value = true;
listTaskProblem(query.value).then(data => { listTaskProblem(query.value).then((data) => {
list.value = data.records list.value = data.records;
total.value = data.total total.value = data.total;
loading.value=false; loading.value = false;
}) });
} }
onMounted(() => {
getList()
})
const show = ref(false)
const activeRow = ref({})
async function showDeatil(row) {
show.value = true
activeRow.value = await getTaskProblem(row.id)
}
const upProblemFun = async (row)=>{
upFormData.value=await getTaskProblem(row.id)
upFormData.value.files = JSON.parse(upFormData.value.files )
if(upFormData.value.peoples ){
let lists = JSON.parse(upFormData.value.peoples ); onMounted(() => {
upFormData.value.peoples=lists; getList();
upFormData.value.peopleIds = lists.map((s)=>{ });
return s.idCode
}) const show = ref(false);
const activeRow = ref({});
async function showDeatil(row) {
show.value = true;
activeRow.value = await getTaskProblem(row.id);
}
const upProblemFun = async (row) => {
upFormData.value = await getTaskProblem(row.id);
upFormData.value.files = JSON.parse(upFormData.value.files);
if (upFormData.value.peoples) {
let lists = JSON.parse(upFormData.value.peoples);
upFormData.value.peoples = lists;
upFormData.value.peopleIds = lists.map((s) => {
return s.idCode;
});
let idCodes = [] let idCodes = [];
upFormData.value.peoples.forEach(s=>{ upFormData.value.peoples.forEach((s) => {
if(s.idCode){ if (s.idCode) {
idCodes.push(s.idCode) idCodes.push(s.idCode);
} }
}) });
upQuery.value.idCodes = idCodes; upQuery.value.idCodes = idCodes;
} }
upShow.value=true; upShow.value = true;
} };
watch(()=>upFormData.value.departId,(val)=>{ watch(
() => upFormData.value.departId,
(val) => {
upQuery.value.departId = val; upQuery.value.departId = val;
getPeoplesFun() getPeoplesFun();
},
},{deep:true,immediate:true}) { deep: true, immediate: true }
);
watch(()=>upFormData.value.files,(val)=>{ watch(
console.log('val',val) () => upFormData.value.files,
(val) => {
console.log("val", val);
upFormData.value.files = val; upFormData.value.files = val;
},{immediate:true,deep:true}) },
{ immediate: true, deep: true }
);
const selectRows = ref([]);
function handleTableSelect(selection) {
selectRows.value = selection;
}
const showGenReport = ref(false);
const formData = ref({});
function handleShowGenReport() {
if (selectRows.value.length === 0) {
feedback.msgWarning("请选择要生成报告的数据");
return;
}
formData.value = {
contents1: {
title: "好的方面",
list: [],
},
contents2: {
title: "发现的问题",
list: [],
},
};
formData.value.contents1.list = selectRows.value
.filter((item) => !item.hasProblem)
.map((item) => {
return {
content: item.thingDesc,
};
});
const problmes = selectRows.value.filter((item) => item.hasProblem)
const set = new Set(problmes.filter(item => item.problemType).map(item => item.problemType.indexOf('/') === -1 ? item.problemType : item.problemType.substring(0, item.problemType.indexOf('/'))))
console.log(set)
const arr = [];
set.forEach(item => {
const content = problmes.filter(p => p.problemType && p.problemType.indexOf(item) === 0).map(item => item.thingDesc).join('。')
arr.push({
title: item,
content: content
})
})
formData.value.contents2.list = arr
showGenReport.value = true;
}
const formRef = ref()
async function handleGenReport() {
await formRef.value.validate();
fetch(`${BASE_PATH}/task/problem/genReport`,
{
method: 'POST',
body: JSON.stringify(formData.value),
headers: {
"Authorization": getToken(),
"Content-Type": "application/json"
}
}).then(response => response.blob())
.then(blob => {
// Blob URL
const blobUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = blobUrl;
a.download = formData.value.fileName + ".docx";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
// Blob URL
URL.revokeObjectURL(blobUrl);
})
.catch(error => console.error('下载失败', error));
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped></style>
</style>

393
src/views/sensitivePerception/PoliceNegative.vue

@ -6,65 +6,34 @@
<el-col :span="6"> <el-col :span="6">
<el-form-item label="单位分组"> <el-form-item label="单位分组">
<el-select v-model="query.departGroupId" clearable> <el-select v-model="query.departGroupId" clearable>
<el-option <el-option value="10" label="派出所"></el-option>
value="10" <el-option value="11" label="交警大队"></el-option>
label="派出所" <el-option value="13" label="刑侦大队"></el-option>
></el-option> <el-option value="14" label="禁毒大队"></el-option>
<el-option <el-option value="15" label="治安大队"></el-option>
value="11" <el-option value="16" label="人境大队"></el-option>
label="交警大队"
></el-option>
<el-option
value="13"
label="刑侦大队"
></el-option>
<el-option
value="14"
label="禁毒大队"
></el-option>
<el-option
value="15"
label="治安大队"
></el-option>
<el-option
value="16"
label="人境大队"
></el-option>
<el-option value="12" label="其他"></el-option> <el-option value="12" label="其他"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="统计时间"> <el-form-item label="统计时间">
<date-time-range-picker-ext <date-time-range-picker-ext v-model="query.crtTime" />
v-model="query.crtTime"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="姓名"> <el-form-item label="姓名">
<el-input <el-input v-model="query.name" placeholder="请输入" clearable />
v-model="query.name"
placeholder="请输入"
clearable
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="警号"> <el-form-item label="警号">
<el-input <el-input v-model="query.empNo" placeholder="请输入" clearable />
v-model="query.empNo"
placeholder="请输入"
clearable
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="所属单位"> <el-form-item label="所属单位">
<depart-tree-select <depart-tree-select v-model="query.departId" :check-strictly="false" />
v-model="query.departId"
:check-strictly="false"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -92,24 +61,16 @@
<el-table-column label="职务" align="center" width="160"> <el-table-column label="职务" align="center" width="160">
<template #default="{ row }"> <template #default="{ row }">
<span v-if="row.position">{{ row.position }}</span> <span v-if="row.position">{{ row.position }}</span>
<span v-else>{{ <span v-else>{{ getDictLable(dict.personType, row.personType) }}</span>
getDictLable(dict.personType, row.personType)
}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="警号" prop="empNo" width="160" /> <el-table-column label="警号" prop="empNo" width="160" />
<el-table-column <el-table-column label="入职时间" prop="employmentDate" width="160" />
label="入职时间"
prop="employmentDate"
width="160"
/>
<el-table-column label="所属单位" prop="departName"> <el-table-column label="所属单位" prop="departName">
<template #default="{ row }"> <template #default="{ row }">
<span <span
>{{ >{{
row.parentDepartName row.parentDepartName ? row.parentDepartName + "/" : row.parentDepartName
? row.parentDepartName + "/"
: row.parentDepartName
}}{{ row.departName }}</span }}{{ row.departName }}</span
> >
</template> </template>
@ -120,19 +81,18 @@
width="120" width="120"
align="center" align="center"
/> />
<el-table-column label="风险值" align="center" width="160" prop="score"></el-table-column> <el-table-column
<el-table-column label="操作" width="160"> label="累计分值"
align="center"
width="160"
prop="score"
></el-table-column>
<el-table-column label="操作" width="240">
<template #default="{ row }"> <template #default="{ row }">
<el-button <el-button type="primary" link @click="handleShowProfile(row)"
type="primary"
link
@click="handleShowProfile(row)"
>问题详情 >问题详情
</el-button> </el-button>
<el-button <el-button type="primary" link @click="handleShowNotification(row)"
type="primary"
link
@click="handleShowNotification(row)"
>预警提醒 >预警提醒
</el-button> </el-button>
</template> </template>
@ -178,13 +138,21 @@
element-loading-text="个人问题详情加载中..." element-loading-text="个人问题详情加载中..."
> >
<main> <main>
<el-row class="mb-20"> <el-row class="mb-20" :gutter="20">
<el-col :span="8"> <el-col :span="8">
<h5>民警基本情况</h5> <h5>民警基本情况</h5>
<div class="card-item">
<el-row> <el-row>
<el-col :span="6"> <el-col :span="6">
<img v-if="policeInfo.avatarUrl" :src="`${BASE_PATH}/file/stream/${policeInfo.avatarUrl}`" class="police-avatar" style="width: 94px" /> <div class="flex v-center" style="height: 100%">
<img
v-if="policeInfo.avatarUrl"
:src="`${BASE_PATH}/file/stream/${policeInfo.avatarUrl}`"
class="police-avatar"
style="width: 94px"
/>
<icon name="local-icon-police" :size="120" v-else /> <icon name="local-icon-police" :size="120" v-else />
</div>
</el-col> </el-col>
<el-col :span="18"> <el-col :span="18">
<div class="row"> <div class="row">
@ -194,11 +162,7 @@
</div> </div>
<div class="col col-12"> <div class="col col-12">
<label>性别</label> <label>性别</label>
<span>{{ <span>{{ getGenderFromIdCode(policeInfo.idCode) }}</span>
getGenderFromIdCode(
policeInfo.idCode
)
}}</span>
</div> </div>
<div class="col col-24"> <div class="col col-24">
<label>所属单位</label> <label>所属单位</label>
@ -206,240 +170,195 @@
<span <span
>{{ >{{
activeRow.parentDepartName activeRow.parentDepartName
? activeRow.parentDepartName + ? activeRow.parentDepartName + "/"
"/"
: activeRow.parentDepartName : activeRow.parentDepartName
}}{{ }}{{ activeRow.departName }}</span
activeRow.departName
}}</span
> >
</span> </span>
</div> </div>
<div class="col col-12"> <div class="col col-24">
<label>警号</label> <label>警号</label>
<span>{{ policeInfo.empNo }}</span> <span>{{ policeInfo.empNo }}</span>
</div> </div>
<div class="col col-12"> <div class="col col-24">
<label>身份证号</label> <label>身份证号</label>
<span>{{ policeInfo.idCode }}</span> <span>{{ policeInfo.idCode }}</span>
</div> </div>
<div class="col col-12"> <div class="col col-24">
<label>入职时间</label> <label>入职时间</label>
<span>{{ <span>{{ policeInfo.employmentDate || "/" }}</span>
policeInfo.employmentDate || "/"
}}</span>
</div> </div>
<div class="col col-12"> <div class="col col-24">
<label>手机号</label> <label>手机号</label>
<span>{{ <span>{{ policeInfo.mobile || "/" }}</span>
policeInfo.mobile || "/"
}}</span>
</div> </div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<h5>问题情况</h5> <h5>问题情况</h5>
<el-row <div class="card-item">
class="flex v-center" <div class="flex v-center" style="min-height: 200px; width: 100%">
style="height: calc(100% - 76px)" <el-row style="width: 100%">
>
<el-col :span="6" class="text-center"> <el-col :span="6" class="text-center">
<div <div class="text-primary" style="font-size: 34px">
class="text-primary"
style="font-size: 34px"
>
{{ negativeInfo.size }} {{ negativeInfo.size }}
</div> </div>
<div class="mb-10">问题总数</div> <div class="mb-10">问题总数</div>
<div
class="text-danger"
style="font-size: 34px"
>
{{ negativeInfo.score }}
</div>
<div>风险值</div>
</el-col> </el-col>
<el-col :span="18"> <el-col :span="18">
<el-row> <el-row>
<el-col <el-col
:span="12" :span="24"
class="mb-20" class="mb-20"
v-if=" v-if="negativeInfo.jcj110BusinessSize || negativeInfo.jcj110Size"
negativeInfo.jcj110BusinessSize ||
negativeInfo.jcj110Size
"
> >
<description-pair <description-pair
label="110接处警" label="110接处警"
label1="量" label1="量"
label2="问题数" label2="问题数"
:value1=" :value1="negativeInfo.jcj110BusinessSize"
negativeInfo.jcj110BusinessSize
"
:value2="negativeInfo.jcj110Size" :value2="negativeInfo.jcj110Size"
/> />
</el-col> </el-col>
<el-col <el-col
:span="12" :span="24"
v-if=" v-if="negativeInfo.jcj122BusinessSize || negativeInfo.jcj122Size"
negativeInfo.jcj122BusinessSize || class="mb-20"
negativeInfo.jcj122Size
"
> >
<description-pair <description-pair
label="122接处警" label="122接处警"
label1="量" label1="量"
label2="问题数" label2="问题数"
:value1=" :value1="negativeInfo.jcj122BusinessSize"
negativeInfo.jcj122BusinessSize
"
:value2="negativeInfo.jcj122Size" :value2="negativeInfo.jcj122Size"
/> />
</el-col> </el-col>
<el-col :span="12"> <el-col :span="24">
<description-pair <description-pair
label="执法办案" label="执法办案"
label2="问题数" label2="问题数"
:value1=" :value1="negativeInfo.zfbaBusinessSize"
negativeInfo.zfbaBusinessSize
"
:value2="negativeInfo.zfbaSize" :value2="negativeInfo.zfbaSize"
/> />
</el-col> </el-col>
</el-row> </el-row>
</el-col> </el-col>
</el-row> </el-row>
</div>
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<h5 style="margin-bottom: 0">风险指数</h5> <h5>问题累计分值</h5>
<div class="flex center"> <div class="flex center card-item wrap">
<el-progress <el-progress
type="dashboard" type="dashboard"
:percentage="score" :percentage="100"
:stroke-width="16" :stroke-width="16"
:width="220" :width="200"
:color="colors" color="#5B8FF9"
> >
<div class="score-progress-body"> <div class="score-progress-body">
<div v-if="score"> <div>
<div style="font-size: 16px">分数</div>
<div> <div>
<span <span
class="score-progress_score score-theme text-bold" class="score-progress_score score-theme text-bold"
:type="getType(score)" style="color: #19257d"
>{{ score }}</span >{{ score }}</span>
>
<span></span>
</div>
<div
style="font-size: 14px"
class="mb-16"
>
风险指数
</div> </div>
</div> </div>
<div
v-else
style="
font-size: 60px;
line-height: 84px;
color: #999;
"
>
-
</div>
<div
class="score-progress_title score-theme"
:type="getType(score)"
>
{{ getScoreLabel() }}
</div>
</div> </div>
</el-progress> </el-progress>
<div style="width: 100%" class="text-center">累计{{ days }}天分值</div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<el-row class="mb-20"> <el-row class="mb-20" :gutter="20">
<el-col :span="8"> <el-col :span="8">
<h5>问题来源占比</h5> <h5>问题来源占比</h5>
<div class="card-item">
<v-charts <v-charts
style="height: 320px" style="height: 320px"
:option="problemSourcesPieOptions" :option="problemSourcesPieOptions"
autoresize autoresize
/> />
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<h5>问题涉及方面分布</h5> <h5>问题涉及方面</h5>
<div class="card-item">
<v-charts <v-charts
style="height: 320px" style="height: 320px"
:option="problemTypePieOptions" :option="problemTypePieOptions"
autoresize autoresize
/> />
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<h5 style="margin-bottom: 0">风险构成</h5> <h5>突出问题排名</h5>
<div class="flex center" style="width: 100%"> <div class="flex center card-item" style="width: 100%">
<v-charts <datav-chart-bar
style="height: 340px; width: 100%" size="small"
:option="radarOption" :data="problemTypeBarList"
autoresize :color="colors"
labelPosition="top"
/> />
<el-empty v-if="problemTypeBarList.length === 0" />
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<h5>问题变化趋势</h5> <h5>问题变化趋势</h5>
<v-charts
style="height: 320px" <div class="card-item">
:option="barOption" <v-charts style="height: 320px" :option="barOption" autoresize />
autoresize </div>
/>
<div></div>
<h5>问题清单</h5> <h5>问题清单</h5>
<el-table :data="negativeList"> <el-table :data="negativeList" height="500">
<el-table-column label="发现时间" prop="discoveryTime" /> <el-table-column label="发现时间" prop="discoveryTime" width="160" />
<el-table-column label="问题来源" prop="problemSources" /> <el-table-column label="问题来源" prop="problemSources" width="150" />
<el-table-column label="业务类别" prop="businessTypeName" /> <el-table-column label="业务类别" prop="businessTypeName" width="150" />
<el-table-column <el-table-column
label="涉及单位" label="问题详情"
prop="involveDepartName" prop="thingDesc"
show-overflow-tooltip
/> />
<el-table-column <el-table-column
label="核查情况" label="核查情况"
prop="checkStatusName" prop="checkStatusDesc"
width="140" show-overflow-tooltip
/>
<el-table-column
label="问题类型"
prop="problemType"
show-overflow-tooltip
/>
<el-table-column
label="分值"
prop="score"
width="100"
align="center" align="center"
/> />
<el-table-column label="操作" width="160"> <el-table-column label="操作" width="160">
<template #default="{ row }"> <template #default="{ row }">
<el-button <el-button type="primary" link @click="handleAction(row)"
type="primary"
link
@click="handleAction(row)"
>查看详情 >查看详情
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="flex end mt-8">
<el-pagination
@size-change="getNegativeList"
@current-change="getNegativeList"
:current-page="negativeQuery.current"
:page-sizes="[10, 20, 50]"
:page-size="negativeQuery.size"
v-model:current-page="negativeQuery.current"
layout="total, sizes, prev, pager, next"
:total="negativeTotal"
>
</el-pagination>
</div>
</main> </main>
</el-scrollbar> </el-scrollbar>
</el-dialog> </el-dialog>
<alarm-dialog v-model="showNotification" :departId="activeDepartId" @close="showNotification = false" /> <alarm-dialog
v-model="showNotification"
:departId="activeDepartId"
@close="showNotification = false"
/>
<negative-dialog <negative-dialog
v-model="negativeShow" v-model="negativeShow"
@ -467,17 +386,17 @@ import feedback from "~/utils/feedback";
const catchStore = useCatchStore(); const catchStore = useCatchStore();
const dict = catchStore.getDicts(["personType"]); const dict = catchStore.getDicts(["personType"]);
let showNotification = ref(false); let showNotification = ref(false);
const activeDepartId = ref('') const activeDepartId = ref("");
const handleShowNotification = (row) => { const handleShowNotification = (row) => {
showNotification.value = true; showNotification.value = true;
activeDepartId.value = row.departId activeDepartId.value = row.departId;
}; };
const query = ref({ const query = ref({
current: 1, current: 1,
size: 10, size: 10,
crtTime: [ crtTime: [
moment().subtract(12, 'month').format("YYYY-MM-DD HH:mm:ss"), moment().startOf('year').format("YYYY-MM-DD HH:mm:ss"),
moment().format("YYYY-MM-DD HH:mm:ss"), moment().format("YYYY-MM-DD HH:mm:ss"),
], ],
}); });
@ -500,7 +419,7 @@ function reset() {
current: 1, current: 1,
size: 10, size: 10,
crtTime: [ crtTime: [
moment().subtract(12, 'month').format("YYYY-MM-DD HH:mm:ss"), moment().startOf('year').format("YYYY-MM-DD HH:mm:ss"),
moment().format("YYYY-MM-DD HH:mm:ss"), moment().format("YYYY-MM-DD HH:mm:ss"),
], ],
}; };
@ -517,9 +436,6 @@ const policeInfo = ref({});
const negativeInfo = ref({}); const negativeInfo = ref({});
const loading = ref(false); const loading = ref(false);
const negativeQuery = ref({
checkStatusList: [InspectCase.TRUE, InspectCase.TRUE],
});
const negativeList = ref([]); const negativeList = ref([]);
const negativeTotal = ref(0); const negativeTotal = ref(0);
@ -572,7 +488,7 @@ async function handleShowProfile(row) {
watch(activeRow, async () => { watch(activeRow, async () => {
time.value = [ time.value = [
moment().subtract(12, 'month').format("YYYY-MM-DD HH:mm:ss"), moment().startOf('year').format("YYYY-MM-DD HH:mm:ss"),
moment().format("YYYY-MM-DD HH:mm:ss"), moment().format("YYYY-MM-DD HH:mm:ss"),
]; ];
await getProfileData(); await getProfileData();
@ -584,85 +500,29 @@ watch(activeRow, async () => {
const time = ref([]); const time = ref([]);
const radarOption = ref({ const problemTypeBarList = ref([]);
color: ["#F60000", "#162582"],
legend: {
data: ["风险指数", "权重"],
},
radar: {
indicator: [
{ name: "110接处警", max: 100 },
{ name: "122接处警", max: 100 },
{ name: "人境窗口服务", max: 100 },
{ name: "车驾管服务", max: 100 },
{ name: "交警执法", max: 100 },
{ name: "执法办案", max: 100 },
{ name: "专项工作", max: 100 },
{ name: "安保维稳", max: 100 },
],
},
series: [
{
type: "radar",
data: [
{
value: [],
name: "风险指数",
label: {
show: true,
},
},
{
value: [],
name: "权重",
label: {
show: true,
},
},
],
},
],
});
const score = ref(0); const score = ref(0);
const days = ref(0)
async function getProfileData() { async function getProfileData() {
loading.value = true; loading.value = true;
negativeQuery.value.idCode = activeRow.value.idCode;
getNegativeList();
const data = await getPoliceProfile(activeRow.value.idCode, { const data = await getPoliceProfile(activeRow.value.idCode, {
beginTime: time.value.length ? time.value[0] : "", beginTime: time.value.length ? time.value[0] : "",
endTime: time.value.length ? time.value[1] : "", endTime: time.value.length ? time.value[1] : "",
}); });
score.value = Math.round(data.score); score.value = data.score;
console.log(data.expression); days.value = data.days
console.log(data.remarks); negativeList.value = data.negatives;
policeInfo.value = data.policeInfo; policeInfo.value = data.policeInfo;
negativeInfo.value = data.negativeInfo; negativeInfo.value = data.negativeInfo;
problemSourcesPieOptions.value.series[0].data = data.problemSourcesList; problemSourcesPieOptions.value.series[0].data = data.problemSourcesList;
problemTypePieOptions.value.series[0].data = data.problemTypeList; problemTypePieOptions.value.series[0].data = data.problemTypeList;
problemTypeBarList.value = data.problemTypeBarList
radarOption.value.radar.indicator = data.businessTypeRadarIndicator;
radarOption.value.series[0].data[0].value = data.businessTypeScoreRadarData;
radarOption.value.series[0].data[1].value =
data.businessTypeWeightRadarData;
loading.value = false; loading.value = false;
} }
function getNegativeList() {
if (time.value.length === 2) {
negativeQuery.value.beginTime = time.value[0];
negativeQuery.value.endTime = time.value[1];
}
listNegativeByPoliceIdCode(
activeRow.value.idCode,
negativeQuery.value
).then((data) => {
negativeList.value = data.records;
negativeTotal.value = data.total;
});
}
const negativeShow = ref(false); const negativeShow = ref(false);
const activeNegativeId = ref(""); const activeNegativeId = ref("");
@ -743,4 +603,13 @@ function getScoreLabel() {
color: var(--danger-color); color: var(--danger-color);
} }
} }
h5 {
margin-bottom: 12px;
}
.card-item {
background: #f9faff;
padding: 16px;
min-height: 200px;
}
</style> </style>

Loading…
Cancel
Save