Browse Source

fit 优化风险人员库查询

main
wxc 1 year ago
parent
commit
02a4782dd8
  1. 2
      src/components/home/work/my-alarm.vue
  2. 283
      src/components/negative/add.vue
  3. 6
      src/components/negative/confirmation-completion.vue
  4. 6
      src/components/negative/dialog.vue
  5. 176
      src/components/query-select-row.vue
  6. 86
      src/components/query-select.vue
  7. 4
      src/layout/components/Header.vue
  8. 2
      src/utils/util.ts
  9. 319
      src/views/sensitivePerception/Model.vue
  10. 11
      src/views/sensitivePerception/ModelClue.vue
  11. 2
      src/views/sensitivePerception/ModelClueManual.vue
  12. 12
      src/views/sensitivePerception/RiskClue.vue
  13. 357
      src/views/sensitivePerception/RiskPersonnel.vue
  14. 19
      src/views/sensitivePerception/RiskScoreRule.vue
  15. 2
      src/views/work/Query.vue
  16. 18
      src/views/work/Todo.vue

2
src/components/home/work/my-alarm.vue

@ -1,5 +1,5 @@
<template> <template>
<div class="table-container" v-loading="loading"> <div class="table-container">
<el-table :data="data"> <el-table :data="data">
<el-table-column label="提醒时间" prop="alarmTime" width="170" /> <el-table-column label="提醒时间" prop="alarmTime" width="170" />
<el-table-column label="提醒类型" prop="alarmType" width="90" /> <el-table-column label="提醒类型" prop="alarmType" width="90" />

283
src/components/negative/add.vue

@ -293,170 +293,147 @@
tips="为便于“办理单位”更全面了解问题详情,请上传相关附件,如现场督察、数字督察等相关照片、视频及其他佐证材料。" tips="为便于“办理单位”更全面了解问题详情,请上传相关附件,如现场督察、数字督察等相关照片、视频及其他佐证材料。"
/> />
</el-form-item> </el-form-item>
<el-form-item label="流程" prop=""> </div>
<el-switch <el-divider />
v-model="form.flowFlag" <h2>办理单位</h2>
inline-prompt <div class="add-negation-container">
active-text="开启" <el-form-item
inactive-text="关闭" label="主办层级"
:active-value="true" prop="hostLevel"
:inactive-value="false" :rules="{
required: true,
message: '请选择主办层级',
trigger: ['blur'],
}"
>
<el-select
style="width: 280px"
v-model="form.hostLevel"
@change="handleChangeHostLevel"
>
<el-option
v-for="item in dict.hostLevel"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<div class="tips mt-10">
<p>如主办层级 市局主办 则由<span :danger="form.hostLevel === HostLevel.FIRST">督察支队</span>办理</p>
<p>
如主办层级为
二级机构主办则由<span :danger="form.hostLevel === HostLevel.SECOND">督察部门</span>办理可进一步下发
</p>
<p>
如主办层级为 三级机构主办则由<span :danger="form.hostLevel === HostLevel.THREE">所队</span>办理
</p>
</div>
</el-form-item>
<el-form-item
label="指定办理单位"
prop="departId"
:rules="{
required: true,
message: '请选择办理单位',
trigger: ['blur'],
}"
>
<div class="flex gap">
<div style="width: 280px">
<template
v-if="form.hostLevel === HostLevel.THREE"
>
<depart-tree-select
v-model="form.departId"
v-loading="departLoading"
/>
</template>
<el-tree-select
v-else
:data="departs"
:props="{
label: 'shortName',
value: 'id',
}"
node-key="id"
clearable
filterable
v-model="form.departId"
@node-click="handleSelectDepart"
check-strictly
style="width: 280px"
v-loading="departLoading"
/>
</div>
<el-button
type="primary"
@click="handleLinkDepart"
text
v-if="form.hostLevel !== HostLevel.FIRST"
>关联问题涉及单位</el-button
>
</div>
<div class="tips mt-10">
<p>问题涉及单位 指与该问题相关的单位</p>
<p>指定办理单位 指将问题分派给哪个单位办理</p>
</div>
</el-form-item>
</div>
<h2>办理时限</h2>
<div class="add-negation-container">
<el-form-item
label="办理时限"
prop="timeLimit"
:rules="{
required: true,
message: '请选择办理时限',
trigger: ['blur'],
}"
>
<time-limit-select
v-model="form.timeLimit"
v-model:maxSignDuration="form.maxSignDuration"
v-model:maxHandleDuration="form.maxHandleDuration"
v-model:maxExtensionDuration="
form.maxExtensionDuration
"
/> />
</el-form-item> </el-form-item>
</div> </div>
<template v-if="form.flowFlag"> <div>
<el-divider /> <h2>审批流程</h2>
<h2>办理单位</h2>
<div class="add-negation-container"> <div class="add-negation-container">
<el-form-item <el-form-item
label="主办层级" label="审批流程"
prop="hostLevel" prop="approvalFlow"
:rules="{ :rules="{
required: true, required: true,
message: '请选择主办层级', message: '请选择审批流程',
trigger: ['blur'], trigger: ['blur'],
}" }"
> >
<el-select <el-radio-group v-model="form.approvalFlow">
style="width: 280px" <el-radio
v-model="form.hostLevel" v-for="item in dict.approvalFlow"
@change="handleChangeHostLevel" :key="item.dictCode"
>
<el-option
v-for="item in dict.hostLevel"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue" :value="item.dictValue"
/> >{{ item.dictLabel
</el-select> }}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</el-radio-group>
<div class="tips mt-10"> <div class="tips mt-10">
<p> <p>
如主办层级 市局主办 三级审核 在问题提交办结时需经过所队>二级机构>市局三级审核通过后方可办结
则由督察支队办理
</p> </p>
<p> <p>
如主办层级为 二级机构主办则由督察部门办理可进一步下发 二级审核 在问题提交办结时仅需经过所队>二级机构两级审核通过后即可办结
</p>
<p style="color: var(--danger-color)">
如主办层级为 三级机构主办则由所队办理
</p>
</div>
</el-form-item>
<el-form-item
label="指定办理单位"
prop="departId"
:rules="{
required: true,
message: '请选择办理单位',
trigger: ['blur'],
}"
>
<div class="flex gap">
<div style="width: 280px">
<template
v-if="
form.hostLevel === HostLevel.THREE
"
>
<depart-tree-select
v-model="form.departId"
v-loading="departLoading"
/>
</template>
<el-tree-select
v-else
:data="departs"
:props="{
label: 'shortName',
value: 'id',
}"
node-key="id"
clearable
filterable
v-model="form.departId"
@node-click="handleSelectDepart"
check-strictly
style="width: 280px"
v-loading="departLoading"
/>
</div>
<el-button
type="primary"
@click="handleLinkDepart"
text
v-if="form.hostLevel !== HostLevel.FIRST"
>关联问题涉及单位</el-button
>
</div>
<div class="tips mt-10">
<p>问题涉及单位 指与该问题相关的单位</p>
<p>
指定具体办理单位
指将问题分派给哪个单位办理
</p> </p>
</div> </div>
</el-form-item> </el-form-item>
</div> </div>
<h2>办理时限</h2> </div>
<div class="add-negation-container">
<el-form-item
label="办理时限"
prop="timeLimit"
:rules="{
required: true,
message: '请选择办理时限',
trigger: ['blur'],
}"
>
<time-limit-select
v-model="form.timeLimit"
v-model:maxSignDuration="form.maxSignDuration"
v-model:maxHandleDuration="
form.maxHandleDuration
"
v-model:maxExtensionDuration="
form.maxExtensionDuration
"
/>
</el-form-item>
</div>
<div>
<h2>审批流程</h2>
<div class="add-negation-container">
<el-form-item
label="审批流程"
prop="approvalFlow"
:rules="{
required: true,
message: '请选择审批流程',
trigger: ['blur'],
}"
>
<el-radio-group v-model="form.approvalFlow">
<el-radio
v-for="item in dict.approvalFlow"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark
? `(${item.remark})`
: ""
}}</el-radio
>
</el-radio-group>
<div class="tips mt-10">
<p>
三级审核 在问题提交办结时需经过所队>二级机构>市局三级审核通过后方可办结
</p>
<p>
二级审核 在问题提交办结时仅需经过所队>二级机构两级审核通过后即可办结
</p>
</div>
</el-form-item>
</div>
</div>
</template>
</el-form> </el-form>
</el-scrollbar> </el-scrollbar>
<footer class="flex end"> <footer class="flex end">
@ -509,8 +486,7 @@ const form = ref({
thingFiles: [], thingFiles: [],
hostLevel: HostLevel.THREE, hostLevel: HostLevel.THREE,
timeLimit: TimeLimit.WORK_137, timeLimit: TimeLimit.WORK_137,
approvalFlow: ApprovalFlow.SECOND, approvalFlow: ApprovalFlow.SECOND
flowFlag: true
}); });
watch( watch(
@ -547,7 +523,7 @@ async function handleAddNegative() {
thingFiles: [], thingFiles: [],
hostLevel: HostLevel.THREE, hostLevel: HostLevel.THREE,
timeLimit: TimeLimit.WORK_137, timeLimit: TimeLimit.WORK_137,
approvalFlow: ApprovalFlow.SECOND, approvalFlow: ApprovalFlow.SECOND
}; };
feedback.msgSuccess("下发成功"); feedback.msgSuccess("下发成功");
emit("close"); emit("close");
@ -571,8 +547,10 @@ function handleSelectDepart(row, node) {
function handleLinkDepart() { function handleLinkDepart() {
if (form.value.hostLevel === HostLevel.SECOND) { if (form.value.hostLevel === HostLevel.SECOND) {
feedback.msgWarning('当前选择二级机构主办,指定办理单位请选择二级机构!') feedback.msgWarning(
return "当前选择二级机构主办,指定办理单位请选择二级机构!"
);
return;
} }
form.value.departId = form.value.involveDepartId; form.value.departId = form.value.involveDepartId;
form.value.departName = form.value.involveDepartName; form.value.departName = form.value.involveDepartName;
@ -595,6 +573,11 @@ function disabledDate(time) {
.add-negation-container { .add-negation-container {
padding: 0 60px; padding: 0 60px;
} }
.tips {
[danger=true] {
color: var(--danger-color);
}
}
:deep() { :deep() {
.el-form-item__content { .el-form-item__content {
flex-direction: column; flex-direction: column;

6
src/components/negative/confirmation-completion.vue

@ -64,8 +64,6 @@
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ item.dictLabel >{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio }}</el-radio
> >
</el-radio-group> </el-radio-group>
@ -151,8 +149,6 @@
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ item.dictLabel >{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio }}</el-radio
> >
</el-radio-group> </el-radio-group>
@ -176,8 +172,6 @@
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ item.dictLabel >{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio }}</el-radio
> >
</el-radio-group> </el-radio-group>

6
src/components/negative/dialog.vue

@ -91,7 +91,7 @@
getDictLable( getDictLable(
dict.timeLimit, dict.timeLimit,
negative.timeLimit negative.timeLimit
) ) || '/'
}}</span> }}</span>
</div> </div>
<div class="col col-24" style="--label-width: 60px"> <div class="col col-24" style="--label-width: 60px">
@ -100,7 +100,7 @@
getDictLable( getDictLable(
dict.hostLevel, dict.hostLevel,
negative.hostLevel negative.hostLevel
) ) || '/'
}}</span> }}</span>
</div> </div>
<div class="col col-24" style="--label-width: 60px"> <div class="col col-24" style="--label-width: 60px">
@ -109,7 +109,7 @@
getDictLable( getDictLable(
dict.approvalFlow, dict.approvalFlow,
negative.approvalFlow negative.approvalFlow
) ) || '/'
}}</span> }}</span>
</div> </div>
</div> </div>

176
src/components/query-select-row.vue

@ -1,176 +0,0 @@
<template>
<div class="query-select flex" :multiple="multiple">
<label
class="text-center query-select-label"
:style="{ width: `${labelWidth}px` }"
>{{ label }}</label
>
<div
class="query-select-body"
:style="{ width: `calc(100% - ${labelWidth}px)` }"
>
<div class="flex gap">
<div class="query-select-content">
<el-checkbox-group v-model="checkList" class="flex wrap">
<template v-if="multiple">
<el-checkbox
size="small"
v-for="item in data"
:key="item.value"
:label="item.value"
>
<span class="text-primary mr-8">{{
item.text
}}</span>
<span class="total">{{ item.total }}</span>
</el-checkbox>
</template>
<template v-else>
<div
class="flex v-center gap query-select-item pointer"
v-for="item in more? data : data.slice(0, 10)"
:key="item.value"
@click="check(item.value)"
>
<span class="text-primary">{{
item.text
}}</span>
<span class="total">{{ item.total }}</span>
</div>
</template>
</el-checkbox-group>
</div>
<div class="flex end query-select-tools">
<el-button
size="small"
v-if="data.length > 13 && !multiple"
@click="more = !more"
class="more-btn"
:more="more"
>{{ more? '收起' : '更多' }}<icon name="el-icon-ArrowDown" class="ml-4" /></el-button>
<el-button
size="small"
@click="multiple = true"
v-if="!multiple"
><icon
name="el-icon-plus"
class="mr-4"
/></el-button
>
</div>
</div>
<div v-if="multiple" class="flex center">
<el-button type="primary" size="small" @click="submit">确定</el-button>
<el-button size="small" @click="multiple = false"
>取消</el-button
>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
label: {
type: String,
default: "",
},
labelWidth: {
type: Number,
default: 126,
},
data: {
type: Array,
default: [],
},
modelValue: {
type: Array,
default: [],
},
});
const emit = defineEmits(["update:modelValue", "update"]);
const more = ref(false);
const multiple = ref(false);
watch(multiple, (val) => {
more.value = val;
});
const checkList = ref([]);
function check(val) {
if (!multiple.value) {
emit("update:modelValue", [val]);
emit("update");
}
const index = checkList.value.indexOf(val);
if (index === -1) {
checkList.value.push(val);
} else {
checkList.value.slice(index, 1);
}
}
function submit() {
emit("update:modelValue", checkList.value);
emit("update");
multiple.value = false
}
</script>
<style lang="scss" scoped>
.query-select {
box-shadow: inset 0px -1px 0px 0px #ebebeb;
&[multiple="true"] {
border: 1px solid #19257d;
.query-select-label {
background: #e8ebfd;
}
}
.query-select-label {
padding: 8px 0;
}
}
.query-select-body {
padding: 8px 0;
.query-select-tools {
width: 140px;
}
.el-button + .el-button {
margin-left: 8px;
}
}
.query-select-content {
width: calc(100% - 130px);
.el-checkbox-group {
font-size: inherit;
line-height: inherit;
padding: 0 20px;
gap: 8px 20px;
.el-checkbox {
margin-right: 0;
}
}
.text-primary {
font-size: 14px;
}
.total {
font-size: 12px;
color: #666;
}
}
.query-select-item {
&:hover {
.text-primary {
font-weight: 700;
}
}
}
.more-btn {
.el-icon {
transition: .6s;
}
&[more=true] {
.el-icon {
transform: rotate(180deg);
}
}
}
</style>

86
src/components/query-select.vue

@ -0,0 +1,86 @@
<template>
<div class="query-row flex v-center">
<label class="text-center">{{ label }}</label>
<div class="flex gap query-check wrap">
<span v-for="item in data" :key="item" class="text-primary" @click="handleCheck(item.value)" :check="values.indexOf(item.value) > -1">{{
item.label
}}</span>
</div>
</div>
</template>
<script setup>
const props = defineProps({
label: {
type: String
},
data: {
type: Array,
default: []
},
modelValue: {
type: Array,
default: []
}
});
const emit = defineEmits(['update:modelValue', 'change'])
const values = ref(props.modelValue || [])
watch(() => props.modelValue, (val) => {
if (!val || val.length === 0) {
values.value = []
}
})
function handleCheck(val) {
const index = values.value.indexOf(val);
if (index === -1) {
if (event.ctrlKey) {
values.value.push(val)
} else {
values.value = []
values.value.push(val)
}
} else {
values.value.splice(index, 1)
}
emit('update:modelValue', values.value)
emit('change')
}
</script>
<style lang="scss" scoped>
.query-row {
padding: 8px 0;
box-shadow: inset 0px -1px 0px 0px #ebebeb;
label {
width: 126px;
line-height: 24px;
& + * {
width: calc(100% - 126px);
}
}
.el-form-item {
margin-bottom: 0;
}
}
.query-check {
gap: 4px;
span {
padding: 2px 4px;
border: 1px solid transparent;
border-radius: 4px;
&:hover, &[check=true] {
cursor: pointer;
background-color: #e8e9f3;
}
&[check=true] {
border-color: var(--primary-color);
background-color: #e8e9f3;
}
}
}
</style>

4
src/layout/components/Header.vue

@ -16,10 +16,10 @@
</section> </section>
</header> </header>
<ul class="userinfo-dropdown" v-if="dropdownShow"> <ul class="userinfo-dropdown" v-if="dropdownShow">
<li class="flex gap v-center" @click="openHelp"> <!-- <li class="flex gap v-center" @click="openHelp">
<icon name="local-icon-question" :size="22" /> <icon name="local-icon-question" :size="22" />
<span>帮助手册</span> <span>帮助手册</span>
</li> </li> -->
<li class="flex gap v-center" @click="supportShow = true"> <li class="flex gap v-center" @click="supportShow = true">
<icon name="el-icon-Star" :size="22" /> <icon name="el-icon-Star" :size="22" />
<span>技术支持</span> <span>技术支持</span>

2
src/utils/util.ts

@ -367,7 +367,7 @@ export function getInvolveProblem(values, dicts) {
if (!values) { if (!values) {
return '' return ''
} }
return values.split(",").map(val => dicts.find(item => item.dictValue === val).dictLabel).join("、") return values.split(",").map(val => dicts.find(item => item.dictValue === val)?.dictLabel).join("、")
} }
export function getGenderFromIdCode(idCode) { export function getGenderFromIdCode(idCode) {

319
src/views/sensitivePerception/Model.vue

@ -13,14 +13,16 @@
:active="query.classId === item.id" :active="query.classId === item.id"
> >
<span :title="item.name">{{ item.name }}</span> <span :title="item.name">{{ item.name }}</span>
<span class="ml-8 text-primary text-bold">{{ item.size }}</span> <span class="ml-8 text-primary text-bold">{{
item.size
}}</span>
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :span="20"> <el-col :span="20">
<el-form :label-width="140"> <el-form :label-width="140">
<el-row> <el-row>
<el-col :span="8"> <el-col :span="9">
<el-form-item label="模型名称"> <el-form-item label="模型名称">
<el-input <el-input
placeholder="请输入" placeholder="请输入"
@ -64,8 +66,13 @@
</div> </div>
</div> </div>
<div> <div>
<el-row :gutter="18"> <el-row :gutter="17">
<el-col :span="8" v-for="item in list" class="mb-18"> <el-col
:span="8"
v-for="item in list"
:key="item"
class="mb-18"
>
<div class="model-card" @click="openDetail(item)"> <div class="model-card" @click="openDetail(item)">
<div class="flex v-center"> <div class="flex v-center">
<div <div
@ -204,100 +211,88 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-row> <el-form-item
<el-col :span="12"> label="模型分类"
<el-form-item prop="modelType"
label="模型类型" :rules="{
prop="classId" required: true,
:rules="{ message: '请选择模型分类',
required: true, }"
message: '请选择模型类型', >
}" <el-radio-group v-model="form.modelType">
> <el-radio
<el-select v-model="form.classId" style="width: 340px"> v-for="item in dict.modelType"
<el-option :key="item.dictCode"
v-for="item in classes" :value="item.dictValue"
:key="item.id" >{{ item.dictLabel }}</el-radio
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="风险因素"
:rules="{
required: true,
message: '请选择风险因素',
}"
prop="riskScoreRuleId"
v-if="form.classId === GRJDBLFX_CLASS_ID"
>
<el-tree-select
class="flex-1"
v-model="form.riskScoreRuleId"
:data="treeOptions"
clearable
node-key="id"
:props="{
label: 'riskName',
}"
placeholder="请选择风险因素"
filterable
style="width: 340px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row >
<el-col :span="12">
<el-form-item
label="数据类型"
prop="modelDataType"
:rules="{
required: true,
message: '请选择数据类型',
}"
>
<el-radio-group
v-model="form.modelDataType"
class="block"
>
<el-radio
v-for="item in dict.modelDataType"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="通知类型"
prop="modelDataType"
:rules="{
required: true,
message: '请选择通知类型',
}"
v-if="form.modelDataType === '2'"
> >
<el-select </el-radio-group>
style="width: 280px" </el-form-item>
clearable <el-divider />
v-model="form.warningHandling"
>
<el-option label="预警处置" :value="1" />
<el-option label="提醒通知" :value="2" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item
label="模型类型"
prop="classId"
:rules="{
required: true,
message: '请选择模型类型',
}"
>
<el-select v-model="form.classId" style="width: 340px">
<el-option
v-for="item in classes"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item
label="风险因素"
:rules="{
required: true,
message: '请选择风险因素',
}"
prop="riskScoreRuleId"
v-if="form.modelType === '2'"
>
<el-tree-select
class="flex-1"
v-model="form.riskScoreRuleId"
:data="treeOptions"
clearable
node-key="id"
:props="{
label: 'riskName',
}"
placeholder="请选择风险因素"
filterable
style="width: 340px"
/>
</el-form-item>
<el-form-item
label="预警类型"
prop="modelDataType"
:rules="{
required: true,
message: '请选择预警类型',
}"
>
<el-radio-group v-model="form.modelDataType" class="block">
<el-radio value="1">{{
form.modelType === "2" ? "预警处置" : "预警问题"
}}</el-radio>
<el-radio value="2">提醒通知</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="说明"
v-if="form.modelType === '2' && form.modelDataType === '1'"
>
<div style="line-height: 1.4">
通过情指行一体化平台进行处置反馈
</div>
</el-form-item>
<el-form-item <el-form-item
label="分发方式" label="分发方式"
prop="distributionMethod" prop="distributionMethod"
@ -305,23 +300,24 @@
required: true, required: true,
message: '请选择分发方式', message: '请选择分发方式',
}" }"
v-if="form.classId !== GRJDBLFX_CLASS_ID" v-if="form.modelType === '1' && form.modelDataType === '1'"
> >
<el-radio-group v-model="form.distributionMethod" class="block"> <el-radio-group v-model="form.distributionMethod" class="block">
<el-radio <el-radio
v-for="item in dict.distributionMethod" v-for="item in dict.distributionMethod"
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ item.dictLabel >{{ item.dictLabel }}</el-radio
}}{{ item.remark ? `(${item.remark})` : "" }}</el-radio
> >
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<template <template
v-if=" v-if="
form.modelType === '1' &&
form.modelDataType === '1' &&
form.distributionMethod === form.distributionMethod ===
DistributionMethod.DIRECTLY_DISTRIBUTE DistributionMethod.DIRECTLY_DISTRIBUTE
" "
> >
<el-divider /> <el-divider />
@ -341,10 +337,7 @@
v-for="item in dict.distributionCycle" v-for="item in dict.distributionCycle"
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ item.dictLabel >{{ item.dictLabel }}</el-radio
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
> >
</el-radio-group> </el-radio-group>
<div class="flex ml-20" v-if="form.distributionCycle"> <div class="flex ml-20" v-if="form.distributionCycle">
@ -393,16 +386,7 @@
</el-form-item> </el-form-item>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="指定办理单位" prop="departId">
<div class="flex gap">
<div style="width: 280px">
<depart-tree-select v-model="form.handleDepartId" />
</div>
<div class="tips mt-10">
<p>指定具体办理单位 指将问题分派给哪个单位办理</p>
</div>
</div>
</el-form-item>
<el-form-item <el-form-item
label="业务类别" label="业务类别"
prop="businessTypeCode" prop="businessTypeCode"
@ -528,10 +512,7 @@
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 >{{ item.dictLabel }}</el-radio
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
> >
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
@ -548,20 +529,96 @@
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 }}</el-radio
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
> >
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</template> </template>
<template v-if="form.modelDataType === '2'">
<el-form-item label="提示"> <el-form-item
<div style="line-height: 1.4"> label="回复方式"
预警数据将以任务形式分批下发至相关单位处理每次下发的预警数据都会在任务分发模块中生成一条记录任务名称将按照模型名称_下发时间的格式命名例如取保候审期间未按要求传讯犯罪嫌疑人_20240919 :rules="{
</div> required: true,
</el-form-item> message: '请选择回复方式',
}"
>
<el-switch
v-model="form.requestReply"
inline-prompt
active-text="必须回复"
inactive-text="消息确认"
:active-value="true"
:inactive-value="false"
/>
</el-form-item>
<el-form-item
label="时限设置"
prop=""
:rules="{
required: true,
message: '请选择时限设置',
}"
>
<div class="flex gap">
<el-input style="width: 100px" type="number" v-model="form" /><span
>工作日</span
>
</div>
</el-form-item>
</template>
<template
v-if="
(form.modelType === '1' &&
form.modelDataType === '1' &&
form.distributionMethod ===
DistributionMethod.DIRECTLY_DISTRIBUTE) ||
form.modelDataType === '2'
"
>
<el-form-item
label="通知单位"
prop="handleDepartType"
:rules="{
required: true,
message: '请选择通知单位',
}"
>
<div>
<el-radio-group
v-model="form.handleDepartType"
class="block"
style="width: 270px"
>
<el-radio value="1">问题涉及单位</el-radio>
<el-radio value="2">指定单位</el-radio>
</el-radio-group>
<div class="tips">
<span class="text-danger mr-8">说明</span>
<span style="line-height: 1.2"
>选择问题涉及单位直接将通知发送至该问题的涉及单位选择指定单位则将通知发送至指定单位</span
>
</div>
</div>
</el-form-item>
<el-form-item
label="指定单位"
prop="handleDepartId"
v-if="form.handleDepartType === '2'"
:rules="{
required: true,
message: '请选择指定单位',
}"
>
<div class="flex gap">
<div style="width: 280px">
<depart-tree-select v-model="form.handleDepartId" />
</div>
<div class="tips mt-10">
<p>指定具体办理单位 指将问题分派给哪个单位办理</p>
</div>
</div>
</el-form-item>
</template>
</el-form> </el-form>
<footer class="flex end"> <footer class="flex end">
<el-button @click="show = false" size="large">取消</el-button> <el-button @click="show = false" size="large">取消</el-button>
@ -820,6 +877,7 @@ const dict = catchStore.getDicts([
"businessType", "businessType",
"suspectProblem", "suspectProblem",
"policeType", "policeType",
"modelType",
]); ]);
// //
@ -872,6 +930,7 @@ const mode = ref("add");
const form = ref({ const form = ref({
distributionMethod: "1", distributionMethod: "1",
problems: [], problems: [],
requestReply: true
}); });
watch(mode, (val) => { watch(mode, (val) => {
@ -884,6 +943,7 @@ function initForm() {
form.value = { form.value = {
distributionMethod: "1", distributionMethod: "1",
problems: [], problems: [],
requestReply: true
}; };
} }
const formRef = ref(null); const formRef = ref(null);
@ -972,14 +1032,13 @@ function goClue() {
}); });
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.menu { .menu {
> div { > div {
height: 47px; height: 47px;
line-height: 47px; line-height: 47px;
padding-left: 36px; padding-left: 16px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;

11
src/views/sensitivePerception/ModelClue.vue

@ -107,15 +107,12 @@
<el-table-column <el-table-column
label="分发状态" label="分发状态"
align="center" align="center"
width="120" width="130"
> >
<template #default="{ row }"> <template #default="{ row }">
<span>{{ <el-tag v-if="row.distributionState === '0'" type="info">未分发</el-tag>
getDictLable( <el-tag v-if="row.distributionState === '1'" type="success">已分发</el-tag>
dict.distributionState, <el-tag v-if="row.distributionState === '2'">已处置{{ row.negativeId ? '' : '(未分发)' }}</el-tag>
row.distributionState
)
}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="180"> <el-table-column label="操作" width="180">

2
src/views/sensitivePerception/ModelClueManual.vue

@ -420,7 +420,7 @@
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ item.dictLabel >{{ item.dictLabel
}}{{ item.remark ? `(${item.remark})` : "" }}</el-radio }}</el-radio
> >
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>

12
src/views/sensitivePerception/RiskClue.vue

@ -44,7 +44,12 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
<div class="flex end mb-20"> <div class="flex between mb-20">
<el-button type="primary" @click="addShow = true"
><template #icon>
<icon name="el-icon-Plus" /> </template
>风险问题录入</el-button
>
<div> <div>
<el-button type="primary" @click="getList"> <el-button type="primary" @click="getList">
<template #icon> <template #icon>
@ -223,7 +228,7 @@ let formData2 = ref({
blameEmpNo: "", blameEmpNo: "",
blames: {}, blames: {},
level: -1, level: -1,
requestReply: true requestReply: true,
}); });
let police = ref({}); let police = ref({});
let polices = ref([]); let polices = ref([]);
@ -351,6 +356,9 @@ function reset() {
query.value = {}; query.value = {};
getList(); getList();
} }
const addShow = ref(false)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
</style> </style>

357
src/views/sensitivePerception/RiskPersonnel.vue

@ -1,58 +1,68 @@
<template> <template>
<div class="container"> <div class="container">
<header> <header>
<el-form :label-width="114"> <el-form>
<el-row> <query-select
<el-col :span="6"> label="人员标签"
<el-form-item label="姓名"> :data="tags"
<el-input v-model="query.tags"
placeholder="请输入" @change="getList"
v-model="query.name" />
clearable <query-select
/> label="风险因素"
</el-form-item> :data="riskReasons"
</el-col> v-model="query.smallTags"
<el-col :span="6"> @change="getList"
<el-form-item label="身份证号"> />
<el-input <query-select
placeholder="请输入" label="学历"
v-model="query.idCode" :data="educations"
clearable v-model="query.educationTags"
/> @change="getList"
</el-form-item> />
</el-col> <query-select
<el-col :span="6"> label="年龄"
<el-form-item label="手机号"> :data="ages"
<el-input v-model="query.ageTags"
placeholder="请输入" @change="getList"
v-model="query.mobileNumber" />
clearable <div class="query-row flex v-center">
/> <label class="text-center">人员信息</label>
</el-form-item> <el-row>
</el-col> <el-col :span="5">
<el-col :span="6"> <el-form-item label="姓名">
<el-form-item label="年龄"> <el-input
<el-input size="small"
placeholder="请输入" style="width: 200px"
v-model="query.age" placeholder="请输入"
type="number" v-model="query.name"
clearable />
/> </el-form-item>
</el-form-item> </el-col>
</el-col> <el-col :span="5">
<el-col :span="6"> <el-form-item label="身份证">
<el-form-item label="人员标签"> <el-input
<el-input v-model="query.tags" placeholder="请输入" clearable /> size="small"
</el-form-item> style="width: 200px"
</el-col> placeholder="请输入"
<el-col :span="6"> v-model="query.mobileNumber"
<el-form-item label="高风险因素"> />
<el-input v-model="query.smallTags" placeholder="请输入" clearable /> </el-form-item>
</el-form-item> </el-col>
</el-col> <el-col :span="5">
</el-row> <el-form-item label="手机号">
<el-input
size="small"
style="width: 200px"
placeholder="请输入"
v-model="query.idCode"
/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form> </el-form>
<div class="mb-25 flex end"> <div class="mb-25 flex end mt-8">
<div> <div>
<el-button type="primary" @click="getList"> <el-button type="primary" @click="getList">
<template #icon> <template #icon>
@ -64,32 +74,35 @@
</div> </div>
</div> </div>
</header> </header>
<div class="table-container"> <div class="table-container" v-loading="loading">
<el-table :data="list"> <el-table :data="list">
<el-table-column label="姓名" prop="name" width="80" /> <el-table-column label="姓名" prop="name" width="70" />
<el-table-column <el-table-column
label="性别" label="性别"
prop="gender" prop="gender"
width="60" width="56"
align="center" align="center"
> >
<template #default="{ row }"> <template #default="{ row }">
<span>{{ getGender(row.gender) }}</span> <span>{{ getGender(row.gender) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="年龄" prop="age" width="60" /> <el-table-column label="年龄" prop="age" width="56" />
<el-table-column label="身份证号" prop="idCode" width="180" /> <el-table-column label="身份证号" prop="idCode" width="174" />
<el-table-column <el-table-column
label="手机号" label="手机号"
prop="mobileNumber" prop="mobileNumber"
width="120" width="116"
/> />
<el-table-column <el-table-column
label="管控单位" label="管控单位"
prop="controlDepartName" prop="controlDepartName"
width="120" width="120"
/> />
<el-table-column label="人员标签" show-overflow-tooltip> <el-table-column
label="人员标签"
width="240"
>
<template #default="{ row }"> <template #default="{ row }">
<div class="flex gap-4 wrap" v-if="row.tags"> <div class="flex gap-4 wrap" v-if="row.tags">
<el-tag <el-tag
@ -100,11 +113,11 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="高风险因素" show-overflow-tooltip> <el-table-column label="高风险因素">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex gap-4 wrap" v-if="row.smallTags"> <div class="flex gap-4 wrap" v-if="row.smallTags">
<el-tag <el-tag
type="danger" :type="getTagType(item)"
v-for="item in row.smallTags" v-for="item in row.smallTags"
:key="item" :key="item"
>{{ item }} >{{ item }}
@ -115,17 +128,19 @@
<el-table-column <el-table-column
label="高风险指数" label="高风险指数"
prop="riskScore" prop="riskScore"
width="120" width="100"
align="center" align="center"
/> />
<el-table-column label="操作" width="160"> <el-table-column label="操作" width="90">
<template #default="{ row }"> <template #default="{ row }">
<el-button <div>
type="primary" <el-button
link type="primary"
@click="handleShowDesc(row)" link
>查看详情 @click="handleShowDesc(row)"
</el-button> >查看详情
</el-button>
</div>
<el-button <el-button
type="primary" type="primary"
link link
@ -206,15 +221,15 @@
<div style="min-height: 50vh"> <div style="min-height: 50vh">
<div v-for="(item, index) in personal.riskClueList" :key="index"> <div v-for="(item, index) in personal.riskClueList" :key="index">
<h5>{{ item.riskName }}</h5> <h5>{{ item.riskName }}</h5>
<el-table :data="item.clues" max-height="300"> <el-table :data="item.clues">
<el-table-column <el-table-column
label="发生时间" label="发生时间"
prop="eventTime" prop="eventTime"
width="160" width="180"
/> />
<el-table-column <el-table-column
label="风险因素" label="风险因素"
prop="riskReason" prop="riskName"
width="160" width="160"
show-overflow-tooltip show-overflow-tooltip
/> />
@ -225,7 +240,7 @@
}}</span> }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column width="80" label="分值" prop="score" /> <el-table-column width="80" label="分值" prop="scoreResult" />
</el-table> </el-table>
</div> </div>
</div> </div>
@ -406,10 +421,13 @@ function getPolices(departId) {
}); });
} }
const loading = ref(false);
function getList() { function getList() {
loading.value = true;
listRiskPersonnel(query.value).then((data) => { listRiskPersonnel(query.value).then((data) => {
list.value = data.records; list.value = data.records;
total.value = data.total; total.value = data.total;
loading.value = false;
}); });
} }
@ -477,6 +495,187 @@ function getGender(val) {
} }
return ""; return "";
} }
const tags = [
{
label: "涉相关警情人员",
value: "涉相关警情人员",
},
{
label: "涉违法犯罪人员",
value: "涉违法犯罪人员",
},
{
label: "涉举报投诉信访人员",
value: "涉举报投诉信访人员",
},
{
label: "涉诉讼人员",
value: "涉诉讼人员",
},
{
label: "重点人员",
value: "重点人员",
},
{
label: "专项排查关注人员",
value: "专项排查关注人员",
},
{
label: "推送排查人员",
value: "推送排查人员",
},
{
label: "其他人员",
value: "其他人员",
},
];
const riskReasons = [
{
label: "在逃人员",
value: "在逃人员",
},
{
label: "重大刑事犯罪前科人员",
value: "重大刑事犯罪前科人员",
},
{
label: "肇事肇祸等严重精神障碍患者",
value: "肇事肇祸等严重精神障碍患者",
},
{
label: "个人极端案事件重点人员",
value: "个人极端案事件重点人员",
},
{
label: "涉稳人员",
value: "涉稳人员",
},
{
label: "涉毒人员",
value: "涉毒人员",
},
{
label: "重点上访人员",
value: "重点上访人员",
},
{
label: "取保候审",
value: "取保候审",
},
{
label: "监视居住",
value: "监视居住",
},
{
label: "其它潜在危害人员",
value: "其它潜在危害人员",
},
{
label: "殴打他人",
value: "殴打他人",
},
{
label: "故意伤害",
value: "故意伤害",
},
{
label: "寻衅滋事",
value: "寻衅滋事",
},
{
label: "精神障碍患者",
value: "精神障碍患者",
},
{
label: '"扬言滋事、自杀等行为”',
value: "扬言滋事、自杀等行为”",
},
{
label: "家暴",
value: "家暴",
},
{
label: "离婚",
value: "离婚",
},
{
label: "酗酒",
value: "酗酒",
},
{
label: "有车",
value: "有车",
},
{
label: "纠纷",
value: "纠纷",
},
{
label: "无业人员",
value: "无业人员",
},
];
const educations = [
{
label: "小学",
value: "小学",
},
{
label: "初中",
value: "初中",
},
{
label: "中专/高中",
value: "中专/高中",
},
{
label: "专科/本科",
value: "专科/本科",
},
{
label: "研究生以上",
value: "研究生以上",
},
];
const ages = [
{
label: "16~24岁",
value: "16岁至24岁",
},
{
label: "25~34岁",
value: "25岁至34岁",
},
{
label: "35~55岁",
value: "35岁至55岁",
},
{
label: "56~65岁",
value: "56岁至65岁",
},
{
label: "66~75岁",
value: "66岁至74岁",
},
];
function getTagType(item) {
if (item.includes('在逃') || item.includes('重大刑事犯罪') || item.includes('个人极端') || item.includes('涉稳人员')
|| item.includes('涉毒') || item.includes('重点上访人员')) {
return 'danger';
}
if (item.includes('取保候审') || item.includes('监视居住') || item.includes('其它潜在危害人员') || item.includes('殴打他人')
|| item.includes('故意伤害') || item.includes('寻衅滋事') || item.includes('精神障碍患者') || item.includes('扬言滋事')
|| item.includes('家暴') || item.includes('离婚') || item.includes('酗酒') || item.includes('纠纷') || item.includes('无业人员')) {
return 'warning';
}
return 'info'
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.socre-box { .socre-box {
@ -498,4 +697,18 @@ function getGender(val) {
max-height: 100%; max-height: 100%;
width: 200px; width: 200px;
} }
.query-row {
padding: 8px 0;
box-shadow: inset 0px -1px 0px 0px #ebebeb;
label {
width: 126px;
line-height: 24px;
& + * {
width: calc(100% - 126px);
}
}
.el-form-item {
margin-bottom: 0;
}
}
</style> </style>

19
src/views/sensitivePerception/RiskScoreRule.vue

@ -18,7 +18,7 @@
</div> </div>
<div class="flex between mt-10 v-center"> <div class="flex between mt-10 v-center">
<div> <div>
<div><span class="text-primary">个人极端暴力风险指数</span> =基础因素得分百分比 × 15%诱发因素得分百分比 × 30%行为因素得分百分比 × 45%管控因素得分百分比 × 10%</div> <div><span class="text-primary">个人极端暴力风险指数</span> = ((基础因素得分 × 权重诱发因素得分 × 权重行为因素得分 × 权重管控因素得分 × 权重)) × 20</div>
</div> </div>
<a <a
class="flex v-center gap file-link" class="flex v-center gap file-link"
@ -48,10 +48,15 @@
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="因素权重" label="因素权重"
prop="weight"
width="100" width="100"
align="center" align="center"
/> >
<template #default="{ row }">
<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 <el-table-column
label="开启状态" label="开启状态"
width="100" width="100"
@ -285,6 +290,14 @@ async function handleCalculate() {
feedback.msgSuccess("风险指数计算完成"); feedback.msgSuccess("风险指数计算完成");
loading.value = false loading.value = false
} }
function getChildWeightSum(row) {
const arr = row.children.map(item => item.weight || 0);
if (arr.length === 0) {
return 0;
}
return arr.reduce((a, b) => a + b).toFixed(2)
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.file-link { .file-link {

2
src/views/work/Query.vue

@ -273,7 +273,7 @@
getInvolveProblem( getInvolveProblem(
row.involveProblem, row.involveProblem,
dict.suspectProblem dict.suspectProblem
) ) || '/'
}}</span> }}</span>
</div> </div>
</div> </div>

18
src/views/work/Todo.vue

@ -347,12 +347,18 @@
/> />
<el-table-column label="办理状态"> <el-table-column label="办理状态">
<template #default="{ row }"> <template #default="{ row }">
<el-tag>{{ <el-tag
getDictLable( >{{
dict.processingStatus, getDictLable(
row.processingStatus dict.processingStatus,
) row.processingStatus
}}</el-tag> )
}}{{
row.extensionApplyFlag ? "" : "(延期申请)"
}}{{
row.workFlowKey === 'countersign' ? "(单位会签)" : ""
}}</el-tag
>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="流程限时" width="150" align="center"> <el-table-column label="流程限时" width="150" align="center">

Loading…
Cancel
Save