1 changed files with 370 additions and 0 deletions
@ -0,0 +1,370 @@ |
|||||||
|
<template> |
||||||
|
<el-dialog |
||||||
|
title="个人问题详情" |
||||||
|
:model-value="modelValue" |
||||||
|
@update:model-value="emit('update:modelValue', $event)" |
||||||
|
width="85vw" |
||||||
|
top="1vh" |
||||||
|
style="margin: 1vh auto" |
||||||
|
> |
||||||
|
<header class="flex center v-center gap"> |
||||||
|
<label>统计范围</label> |
||||||
|
<div style="width: 320px"> |
||||||
|
<date-time-range-picker-ext |
||||||
|
v-model="time" |
||||||
|
style="width: 300px" |
||||||
|
@change="getProfileData" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<el-button type="primary" @click="getProfileData">查询</el-button> |
||||||
|
</header> |
||||||
|
<el-scrollbar |
||||||
|
max-height="calc(98vh - 120px)" |
||||||
|
v-loading="loading" |
||||||
|
element-loading-text="个人问题详情加载中..." |
||||||
|
> |
||||||
|
<main> |
||||||
|
<el-row class="mb-20" :gutter="20"> |
||||||
|
<el-col :span="8"> |
||||||
|
<h5>民警基本情况</h5> |
||||||
|
<div class="card-item h-220"> |
||||||
|
<el-row> |
||||||
|
<el-col :span="6"> |
||||||
|
<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 /> |
||||||
|
</div> |
||||||
|
</el-col> |
||||||
|
<el-col :span="18"> |
||||||
|
<div class="row"> |
||||||
|
<div class="col col-12"> |
||||||
|
<label>姓名</label> |
||||||
|
<span>{{ policeInfo.name }}</span> |
||||||
|
</div> |
||||||
|
<div class="col col-12"> |
||||||
|
<label>性别</label> |
||||||
|
<span>{{ getGenderFromIdCode(policeInfo.idCode) }}</span> |
||||||
|
</div> |
||||||
|
<div class="col col-24"> |
||||||
|
<label>所属单位</label> |
||||||
|
<span> |
||||||
|
<span |
||||||
|
>{{ |
||||||
|
activeRow.parentDepartName |
||||||
|
? activeRow.parentDepartName + "/" |
||||||
|
: "" |
||||||
|
}}{{ activeRow.departName || "/" }}</span |
||||||
|
> |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
<div class="col col-24"> |
||||||
|
<label>警号</label> |
||||||
|
<span>{{ policeInfo.empNo }}</span> |
||||||
|
</div> |
||||||
|
<div class="col col-24"> |
||||||
|
<label>身份证号</label> |
||||||
|
<span>{{ policeInfo.idCode }}</span> |
||||||
|
</div> |
||||||
|
<div class="col col-24"> |
||||||
|
<label>入职时间</label> |
||||||
|
<span>{{ policeInfo.employmentDate || "/" }}</span> |
||||||
|
</div> |
||||||
|
<div class="col col-24"> |
||||||
|
<label>手机号</label> |
||||||
|
<span>{{ policeInfo.mobile || "/" }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
</div> |
||||||
|
</el-col> |
||||||
|
<el-col :span="8"> |
||||||
|
<h5>问题情况</h5> |
||||||
|
<div class="card-item h-220"> |
||||||
|
<div class="flex v-center h100"> |
||||||
|
<div style="width: 25%" class="text-center"> |
||||||
|
<div class="text-primary" style="font-size: 34px"> |
||||||
|
{{ negativeInfo.size }} |
||||||
|
</div> |
||||||
|
<div class="mb-10">问题总数</div> |
||||||
|
</div> |
||||||
|
<div style="width: 75%" class="text-center"> |
||||||
|
<div |
||||||
|
v-if="negativeInfo.jcj110BusinessSize || negativeInfo.jcj110Size" |
||||||
|
class="mb-20" |
||||||
|
> |
||||||
|
<description-pair |
||||||
|
label="110接处警" |
||||||
|
label1="量" |
||||||
|
label2="问题数" |
||||||
|
:value1="negativeInfo.jcj110BusinessSize" |
||||||
|
:value2="negativeInfo.jcj110Size" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div |
||||||
|
v-if="negativeInfo.jcj122BusinessSize || negativeInfo.jcj122Size" |
||||||
|
class="mb-20" |
||||||
|
> |
||||||
|
<description-pair |
||||||
|
label="122接处警" |
||||||
|
label1="量" |
||||||
|
label2="问题数" |
||||||
|
:value1="negativeInfo.jcj122BusinessSize" |
||||||
|
:value2="negativeInfo.jcj122Size" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<description-pair |
||||||
|
label="执法办案" |
||||||
|
label2="问题数" |
||||||
|
:value1="negativeInfo.zfbaBusinessSize" |
||||||
|
:value2="negativeInfo.zfbaSize" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-col> |
||||||
|
<el-col :span="8"> |
||||||
|
<h5>问题累计分值</h5> |
||||||
|
<div class="flex center card-item wrap h-220"> |
||||||
|
<el-progress |
||||||
|
type="dashboard" |
||||||
|
:percentage="100" |
||||||
|
:stroke-width="16" |
||||||
|
:width="200" |
||||||
|
color="#5B8FF9" |
||||||
|
> |
||||||
|
<div class="score-progress-body"> |
||||||
|
<div> |
||||||
|
<div style="font-size: 16px">分数</div> |
||||||
|
<div> |
||||||
|
<span |
||||||
|
class="score-progress_score score-theme text-bold" |
||||||
|
style="color: #19257d" |
||||||
|
>{{ score }}</span |
||||||
|
> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-progress> |
||||||
|
<div style="width: 100%" class="text-center">累计{{ days }}天分值</div> |
||||||
|
</div> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
<el-row class="mb-20" :gutter="20"> |
||||||
|
<el-col :span="8"> |
||||||
|
<h5>问题来源占比</h5> |
||||||
|
<div class="card-item"> |
||||||
|
<v-charts |
||||||
|
style="height: 320px" |
||||||
|
:option="problemSourcesPieOptions" |
||||||
|
autoresize |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</el-col> |
||||||
|
<el-col :span="8"> |
||||||
|
<h5>问题涉及方面</h5> |
||||||
|
<div class="card-item"> |
||||||
|
<v-charts |
||||||
|
style="height: 320px" |
||||||
|
:option="problemTypePieOptions" |
||||||
|
autoresize |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</el-col> |
||||||
|
<el-col :span="8"> |
||||||
|
<h5>突出问题排名</h5> |
||||||
|
<div class="flex center card-item h-320"> |
||||||
|
<datav-chart-bar1 |
||||||
|
size="small" |
||||||
|
:data="problemTypeBarList" |
||||||
|
:color="colors" |
||||||
|
labelPosition="top" |
||||||
|
/> |
||||||
|
<el-empty v-if="problemTypeBarList.length === 0" /> |
||||||
|
</div> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
|
||||||
|
<h5>问题变化趋势</h5> |
||||||
|
|
||||||
|
<div class="card-item"> |
||||||
|
<v-charts style="height: 320px" :option="barOption" autoresize /> |
||||||
|
</div> |
||||||
|
<h5>问题清单 {{ negativeList.length }}</h5> |
||||||
|
<el-table :data="negativeList" height="500"> |
||||||
|
<el-table-column label="发现时间" prop="discoveryTime" width="160" /> |
||||||
|
<el-table-column label="问题来源" prop="problemSources" width="150" /> |
||||||
|
<el-table-column label="业务类别" prop="businessTypeName" width="150" /> |
||||||
|
<el-table-column label="问题详情" 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="分值" width="100" align="center"> |
||||||
|
<template #default="{ row }"> |
||||||
|
<span class="text-danger">{{ row.score }}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" width="160"> |
||||||
|
<template #default="{ row }"> |
||||||
|
<el-button type="primary" link @click="handleAction(row)" |
||||||
|
>查看详情 |
||||||
|
</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
</main> |
||||||
|
</el-scrollbar> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<negative-dialog |
||||||
|
v-model="negativeShow" |
||||||
|
:id="activeNegativeId" |
||||||
|
@close="negativeShow = false" |
||||||
|
/> |
||||||
|
</template> |
||||||
|
<script setup> |
||||||
|
import { BASE_PATH } from "@/api/request"; |
||||||
|
import vCharts from "vue-echarts"; |
||||||
|
import { getPoliceProfile, listNegativeMonthly } from "@/api/sensitivePerception/profilePolice"; |
||||||
|
import { getGenderFromIdCode } from "@/utils/util"; |
||||||
|
import moment from "moment"; |
||||||
|
|
||||||
|
const props = defineProps({ |
||||||
|
modelValue: Boolean, |
||||||
|
idCode: String, |
||||||
|
activeRow: { type: Object, default: () => ({}) }, |
||||||
|
initialTime: { type: Array, default: () => [] }, |
||||||
|
}); |
||||||
|
const emit = defineEmits(["update:modelValue"]); |
||||||
|
|
||||||
|
const time = ref([]); |
||||||
|
const policeInfo = ref({}); |
||||||
|
const negativeInfo = ref({}); |
||||||
|
const loading = ref(false); |
||||||
|
const negativeList = ref([]); |
||||||
|
const problemTypeBarList = ref([]); |
||||||
|
const score = ref(0); |
||||||
|
const days = ref(0); |
||||||
|
const problemSourcesPieOptions = ref({ |
||||||
|
tooltip: { trigger: "item" }, |
||||||
|
series: [{ type: "pie", radius: ["40%", "70%"], data: [] }], |
||||||
|
}); |
||||||
|
const problemTypePieOptions = ref({ |
||||||
|
tooltip: { trigger: "item" }, |
||||||
|
series: [{ type: "pie", radius: ["40%", "70%"], data: [] }], |
||||||
|
}); |
||||||
|
const barOption = ref({ |
||||||
|
xAxis: { type: "category", data: [] }, |
||||||
|
yAxis: { type: "value" }, |
||||||
|
series: [{ data: [], type: "bar", color: "#5B8FF9 " }], |
||||||
|
}); |
||||||
|
const colors = [ |
||||||
|
{ color: "var(--success-color)", percentage: 60 }, |
||||||
|
{ color: "#DC6231", percentage: 80 }, |
||||||
|
{ color: "var(--danger-color)", percentage: 100 }, |
||||||
|
]; |
||||||
|
|
||||||
|
watch( |
||||||
|
() => [props.idCode, props.modelValue], |
||||||
|
([idCode, isOpen]) => { |
||||||
|
if (!isOpen || !idCode) return; |
||||||
|
time.value = props.initialTime.length === 2 |
||||||
|
? [...props.initialTime] |
||||||
|
: [ |
||||||
|
moment().startOf("year").format("YYYY-MM-DD HH:mm:ss"), |
||||||
|
moment().format("YYYY-MM-DD HH:mm:ss"), |
||||||
|
]; |
||||||
|
getProfileData(); |
||||||
|
listNegativeMonthly(idCode).then((data) => { |
||||||
|
barOption.value.xAxis.data = data.months; |
||||||
|
barOption.value.series[0].data = data.values; |
||||||
|
}); |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
async function getProfileData() { |
||||||
|
if (!props.idCode) return; |
||||||
|
loading.value = true; |
||||||
|
try { |
||||||
|
const data = await getPoliceProfile(props.idCode, { |
||||||
|
beginTime: time.value.length ? time.value[0] : "", |
||||||
|
endTime: time.value.length ? time.value[1] : "", |
||||||
|
}); |
||||||
|
score.value = Math.round(data.score); |
||||||
|
days.value = data.days; |
||||||
|
negativeList.value = data.negatives; |
||||||
|
policeInfo.value = data.policeInfo; |
||||||
|
negativeInfo.value = data.negativeInfo; |
||||||
|
problemSourcesPieOptions.value.series[0].data = data.problemSourcesList; |
||||||
|
problemTypePieOptions.value.series[0].data = data.problemTypeList; |
||||||
|
problemTypeBarList.value = data.problemTypeBarList; |
||||||
|
} finally { |
||||||
|
loading.value = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const negativeShow = ref(false); |
||||||
|
const activeNegativeId = ref(""); |
||||||
|
function handleAction(row) { |
||||||
|
negativeShow.value = true; |
||||||
|
activeNegativeId.value = row.id; |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
.col { |
||||||
|
--label-width: 60px; |
||||||
|
} |
||||||
|
|
||||||
|
.score-progress-body { |
||||||
|
text-align: center; |
||||||
|
font-size: 18px; |
||||||
|
|
||||||
|
.score-progress_score { |
||||||
|
font-size: 50px; |
||||||
|
line-height: 70px; |
||||||
|
} |
||||||
|
|
||||||
|
.score-progress_title { |
||||||
|
font-size: 26px; |
||||||
|
line-height: 22px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.score-theme { |
||||||
|
&[type="success"] { |
||||||
|
color: var(--success-color); |
||||||
|
} |
||||||
|
|
||||||
|
&[type="warning"] { |
||||||
|
color: #e87749; |
||||||
|
} |
||||||
|
|
||||||
|
&[type="danger"] { |
||||||
|
color: var(--danger-color); |
||||||
|
} |
||||||
|
} |
||||||
|
h5 { |
||||||
|
margin-bottom: 12px; |
||||||
|
} |
||||||
|
.card-item { |
||||||
|
background: #f9faff; |
||||||
|
padding: 16px; |
||||||
|
min-height: 200px; |
||||||
|
} |
||||||
|
.h-220 { |
||||||
|
height: 220px; |
||||||
|
} |
||||||
|
.h-320 { |
||||||
|
height: 320px; |
||||||
|
} |
||||||
|
</style> |
||||||
Loading…
Reference in new issue