|
|
<template> |
|
|
<div class="container h100"> |
|
|
<el-tabs v-model="activeTab"> |
|
|
<!-- 问题线索 --> |
|
|
<el-tab-pane label="问题线索" name="modelClue"> |
|
|
<div class="h100"> |
|
|
<el-row :gutter="20" class="h100"> |
|
|
<el-col :span="6" class="h100"> |
|
|
<model-tree v-model="modelClueQuery.modelIds" /> |
|
|
</el-col> |
|
|
<el-col :span="18"> |
|
|
<header> |
|
|
<el-form :label-width="140"> |
|
|
<el-row> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="预警时间"> |
|
|
<date-time-range-picker-ext |
|
|
v-model="modelClueQuery.createTime" |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="涉及单位"> |
|
|
<depart-tree-select |
|
|
v-model="modelClueQuery.involveDepartId" |
|
|
:check-strictly="false" |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="预警内容"> |
|
|
<el-input |
|
|
placeholder="请输入" |
|
|
v-model="modelClueQuery.thingDesc" |
|
|
clearable |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="分发状态"> |
|
|
<el-select |
|
|
v-model="modelClueQuery.distributionState" |
|
|
clearable |
|
|
> |
|
|
<el-option |
|
|
v-for="item in dict.distributionState" |
|
|
:label="item.dictLabel" |
|
|
:value="item.dictValue" |
|
|
/> |
|
|
</el-select> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8" v-if="modelClueQuery.distributionState === '1'"> |
|
|
<el-form-item label="办理状态"> |
|
|
<el-select |
|
|
placeholder="办理状态" |
|
|
clearable |
|
|
v-model="modelClueQuery.processingStatus" |
|
|
> |
|
|
<el-option |
|
|
v-for="item in dict.processingStatus" |
|
|
:key="item.id" |
|
|
:label="item.dictLabel" |
|
|
:value="item.dictValue" |
|
|
/> |
|
|
</el-select> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
</el-row> |
|
|
</el-form> |
|
|
<div class="flex end mb-20"> |
|
|
<div> |
|
|
<el-button type="primary" @click="getModelClueList"> |
|
|
<template #icon> |
|
|
<icon name="el-icon-Search" /> |
|
|
</template> |
|
|
查询 |
|
|
</el-button> |
|
|
<el-button @click="resetModelClue">重置</el-button> |
|
|
</div> |
|
|
</div> |
|
|
</header> |
|
|
<div class="table-container" v-loading="modelClueLoading"> |
|
|
<el-table :data="modelClueList"> |
|
|
<el-table-column |
|
|
label="预警时间" |
|
|
prop="createTime" |
|
|
width="150" |
|
|
/> |
|
|
<el-table-column |
|
|
label="涉及单位" |
|
|
show-overflow-tooltip |
|
|
width="160" |
|
|
> |
|
|
<template #default="{ row }"> |
|
|
<span>{{ row.involveParentDepartName }}</span |
|
|
><span v-if="row.involveDepartName" |
|
|
><br />{{ row.involveDepartName }}</span |
|
|
> |
|
|
</template> |
|
|
</el-table-column> |
|
|
<el-table-column |
|
|
label="涉及人员" |
|
|
prop="involvePoliceName" |
|
|
width="160" |
|
|
> |
|
|
<template #default="{ row }"> |
|
|
<div v-if="row.involvePoliceName"> |
|
|
<div |
|
|
v-for="item in row.involvePoliceName.split( |
|
|
' ' |
|
|
)" |
|
|
class="text-nowrap" |
|
|
> |
|
|
{{ item }} |
|
|
</div> |
|
|
</div> |
|
|
<div v-else>略</div> |
|
|
</template> |
|
|
</el-table-column> |
|
|
<el-table-column |
|
|
label="预警内容" |
|
|
prop="thingDesc" |
|
|
show-overflow-tooltip |
|
|
/> |
|
|
<el-table-column |
|
|
label="分发状态" |
|
|
align="center" |
|
|
width="130" |
|
|
> |
|
|
<template #default="{ row }"> |
|
|
<el-tag |
|
|
v-if="row.distributionState === '0'" |
|
|
type="info" |
|
|
>未分发</el-tag |
|
|
> |
|
|
<el-tag |
|
|
v-if="row.distributionState === '1'" |
|
|
type="success" |
|
|
>已分发 |
|
|
<span v-if="row.processingStatus">{{ row.processingStatus ? `(${getDictLable(dict.processingStatus, row.processingStatus)})` : "" }}</span> |
|
|
</el-tag |
|
|
> |
|
|
<el-tag v-if="row.distributionState === '2'" |
|
|
>已处置{{ |
|
|
row.negativeId ? "" : " (未分发)" |
|
|
}}</el-tag |
|
|
> |
|
|
</template> |
|
|
</el-table-column> |
|
|
<el-table-column label="操作" width="180"> |
|
|
<template #default="{ row }"> |
|
|
<el-button |
|
|
type="primary" |
|
|
link |
|
|
@click="handleModelClueShowDetail(row)" |
|
|
>查看详情 |
|
|
</el-button> |
|
|
<el-button |
|
|
v-if="row.negativeId" |
|
|
type="primary" |
|
|
link |
|
|
@click="handleModelClueAction(row)" |
|
|
>处理详情 |
|
|
</el-button> |
|
|
<el-button |
|
|
type="primary" |
|
|
link |
|
|
v-if="row.notificationId" |
|
|
@click="handleModelClueClue(row)" |
|
|
>查看提醒 |
|
|
</el-button> |
|
|
</template> |
|
|
</el-table-column> |
|
|
</el-table> |
|
|
</div> |
|
|
<div class="flex end mt-8"> |
|
|
<el-pagination |
|
|
@size-change="getModelClueList" |
|
|
@current-change="getModelClueList" |
|
|
:page-sizes="[9, 18, 36]" |
|
|
v-model:page-size="modelClueQuery.size" |
|
|
v-model:current-page="modelClueQuery.current" |
|
|
layout="total, sizes, prev, pager, next" |
|
|
:total="modelClueTotal" |
|
|
> |
|
|
</el-pagination> |
|
|
</div> |
|
|
</el-col> |
|
|
</el-row> |
|
|
</div> |
|
|
</el-tab-pane> |
|
|
|
|
|
<!-- 任务分发 --> |
|
|
<el-tab-pane label="任务分发" name="modelTask"> |
|
|
<div class="h100"> |
|
|
<el-row :gutter="20" class="h100"> |
|
|
<el-col :span="4"> |
|
|
<model-tree v-model="modelTaskQuery.modelIds" /> |
|
|
</el-col> |
|
|
<el-col :span="20"> |
|
|
<header> |
|
|
<el-form :label-width="140"> |
|
|
<el-row> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="任务名称"> |
|
|
<el-input |
|
|
placeholder="请输入" |
|
|
v-model="modelTaskQuery.thingDesc" |
|
|
clearable |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="下发时间"> |
|
|
<date-time-range-picker-ext |
|
|
v-model="modelTaskQuery.createTime" |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
</el-row> |
|
|
</el-form> |
|
|
<div class="flex end mb-20"> |
|
|
<div> |
|
|
<el-button type="primary" @click="getModelTaskList"> |
|
|
<template #icon> |
|
|
<icon name="el-icon-Search" /> |
|
|
</template> |
|
|
查询</el-button |
|
|
> |
|
|
<el-button @click="resetModelTask">重置</el-button> |
|
|
</div> |
|
|
</div> |
|
|
</header> |
|
|
<div class="table-container"> |
|
|
<el-table :data="modelTaskList"> |
|
|
<el-table-column |
|
|
label="任务名称" |
|
|
prop="taskName" |
|
|
width="200" |
|
|
show-overflow-tooltip |
|
|
/> |
|
|
<el-table-column |
|
|
label="模型名称" |
|
|
prop="modelName" |
|
|
width="200" |
|
|
show-overflow-tooltip |
|
|
/> |
|
|
<el-table-column |
|
|
label="下发时间" |
|
|
prop="distributionTime" |
|
|
width="200" |
|
|
/> |
|
|
<el-table-column |
|
|
label="问题条数" |
|
|
prop="size" |
|
|
align="center" |
|
|
/> |
|
|
<el-table-column |
|
|
label="办结数量" |
|
|
align="center" |
|
|
prop="completedSize" |
|
|
/> |
|
|
<el-table-column |
|
|
label="查实数量" |
|
|
align="center" |
|
|
prop="verifySize" |
|
|
/> |
|
|
<el-table-column |
|
|
label="涉及单位数" |
|
|
align="center" |
|
|
prop="departSize" |
|
|
width="130" |
|
|
/> |
|
|
<el-table-column |
|
|
label="涉及人数" |
|
|
align="center" |
|
|
prop="personalSize" |
|
|
/> |
|
|
<el-table-column label="操作" width="200"> |
|
|
<template #default="{ row }"> |
|
|
<el-button |
|
|
type="primary" |
|
|
link |
|
|
@click="handleModelTaskStatisticsShow(row.id)" |
|
|
>任务统计</el-button |
|
|
> |
|
|
</template> |
|
|
</el-table-column> |
|
|
</el-table> |
|
|
</div> |
|
|
<div class="flex end mt-8"> |
|
|
<el-pagination |
|
|
@size-change="getModelTaskList" |
|
|
@current-change="getModelTaskList" |
|
|
:page-sizes="[10, 20, 50, 100]" |
|
|
v-model:page-size="modelTaskQuery.size" |
|
|
v-model:current-page="modelTaskQuery.current" |
|
|
layout="total, sizes, prev, pager, next" |
|
|
:total="modelTaskTotal" |
|
|
v-if="modelTaskList.length" |
|
|
> |
|
|
</el-pagination> |
|
|
</div> |
|
|
</el-col> |
|
|
</el-row> |
|
|
</div> |
|
|
</el-tab-pane> |
|
|
|
|
|
<!-- 人工核验 --> |
|
|
<el-tab-pane label="人工核验" name="modelClueManual"> |
|
|
<div class="h100"> |
|
|
<el-row :gutter="20" class="h100"> |
|
|
<el-col :span="6"> |
|
|
<model-tree v-model="modelClueManualQuery.modelIds" /> |
|
|
</el-col> |
|
|
<el-col :span="18"> |
|
|
<header> |
|
|
<el-form :label-width="140"> |
|
|
<el-row> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="预警时间"> |
|
|
<date-time-range-picker-ext |
|
|
v-model="modelClueManualQuery.createTime" |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="涉及单位"> |
|
|
<depart-tree-select |
|
|
v-model="modelClueManualQuery.involveDepartId" |
|
|
:check-strictly="false" |
|
|
/> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="预警内容"> |
|
|
<el-input |
|
|
placeholder="请输入" |
|
|
v-model="modelClueManualQuery.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="getModelClueManualList"> |
|
|
<template #icon> |
|
|
<icon name="el-icon-Search" /> |
|
|
</template> |
|
|
查询</el-button |
|
|
> |
|
|
<el-button @click="resetModelClueManual">重置</el-button> |
|
|
</div> |
|
|
</div> |
|
|
</header> |
|
|
<div class="table-container" v-loading="modelClueManualLoading"> |
|
|
<el-table :data="modelClueManualList" ref="tableRef" max-height="600"> |
|
|
<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="120" |
|
|
> |
|
|
<template #default="{ row }"> |
|
|
<div v-if="row.involvePoliceName"> |
|
|
<div v-for="item in row.involvePoliceName.split( |
|
|
' ') |
|
|
" |
|
|
class="text-nowrap" |
|
|
> |
|
|
{{ item }} |
|
|
</div> |
|
|
</div> |
|
|
<div v-else>略</div> |
|
|
</template> |
|
|
</el-table-column> |
|
|
<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 |
|
|
> |
|
|
</template> |
|
|
</el-table-column> |
|
|
</el-table> |
|
|
</div> |
|
|
<div class="flex end mt-8"> |
|
|
<el-pagination |
|
|
@size-change="getModelClueManualList" |
|
|
@current-change="getModelClueManualList" |
|
|
:page-sizes="[10, 20, 50, 100]" |
|
|
v-model:page-size="modelClueManualQuery.size" |
|
|
v-model:current-page="modelClueManualQuery.current" |
|
|
layout="total, sizes, prev, pager, next" |
|
|
:total="modelClueManualTotal" |
|
|
> |
|
|
</el-pagination> |
|
|
</div> |
|
|
</el-col> |
|
|
</el-row> |
|
|
</div> |
|
|
</el-tab-pane> |
|
|
</el-tabs> |
|
|
|
|
|
<!-- 模型预警问题 - 详情弹窗 --> |
|
|
<el-dialog title="预警线索数据详情" v-model="modelClueShow" width="50vw"> |
|
|
<div class="dialog-container"> |
|
|
<div class="row mt-10"> |
|
|
<div class="col col-12"> |
|
|
<label>预警时间</label> |
|
|
<span>{{ activeModelClue.createTime }}</span> |
|
|
</div> |
|
|
<div class="col col-12"> |
|
|
<label>预警模型</label> |
|
|
<span>{{ activeModelClue.modelName }}</span> |
|
|
</div> |
|
|
<div class="col col-12"> |
|
|
<label>涉及单位</label> |
|
|
<span> |
|
|
<span>{{ |
|
|
activeModelClue.involveParentDepartName |
|
|
}}</span |
|
|
><span>{{ |
|
|
activeModelClue.involveDepartName |
|
|
? "/" + activeModelClue.involveDepartName |
|
|
: "" |
|
|
}}</span> |
|
|
</span> |
|
|
</div> |
|
|
<div class="col col-6"> |
|
|
<label>涉及人员</label> |
|
|
<span>{{ activeModelClue.involvePoliceName }}</span> |
|
|
</div> |
|
|
<div class="col col-12"> |
|
|
<label>分发状态</label> |
|
|
<span>{{ |
|
|
getDictLable( |
|
|
dict.distributionState, |
|
|
activeModelClue.distributionState |
|
|
) |
|
|
}}</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="row mt-10" style="margin-bottom: 60px"> |
|
|
<div class="col col-24"> |
|
|
<label>预警内容</label> |
|
|
<span>{{ activeModelClue.thingDesc }}</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</el-dialog> |
|
|
|
|
|
<!-- 模型预警问题 - 提醒详情弹窗 --> |
|
|
<el-dialog title="查看详情" v-model="modelClueDialogShow" width="800"> |
|
|
<el-form :model="modelClueShowData" :label-width="120" ref="fomrRef"> |
|
|
<el-row> |
|
|
<el-col :span="12"> |
|
|
<el-form-item label="提醒类型"> |
|
|
<div>{{ modelClueShowData.alarmType }}</div> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="12"> |
|
|
<el-form-item label="提醒时间"> |
|
|
<el-text>{{ modelClueShowData.alarmTime }}</el-text> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
</el-row> |
|
|
<el-row style="margin-top: 5px"> |
|
|
<el-col :span="12"> |
|
|
<el-form-item label="被通知单位"> |
|
|
<el-text>{{ modelClueShowData.notificationDepartName }}</el-text> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
<el-col :span="12" v-if="modelClueShowData.policeName != undefined"> |
|
|
<el-form-item label="被通知民警"> |
|
|
<el-text>{{ modelClueShowData.policeName }}</el-text> |
|
|
</el-form-item> |
|
|
</el-col> |
|
|
</el-row> |
|
|
<el-row style="margin-top: 5px"> |
|
|
<el-form-item label="提醒内容"> |
|
|
<el-text style="width: 588px">{{ |
|
|
modelClueShowData.alarmContent |
|
|
}}</el-text> |
|
|
</el-form-item> |
|
|
</el-row> |
|
|
<el-row style="margin-top: 5px" v-if="modelClueShowData.replyState == 1"> |
|
|
<el-form-item label="回复内容"> |
|
|
<el-text style="width: 588px">{{ |
|
|
modelClueShowData.replyResultContent |
|
|
}}</el-text> |
|
|
</el-form-item> |
|
|
</el-row> |
|
|
<el-row |
|
|
style="margin-top: 10px" |
|
|
v-if="modelClueShowData.files != undefined && modelClueShowData.files.length > 0" |
|
|
> |
|
|
<el-form-item label="问题附件"> |
|
|
<div |
|
|
v-for="(item, index) in modelClueShowData.files" |
|
|
:key="index" |
|
|
style="margin-top: 10px" |
|
|
> |
|
|
<el-image |
|
|
:preview-src-list="modelCluePreviewList" |
|
|
style=" |
|
|
width: 100px; |
|
|
height: 100px; |
|
|
margin-right: 8px; |
|
|
" |
|
|
:initial-index="index" |
|
|
:src="item.path" |
|
|
fit="cover" |
|
|
:hide-on-click-modal="true" |
|
|
:lazy="true" |
|
|
:z-index="index" |
|
|
/> |
|
|
</div> |
|
|
</el-form-item> |
|
|
</el-row> |
|
|
</el-form> |
|
|
<footer class="flex end"> |
|
|
<el-button @click="modelClueDialogShow = false">关闭</el-button> |
|
|
</footer> |
|
|
</el-dialog> |
|
|
|
|
|
<!-- 模型预警问题 - 处理详情弹窗 --> |
|
|
<negative-dialog |
|
|
v-model="modelClueNegativeShow" |
|
|
:id="modelClueActiveNegativeId" |
|
|
@close="modelClueNegativeShow = false" |
|
|
/> |
|
|
|
|
|
<!-- 任务分发 - 任务统计弹窗 --> |
|
|
<el-dialog title="任务统计" v-model="modelTaskStatisticsShow" width="80vw"> |
|
|
<div style="min-height: 500px"> |
|
|
<div class="table-container"> |
|
|
<el-table :data="modelTaskDepartList"> |
|
|
<el-table-column |
|
|
label="单位名称" |
|
|
prop="departName" |
|
|
width="200" |
|
|
show-overflow-tooltip |
|
|
/> |
|
|
<el-table-column |
|
|
label="问题数量" |
|
|
prop="size" |
|
|
width="200" |
|
|
show-overflow-tooltip |
|
|
/> |
|
|
<el-table-column |
|
|
label="办结数量" |
|
|
prop="completedSize" |
|
|
width="200" |
|
|
/> |
|
|
<el-table-column |
|
|
label="办结率" |
|
|
align="center" |
|
|
prop="completedSize" |
|
|
/> |
|
|
<el-table-column |
|
|
label="查实数量" |
|
|
align="center" |
|
|
prop="verifySize" |
|
|
/> |
|
|
<el-table-column |
|
|
label="涉及人数" |
|
|
align="center" |
|
|
prop="personalSize" |
|
|
/> |
|
|
</el-table> |
|
|
</div> |
|
|
</div> |
|
|
</el-dialog> |
|
|
|
|
|
<!-- 人工核验 - 分发列表弹窗 --> |
|
|
<el-dialog title="问题分发" v-model="manualShow" width="80vw" top="5vh" style="margin-bottom: 0"> |
|
|
<header> |
|
|
<el-form :label-width="140"> |
|
|
<el-row> |
|
|
<el-col :span="8"> |
|
|
<el-form-item label="模型"> |
|
|
<el-select v-model="manualQuery.modelId" clearable> |
|
|
<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" max-height="580"> |
|
|
<el-table-column type="index" width="50" /> |
|
|
<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" |
|
|
> |
|
|
<template #default="{ row }"> |
|
|
<div v-if="row.involvePoliceName"> |
|
|
<div |
|
|
v-for="item in row.involvePoliceName.split( |
|
|
' ' |
|
|
)" |
|
|
class="text-nowrap" |
|
|
> |
|
|
{{ item }} |
|
|
</div> |
|
|
</div> |
|
|
<div v-else>略</div> |
|
|
</template> |
|
|
</el-table-column> |
|
|
<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="2vh" style="margin-bottom: 0"> |
|
|
<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> |
|
|
</div> |
|
|
</template> |
|
|
<script lang="ts" setup> |
|
|
import { ref, computed, onMounted } from "vue"; |
|
|
import { useRoute } from "vue-router"; |
|
|
import { listModelClue } from "@/api/sensitivePerception/modelClue"; |
|
|
import { alarmDetails } from "@/api/work/alarm"; |
|
|
import { listModelClueTask, listModelClueByDepart, listModelClues } from "@/api/sensitivePerception/modelClueTask"; |
|
|
import { DistributionMethod } from "@/enums/dictEnums"; |
|
|
import { 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", "handleState", "processingStatus", "timeLimit", "approvalFlow", "distributionFlow", "businessType", "suspectProblem", "policeType"]); |
|
|
|
|
|
// 标签页状态 |
|
|
const activeTab = ref('modelClue'); |
|
|
|
|
|
// 模型预警问题相关 |
|
|
const modelClueQuery = ref({}); |
|
|
const modelClueList = ref([]); |
|
|
const modelClueTotal = ref(0); |
|
|
const modelClueLoading = ref(false); |
|
|
const modelClueShow = ref(false); |
|
|
const activeModelClue = ref({}); |
|
|
const modelClueDialogShow = ref(false); |
|
|
let modelClueShowData = ref({}); |
|
|
let modelCluePreviewList = ref([]); |
|
|
const modelClueNegativeShow = ref(false); |
|
|
const modelClueActiveNegativeId = ref(""); |
|
|
|
|
|
// 任务分发相关 |
|
|
const modelTaskQuery = ref({}); |
|
|
const modelTaskList = ref([]); |
|
|
const modelTaskTotal = ref(0); |
|
|
const modelTaskStatisticsShow = ref(false); |
|
|
const modelTaskDepartList = ref([]); |
|
|
|
|
|
// 人工核验相关 |
|
|
const modelClueManualQuery = ref({ |
|
|
distributionMethod: DistributionMethod.MANUALLY_DISTRIBUTE, |
|
|
distributionState: "0", |
|
|
}); |
|
|
const modelClueManualList = ref([]); |
|
|
const modelClueManualTotal = ref(0); |
|
|
const modelClueManualLoading = ref(false); |
|
|
const manualList = ref([]); |
|
|
const manualShow = ref(false); |
|
|
const manualQuery = ref({}); |
|
|
const distributeShow = ref(false); |
|
|
const form = ref({ |
|
|
modelClues: [], |
|
|
thingFiles: [], |
|
|
problems: [] |
|
|
}); |
|
|
const formRef = ref(null); |
|
|
const submitLoading = ref(false); |
|
|
const editDepartShow = ref(false); |
|
|
const editDepartForm = ref({}); |
|
|
const editDepartFormRef = ref(); |
|
|
let activeModelClueId = 0; |
|
|
const tableRef = ref(); |
|
|
|
|
|
// 路由和生命周期 |
|
|
const route = useRoute(); |
|
|
onMounted(() => { |
|
|
if (route.query.modelId) { |
|
|
modelClueQuery.value.modelIds = [route.query.modelId]; |
|
|
modelTaskQuery.value.modelIds = [route.query.modelId]; |
|
|
modelClueManualQuery.value.modelIds = [route.query.modelId]; |
|
|
} |
|
|
getModelClueList(); |
|
|
getModelTaskList(); |
|
|
getModelClueManualList(); |
|
|
}); |
|
|
|
|
|
// 模型预警问题相关方法 |
|
|
function getModelClueList() { |
|
|
modelClueLoading.value = true |
|
|
listModelClue(modelClueQuery.value).then((data) => { |
|
|
modelClueList.value = data.records; |
|
|
modelClueTotal.value = data.total; |
|
|
modelClueLoading.value = false |
|
|
console.log('length:', modelClueList.value.length, 'total:', modelClueTotal.value); |
|
|
}); |
|
|
} |
|
|
|
|
|
function resetModelClue() { |
|
|
modelClueQuery.value = { |
|
|
current: 1, |
|
|
size: 9 |
|
|
}; |
|
|
getModelClueList(); |
|
|
} |
|
|
|
|
|
function handleModelClueShowDetail(row) { |
|
|
activeModelClue.value = row; |
|
|
modelClueShow.value = true; |
|
|
} |
|
|
|
|
|
function handleModelClueAction(row) { |
|
|
modelClueNegativeShow.value = true; |
|
|
modelClueActiveNegativeId.value = row.negativeId; |
|
|
} |
|
|
|
|
|
const handleModelClueClue = (row) => { |
|
|
alarmDetails(row.notificationId).then((res) => { |
|
|
modelClueShowData.value = res; |
|
|
let arr = []; |
|
|
if (res.files != undefined) { |
|
|
res.files.forEach((item) => { |
|
|
arr.push(item.path); |
|
|
}); |
|
|
} |
|
|
modelCluePreviewList.value = arr; |
|
|
modelClueDialogShow.value = true; |
|
|
}); |
|
|
}; |
|
|
|
|
|
// 任务分发相关方法 |
|
|
function getModelTaskList() { |
|
|
listModelClueTask(modelTaskQuery.value).then((data) => { |
|
|
modelTaskList.value = data.records; |
|
|
modelTaskTotal.value = data.total; |
|
|
}); |
|
|
} |
|
|
|
|
|
function resetModelTask() { |
|
|
modelTaskQuery.value = {}; |
|
|
getModelTaskList(); |
|
|
} |
|
|
|
|
|
async function handleModelTaskStatisticsShow(id) { |
|
|
const data = await listModelClueByDepart(id) |
|
|
modelTaskDepartList.value = data; |
|
|
modelTaskStatisticsShow.value = true; |
|
|
} |
|
|
|
|
|
// 人工核验相关方法 |
|
|
function getModelClueManualList() { |
|
|
modelClueManualLoading.value = true |
|
|
listModelClue(modelClueManualQuery.value).then((data) => { |
|
|
modelClueManualList.value = data.records; |
|
|
modelClueManualTotal.value = data.total; |
|
|
modelClueManualLoading.value = false |
|
|
}); |
|
|
} |
|
|
|
|
|
function resetModelClueManual() { |
|
|
modelClueManualQuery.value = { |
|
|
distributionMethod: DistributionMethod.MANUALLY_DISTRIBUTE, |
|
|
distributionState: "0", |
|
|
}; |
|
|
getModelClueManualList(); |
|
|
} |
|
|
|
|
|
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); |
|
|
} |
|
|
|
|
|
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; |
|
|
form.value.taskName = filterManualList.value[0].modelName |
|
|
} |
|
|
|
|
|
function handleAddProblem() { |
|
|
form.value.problems.push({}) |
|
|
} |
|
|
|
|
|
function handleRemoveProblem(index) { |
|
|
form.value.problems.splice(index, 1) |
|
|
} |
|
|
|
|
|
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 = []; |
|
|
getModelClueManualList(); |
|
|
} |
|
|
|
|
|
async function handleUpdatDepartModelClue() { |
|
|
await editDepartFormRef.value.validate(); |
|
|
await updateDepartModelClue(activeModelClueId, editDepartForm.value); |
|
|
editDepartShow.value = false; |
|
|
editDepartForm.value = {}; |
|
|
getModelClueManualList(); |
|
|
} |
|
|
|
|
|
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> |