|
|
@@ -65,14 +65,12 @@
|
|
|
|
|
|
<el-card shadow="never" class="page-card">
|
|
|
<el-table v-loading="loading" :data="warningList">
|
|
|
- <el-table-column label="序号" width="70" align="center">
|
|
|
- <template #default="scope">
|
|
|
- {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="预警编号" prop="warningNo" width="180" />
|
|
|
+ <el-table-column label="预警编号" prop="warningNo" width="210" show-overflow-tooltip />
|
|
|
|
|
|
<el-table-column label="预警类型" prop="warningTypeText" width="120" />
|
|
|
+ <el-table-column label="预警内容" min-width="240">
|
|
|
+ <template #default="scope"><WarningContentCell :content="scope.row.warningContent" /></template>
|
|
|
+ </el-table-column>
|
|
|
<el-table-column label="预警级别" width="110" align="center">
|
|
|
<template #default="scope">
|
|
|
<el-tag :type="getLevelTagType(scope.row.warningLevel)">
|
|
|
@@ -96,7 +94,7 @@
|
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" fixed="right" width="280" align="center">
|
|
|
<template #default="scope">
|
|
|
- <el-button v-hasPermi="['warning:warning:query']" link type="primary" @click="handleView(scope.row)">查看</el-button>
|
|
|
+ <el-button v-hasPermi="['warning:warning:query']" link type="primary" @click="handleView(scope.row)">详情</el-button>
|
|
|
<el-button v-if="scope.row.status === 'DRAFT'" v-hasPermi="['warning:warning:edit']" link type="primary" @click="handleEdit(scope.row)">编辑</el-button>
|
|
|
<el-button v-if="scope.row.status === 'DRAFT'" v-hasPermi="['warning:warning:publish']" link type="success" @click="handlePublish(scope.row)">发布</el-button>
|
|
|
<el-button v-if="scope.row.status === 'DRAFT'" v-hasPermi="['warning:warning:remove']" link type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
|
|
@@ -118,7 +116,7 @@
|
|
|
<el-row :gutter="16">
|
|
|
<el-col :span="12">
|
|
|
<el-form-item label="预警类型" prop="warningType">
|
|
|
- <el-select v-model="formData.warningType" placeholder="请选择预警类型" style="width: 100%" @change="handleTypeLevelChange">
|
|
|
+ <el-select v-model="formData.warningType" placeholder="请选择预警类型" style="width: 100%" @change="handleWarningTypeChange">
|
|
|
<el-option
|
|
|
v-for="item in warningTypeOptions"
|
|
|
:key="item.dictValue"
|
|
|
@@ -140,49 +138,9 @@
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
- <el-col :span="24">
|
|
|
- <el-form-item label="关联预警事项">
|
|
|
- <el-select v-model="formData.itemId" clearable filterable :loading="itemLoading" placeholder="可选;不关联事项也可直接发布" style="width:100%" @change="selectItem">
|
|
|
- <el-option v-for="item in itemOptions" :key="item.itemId" :label="`${item.itemName}(${item.itemCode})`" :value="item.itemId" />
|
|
|
- </el-select>
|
|
|
- <div class="el-form-item__extra">仅列出当前类型、级别下启用的事项。关联后带出处置时限与要求。</div>
|
|
|
- </el-form-item>
|
|
|
- <WarningItemSummary :warning="formData" />
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="预警专项">
|
|
|
- <el-input v-model="formData.warningSpecial" placeholder="请输入预警专项" />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="权属单位">
|
|
|
- <el-input v-model="formData.ownershipUnit" placeholder="请输入权属单位" />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="发布人">
|
|
|
- <el-input :model-value="formData.publisher || '发布时确定'" disabled />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="处置人">
|
|
|
- <el-input v-model="formData.handler" placeholder="请选择处置人" readonly @click="openUserPicker">
|
|
|
- <template #suffix>
|
|
|
- <el-icon style="cursor: pointer;" @click="openUserPicker"><Search /></el-icon>
|
|
|
- </template>
|
|
|
- </el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="核查人">
|
|
|
- <el-input v-model="formData.reviewer" placeholder="默认发布人,可选择其他核查人" readonly clearable @click="openReviewerPicker">
|
|
|
- <template #suffix><el-icon style="cursor:pointer" @click="openReviewerPicker"><Search /></el-icon></template>
|
|
|
- </el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
<el-col :span="24">
|
|
|
<el-form-item label="关联设备" prop="deviceCode">
|
|
|
- <el-input :model-value="formData.deviceName || formData.deviceCode" placeholder="点击选择关联设备" readonly @click="openDevicePicker">
|
|
|
+ <el-input :model-value="formData.deviceName || formData.deviceCode" placeholder="请先选择预警类型,再选择对应类型的设备" readonly @click="openDevicePicker">
|
|
|
<template #append>
|
|
|
<el-button :icon="Search" @click="openDevicePicker">选择</el-button>
|
|
|
</template>
|
|
|
@@ -201,6 +159,25 @@
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="关联预警事项">
|
|
|
+ <el-select v-model="formData.itemId" clearable filterable :loading="itemLoading" placeholder="可选;不关联事项也可直接发布" style="width:100%" @change="selectItem">
|
|
|
+ <el-option v-for="item in itemOptions" :key="item.itemId" :label="`${item.itemName}(${item.itemCode})`" :value="item.itemId" />
|
|
|
+ </el-select>
|
|
|
+ <div class="el-form-item__extra">仅列出当前类型、级别下启用的事项。关联后带出处置时限与要求。</div>
|
|
|
+ </el-form-item>
|
|
|
+ <WarningItemSummary :warning="formData" />
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="预警专项">
|
|
|
+ <el-input v-model="formData.warningSpecial" placeholder="请输入预警专项" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="权属单位">
|
|
|
+ <el-input v-model="formData.ownershipUnit" placeholder="请输入权属单位" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
<el-col :span="24" v-if="reasonOptions.length">
|
|
|
<el-form-item label="推荐原因">
|
|
|
<div class="reason-wrap">
|
|
|
@@ -267,90 +244,40 @@
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
|
|
|
- <el-drawer v-model="detailVisible" title="预警详情" size="900px" append-to-body class="detail-drawer" direction="rtl">
|
|
|
- <template v-if="detailData.basicInfo">
|
|
|
- <WarningItemSummary :warning="detailData.basicInfo" />
|
|
|
- <el-descriptions :column="2" border>
|
|
|
- <el-descriptions-item label="预警编号">{{ detailData.basicInfo.warningNo || "-" }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="预警类型">{{ formatTypeText(detailData.basicInfo.warningType) }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="预警级别">
|
|
|
- <el-tag :type="getLevelTagType(detailData.basicInfo.warningLevel)">
|
|
|
- {{ formatLevelText(detailData.basicInfo.warningLevel) }}
|
|
|
- </el-tag>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="预警专项">{{ detailData.basicInfo.warningSpecial || "-" }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="权属单位">{{ detailData.basicInfo.ownershipUnit || "-" }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="发布人">{{ detailData.basicInfo.publisher || "-" }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="处置人">{{ detailData.basicInfo.handler || "-" }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="关联设备" :span="2">
|
|
|
- <template v-if="detailData.basicInfo.deviceCode || detailData.basicInfo.deviceName">
|
|
|
- {{ detailData.basicInfo.deviceName || "-" }}
|
|
|
- <span v-if="detailData.basicInfo.deviceCode" style="color: #909399;">({{ detailData.basicInfo.deviceCode }})</span>
|
|
|
- </template>
|
|
|
- <span v-else>-</span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="发布时间">{{ formatDateTime(detailData.basicInfo.publishTime) }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="状态">
|
|
|
- <WarningStatusTag :status="detailData.basicInfo.status">
|
|
|
- {{ getStatusText(detailData.basicInfo.status) }}
|
|
|
- </WarningStatusTag>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="内容描述" :span="2"><span class="warning-content">{{ detailData.basicInfo.warningContent || "-" }}</span></el-descriptions-item>
|
|
|
- <el-descriptions-item label="备注" :span="2">{{ detailData.basicInfo.remark || "-" }}</el-descriptions-item>
|
|
|
- </el-descriptions>
|
|
|
-
|
|
|
- <el-divider content-position="left">关联报警</el-divider>
|
|
|
- <el-table :data="detailData.alarmList || []" border size="small">
|
|
|
- <el-table-column label="报警ID" prop="alarmId" min-width="160" />
|
|
|
- <el-table-column label="报警名称" prop="alarmName" min-width="180" show-overflow-tooltip />
|
|
|
- <el-table-column label="报警类型" min-width="120">
|
|
|
- <template #default="scope">
|
|
|
- {{ formatTypeText(scope.row.alarmType || scope.row.warningType) }}
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
-
|
|
|
- <el-divider content-position="left">处置记录</el-divider>
|
|
|
- <el-table :data="detailData.disposalHistory || detailData.disposalList || []" border size="small">
|
|
|
- <el-table-column label="处置类型" prop="disposalTypeName" min-width="120" />
|
|
|
- <el-table-column label="处置人" prop="disposalUser" min-width="120" />
|
|
|
- <el-table-column label="处置内容" prop="disposalContent" min-width="220" show-overflow-tooltip />
|
|
|
- <el-table-column label="处置时间" prop="createTime" min-width="180" />
|
|
|
- <el-table-column label="附件" min-width="300">
|
|
|
- <template #default="{ row }">
|
|
|
- <WarningAttachments :attachments="attachmentsForDisposal(row, detailData.attachmentList)" empty-text="无附件" />
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
-
|
|
|
- <el-divider content-position="left">其他预警附件</el-divider>
|
|
|
- <WarningAttachments :attachments="unlinkedWarningAttachments(detailData.disposalHistory, detailData.attachmentList)" empty-text="暂无其他附件" />
|
|
|
- </template>
|
|
|
- </el-drawer>
|
|
|
+ <WarningDetailDrawer v-model="detailVisible" :warning-id="selectedWarningId" />
|
|
|
|
|
|
<!-- 关联设备选择对话框 -->
|
|
|
<el-dialog v-model="devicePickerVisible" title="选择关联设备" width="860px" append-to-body @open="loadDevicePickerData">
|
|
|
<div class="device-picker-container">
|
|
|
- <div class="device-picker-left">
|
|
|
+ <div v-loading="deviceConfigLoading" class="device-picker-left">
|
|
|
<div class="picker-title">设备类型</div>
|
|
|
<button
|
|
|
- :class="{ active: deviceRootTypeId === '' }"
|
|
|
+ :class="{ active: selectedDeviceTypeId === '' }"
|
|
|
class="device-type-item"
|
|
|
- @click="selectDeviceRootType('')"
|
|
|
+ @click="selectDeviceType('')"
|
|
|
>
|
|
|
全部类型
|
|
|
</button>
|
|
|
<button
|
|
|
- v-for="item in deviceRootTypes"
|
|
|
+ v-for="item in availableDeviceTypes"
|
|
|
:key="item.id"
|
|
|
- :class="{ active: String(deviceRootTypeId) === String(item.id) }"
|
|
|
+ :class="{ active: String(selectedDeviceTypeId) === String(item.id) }"
|
|
|
class="device-type-item"
|
|
|
- @click="selectDeviceRootType(item.id)"
|
|
|
+ @click="selectDeviceType(item.id)"
|
|
|
>
|
|
|
{{ item.typeName }}
|
|
|
</button>
|
|
|
+ <div v-if="!deviceConfigLoading && !availableDeviceTypes.length" class="device-type-empty">暂无可选设备类型</div>
|
|
|
</div>
|
|
|
<div class="device-picker-right">
|
|
|
+ <el-alert
|
|
|
+ v-if="!deviceConfigLoading && !deviceTypeIds.length"
|
|
|
+ title="当前预警类型未配置可关联的设备类型"
|
|
|
+ type="warning"
|
|
|
+ :closable="false"
|
|
|
+ show-icon
|
|
|
+ style="margin-bottom: 12px"
|
|
|
+ />
|
|
|
<el-form :inline="true" @submit.prevent>
|
|
|
<el-form-item>
|
|
|
<el-input v-model="deviceQuery.equipmentCode" placeholder="设备编码" clearable style="width: 180px" @keyup.enter="loadDeviceList" />
|
|
|
@@ -388,8 +315,30 @@
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
|
|
|
+ <el-dialog v-model="publishVisible" title="发布预警" width="560px" append-to-body destroy-on-close>
|
|
|
+ <el-form label-width="90px">
|
|
|
+ <el-form-item label="预警编号">
|
|
|
+ <el-input :model-value="publishRow?.warningNo || '-'" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="处置人" required>
|
|
|
+ <el-input v-model="publishForm.handler" placeholder="请选择处置人" readonly @click="openUserPicker('handler')">
|
|
|
+ <template #append><el-button :icon="Search" @click="openUserPicker('handler')">选择</el-button></template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="核验人" required>
|
|
|
+ <el-input v-model="publishForm.reviewer" placeholder="请选择核验人" readonly @click="openUserPicker('reviewer')">
|
|
|
+ <template #append><el-button :icon="Search" @click="openUserPicker('reviewer')">选择</el-button></template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="publishVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" :loading="publishLoading" @click="submitPublish">确认发布</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
<!-- 处置人选择对话框 -->
|
|
|
- <el-dialog v-model="userPickerVisible" :title="pickerTarget === 'reviewer' ? '选择核查人' : '选择处置人'" width="900px" append-to-body @open="loadUserPickerData" @closed="closeUserPicker">
|
|
|
+ <el-dialog v-model="userPickerVisible" :title="pickerTarget === 'reviewer' ? '选择核验人' : '选择处置人'" width="900px" append-to-body @open="loadUserPickerData" @closed="closeUserPicker">
|
|
|
<el-alert v-if="userPickerError" :title="userPickerError" type="error" :closable="false" show-icon style="margin-bottom: 12px">
|
|
|
<el-button link type="primary" @click="loadUserPickerData">重新加载</el-button>
|
|
|
</el-alert>
|
|
|
@@ -445,6 +394,8 @@
|
|
|
|
|
|
<script setup>
|
|
|
import WarningStatusTag from "../components/WarningStatusTag.vue"
|
|
|
+import WarningContentCell from "../components/WarningContentCell.vue"
|
|
|
+import WarningDetailDrawer from "../components/WarningDetailDrawer.vue"
|
|
|
import { useWarningStatuses } from '@/views/subSystem/lifeCompany/warningWorkflow'
|
|
|
const { warningStatusOptions, databaseStatusLabels } = useWarningStatuses()
|
|
|
import WarningItemSummary from '../components/WarningItemSummary.vue';
|
|
|
@@ -452,19 +403,17 @@ import {computed, onMounted, reactive, ref, watch} from "vue";
|
|
|
import {ElMessage, ElMessageBox} from "element-plus";
|
|
|
import { Search } from "@element-plus/icons-vue";
|
|
|
import { parseTime } from "@/utils/ruoyi";
|
|
|
-import WarningDisposalReasons from '../components/WarningDisposalReasons.vue';
|
|
|
-import WarningAttachments from "../components/WarningAttachments.vue";
|
|
|
-import { attachmentsForDisposal, unlinkedWarningAttachments } from "../warningAttachments";
|
|
|
+import { getWarningFullDetailData } from "@/api/pipeNetwork/earlyWarning";
|
|
|
import { listEquipment, listEquipmentTypeAll } from "@/api/pipeNetwork/pdeviceInform";
|
|
|
import {
|
|
|
deleteYjxxData,
|
|
|
getAlertTypeDictionaryData,
|
|
|
getdbyjlistData,
|
|
|
- getWarningDetailData,
|
|
|
getWarningReasonListData,
|
|
|
getWarningItemListData,
|
|
|
getWarningParticipantDepartments,
|
|
|
getWarningParticipants,
|
|
|
+ getWarningEquipmentTypeIdsData,
|
|
|
releaseYjxxData,
|
|
|
submitYjxxData,
|
|
|
updateYjxxData
|
|
|
@@ -488,19 +437,25 @@ const editVisible = ref(false);
|
|
|
const detailVisible = ref(false);
|
|
|
const userPickerVisible = ref(false);
|
|
|
const pickerTarget = ref('handler');
|
|
|
+const publishVisible = ref(false);
|
|
|
+const publishLoading = ref(false);
|
|
|
+const publishRow = ref(null);
|
|
|
+const publishForm = reactive({ handler: '', reviewer: '' });
|
|
|
const dialogTitle = ref("新增预警");
|
|
|
const isEdit = ref(false);
|
|
|
const formRef = ref();
|
|
|
-const detailData = ref({});
|
|
|
+const selectedWarningId = ref("");
|
|
|
|
|
|
// 关联设备选择器
|
|
|
const devicePickerVisible = ref(false);
|
|
|
-const deviceRootTypeId = ref("");
|
|
|
-const deviceRootTypes = ref([]);
|
|
|
+const selectedDeviceTypeId = ref("");
|
|
|
+const availableDeviceTypes = ref([]);
|
|
|
const deviceList = ref([]);
|
|
|
const deviceTotal = ref(0);
|
|
|
const deviceLoading = ref(false);
|
|
|
+const deviceConfigLoading = ref(false);
|
|
|
const deviceTypeNameMap = ref({});
|
|
|
+const deviceTypeIds = ref([]);
|
|
|
const deviceQuery = reactive({
|
|
|
pageNum: 1,
|
|
|
pageSize: 10,
|
|
|
@@ -574,10 +529,7 @@ function createEmptyForm() {
|
|
|
|
|
|
|
|
|
ownershipUnit: "",
|
|
|
- publisher: "",
|
|
|
publishTime: "",
|
|
|
- handler: "",
|
|
|
- reviewer: "",
|
|
|
status: "DRAFT",
|
|
|
warningContent: "",
|
|
|
remark: ""
|
|
|
@@ -590,6 +542,8 @@ function resetForm() {
|
|
|
itemOptions.value = [];
|
|
|
itemRequestVersion++;
|
|
|
formAttachments.value = [];
|
|
|
+ deviceTypeIds.value = [];
|
|
|
+ selectedDeviceTypeId.value = '';
|
|
|
uploadRef.value?.clearFiles?.();
|
|
|
formRef.value?.clearValidate();
|
|
|
}
|
|
|
@@ -695,25 +649,6 @@ function normalizeWarningRow(item) {
|
|
|
return row;
|
|
|
}
|
|
|
|
|
|
-function normalizeAlarmRow(item) {
|
|
|
- return {
|
|
|
- ...item,
|
|
|
- alarmId: item.alarmId || item.alarm_id || "",
|
|
|
- alarmName: item.alarmName || item.alarm_name || item.deviceName || item.device_name || "",
|
|
|
- alarmType: item.alarmType || item.alarm_type || item.warningType || item.warning_type || ""
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-function normalizeDisposalRow(item) {
|
|
|
- return {
|
|
|
- ...item,
|
|
|
- disposalTypeName: item.disposalTypeName || item.disposal_type_name || item.disposalType || item.disposal_type || "",
|
|
|
- disposalUser: item.disposalUser || item.disposal_user || "",
|
|
|
- disposalContent: item.disposalContent || item.disposal_content || "",
|
|
|
- createTime: item.createTime || item.create_time || ""
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
async function loadDicts() {
|
|
|
const [typeResult, levelResult] = await Promise.allSettled([
|
|
|
getAlertTypeDictionaryData({ dictType: "alert_type" }),
|
|
|
@@ -744,6 +679,14 @@ function handleTypeLevelChange() {
|
|
|
loadReasonOptions().catch(() => { reasonOptions.value = []; });
|
|
|
loadItemOptions();
|
|
|
}
|
|
|
+
|
|
|
+function handleWarningTypeChange() {
|
|
|
+ formData.deviceCode = '';
|
|
|
+ formData.deviceName = '';
|
|
|
+ deviceTypeIds.value = [];
|
|
|
+ formRef.value?.clearValidate('deviceCode');
|
|
|
+ handleTypeLevelChange();
|
|
|
+}
|
|
|
async function loadItemOptions() {
|
|
|
const version = ++itemRequestVersion;
|
|
|
itemOptions.value = [];
|
|
|
@@ -885,16 +828,8 @@ function handleUserCurrentChange(row) {
|
|
|
selectedUser.value = row;
|
|
|
}
|
|
|
|
|
|
-function openUserPicker() {
|
|
|
- pickerTarget.value = 'handler';
|
|
|
- selectedUser.value = null;
|
|
|
- userFilterText.value = "";
|
|
|
- deptFilterText.value = "";
|
|
|
- userPickerVisible.value = true;
|
|
|
-}
|
|
|
-
|
|
|
-function openReviewerPicker() {
|
|
|
- pickerTarget.value = 'reviewer';
|
|
|
+function openUserPicker(target) {
|
|
|
+ pickerTarget.value = target;
|
|
|
selectedUser.value = null;
|
|
|
userFilterText.value = '';
|
|
|
deptFilterText.value = '';
|
|
|
@@ -906,39 +841,60 @@ function confirmSelectUser() {
|
|
|
ElMessage.warning("请选择用户");
|
|
|
return;
|
|
|
}
|
|
|
- formData[pickerTarget.value] = selectedUser.value.userName;
|
|
|
+ publishForm[pickerTarget.value] = selectedUser.value.userName;
|
|
|
userPickerVisible.value = false;
|
|
|
}
|
|
|
|
|
|
function openDevicePicker() {
|
|
|
+ if (!formData.warningType) {
|
|
|
+ ElMessage.warning('请先选择预警类型');
|
|
|
+ return;
|
|
|
+ }
|
|
|
devicePickerVisible.value = true;
|
|
|
}
|
|
|
|
|
|
async function loadDevicePickerData() {
|
|
|
+ deviceConfigLoading.value = true;
|
|
|
+ selectedDeviceTypeId.value = '';
|
|
|
deviceQuery.pageNum = 1;
|
|
|
deviceQuery.equipmentCode = "";
|
|
|
deviceQuery.equipmentName = "";
|
|
|
try {
|
|
|
- const typeRes = await listEquipmentTypeAll();
|
|
|
+ const [typeRes, relationRes] = await Promise.all([
|
|
|
+ listEquipmentTypeAll(),
|
|
|
+ getWarningEquipmentTypeIdsData(formData.warningType)
|
|
|
+ ]);
|
|
|
const allTypes = typeRes.data || [];
|
|
|
- deviceRootTypes.value = allTypes.filter((t) => String(t.parentId) === "0" || t.parentId === 0 || t.parentId === null || t.parentId === undefined || t.parentId === "");
|
|
|
+ deviceTypeIds.value = (relationRes.data || []).map(String);
|
|
|
+ const allowed = new Set(deviceTypeIds.value);
|
|
|
+ // 左栏名称和主键直接取 equipment_type 接口,关联表只负责约束可选范围。
|
|
|
+ availableDeviceTypes.value = allTypes.filter(type => allowed.has(String(type.id)));
|
|
|
deviceTypeNameMap.value = allTypes.reduce((acc, t) => {
|
|
|
acc[t.id] = t.typeName;
|
|
|
return acc;
|
|
|
}, {});
|
|
|
} catch (e) {
|
|
|
- deviceRootTypes.value = [];
|
|
|
+ availableDeviceTypes.value = [];
|
|
|
+ deviceTypeIds.value = [];
|
|
|
+ ElMessage.error(e?.msg || e?.message || '加载预警类型对应设备失败');
|
|
|
+ } finally {
|
|
|
+ deviceConfigLoading.value = false;
|
|
|
}
|
|
|
await loadDeviceList();
|
|
|
}
|
|
|
|
|
|
-function selectDeviceRootType(rootTypeId) {
|
|
|
- deviceRootTypeId.value = rootTypeId === "" ? "" : String(rootTypeId);
|
|
|
+function selectDeviceType(typeId) {
|
|
|
+ selectedDeviceTypeId.value = typeId === "" ? "" : String(typeId);
|
|
|
deviceQuery.pageNum = 1;
|
|
|
loadDeviceList();
|
|
|
}
|
|
|
|
|
|
async function loadDeviceList() {
|
|
|
+ if (!deviceTypeIds.value.length) {
|
|
|
+ deviceList.value = [];
|
|
|
+ deviceTotal.value = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
deviceLoading.value = true;
|
|
|
try {
|
|
|
const res = await listEquipment({
|
|
|
@@ -946,7 +902,8 @@ async function loadDeviceList() {
|
|
|
pageSize: deviceQuery.pageSize,
|
|
|
equipmentCode: deviceQuery.equipmentCode || undefined,
|
|
|
equipmentName: deviceQuery.equipmentName || undefined,
|
|
|
- rootTypeId: deviceRootTypeId.value || undefined
|
|
|
+ equipmentTypeId: selectedDeviceTypeId.value || undefined,
|
|
|
+ equipmentTypeIds: deviceTypeIds.value.join(',')
|
|
|
});
|
|
|
deviceList.value = res.records || [];
|
|
|
deviceTotal.value = Number(res.total || 0);
|
|
|
@@ -980,9 +937,8 @@ async function handleEdit(row) {
|
|
|
dialogTitle.value = "编辑预警";
|
|
|
resetForm();
|
|
|
Object.assign(formData, { ...row });
|
|
|
- const detailRes = await getWarningDetailData(row.warningId);
|
|
|
+ const detailRes = await getWarningFullDetailData(row.warningId);
|
|
|
const detail = detailRes.data || {};
|
|
|
- formData.reviewer = detail.basicInfo?.reviewer || "";
|
|
|
formAttachments.value = (detail.attachmentList || []).map(normalizeExistingAttachment);
|
|
|
formData.itemId = detail.basicInfo?.item_id || detail.basicInfo?.itemId || "";
|
|
|
formData.itemSnapshot = detail.basicInfo?.item_snapshot || detail.basicInfo?.itemSnapshot || "";
|
|
|
@@ -1007,8 +963,6 @@ async function submitForm() {
|
|
|
|
|
|
|
|
|
ownershipUnit: formData.ownershipUnit,
|
|
|
- handler: formData.handler,
|
|
|
- reviewer: formData.reviewer,
|
|
|
warningContent: formData.warningContent,
|
|
|
deviceCode: formData.deviceCode || "",
|
|
|
deviceName: formData.deviceName || "",
|
|
|
@@ -1030,15 +984,7 @@ async function submitForm() {
|
|
|
}
|
|
|
|
|
|
async function handleView(row) {
|
|
|
- const res = await getWarningDetailData(row.warningId);
|
|
|
- const detail = res.data || {};
|
|
|
- const basicSource = detail.basicInfo || detail;
|
|
|
- detailData.value = {
|
|
|
- ...detail,
|
|
|
- basicInfo: normalizeWarningRow({ ...row, ...basicSource }),
|
|
|
- alarmList: (detail.alarmList || []).map(normalizeAlarmRow),
|
|
|
- disposalHistory: (detail.disposalHistory || detail.disposalList || []).map(normalizeDisposalRow)
|
|
|
- };
|
|
|
+ selectedWarningId.value = row.warningId;
|
|
|
detailVisible.value = true;
|
|
|
}
|
|
|
|
|
|
@@ -1054,18 +1000,33 @@ async function handleDelete(row) {
|
|
|
}
|
|
|
|
|
|
async function handlePublish(row) {
|
|
|
- if (!row.handler) {
|
|
|
- ElMessage.warning("发布前请先编辑预警并选择处置人");
|
|
|
+ publishRow.value = row;
|
|
|
+ publishForm.handler = '';
|
|
|
+ publishForm.reviewer = '';
|
|
|
+ publishVisible.value = true;
|
|
|
+}
|
|
|
+
|
|
|
+async function submitPublish() {
|
|
|
+ if (!publishForm.handler || !publishForm.reviewer) {
|
|
|
+ ElMessage.warning('请选择处置人和核验人');
|
|
|
return;
|
|
|
}
|
|
|
- await ElMessageBox.confirm(`确认发布预警“${row.warningNo}”吗?`, "提示", { type: "warning" });
|
|
|
- const res = await releaseYjxxData(row.warningId, { reviewer: row.reviewer || undefined });
|
|
|
- if (res.code !== 200) {
|
|
|
- ElMessage.error(res.msg || "发布失败");
|
|
|
- return;
|
|
|
+ publishLoading.value = true;
|
|
|
+ try {
|
|
|
+ const res = await releaseYjxxData(publishRow.value.warningId, {
|
|
|
+ handler: publishForm.handler,
|
|
|
+ reviewer: publishForm.reviewer
|
|
|
+ });
|
|
|
+ if (res.code !== 200) {
|
|
|
+ ElMessage.error(res.msg || '发布失败');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ElMessage.success('发布成功');
|
|
|
+ publishVisible.value = false;
|
|
|
+ await loadList();
|
|
|
+ } finally {
|
|
|
+ publishLoading.value = false;
|
|
|
}
|
|
|
- ElMessage.success("发布成功");
|
|
|
- loadList();
|
|
|
}
|
|
|
|
|
|
onMounted(async () => {
|
|
|
@@ -1259,4 +1220,13 @@ onMounted(async () => {
|
|
|
background: #eff6ff;
|
|
|
font-weight: 600;
|
|
|
}
|
|
|
+
|
|
|
+.device-type-empty {
|
|
|
+ padding: 16px 4px;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 1.5;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
</style>
|