Browse Source

优化风险人员库; 一些BUG修复

main
wxc 12 months ago
parent
commit
57f2c8d162
  1. 7
      src/api/sensitivePerception/riskClue.ts
  2. 7
      src/api/sensitivePerception/riskPersonnel.ts
  3. 2
      src/assets/icons/ic_01.svg
  4. 2
      src/assets/icons/ic_04.svg
  5. 5
      src/components/negative/add.vue
  6. 7
      src/style/element.scss
  7. 3
      src/style/public.scss
  8. 4
      src/utils/util.ts
  9. 239
      src/views/sensitivePerception/Model.vue
  10. 243
      src/views/sensitivePerception/RiskClue.vue
  11. 452
      src/views/sensitivePerception/RiskPersonnel.vue
  12. 125
      src/views/sensitivePerception/RiskScoreRule.vue
  13. 7
      src/views/system/Police.vue
  14. 16
      src/views/system/User.vue
  15. 69
      src/views/work/Done.vue
  16. 65
      src/views/work/Query.vue
  17. 80
      src/views/work/Todo.vue

7
src/api/sensitivePerception/riskClue.ts

@ -5,4 +5,11 @@ export function listRiskClues(query) {
url: `/risk/clues`,
query
});
}
export function addRiskClue(body) {
return request.post({
url: `/risk/clues`,
body
});
}

7
src/api/sensitivePerception/riskPersonnel.ts

@ -7,6 +7,13 @@ export function listRiskPersonnel(query) {
});
}
export function listQueryRiskPersonnel(query) {
return request.get({
url: '/risk/personal/query',
query
});
}
export function getRiskPersonnel(id) {
return request.get({
url: '/risk/personal/' + id

2
src/assets/icons/ic_01.svg

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="80px" height="80px" viewBox="0 0 80 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg viewBox="0 0 80 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_01</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-97, -46)" fill="#FFFFFF" fill-rule="nonzero">

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

2
src/assets/icons/ic_04.svg

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_04</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-449, -46)" fill="#FFFFFF" fill-rule="nonzero">

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

5
src/components/negative/add.vue

@ -461,6 +461,7 @@ import feedback from "@/utils/feedback";
import { addNegative, generateOriginId } from "@/api/work/negative";
import { secondList, listByFirstHost } from "@/api/system/depart";
import useCatchStore from "@/stores/modules/catch";
import { disabledDate } from '@/utils/util'
const catchStore = useCatchStore();
const dict = catchStore.getDicts([
@ -565,9 +566,7 @@ function handleChangeHostLevel(val) {
}
}
function disabledDate(time) {
return time.getTime() < moment("1949-10-01", "YYYY-MM-DD").valueOf();
}
</script>
<style lang="scss" scoped>
.add-negation-container {

7
src/style/element.scss

@ -67,6 +67,13 @@ div.el-card {
margin-right: 0;
}
&>.el-dialog__body {
padding-left: 0;
padding-right: 0;
}
}
&.dialog-body-nopadding {
&>.el-dialog__body {
padding-left: 0;
padding-right: 0;

3
src/style/public.scss

@ -354,6 +354,9 @@ svg + span {
--gap-width: 10px;
display: flex;
gap: var(--gap-width);
&.col-4 {
width: 16.6%;
}
&.col-6 {
width: 25%;

4
src/utils/util.ts

@ -383,4 +383,8 @@ export function getGenderFromIdCode(idCode) {
}
// 根据第17位数字判断性别
return genderCode % 2 === 0 ? "女" : "男";
}
export function disabledDate(time) {
return time.getTime() < moment("1949-10-01", "YYYY-MM-DD").valueOf();
}

239
src/views/sensitivePerception/Model.vue

@ -114,7 +114,7 @@
</div>
</div>
<div class="col col-24">
<label>最近活跃时间</label>
<label>活跃时间</label>
<span>{{
item.updateTime
}}</span>
@ -560,9 +560,11 @@
}"
>
<div class="flex gap">
<el-input style="width: 100px" type="number" v-model="form" /><span
>工作日</span
>
<el-input
style="width: 100px"
type="number"
v-model="form"
/><span></span>
</div>
</el-form-item>
</template>
@ -629,120 +631,112 @@
</el-dialog>
<el-dialog title="模型详情" v-model="detailShow" top="5vh" width="70vw">
<h4 style="margin: 10px 0" class="text-primary">模型信息</h4>
<el-row>
<el-col :span="4">
<div class="mb-10">模型图标</div>
<div>
<header class="model-info-header" style="">
<el-row :gutter="40">
<el-col :span="2">
<div
class="model-icon"
:style="{ background: activeModel.iconColor }"
>
<icon :name="activeModel.icon" :size="80" />
</div>
</div>
</el-col>
<el-col :span="20">
<div class="row">
<div class="col col-24">
<label>模型名称</label>
<span>{{ activeModel.modelName }}</span>
</div>
</div>
<div class="row">
<div class="col col-8">
<label>建模方式</label>
<span>{{
getDictLable(
dict.modelingMethod,
activeModel.modelingMethod
)
}}</span>
</div>
<div class="col col-8">
<label>数据类型</label>
<span>{{
getDictLable(
dict.modelDataType,
activeModel.modelDataType
)
}}</span>
</div>
</div>
<div class="row">
<div class="col col-8">
<label>分发方式</label>
<span>{{
getDictLable(
dict.distributionMethod,
activeModel.distributionMethod
)
}}</span>
</div>
<div class="col col-8">
<label>分发周期</label>
<span>
<span>{{
getDictLable(
dict.distributionCycle,
activeModel.distributionCycle
)
}}</span>
<span class="ml-20">{{
activeModel.distributionCycleTime
}}</span>
</span>
</div>
</div>
<div class="row">
<div class="col col-8">
<label>办理时限</label>
<span>{{
getDictLable(dict.timeLimit, activeModel.timeLimit)
}}</span>
</div>
<div class="col col-8">
<label>下发流程</label>
<span>{{
getDictLable(
dict.distributionFlow,
activeModel.distributionFlow
)
}}</span>
</div>
<div class="col col-8">
<label>审核流程</label>
<span>{{
getDictLable(
dict.approvalFlow,
activeModel.approvalFlow
)
}}</span>
</div>
</div>
<div class="row">
<div class="col col-8">
<label>最近活跃时间</label>
<span>{{ activeModel.updateTime }}</span>
</div>
<div class="col col-8">
<label>创建单位</label>
<span>{{ activeModel.createDepartName }}</span>
</div>
</div>
<div class="row mb-20">
<div class="col col-24">
<label>模型描述</label>
<span>{{ activeModel.remarks }}</span>
</div>
</div>
<div class="flex end mb-20">
<el-button type="primary" plain @click="goClue">{{
activeModel.classId === GRJDBLFX_CLASS_ID
? "查看风险问题"
: "查看线索数据"
}}</el-button>
<!-- <el-button
</el-col>
<el-col :span="21">
<h1 style="color: #333; margin-top: 0" class="mb-10">
{{ activeModel.modelName }}
</h1>
<p>{{ activeModel.remarks }}</p>
</el-col>
</el-row>
</header>
<h4 style="margin: 10px 0" class="text-primary">模型信息</h4>
<div class="row">
<div class="col col-6">
<label>建模方式</label>
<span>{{
getDictLable(
dict.modelingMethod,
activeModel.modelingMethod
)
}}</span>
</div>
<div class="col col-6">
<label>模型分类</label>
<span>{{
getDictLable(dict.modelType, activeModel.modelType)
}}</span>
</div>
<div class="col col-6">
<label>最近活跃时间</label>
<span>{{ activeModel.updateTime }}</span>
</div>
<div class="col col-6">
<label>创建单位</label>
<span>{{ activeModel.createDepartName || "/" }}</span>
</div>
<div class="col col-6" v-if="form.modelDataType">
<label>预警类型</label>
<span>{{
modelDataType === '1'? form.modelType === "2" ? "预警处置" : "预警问题" : '提醒通知'
}}</span>
</div>
</div>
<el-divider />
<div class="row">
<div class="col col-6">
<label>分发方式</label>
<span>{{
getDictLable(
dict.distributionMethod,
activeModel.distributionMethod
)
}}</span>
</div>
<div class="col col-6" v-if="activeModel.distributionCycle">
<label>分发周期</label>
<span>
<span>{{
getDictLable(
dict.distributionCycle,
activeModel.distributionCycle
)
}}</span>
<span class="ml-20">{{
activeModel.distributionCycleTime
}}</span>
</span>
</div>
<div class="col col-6" v-if="activeModel.timeLimit">
<label>办理时限</label>
<span>{{
getDictLable(dict.timeLimit, activeModel.timeLimit)
}}</span>
</div>
<div class="col col-6" v-if="activeModel.distributionFlow">
<label>下发流程</label>
<span>{{
getDictLable(
dict.distributionFlow,
activeModel.distributionFlow
)
}}</span>
</div>
<div class="col col-6" v-if="activeModel.approvalFlow">
<label>审核流程</label>
<span>{{
getDictLable(dict.approvalFlow, activeModel.approvalFlow)
}}</span>
</div>
</div>
<el-divider />
<div class="flex end mb-20">
<el-button type="primary" plain @click="goClue">{{
activeModel.classId === GRJDBLFX_CLASS_ID
? "查看风险问题"
: "查看线索数据"
}}</el-button>
<!-- <el-button
type="primary"
plain
@click="handleDetailConfigShow"
@ -752,9 +746,7 @@
</template>
线索详细信息配置</el-button
> -->
</div>
</el-col>
</el-row>
</div>
<div class="mb-10">
<h4 style="margin: 10px 0" class="text-primary">预警记录</h4>
<div style="min-height: 300px">
@ -852,7 +844,7 @@ import {
import { WEEKS } from "@/enums/appEnums";
import { MENU_ROOT_ID } from "@/enums/appEnums";
import { listModelClass } from "@/api/sensitivePerception/modelClass";
import { listRiskScoreRuleTree } from "@/api/sensitivePerception/riskScoreRule";
import { listRiskScoreRuleTreeOld } from "@/api/sensitivePerception/riskScoreRule";
import {
addModel,
updateModel,
@ -915,7 +907,7 @@ onMounted(() => {
listModelClass().then((data) => {
classes.value = data;
});
listRiskScoreRuleTree().then((data) => {
listRiskScoreRuleTreeOld().then((data) => {
treeOptions.value = data;
});
});
@ -930,7 +922,7 @@ const mode = ref("add");
const form = ref({
distributionMethod: "1",
problems: [],
requestReply: true
requestReply: true,
});
watch(mode, (val) => {
@ -943,7 +935,7 @@ function initForm() {
form.value = {
distributionMethod: "1",
problems: [],
requestReply: true
requestReply: true,
};
}
const formRef = ref(null);
@ -1020,7 +1012,7 @@ function goClue() {
router.push({
path: `/sensitivePerception/riskClue`,
query: {
riskScoreRuleId: activeModel.value.riskScoreRuleId,
riskScoreRuleId: activeModel.value.id,
},
});
} else {
@ -1064,7 +1056,12 @@ function goClue() {
}
}
.model-icon {
width: 76px;
width: 80px;
border-radius: 8px;
}
.model-info-header {
background: #f9faff;
box-shadow: 0px 2px 4px 0px rgba(133, 150, 248, 0.47);
padding: 28px;
}
</style>

243
src/views/sensitivePerception/RiskClue.vue

@ -1,10 +1,10 @@
<template>
<div class="container h100">
<el-row :gutter="20" class="h100">
<el-col :span="6" class="h100">
<el-col :span="4" class="h100">
<model-risk-tree v-model="query.riskScoreRuleId" />
</el-col>
<el-col :span="18">
<el-col :span="20">
<header>
<el-form :label-width="140">
<el-row>
@ -45,7 +45,7 @@
</el-row>
</el-form>
<div class="flex between mb-20">
<el-button type="primary" @click="addShow = true"
<el-button type="primary" @click="showAdd = true"
><template #icon>
<icon name="el-icon-Plus" /> </template
>风险问题录入</el-button
@ -66,13 +66,13 @@
<el-table-column
label="发生时间"
prop="eventTime"
width="160"
width="168"
/>
<el-table-column label="姓名" prop="name" width="120" />
<el-table-column label="姓名" prop="name" width="90" />
<el-table-column
label="身份证号码"
prop="idCode"
width="170"
width="178"
show-overflow-tooltip
/>
<el-table-column
@ -83,12 +83,14 @@
/>
<el-table-column label="风险内容" show-overflow-tooltip>
<template #default="{ row }">
<span style="white-space: pre-wrap">{{
row.data
}}</span>
<el-scrollbar max-height="72px">
<span style="white-space: pre-wrap">{{
row.data
}}</span>
</el-scrollbar>
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<el-table-column label="操作" width="100">
<template #default="{ row }">
<el-button
type="primary"
@ -121,7 +123,7 @@
<el-form
label-width="148"
:model="formData2"
ref="formRef"
ref="formRef2"
class="mr-40"
>
<el-form-item label="提醒类型">
@ -186,11 +188,152 @@
</footer>
</el-dialog>
</div>
<el-dialog v-model="showAdd" title="风险问题录入" width="900px">
<el-form
label-width="148"
:model="formData"
ref="formRef"
style="min-height: 50vh"
>
<el-form-item
label="风险人员"
:rules="{
required: true,
message: '请选择风险人员',
}"
prop="idCode"
>
<el-autocomplete
v-model="formData.name"
:fetch-suggestions="querySearch"
@select="handleSelect"
clearable
placeholder="请输入"
style="width: 280px"
>
<template #default="{ item }">
<div class="flex gap">
<span>{{ item.name }}</span>
<span style="color: #999">{{ item.idCode }}</span>
</div>
</template>
</el-autocomplete>
</el-form-item>
<div class="row mb-10" v-if="formData.idCode">
<div class="col col-4">
<label>姓名</label>
<span>{{ formData.name }}</span>
</div>
<div class="col col-4">
<label>年龄</label>
<span>{{ formData.age }}</span>
</div>
<div class="col col-4">
<label>性别</label>
<span>{{ formData.six }}</span>
</div>
<div class="col col-8">
<label>证件号码</label>
<span>{{ formData.idCode }}</span>
</div>
</div>
<el-form-item
label="风险因素"
:rules="{
required: true,
message: '请选择风险因素',
}"
prop="riskScoreRuleId"
>
<el-tree-select
class="flex-1"
v-model="formData.riskScoreRuleId"
:data="treeOptions"
clearable
node-key="id"
:props="{
label: 'riskName',
}"
placeholder="请选择风险因素"
filterable
style="width: 280px"
@node-click="handleRiskChange"
/>
</el-form-item>
<el-form-item
label="问题发生时间"
prop="eventTime"
:rules="{
required: true,
message: '请选择问题发生时间',
}"
>
<el-date-picker
v-model="formData.eventTime"
type="datetime"
placeholder="请选择"
value-format="YYYY-MM-DD HH:mm"
time-format="HH:mm"
style="width: 280px"
:disabled-date="disabledDate"
/>
</el-form-item>
<el-form-item
label="风险问题"
:rules="{
required: true,
message: '请输入风险问题',
}"
prop="data"
>
<el-input
type="textarea"
placeholder="请输入"
v-model="formData.data"
:autosize="{ minRows: 5, maxRows: 12 }"
/>
</el-form-item>
<el-form-item
label="风险分值"
:rules="{
required: true,
message: '请选择风险分值',
}"
prop="score"
>
<el-radio-group v-model="formData.score">
<el-radio :value="1">1</el-radio>
<el-radio :value="2">2</el-radio>
<el-radio :value="3">3</el-radio>
<el-radio :value="4">4</el-radio>
<el-radio :value="5">5</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="计算分值" v-if="formData.scoreCalc">
<span
>{{ formData.score }} (风险分值) *
{{ formData.riskWeight }} (权重) * 20 / 100 =
<span class="text-danger">{{
formData.scoreCalc
}}</span></span
>
</el-form-item>
</el-form>
<footer class="flex end">
<el-button @click="showAdd = false" size="large">取消</el-button>
<el-button type="primary" @click="handleAdd" size="large"
>提交
</el-button>
</footer>
</el-dialog>
</template>
<script lang="ts" setup>
import { listRiskClues } from "@/api/sensitivePerception/riskClue";
import { listRiskClues, addRiskClue } from "@/api/sensitivePerception/riskClue";
import { listPoliceAll } from "~/api/system/police";
import { ref } from "vue";
import { listQueryRiskPersonnel } from "@/api/sensitivePerception/riskPersonnel";
import { listRiskScoreRuleTreeOld } from "@/api/sensitivePerception/riskScoreRule";
import { disabledDate } from "@/utils/util";
import { alarmNotificationCommit } from "~/api/work/alarm";
import feedback from "~/utils/feedback";
const query = ref({});
@ -198,8 +341,17 @@ const query = ref({});
const list = ref([]);
const total = ref(0);
const treeOptions = ref([]);
onMounted(() => {
getList();
if (route.query.riskScoreRuleId) {
query.value.riskScoreRuleId = [route.query.riskScoreRuleId];
} else {
getList();
}
listRiskScoreRuleTreeOld().then((data) => {
treeOptions.value = data;
});
});
watch(
() => query.value.riskScoreRuleId,
@ -210,8 +362,8 @@ watch(
const route = useRoute();
watch(
() => route.query.riskScoreRuleId,
(val) => {
query.value.riskScoreRuleId = [val];
() => {
query.value.riskScoreRuleId = [route.query.riskScoreRuleId];
}
);
@ -357,8 +509,65 @@ function reset() {
getList();
}
const addShow = ref(false)
const showAdd = ref(false);
const formData = ref({});
async function querySearch(queryString, cb) {
if (!queryString) {
cb([]);
return;
}
const results = await listQueryRiskPersonnel({ queryString });
cb(results);
}
function handleSelect(item) {
formData.value.name = item.name;
formData.value.age = item.age;
formData.value.idCode = item.idCode;
}
watch(
() => formData.value.name,
(val) => {
if (!val) {
delete formData.value.age;
delete formData.value.idCode;
}
}
);
function handleRiskChange(node) {
if (node.weight) {
formData.value.riskWeight = node.weight;
} else {
delete formData.value.riskWeight;
}
}
watch(
() => formData.value.score && formData.value.riskWeight,
() => {
if (formData.value.score && formData.value.riskWeight) {
formData.value.scoreCalc = (
(formData.value.score * formData.value.riskWeight * 20) /
100
).toFixed(2);
} else {
formData.value.scoreCalc = 0;
}
}
);
const formRef = ref();
async function handleAdd() {
await formRef.value.validate();
await addRiskClue(formData.value);
feedback.msgSuccess("录入成功");
getList();
formData.value = {};
showAdd.value = false;
}
</script>
<style lang="scss" scoped>
</style>

452
src/views/sensitivePerception/RiskPersonnel.vue

@ -45,7 +45,7 @@
size="small"
style="width: 200px"
placeholder="请输入"
v-model="query.mobileNumber"
v-model="query.idCode"
/>
</el-form-item>
</el-col>
@ -55,7 +55,7 @@
size="small"
style="width: 200px"
placeholder="请输入"
v-model="query.idCode"
v-model="query.mobileNumber"
/>
</el-form-item>
</el-col>
@ -112,14 +112,16 @@
</el-table-column>
<el-table-column label="高风险因素">
<template #default="{ row }">
<div class="flex gap-4 wrap" v-if="row.smallTags">
<el-tag
v-for="item in getSmallTags(row.smallTags)"
:type="item.type"
:key="item"
>{{ item.value }}
</el-tag>
</div>
<el-scrollbar max-height="80px">
<div class="flex gap-4 wrap">
<el-tag
v-for="item in getSmallTags(row.smallTags)"
:type="item.type"
:key="item"
>{{ item.value }}
</el-tag>
</div>
</el-scrollbar>
</template>
</el-table-column>
<el-table-column
@ -163,117 +165,184 @@
</div>
</div>
<el-dialog title="风险人员详情" v-model="show" width="80vw" top="2vh">
<el-row>
<el-col :span="4">
<div v-for="item in rules" :key="item">
<div class="risk-first">{{ item.riskName }}</div>
<el-dialog
title="风险人员详情"
v-model="show"
width="80vw"
top="2vh"
style="margin-bottom: 2vh"
class="dialog-body-nopadding"
>
<el-row :gutter="20">
<el-col :span="5">
<el-scrollbar max-height="calc(96vh - 92px)" class="ml-16">
<div
v-for="risk in item.children"
:key="risk"
class="risk-second pointer"
v-for="item in personal.riskClues"
:key="item"
>
{{ risk.riskName }}
<div class="risk-anchor-title flex between">
<span>{{ item.riskName }}</span>
<span style="color: #999">
<span style="color: #333">{{
item.score
}}</span>
</span>
</div>
<div
v-for="(risk, index) in item.riskIndexs"
:key="index"
class="risk-anchor pointer flex between"
:active="activeRiskIndex === risk.riskIndex"
@click="handlescrollbarTo(risk.riskIndex)"
:disabled="risk.score === 0"
>
<span>{{ risk.riskIndex }}</span>
<span style="color: #999">
<span style="color: #333">{{
risk.score
}}</span>
</span>
</div>
</div>
</div>
</el-scrollbar>
</el-col>
<el-col :span="20">
<el-row class="mt-20">
<el-col :span="19">
<p class="text-primary mb-10">风险人员基本情况</p>
<el-row>
<el-col :span="4">
<img :src="personal.riskPersonal?.avatar" v-if="personal.riskPersonal?.avatar"
<el-col :span="19">
<el-scrollbar
height="calc(96vh - 92px)"
style="padding-right: 16px"
ref="riskClueScrollbarRef"
>
<el-row class="mt-20 mb-20">
<el-col :span="19">
<p class="text-primary mb-10">风险人员基本情况</p>
<el-row>
<el-col :span="4">
<img
:src="personal.riskPersonal?.avatar"
v-if="personal.riskPersonal?.avatar"
style="height: 180px; width: 140px"
/>
<img src="@/assets/images/defaultPhoto.png" v-else
<img
src="@/assets/images/defaultPhoto.png"
v-else
style="height: 180px; width: 140px"
/>
</el-col>
<el-col :span="20">
<div class="row">
<div class="col col-12">
<label>姓名</label>
<span>{{ activeRow.name }}</span>
</div>
<div class="col col-12">
<label>性别</label>
<span>{{
getGender(activeRow.gender)
}}</span>
</div>
<div class="col col-12">
<label>年龄</label>
<span>{{ activeRow.age }}</span>
</div>
<div class="col col-12">
<label>证件号码</label>
<span>{{ activeRow.idCode }}</span>
</div>
<div class="col col-12">
<label>手机号码</label>
<span>{{
activeRow.mobileNumber
}}</span>
</div>
<div class="col col-12">
<label>管控单位</label>
<span>{{
activeRow.controlDepartName
}}</span>
</el-col>
<el-col :span="20">
<div class="row">
<div class="col col-12">
<label>姓名</label>
<span>{{ activeRow.name }}</span>
</div>
<div class="col col-12">
<label>性别</label>
<span>{{
getGender(activeRow.gender)
}}</span>
</div>
<div class="col col-12">
<label>年龄</label>
<span>{{ activeRow.age }}</span>
</div>
<div class="col col-12">
<label>证件号码</label>
<span>{{ activeRow.idCode }}</span>
</div>
<div class="col col-12">
<label>手机号码</label>
<span>{{
activeRow.mobileNumber
}}</span>
</div>
<div class="col col-12">
<label>管控单位</label>
<span>{{
activeRow.controlDepartName
}}</span>
</div>
</div>
</el-col>
</el-row>
</el-col>
<el-col :span="5">
<div class="flex center column text-center">
<div
class="socre-box"
:type="
getScoreType(
personal.riskPersonal?.riskScore
)
"
>
{{
personal.riskPersonal?.riskScore.toFixed(
0
)
}}
</div>
</el-col>
</el-row>
</el-col>
<el-col :span="5">
<div class="flex center column text-center">
<div class="socre-box">
{{ personal.riskPersonal.riskScore.toFixed(1) }}
<span style="font-size: 24px" class="mt-10"
>风险指数</span
>
</div>
</el-col>
</el-row>
<div style="min-height: 50vh" class="risk-clue-container">
<div
v-for="(item, index) in personal.riskClues"
:key="index"
>
<h4>{{ item.riskName }}</h4>
<div v-for="risk in item.riskIndexs" :key="risk">
<div
class="second-title mb-8 mt-20"
:id="risk.riskIndex"
>
{{ risk.riskIndex }}
</div>
<el-table :data="risk.clues">
<el-table-column
label="发生时间"
prop="eventTime"
width="180"
/>
<el-table-column
label="风险因素"
prop="riskName"
width="160"
show-overflow-tooltip
/>
<el-table-column
label="风险内容"
show-overflow-tooltip
>
<template #default="{ row }">
<span
style="white-space: pre-wrap"
>{{ row.data }}</span
>
</template>
</el-table-column>
<el-table-column
width="80"
label="分值"
prop="scoreResult"
>
<template #default="{ row }">
<span
v-if="row.scoreResult != null"
>{{ row.scoreResult.toFixed(0) }}</span
>
</template>
</el-table-column>
</el-table>
</div>
<span style="font-size: 24px" class="mt-10"
>风险指数</span
>
</div>
</el-col>
</el-row>
<div style="min-height: 50vh">
<div
v-for="(item, index) in personal.riskClueList"
:key="index"
>
<h5>{{ item.riskName }}</h5>
<el-table :data="item.clues">
<el-table-column
label="发生时间"
prop="eventTime"
width="180"
/>
<el-table-column
label="风险因素"
prop="riskName"
width="160"
show-overflow-tooltip
/>
<el-table-column
label="风险内容"
show-overflow-tooltip
>
<template #default="{ row }">
<span style="white-space: pre-wrap">{{
row.data
}}</span>
</template>
</el-table-column>
<el-table-column
width="80"
label="分值"
prop="scoreResult"
/>
</el-table>
</div>
</div>
<div class="mb-20"></div>
</el-scrollbar>
</el-col>
</el-row>
</el-dialog>
@ -358,7 +427,6 @@ import {
listRiskPersonnel,
getRiskPersonnel,
} from "@/api/sensitivePerception/riskPersonnel";
import { listRiskScoreRuleTree } from "@/api/sensitivePerception/riskScoreRule";
import { alarmNotificationCommit } from "~/api/work/alarm";
import feedback from "~/utils/feedback";
import { listPoliceAll } from "~/api/system/police";
@ -468,12 +536,8 @@ function reset() {
getList();
}
const rules = ref([]);
onMounted(() => {
getList();
listRiskScoreRuleTree().then((data) => {
rules.value = data;
});
});
const activeRow = ref({});
@ -483,6 +547,7 @@ const personal = ref({
async function handleShowDesc(row) {
activeRow.value = row;
activeRiskIndex.value = "";
const data = await getRiskPersonnel(row.id);
show.value = true;
personal.value = data;
@ -561,6 +626,54 @@ const tags = [
label: "推送排查人员",
value: "推送排查人员",
},
{
label: "110纠纷报警3次以上的人员",
value: "110纠纷报警3次以上的人员",
},
{
label: "执法办案嫌疑人员",
value: "执法办案嫌疑人员",
},
{
label: "矛盾纠纷排查人员",
value: "矛盾纠纷排查人员",
},
{
label: "精神疾病人员",
value: "精神疾病人员",
},
{
label: "案件受害人员",
value: "案件受害人员",
},
{
label: "刑事前科人员",
value: "刑事前科人员",
},
{
label: "吸毒涉毒人员",
value: "吸毒涉毒人员",
},
{
label: "个人极端人员",
value: "个人极端人员",
},
{
label: "四无人员",
value: "四无人员",
},
{
label: "涉酒驾人员",
value: "涉酒驾人员",
},
{
label: "借贷人员",
value: "借贷人员",
},
{
label: "违禁物品网购人员",
value: "违禁物品网购人员",
},
{
label: "其他人员",
value: "其他人员",
@ -705,23 +818,23 @@ const educations = [
const ages = [
{
label: "16~24岁",
value: "16岁至24岁",
value: "年龄处于16岁至24岁之间",
},
{
label: "25~34岁",
value: "25岁至34岁",
value: "年龄处于25岁至34岁之间",
},
{
label: "35~55岁",
value: "35岁至55岁",
value: "年龄处于35岁至55岁之间",
},
{
label: "56~65岁",
value: "56岁至65岁",
value: "年龄处于56岁至65岁之间",
},
{
label: "66~75岁",
value: "66岁至74岁",
value: "年龄处于66岁至74岁之间",
},
];
@ -788,17 +901,61 @@ function getColor(score) {
}
return "#333";
}
const riskClueScrollbarRef = ref();
const activeRiskIndex = ref("");
function handlescrollbarTo(id) {
activeRiskIndex.value = id;
riskClueScrollbarRef.value.setScrollTop(
document.getElementById(id).offsetTop
);
}
function getScoreType(score) {
if (score >= 80) {
return "red";
}
if (score >= 60) {
return "orange";
}
if (score >= 40) {
return "yellow";
}
if (score >= 20) {
return "blue";
}
return "green";
}
</script>
<style lang="scss" scoped>
.socre-box {
background: linear-gradient(180deg, #ffa36a 0%, #ff0000 100%);
border-radius: 9px;
border: 2px solid #f11d16;
height: 153px;
line-height: 153px;
text-align: center;
font-size: 124px;
font-size: 120px;
color: #fff;
&[type="red"] {
background: linear-gradient(180deg, #ffa36a 0%, #ff0000 100%);
border-color: #f11d16;
}
&[type="orange"] {
background: linear-gradient(180deg, #febf00 0%, #eca20c 100%);
border-color: #d59705;
}
&[type="yellow"] {
background: linear-gradient(180deg, #ffff00 0%, #e7ba04 100%);
border-color: #efd800;
}
&[type="blue"] {
background: linear-gradient(180deg, #01b0f1 0%, #026cf1 100%);
border-color: #0693c9;
}
&[type="green"] {
background: linear-gradient(180deg, #23e84b 0%, #07b303 100%);
border-color: #0dc916;
}
}
.person-photo {
text-align: center;
@ -823,14 +980,65 @@ function getColor(score) {
margin-bottom: 0;
}
}
.risk-first {
.risk-anchor-title {
height: 60px;
line-height: 60px;
padding: 0 20px;
color: #222;
}
.risk-second {
.risk-anchor {
height: 40px;
line-height: 40px;
box-shadow: inset 0px -1px 0px 0px #e9ebfd;
padding: 0 20px;
&:hover,
&[active="true"] {
background: #d1d7ff;
}
&[disabled=true] {
* {
color: #c2c2c2 !important;
}
}
}
.risk-clue-container {
> div:first-child {
--color: #926509;
--bg-color: #fff5df;
}
> div:nth-child(2) {
--color: #023950;
--bg-color: #e0f6ff;
}
> div:nth-child(3) {
--color: #7f0f25;
--bg-color: #f0f0f0;
}
> div {
--color: var(--primary-color);
--bg-color: #eff0f5;
h4 {
height: 58px;
line-height: 58px;
margin: 0;
background: var(--bg-color);
color: var(--color);
padding-left: 8px;
}
.second-title {
color: var(--color);
padding-left: 8px;
}
:deep() {
.el-table {
thead {
color: #333;
}
th.el-table__cell {
background: var(--bg-color);
}
}
}
}
}
</style>

125
src/views/sensitivePerception/RiskScoreRule.vue

@ -11,14 +11,17 @@
>
</div>
<div style="width: 50%">
<el-row>
</el-row>
<el-row> </el-row>
</div>
</div>
<div class="flex between mt-10 v-center">
<div>
<div><span class="text-primary">个人极端暴力风险指数</span> = ((基础因素得分 × 权重诱发因素得分 × 权重行为因素得分 × 权重管控因素得分 × 权重)) × 20</div>
<div>
<span class="text-primary">个人极端暴力风险指数</span> =
((基础因素得分 × 权重诱发因素得分 ×
权重行为因素得分 × 权重管控因素得分 × 权重))
× 20
</div>
</div>
<a
class="flex v-center gap file-link"
@ -31,14 +34,35 @@
</div>
</header>
<div class="table-container">
<el-table ref="tableRef" :default-expand-all="false" :data="scoreRules" :expand-row-keys="[]" :tree-props="{children: 'children',hasChildren: 'hasChildren'}" row-key="id">
<el-table
ref="tableRef"
:default-expand-all="false"
:data="scoreRules"
:expand-row-keys="[]"
:tree-props="{
children: 'children',
hasChildren: 'hasChildren',
}"
row-key="id"
>
<el-table-column
label="问题条目"
prop="riskName"
show-overflow-tooltip
width="180"
/>
<el-table-column label="因素分值" prop="score" width="200" align="center">
<el-table-column
label="一级指标"
prop="riskIndex"
show-overflow-tooltip
width="180"
/>
<el-table-column
label="因素分值"
prop="score"
width="200"
align="center"
>
</el-table-column>
<el-table-column
label="赋分规则"
@ -46,21 +70,15 @@
show-overflow-tooltip
>
</el-table-column>
<el-table-column
label="因素权重"
width="100"
align="center"
>
<el-table-column label="因素权重" width="100" align="center">
<template #default="{ row }">
<span v-if="row.level === 1">{{ getChildWeightSum(row) }}</span>
<span v-if="row.level === 1">{{
getChildWeightSum(row)
}}</span>
<span v-if="row.level === 2">{{ row.weight }}</span>
</template>
</el-table-column>
<el-table-column
label="开启状态"
width="100"
>
<el-table-column label="开启状态" width="100">
<template #default="{ row }">
<el-tag type="success" v-if="row.status === true"
>开启</el-tag
@ -70,7 +88,11 @@
>
</template>
</el-table-column>
<el-table-column label="最后更新时间" prop="updateTime" width="180" />
<el-table-column
label="最后更新时间"
prop="updateTime"
width="180"
/>
<el-table-column label="操作" width="160">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)"
@ -112,8 +134,27 @@
placeholder="请选择父级节点"
check-strictly
filterable
@node-click="(node) => formData.pLevel = node.level"
/>
</el-form-item>
<el-form-item
label="一级指标"
prop="riskIndex"
:rules="{
required: true,
message: '请选择一级值班',
}"
v-if="formData.pLevel === 1"
>
<el-select clearable v-model="formData.riskIndex">
<el-option
v-for="item in dict.riskIndex"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item
label="风险因素"
prop="riskName"
@ -160,10 +201,7 @@
clearable
/>
</el-form-item>
<el-form-item
label="状态"
prop="status"
>
<el-form-item label="状态" prop="status">
<el-switch
v-model="formData.status"
inline-prompt
@ -188,9 +226,13 @@ import {
listRiskScoreRuleTreeOld,
addRiskScoreRule,
updateRiskScoreRule,
delRiskScoreRule
delRiskScoreRule,
} from "@/api/sensitivePerception/riskScoreRule";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore();
const dict = catchStore.getDicts(["riskIndex"]);
const scoreRules = ref([]);
const treeOptions = ref([
@ -204,18 +246,23 @@ const treeOptions = ref([
function getList() {
listRiskScoreRuleTreeOld().then((data) => {
scoreRules.value = data;
treeOptions.value[0].children = data;
treeOptions.value[0].children = data.map((item) => {
return {
id: item.id,
riskName: item.riskName,
level: item.level
};
});
});
}
onMounted(() => {
getList();
})
getList();
});
const show = ref(false);
const formData = ref({
status: 0
status: 0,
});
const formRef = ref();
@ -249,7 +296,7 @@ function handleAdd() {
function handleEdit(row) {
show.value = true;
mode.value = "edit";
formData.value = {...row};
formData.value = { ...row };
}
const handleDelete = async (row) => {
@ -272,31 +319,33 @@ function getScoreRange(row) {
});
});
if (sorceSet.size === 0) {
return ''
return "";
}
if (sorceSet.size === 1) {
return sorceSet.values().next().value
return sorceSet.values().next().value;
}
const min = Math.min(...sorceSet);
const max = Math.max(...sorceSet);
return `${min}-${max}`
return `${min}-${max}`;
}
const loading = ref(false)
const loading = ref(false);
async function handleCalculate() {
await feedback.confirm("确定要重新计算风险指数?");
loading.value = true
await calculateScore()
loading.value = true;
await calculateScore();
feedback.msgSuccess("风险指数计算完成");
loading.value = false
loading.value = false;
}
function getChildWeightSum(row) {
const arr = row.children.filter(item => item.status).map(item => item.weight || 0);
const arr = row.children
.filter((item) => item.status)
.map((item) => item.weight || 0);
if (arr.length === 0) {
return 0;
}
return arr.reduce((a, b) => a + b).toFixed(2)
return arr.reduce((a, b) => a + b).toFixed(2);
}
</script>
<style lang="scss" scoped>

7
src/views/system/Police.vue

@ -235,7 +235,11 @@
</div>
</template>
</el-table-column>
<!-- <el-table-column label="是否有账号" width="100" align="center">
<template #default="{ row }">
<span></span>
</template>
</el-table-column> -->
<el-table-column label="操作" width="220">
<template #default="{ row }">
<el-button
@ -262,6 +266,7 @@
>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">

16
src/views/system/User.vue

@ -38,13 +38,15 @@
</el-col>
<el-col :span="6">
<div class="flex end">
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
<div>
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
</el-col>
</el-row>

69
src/views/work/Done.vue

@ -38,7 +38,7 @@
placeholder="事情简要描述"
v-model="query.thingDesc"
clearable
style="width: 280px"
style="width: 260px"
/>
<el-select
style="width: 146px"
@ -93,7 +93,7 @@
<div class="form-row flex">
<label class="text-center">核查情况</label>
<div class="flex wrap query-box">
<div style="width: 180px">
<div style="width: 200px">
<depart-tree-select
v-model="query.handleDepartId"
placeholder="办理单位"
@ -128,7 +128,7 @@
<div class="flex gap-4">
<el-select
v-model="query.blameKey"
style="width: 100px"
style="width: 90px"
@change="delete query.blameValue"
>
<el-option value="name" label="姓名" />
@ -158,6 +158,19 @@
<div class="form-row flex">
<label class="text-center">其他选项</label>
<div class="flex wrap query-box">
<el-select
style="width: 200px"
placeholder="流程阶段"
clearable
v-model="query.flowKey"
>
<el-option
v-for="item in flowNodes"
:key="item.flowKey"
:label="item.flowName"
:value="item.flowKey"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="办理状态"
@ -172,19 +185,7 @@
:value="item.dictValue"
/>
</el-select>
<el-select
style="width: 150px"
placeholder="流程阶段"
clearable
v-model="query.flowKey"
>
<el-option
v-for="item in flowNodes"
:key="item.flowKey"
:label="item.flowName"
:value="item.flowKey"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="是否超时"
@ -194,6 +195,22 @@
<el-option label="未超时" :value="false" />
<el-option label="已超时" :value="true" />
</el-select>
<div class="flex gap-4">
<el-select
v-model="query.responderKey"
style="width: 90px"
@change="delete query.responderValue"
>
<el-option value="name" label="姓名" />
<el-option value="phone" label="电话" />
</el-select>
<el-input
placeholder="投诉反映人"
v-model="query.responderValue"
clearable
style="width: 190px"
/>
</div>
<el-select
style="width: 120px"
placeholder="申请延期"
@ -204,30 +221,14 @@
<el-option label="未申请" :value="false" />
</el-select>
<el-select
style="width: 146px"
placeholder="下发单位层级"
style="width: 140px"
placeholder="下发单位层级"
clearable
v-model="query.crtDepartLevel"
>
<el-option label="市局下发" :value="0" />
<el-option label="二级机构下发" :value="2" />
</el-select>
<div class="flex gap-4">
<el-select
v-model="query.responderKey"
style="width: 90px"
@change="delete query.responderValue"
>
<el-option value="name" label="姓名" />
<el-option value="phone" label="电话" />
</el-select>
<el-input
placeholder="投诉反映人"
v-model="query.responderValue"
clearable
style="width: 160px"
/>
</div>
</div>
</div>
</el-form>

65
src/views/work/Query.vue

@ -38,7 +38,7 @@
placeholder="事情简要描述"
v-model="query.thingDesc"
clearable
style="width: 280px"
style="width: 260px"
/>
<el-select
style="width: 146px"
@ -93,7 +93,7 @@
<div class="form-row flex">
<label class="text-center">核查情况</label>
<div class="flex wrap query-box">
<div style="width: 180px">
<div style="width: 200px">
<depart-tree-select
v-model="query.handleDepartId"
placeholder="办理单位"
@ -128,7 +128,7 @@
<div class="flex gap-4">
<el-select
v-model="query.blameKey"
style="width: 100px"
style="width: 90px"
@change="delete query.blameValue"
>
<el-option value="name" label="姓名" />
@ -147,6 +147,19 @@
<div class="form-row flex">
<label class="text-center">其他选项</label>
<div class="flex wrap query-box">
<el-select
style="width: 200px"
placeholder="流程阶段"
clearable
v-model="query.flowKey"
>
<el-option
v-for="item in flowNodes"
:key="item.flowKey"
:label="item.flowName"
:value="item.flowKey"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="办理状态"
@ -161,19 +174,7 @@
:value="item.dictValue"
/>
</el-select>
<el-select
style="width: 150px"
placeholder="流程阶段"
clearable
v-model="query.flowKey"
>
<el-option
v-for="item in flowNodes"
:key="item.flowKey"
:label="item.flowName"
:value="item.flowKey"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="是否超时"
@ -183,6 +184,22 @@
<el-option label="未超时" :value="false" />
<el-option label="已超时" :value="true" />
</el-select>
<div class="flex gap-4">
<el-select
v-model="query.responderKey"
style="width: 90px"
@change="delete query.responderValue"
>
<el-option value="name" label="姓名" />
<el-option value="phone" label="电话" />
</el-select>
<el-input
placeholder="投诉反映人"
v-model="query.responderValue"
clearable
style="width: 190px"
/>
</div>
<el-select
style="width: 120px"
placeholder="申请延期"
@ -201,22 +218,6 @@
<el-option label="市局下发" :value="0" />
<el-option label="二级机构下发" :value="2" />
</el-select>
<div class="flex gap-4">
<el-select
v-model="query.responderKey"
style="width: 90px"
@change="delete query.responderValue"
>
<el-option value="name" label="姓名" />
<el-option value="phone" label="电话" />
</el-select>
<el-input
placeholder="投诉反映人"
v-model="query.responderValue"
clearable
style="width: 160px"
/>
</div>
</div>
</div>
</el-form>

80
src/views/work/Todo.vue

@ -38,7 +38,7 @@
placeholder="事情简要描述"
v-model="query.thingDesc"
clearable
style="width: 280px"
style="width: 260px"
/>
<el-select
style="width: 146px"
@ -93,7 +93,7 @@
<div class="form-row flex">
<label class="text-center">核查情况</label>
<div class="flex wrap query-box">
<div style="width: 180px">
<div style="width: 200px">
<depart-tree-select
v-model="query.handleDepartId"
placeholder="办理单位"
@ -128,7 +128,7 @@
<div class="flex gap-4">
<el-select
v-model="query.blameKey"
style="width: 100px"
style="width: 90px"
@change="delete query.blameValue"
>
<el-option value="name" label="姓名" />
@ -142,13 +142,10 @@
style="width: 190px"
/>
</div>
<el-select
placeholder="处置结果"
v-model="query.handleResultCode"
clearable
style="width: 280px"
multiple
>
<el-select placeholder="处置结果"
v-model="query.handleResultCode"
clearable
style="width: 280px" multiple>
<el-option
v-for="item in dict.handleResult"
:key="item.id"
@ -161,6 +158,19 @@
<div class="form-row flex">
<label class="text-center">其他选项</label>
<div class="flex wrap query-box">
<el-select
style="width: 200px"
placeholder="流程阶段"
clearable
v-model="query.flowKey"
>
<el-option
v-for="item in flowNodes"
:key="item.flowKey"
:label="item.flowName"
:value="item.flowKey"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="办理状态"
@ -175,19 +185,7 @@
:value="item.dictValue"
/>
</el-select>
<el-select
style="width: 150px"
placeholder="流程阶段"
clearable
v-model="query.flowKey"
>
<el-option
v-for="item in flowNodes"
:key="item.flowKey"
:label="item.flowName"
:value="item.flowKey"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="是否超时"
@ -197,6 +195,22 @@
<el-option label="未超时" :value="false" />
<el-option label="已超时" :value="true" />
</el-select>
<div class="flex gap-4">
<el-select
v-model="query.responderKey"
style="width: 90px"
@change="delete query.responderValue"
>
<el-option value="name" label="姓名" />
<el-option value="phone" label="电话" />
</el-select>
<el-input
placeholder="投诉反映人"
v-model="query.responderValue"
clearable
style="width: 190px"
/>
</div>
<el-select
style="width: 120px"
placeholder="申请延期"
@ -207,30 +221,14 @@
<el-option label="未申请" :value="false" />
</el-select>
<el-select
style="width: 146px"
placeholder="下发单位层级"
style="width: 140px"
placeholder="下发单位层级"
clearable
v-model="query.crtDepartLevel"
>
<el-option label="市局下发" :value="0" />
<el-option label="二级机构下发" :value="2" />
</el-select>
<div class="flex gap-4">
<el-select
v-model="query.responderKey"
style="width: 90px"
@change="delete query.responderValue"
>
<el-option value="name" label="姓名" />
<el-option value="phone" label="电话" />
</el-select>
<el-input
placeholder="投诉反映人"
v-model="query.responderValue"
clearable
style="width: 160px"
/>
</div>
</div>
</div>
</el-form>

Loading…
Cancel
Save