You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
315 lines
8.4 KiB
315 lines
8.4 KiB
<template> |
|
<div class="container" v-loading="loading"> |
|
<header class="mb-20"> |
|
<div class="flex between"> |
|
<div> |
|
<el-button type="primary" @click="handleAdd"> |
|
<template #icon> |
|
<icon name="el-icon-Plus"/> |
|
</template> |
|
新增 |
|
</el-button |
|
> |
|
</div> |
|
<div style="width: 50%"> |
|
<el-row> |
|
<el-col :span="12"></el-col> |
|
<el-col :span="12"> |
|
<div class="flex end"> |
|
<el-button type="primary" @click="handleCalculate"> |
|
重新计算分值 |
|
</el-button |
|
> |
|
</div> |
|
</el-col> |
|
</el-row> |
|
</div> |
|
</div> |
|
<div class="flex between mt-10"> |
|
<div> |
|
<div class="text-primary mt-10 mb-10">赋分分公式如下</div> |
|
<div> |
|
问题风险值 = 基础风险值+(基础风险值×问题严重等级系数)+(基础风险值×问题发生频次系数) |
|
</div> |
|
</div> |
|
<a |
|
class="flex v-center gap file-link" |
|
:href="`${BASE_PATH}/templates/长沙公安数字督察灵敏感知体系问题赋分及风险预警机制.pdf`" |
|
target="__blank" |
|
> |
|
<icon name="local-icon-pdf" :size="38"/> |
|
<span>问题赋分机制.pdf</span> |
|
</a> |
|
</div> |
|
</header> |
|
<div class="table-container"> |
|
<el-table :data="dictContents" row-key="id"> |
|
<el-table-column |
|
label="问题条目" |
|
prop="name" |
|
show-overflow-tooltip="" |
|
/> |
|
<el-table-column label="基础分值" prop="score" width="200" align="center"> |
|
<template #default="{ row }"> |
|
<span v-if="row.level === 1">{{ |
|
getScoreRange(row) |
|
}}</span> |
|
<span v-else>{{ row.score }}</span> |
|
</template> |
|
</el-table-column> |
|
<el-table-column |
|
label="问题严重等级" |
|
prop="isActiveLevel" |
|
align="center" |
|
> |
|
<template #default="{ row }"> |
|
<el-tag type="success" v-if="row.isActiveLevel === true" |
|
>开启 |
|
</el-tag |
|
> |
|
<el-tag type="danger" v-if="row.isActiveLevel === false" |
|
>关闭 |
|
</el-tag |
|
> |
|
</template> |
|
</el-table-column> |
|
<el-table-column |
|
label="序号" |
|
prop="sort" |
|
width="100" |
|
align="center" |
|
/> |
|
<el-table-column label="最后更新时间" prop="updTime"/> |
|
<el-table-column label="操作"> |
|
<template #default="{ row }"> |
|
<el-button type="primary" link @click="handleEdit(row)" |
|
>编辑 |
|
</el-button |
|
> |
|
<el-button type="danger" link @click="handleDelete(row)" |
|
>删除 |
|
</el-button |
|
> |
|
</template> |
|
</el-table-column> |
|
</el-table> |
|
</div> |
|
<div class="mt-40"> |
|
<div>基础分值设定规则:</div> |
|
<p> |
|
1、二级问题条目设定的基础分值,作为其下属三级问题条目的默认基础分值。 |
|
</p> |
|
<p> |
|
2、若三级问题条目已单独设置基础分值,则赋分时以该三级条目的基础分值为准。 |
|
</p> |
|
<p> |
|
3、如三级问题条目未设置基础分值,则采用其所属二级问题条目的基础分值进行赋分。 |
|
</p> |
|
</div> |
|
</div> |
|
|
|
<el-dialog |
|
v-model="show" |
|
:title="mode === 'add' ? '新增问题类型' : '编辑问题类型'" |
|
width="600" |
|
> |
|
<el-form label-width="120" ref="formRef" :model="formData"> |
|
<el-form-item |
|
label="父级节点" |
|
:rules="{ |
|
required: true, |
|
message: '请选择父级节点', |
|
}" |
|
prop="parentCode" |
|
> |
|
<el-tree-select |
|
class="flex-1" |
|
v-model="formData.parentCode" |
|
:data="dictContentOptions" |
|
clearable |
|
node-key="id" |
|
:props="{ |
|
label: 'name', |
|
}" |
|
:default-expanded-keys="[DICT_CONTENT_ROOT_ID]" |
|
placeholder="请选择父级节点" |
|
check-strictly |
|
filterable |
|
/> |
|
</el-form-item> |
|
<el-form-item |
|
label="问题条目" |
|
prop="name" |
|
:rules="{ |
|
required: true, |
|
message: '请输入问题条目', |
|
}" |
|
> |
|
<el-input |
|
v-model="formData.name" |
|
placeholder="请输入问题条目" |
|
clearable |
|
/> |
|
</el-form-item> |
|
<el-form-item label="基础分值" prop="score" v-if="formData.parentCode != DICT_CONTENT_ROOT_ID"> |
|
<el-input |
|
v-model="formData.score" |
|
placeholder="请输入序号" |
|
type="number" |
|
clearable |
|
/> |
|
</el-form-item> |
|
<el-form-item label="序号" prop="sort"> |
|
<el-input |
|
v-model="formData.sort" |
|
placeholder="请输入序号" |
|
type="number" |
|
clearable |
|
/> |
|
</el-form-item> |
|
<el-form-item |
|
label="问题严重等级" |
|
prop="isActiveLevel" |
|
:rules="{ |
|
required: true, |
|
message: '请选择问题严重等级', |
|
trigger: ['blur'], |
|
}" |
|
> |
|
<el-switch |
|
v-model="formData.isActiveLevel" |
|
inline-prompt |
|
active-text="开启" |
|
inactive-text="关闭" |
|
:active-value="true" |
|
:inactive-value="false" |
|
/> |
|
</el-form-item> |
|
</el-form> |
|
<footer class="flex end"> |
|
<el-button @click="show = false">取消</el-button> |
|
<el-button type="primary" @click="submit">确定</el-button> |
|
</footer> |
|
</el-dialog> |
|
</template> |
|
<script lang="ts" setup> |
|
import {BASE_PATH} from "@/api/request"; |
|
import {calculateScore} from "@/api/work/negative"; |
|
import {DICT_CONTENT_ROOT_ID} from "@/enums/appEnums"; |
|
import { |
|
listDictContentTree, |
|
addDictContent, |
|
updateDictContent, |
|
delDictContent, |
|
} from "@/api/system/dictContent"; |
|
import feedback from "@/utils/feedback"; |
|
|
|
const dictContents = ref([]); |
|
const dictContentOptions = ref([ |
|
{ |
|
id: DICT_CONTENT_ROOT_ID, |
|
name: "顶级", |
|
children: [], |
|
}, |
|
]); |
|
|
|
function getList() { |
|
listDictContentTree().then((data) => { |
|
dictContents.value = data; |
|
dictContentOptions.value[0].children = data; |
|
}); |
|
} |
|
|
|
getList(); |
|
|
|
const show = ref(false); |
|
const formData = ref({}); |
|
const formRef = ref(); |
|
|
|
const mode = ref<string>("add"); |
|
watch(mode, (val) => { |
|
if (val === "add") { |
|
formData.value = {}; |
|
formRef.value.resetFields(); |
|
} |
|
}); |
|
|
|
async function submit() { |
|
await formRef.value.validate(); |
|
if (mode.value === "add") { |
|
await addDictContent(formData.value); |
|
const parentCode = formData.value.parentCode; |
|
formData.value = {}; |
|
formRef.value.resetFields(); |
|
formData.value.parentCode = parentCode; |
|
} else { |
|
await updateDictContent(formData.value); |
|
} |
|
show.value = false; |
|
getList(); |
|
} |
|
|
|
function handleAdd() { |
|
show.value = true; |
|
mode.value = "add"; |
|
} |
|
|
|
function handleEdit(row) { |
|
show.value = true; |
|
mode.value = "edit"; |
|
formData.value = {...row}; |
|
} |
|
|
|
const handleDelete = async (row) => { |
|
await feedback.confirm(`确定要删除 "${row.name}"?`); |
|
await delDictContent(row.id); |
|
getList(); |
|
feedback.msgSuccess("删除成功"); |
|
}; |
|
|
|
function getScoreRange(row) { |
|
const sorceSet = new Set(); |
|
row.children.forEach((item) => { |
|
if (item.score) { |
|
sorceSet.add(item.score); |
|
} |
|
item.children.forEach((j) => { |
|
if (j.score) { |
|
sorceSet.add(j.score); |
|
} |
|
}); |
|
}); |
|
if (sorceSet.size === 0) { |
|
return '' |
|
} |
|
if (sorceSet.size === 1) { |
|
return sorceSet.values().next().value |
|
} |
|
const min = Math.min(...sorceSet); |
|
const max = Math.max(...sorceSet); |
|
return `${min}-${max}` |
|
} |
|
|
|
const loading = ref(false) |
|
|
|
async function handleCalculate() { |
|
await feedback.confirm("确定要重新计算风险指数?"); |
|
loading.value = true |
|
await calculateScore() |
|
feedback.msgSuccess("风险指数计算完成"); |
|
loading.value = false |
|
} |
|
</script> |
|
<style lang="scss" scoped> |
|
.file-link { |
|
font-size: 16px; |
|
text-decoration: none; |
|
color: #19257d; |
|
padding: 0 8px; |
|
border-radius: 8px; |
|
|
|
&:hover { |
|
background-color: #eee; |
|
} |
|
} |
|
</style> |