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