|
|
<template> |
|
|
<div class="container h100"> |
|
|
<el-row :gutter="20" class="h100"> |
|
|
<el-col :span="4"> |
|
|
<model-tree v-model="query.modelIds" /> |
|
|
</el-col> |
|
|
<el-col :span="20"> |
|
|
<header> |
|
|
<el-form :label-width="140"> |
|
|
<el-row> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="预警时间"> |
|
|
<date-time-range-picker-ext |
|
|
v-model="query.createTime" |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="涉及单位"> |
|
|
<depart-tree-select |
|
|
v-model="query.involveDepartId" |
|
|
:check-strictly="false" |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="预警内容"> |
|
|
<el-input |
|
|
placeholder="请输入" |
|
|
v-model="query.thingDesc" |
|
|
clearable |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
</el-row> |
|
|
</el-form> |
|
|
<div class="flex between mb-20"> |
|
|
<div class="flex gap"> |
|
|
<el-button type="primary" @click="handleBathJoin"> |
|
|
<template #icon> |
|
|
<icon name="el-icon-Plus" /> |
|
|
</template> |
|
|
批量加入</el-button |
|
|
> |
|
|
<el-badge :value="manualList.length"> |
|
|
<el-button |
|
|
type="primary" |
|
|
:disabled="manualList.length === 0" |
|
|
@click="manualShow = true" |
|
|
>分发列表</el-button |
|
|
> |
|
|
</el-badge> |
|
|
</div> |
|
|
<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> |
|
|
</header> |
|
|
<div class="table-container"> |
|
|
<el-table :data="list" ref="tableRef"> |
|
|
<el-table-column type="selection" width="55" /> |
|
|
<el-table-column |
|
|
label="预警时间" |
|
|
prop="createTime" |
|
|
width="150" |
|
|
/> |
|
|
<el-table-column |
|
|
label="预警模型" |
|
|
prop="modelName" |
|
|
width="180" |
|
|
show-overflow-tooltip |
|
|
/> |
|
|
<el-table-column |
|
|
label="涉及单位" |
|
|
show-overflow-tooltip |
|
|
width="200" |
|
|
> |
|
|
<template #default="{ row }"> |
|
|
<span>{{ row.involveParentDepartName }}</span> |
|
|
<span>{{ row.involveDepartName }}</span> |
|
|
</template> |
|
|
</el-table-column> |
|
|
<el-table-column |
|
|
label="涉及人员" |
|
|
prop="involvePoliceName" |
|
|
width="100" |
|
|
/> |
|
|
<el-table-column |
|
|
label="预警内容" |
|
|
prop="thingDesc" |
|
|
show-overflow-tooltip |
|
|
/> |
|
|
<el-table-column |
|
|
label="分发状态" |
|
|
align="center" |
|
|
width="120" |
|
|
> |
|
|
<template #default="{ row }"> |
|
|
<span |
|
|
:class=" |
|
|
row.involveDepartId |
|
|
? '' |
|
|
: 'text-warning' |
|
|
" |
|
|
>{{ |
|
|
getDictLable( |
|
|
dict.distributionState, |
|
|
row.distributionState |
|
|
) |
|
|
}}</span |
|
|
> |
|
|
</template> |
|
|
</el-table-column> |
|
|
<el-table-column label="操作" width="200"> |
|
|
<template #default="{ row }"> |
|
|
<el-button |
|
|
type="primary" |
|
|
link |
|
|
@click="handleAddManuel(row)" |
|
|
v-if=" |
|
|
manualList.filter( |
|
|
(item) => item.id === row.id |
|
|
).length === 0 |
|
|
" |
|
|
>加入分发列表</el-button |
|
|
> |
|
|
<el-button |
|
|
link |
|
|
type="info" |
|
|
@click="handleRemoveManuel(row)" |
|
|
v-else |
|
|
>从分发列表移除</el-button |
|
|
> |
|
|
<!-- <el-button |
|
|
type="danger" |
|
|
link |
|
|
@click="handleNotProcessed(row)" |
|
|
v-if=" |
|
|
manualList.filter( |
|
|
(item) => item.id === row.id |
|
|
).length === 0 |
|
|
" |
|
|
>暂不处理</el-button |
|
|
> --> |
|
|
</template> |
|
|
</el-table-column> |
|
|
</el-table> |
|
|
</div> |
|
|
<div class="flex end mt-8"> |
|
|
<el-pagination |
|
|
@size-change="getList" |
|
|
@current-change="getList" |
|
|
:current-page="query.current" |
|
|
:page-sizes="[9, 18, 36]" |
|
|
v-model:page-size="query.size" |
|
|
v-model:current-page="query.current" |
|
|
layout="total, sizes, prev, pager, next" |
|
|
:total="total" |
|
|
> |
|
|
</el-pagination> |
|
|
</div> |
|
|
</el-col> |
|
|
</el-row> |
|
|
</div> |
|
|
|
|
|
<el-dialog title="问题分发" v-model="manualShow" width="80vw" top="5vh"> |
|
|
<header> |
|
|
<el-form :label-width="140"> |
|
|
<el-row> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="模型"> |
|
|
<el-select v-model="manualQuery.modelId"> |
|
|
<el-option |
|
|
v-for="item in modelOptions" |
|
|
:key="item.value" |
|
|
:value="item.value" |
|
|
:label="item.label" |
|
|
/> |
|
|
</el-select> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="涉及单位"> |
|
|
<depart-tree-select |
|
|
v-model="manualQuery.involveDepartId" |
|
|
:check-strictly="false" |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="预警内容"> |
|
|
<el-input |
|
|
placeholder="请输入" |
|
|
v-model="manualQuery.thingDesc" |
|
|
clearable |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
</el-row> |
|
|
</el-form> |
|
|
<div class="flex v-center end mb-20"> |
|
|
<span class="mr-20" |
|
|
>共 |
|
|
<span class="text-primary">{{ |
|
|
filterManualList.length |
|
|
}}</span> |
|
|
条预警线索</span |
|
|
> |
|
|
|
|
|
<el-button @click="manualReset">重置</el-button> |
|
|
</div> |
|
|
</header> |
|
|
<div style="min-height: 500px"> |
|
|
<div class="table-container"> |
|
|
<el-table :data="filterManualList"> |
|
|
<el-table-column |
|
|
label="预警时间" |
|
|
prop="createTime" |
|
|
width="160" |
|
|
/> |
|
|
<el-table-column |
|
|
label="预警模型" |
|
|
prop="modelName" |
|
|
width="120" |
|
|
show-overflow-tooltip |
|
|
/> |
|
|
<el-table-column |
|
|
label="涉及单位" |
|
|
show-overflow-tooltip |
|
|
width="200" |
|
|
> |
|
|
<template #default="{ row }"> |
|
|
<span>{{ row.involveParentDepartName }}</span> |
|
|
<span>{{ row.involveDepartName }}</span> |
|
|
</template> |
|
|
</el-table-column> |
|
|
<el-table-column |
|
|
label="涉及人员" |
|
|
prop="involvePoliceName" |
|
|
width="120" |
|
|
/> |
|
|
<el-table-column |
|
|
label="预警内容" |
|
|
prop="thingDesc" |
|
|
show-overflow-tooltip |
|
|
/> |
|
|
<el-table-column label="操作" width="140"> |
|
|
<template #default="{ row }"> |
|
|
<el-button |
|
|
type="info" |
|
|
link |
|
|
@click="handleRemoveManuel(row)" |
|
|
>移除</el-button |
|
|
> |
|
|
</template> |
|
|
</el-table-column> |
|
|
</el-table> |
|
|
</div> |
|
|
</div> |
|
|
<footer class="flex end mt-20"> |
|
|
<el-button |
|
|
type="primary" |
|
|
size="large" |
|
|
@click="handleShowDistributeDialog" |
|
|
:disabled="manualList.length === 0" |
|
|
>确认预警线索</el-button |
|
|
> |
|
|
</footer> |
|
|
</el-dialog> |
|
|
|
|
|
<el-dialog title="任务分发" v-model="distributeShow" width="50vw" top="5vh"> |
|
|
<el-form :label-width="120" ref="formRef" :model="form" v-loading="submitLoading"> |
|
|
<el-form-item |
|
|
label="任务名称" |
|
|
prop="taskName" |
|
|
:rules="{ |
|
|
required: true, |
|
|
message: '请输入任务名称', |
|
|
}" |
|
|
> |
|
|
<el-input |
|
|
v-model="form.taskName" |
|
|
style="width: 280px" |
|
|
placeholder="请输入" |
|
|
/> |
|
|
</el-form-item> |
|
|
<el-form-item label="指定办理单位" prop="handleDepartId"> |
|
|
<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 |
|
|
label="业务类别" |
|
|
prop="businessTypeCode" |
|
|
:rules="{ |
|
|
required: true, |
|
|
message: '请选择业务类别', |
|
|
trigger: ['blur'], |
|
|
}" |
|
|
> |
|
|
<el-select v-model="form.businessTypeCode" style="width: 280px"> |
|
|
<el-option |
|
|
v-for="item in dict.businessType" |
|
|
:key="item.id" |
|
|
:label="item.dictLabel" |
|
|
:value="item.dictValue" |
|
|
/> |
|
|
</el-select> |
|
|
</el-form-item> |
|
|
<el-form-item |
|
|
label="涉嫌问题" |
|
|
prop="involveProblem" |
|
|
:rules="{ |
|
|
required: true, |
|
|
message: '请选择涉嫌问题', |
|
|
trigger: ['blur'], |
|
|
}" |
|
|
> |
|
|
<el-select |
|
|
v-model="form.involveProblem" |
|
|
multiple |
|
|
clearable |
|
|
style="width: 280px" |
|
|
> |
|
|
<el-option |
|
|
v-for="item in dict.suspectProblem" |
|
|
:key="item.id" |
|
|
:label="item.dictLabel" |
|
|
:value="item.dictValue" |
|
|
/> |
|
|
</el-select> |
|
|
</el-form-item> |
|
|
<el-form-item label="涉及警种" prop="policeType"> |
|
|
<el-select |
|
|
v-model="form.policeType" |
|
|
clearable |
|
|
style="width: 280px" |
|
|
> |
|
|
<el-option |
|
|
v-for="item in dict.policeType" |
|
|
:key="item.id" |
|
|
:label="item.dictLabel" |
|
|
:value="item.dictValue" |
|
|
/> |
|
|
</el-select> |
|
|
</el-form-item> |
|
|
<div class="flex center mb-12"> |
|
|
<el-button |
|
|
@click="handleAddProblem()" |
|
|
plain |
|
|
type="primary" |
|
|
size="small" |
|
|
> |
|
|
<template #icon> |
|
|
<icon name="el-icon-Plus" /> |
|
|
</template> |
|
|
添加问题 |
|
|
</el-button> |
|
|
</div> |
|
|
<el-form-item |
|
|
label="问题类型" |
|
|
prop="" |
|
|
v-for="(item, index) in form.problems" |
|
|
:key="index" |
|
|
> |
|
|
<div class="flex v-center"> |
|
|
<problem-type-select v-model="item.threeLevelCode" /> |
|
|
<el-button |
|
|
plain |
|
|
type="danger" |
|
|
size="small" |
|
|
class="ml-20" |
|
|
@click="handleRemoveProblem(index)" |
|
|
> |
|
|
<template #icon> |
|
|
<icon name="el-icon-Delete" /> |
|
|
</template> |
|
|
删除问题 |
|
|
</el-button> |
|
|
</div> |
|
|
</el-form-item> |
|
|
<el-form-item |
|
|
label="办理时限" |
|
|
prop="timeLimit" |
|
|
:rules="{ |
|
|
required: true, |
|
|
message: '请选择办理时限', |
|
|
}" |
|
|
> |
|
|
<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 |
|
|
label="下发流程" |
|
|
prop="distributionFlow" |
|
|
:rules="{ |
|
|
required: true, |
|
|
message: '请选择下发流程', |
|
|
}" |
|
|
> |
|
|
<el-radio-group v-model="form.distributionFlow" class="block"> |
|
|
<el-radio |
|
|
v-for="item in dict.distributionFlow" |
|
|
:key="item.dictCode" |
|
|
:value="item.dictValue" |
|
|
>{{ item.dictLabel |
|
|
}}</el-radio |
|
|
> |
|
|
</el-radio-group> |
|
|
</el-form-item> |
|
|
<el-form-item |
|
|
label="审核流程" |
|
|
prop="approvalFlow" |
|
|
:rules="{ |
|
|
required: true, |
|
|
message: '请选择审核流程', |
|
|
}" |
|
|
> |
|
|
<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> |
|
|
<el-form-item label="附件说明" prop="thingFiles"> |
|
|
<file-upload v-model:files="form.thingFiles" /> |
|
|
</el-form-item> |
|
|
</el-form> |
|
|
<footer class="flex end mt-20"> |
|
|
<el-button |
|
|
type="primary" |
|
|
size="large" |
|
|
@click="handleSubmitManuelModelClueTask" |
|
|
v-loading="submitLoading" |
|
|
>确认下发</el-button |
|
|
> |
|
|
</footer> |
|
|
</el-dialog> |
|
|
|
|
|
<el-dialog title="配置涉及单位" v-model="editDepartShow" width="500"> |
|
|
<el-form |
|
|
:label-width="120" |
|
|
:model="editDepartForm" |
|
|
ref="editDepartFormRef" |
|
|
> |
|
|
<el-form-item |
|
|
label="涉及单位" |
|
|
:rules="{ |
|
|
required: true, |
|
|
message: '请选择涉及单位', |
|
|
}" |
|
|
> |
|
|
<depart-tree-select |
|
|
v-model="editDepartForm.departId" |
|
|
@node-click=" |
|
|
(node) => (editDepartForm.name = node.shortName) |
|
|
" |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-form> |
|
|
<footer class="flex end mt-40"> |
|
|
<el-button @click="editDepartShow = false">取消</el-button> |
|
|
<el-button type="primary" @click="handleUpdatDepartModelClue" |
|
|
>确认</el-button |
|
|
> |
|
|
</footer> |
|
|
</el-dialog> |
|
|
</template> |
|
|
<script lang="ts" setup> |
|
|
import { DistributionMethod } from "@/enums/dictEnums"; |
|
|
import { |
|
|
listModelClue, |
|
|
manuelModelClueTask, |
|
|
updateDepartModelClue, |
|
|
} from "@/api/sensitivePerception/modelClue"; |
|
|
|
|
|
import useCatchStore from "@/stores/modules/catch"; |
|
|
import { getDictLable } from "@/utils/util"; |
|
|
import feedback from "@/utils/feedback"; |
|
|
|
|
|
const catchStore = useCatchStore(); |
|
|
const dict = catchStore.getDicts([ |
|
|
"distributionState", |
|
|
"timeLimit", |
|
|
"approvalFlow", |
|
|
"distributionFlow", |
|
|
"businessType", |
|
|
"suspectProblem", |
|
|
"policeType", |
|
|
]); |
|
|
|
|
|
const query = ref({ |
|
|
distributionMethod: DistributionMethod.MANUALLY_DISTRIBUTE, |
|
|
distributionState: "0", |
|
|
}); |
|
|
|
|
|
const list = ref([]); |
|
|
const total = ref(0); |
|
|
|
|
|
onMounted(() => { |
|
|
getList(); |
|
|
}); |
|
|
|
|
|
watch( |
|
|
() => query.value.modelIds, |
|
|
() => { |
|
|
getList(); |
|
|
} |
|
|
); |
|
|
|
|
|
function getList() { |
|
|
listModelClue(query.value).then((data) => { |
|
|
list.value = data.records; |
|
|
total.value = data.total; |
|
|
}); |
|
|
} |
|
|
|
|
|
function reset() { |
|
|
query.value = {}; |
|
|
getList(); |
|
|
} |
|
|
|
|
|
const manualList = ref([]); |
|
|
|
|
|
async function handleAddManuel(row) { |
|
|
if (!row.involveDepartId) { |
|
|
activeModelClueId = row.id; |
|
|
await feedback.confirm( |
|
|
`该数据的"涉及单位"为空,请先配置"涉及单位"再下发`, |
|
|
"去配置" |
|
|
); |
|
|
editDepartShow.value = true; |
|
|
return; |
|
|
} |
|
|
manualList.value.push(row); |
|
|
} |
|
|
|
|
|
function handleRemoveManuel(row) { |
|
|
manualList.value.splice(manualList.value.indexOf(row), 1); |
|
|
} |
|
|
|
|
|
async function handleNotProcessed(row) { |
|
|
await feedback.confirm(`确认该数据暂不处理?`); |
|
|
} |
|
|
|
|
|
const manualShow = ref(false); |
|
|
const manualQuery = ref({}); |
|
|
|
|
|
const filterManualList = computed(() => { |
|
|
let arr = manualList.value; |
|
|
if (manualQuery.value.modelId) { |
|
|
arr = arr.filter((item) => item.modelId === manualQuery.value.modelId); |
|
|
} |
|
|
if (manualQuery.value.involveDepartId) { |
|
|
arr = arr.filter( |
|
|
(item) => item.involveDepartId === manualQuery.value.involveDepartId |
|
|
); |
|
|
} |
|
|
if (manualQuery.value.thingDesc) { |
|
|
arr = arr.filter((item) => |
|
|
item.thingDesc.includes(manualQuery.value.thingDesc) |
|
|
); |
|
|
} |
|
|
return arr; |
|
|
}); |
|
|
|
|
|
const modelOptions = computed(() => { |
|
|
const items = manualList.value.map((item) => { |
|
|
return { |
|
|
value: item.modelId, |
|
|
label: item.modelName, |
|
|
}; |
|
|
}); |
|
|
const uniqueItems = [ |
|
|
...new Map(items.map((item) => [item.value, item])).values(), |
|
|
]; |
|
|
return uniqueItems; |
|
|
}); |
|
|
|
|
|
function manualReset() { |
|
|
manualQuery.value = {}; |
|
|
} |
|
|
|
|
|
function handleShowDistributeDialog() { |
|
|
if (new Set(filterManualList.value.map((item) => item.modelId)).size > 1) { |
|
|
feedback.msgWarning("线索数据包含两个模型,请筛选单个模型再下发"); |
|
|
return; |
|
|
} |
|
|
distributeShow.value = true; |
|
|
} |
|
|
|
|
|
const form = ref({ |
|
|
modelClues: [], |
|
|
thingFiles: [], |
|
|
problems: [] |
|
|
}); |
|
|
const formRef = ref(null); |
|
|
const distributeShow = ref(false); |
|
|
|
|
|
function handleAddProblem() { |
|
|
form.value.problems.push({}) |
|
|
} |
|
|
|
|
|
function handleRemoveProblem(index) { |
|
|
form.value.problems.splice(index, 1) |
|
|
} |
|
|
|
|
|
const submitLoading = ref(false) |
|
|
async function handleSubmitManuelModelClueTask() { |
|
|
await formRef.value.validate(); |
|
|
form.value.modelClues = filterManualList.value; |
|
|
submitLoading.value = true |
|
|
try { |
|
|
await manuelModelClueTask(form.value); |
|
|
} catch(e) { |
|
|
submitLoading.value = false |
|
|
return |
|
|
} |
|
|
submitLoading.value = false |
|
|
feedback.msgSuccess("下发成功"); |
|
|
form.value = { |
|
|
modelClues: [], |
|
|
thingFiles: [], |
|
|
problems: [] |
|
|
}; |
|
|
distributeShow.value = false; |
|
|
manualShow.value = false; |
|
|
manualList.value = []; |
|
|
getList(); |
|
|
} |
|
|
|
|
|
const editDepartShow = ref(false); |
|
|
const editDepartForm = ref({}); |
|
|
const editDepartFormRef = ref(); |
|
|
let activeModelClueId = 0; |
|
|
|
|
|
async function handleUpdatDepartModelClue() { |
|
|
await editDepartFormRef.value.validate(); |
|
|
await updateDepartModelClue(activeModelClueId, editDepartForm.value); |
|
|
editDepartShow.value = false; |
|
|
editDepartForm.value = {}; |
|
|
getList(); |
|
|
} |
|
|
|
|
|
const tableRef = ref(); |
|
|
function handleBathJoin() { |
|
|
const rows = tableRef.value.getSelectionRows(); |
|
|
rows.forEach((row) => { |
|
|
if ( |
|
|
manualList.value.filter((item) => item.id === row.id).length === 0 |
|
|
) { |
|
|
manualList.value.push(row); |
|
|
} |
|
|
}); |
|
|
} |
|
|
</script> |
|
|
<style lang="scss" scoped> |
|
|
</style> |