pull/1/head
LiuJiaNan 2024-01-26 10:24:28 +08:00
parent bd76ab2a39
commit 41f08a759e
21 changed files with 3676 additions and 1 deletions

View File

@ -1971,4 +1971,71 @@ export default [
},
],
},
{
path: "/major_hazard_sources",
redirect: "/major_hazard_sources/major_hazard_management",
meta: { title: "重大危险源监测预警", model: MODEL["4"] },
component: "children",
children: [
{
path: "/major_hazard_sources/major_hazard_management",
meta: { title: "重大危险源管理", isSubMenu: false },
component: "children",
children: [
{
path: "",
component: "major_hazard_sources/major_hazard_management/index",
},
{
path: "/major_hazard_sources/major_hazard_management/add",
meta: {
title: "新增",
activeMenu: "/major_hazard_sources/major_hazard_management",
},
component: "major_hazard_sources/major_hazard_management/add",
},
{
path: "/major_hazard_sources/major_hazard_management/edit",
meta: {
title: "修改",
activeMenu: "/major_hazard_sources/major_hazard_management",
},
component: "major_hazard_sources/major_hazard_management/add",
},
{
path: "/major_hazard_sources/major_hazard_management/view",
meta: {
title: "查看",
activeMenu: "/major_hazard_sources/major_hazard_management",
},
component: "major_hazard_sources/major_hazard_management/view",
},
{
path: "/major_hazard_sources/major_hazard_management/change_record",
meta: {
title: "变更记录",
activeMenu: "/major_hazard_sources/major_hazard_management",
},
component: "children",
children: [
{
path: "",
component:
"major_hazard_sources/major_hazard_management/change_record",
},
{
path: "/major_hazard_sources/major_hazard_management/change_record/view",
meta: {
title: "变更详情",
activeMenu: "/major_hazard_sources/major_hazard_management",
},
component:
"major_hazard_sources/major_hazard_management/change_view",
},
],
},
],
},
],
},
];

View File

@ -237,6 +237,20 @@ export const layoutFnGetCommitmentLevel = async () => {
});
return ref(resData.list);
};
// 申报等级
export const layoutFnGetDeclarationGrade = async () => {
const resData = await getLevels({
DICTIONARIES_ID: "246a2fe3af964eb18f0e005339e334dd",
});
return ref(resData.list);
};
// 重大危险源类型
export const layoutFnGetMajorHazardSourceType = async () => {
const resData = await getLevels({
DICTIONARIES_ID: "6f7469fadb75401e9928edb0ab19b17e",
});
return ref(resData.list);
};
// 部门树
export const layoutFnGetDepartmentTree = async (params) => {
const resData = await getDepartmentTree(params);

View File

@ -5,7 +5,9 @@ export default async function useDownloadFile(url, name) {
if (!url) throw new Error("没有下载地址");
await ElMessageBox.confirm("确定要下载此文件吗?", { type: "warning" });
const FILE_URL = import.meta.env.VITE_FILE_URL;
name = name ? name + getFileSuffix(url) : getFileName(url);
if (name) {
if (!getFileSuffix(url)) name = name + getFileSuffix(url);
} else name = getFileName(url);
fetch(FILE_URL + url)
.then((res) => res.blob())
.then((blob) => {

View File

@ -0,0 +1,68 @@
import { post, upload } from "@/request/axios.js";
export const getMajorHazardManagementList = (params) =>
post("/majordangersource/list", params); // 重大危险源管理列表
export const setMajorHazardManagementDelete = (params) =>
post("/majordangersource/delete", params); // 重大危险源管理删除
export const setMajorHazardManagementDeleteMultiple = (params) =>
post("/majordangersource/deleteAll", params); // 重大危险源管理删除多选
export const setMajorHazardManagementAdd = (params) =>
upload("/majordangersource/add", params); // 重大危险源添加
export const setMajorHazardManagementEdit = (params) =>
upload("/majordangersource/edit", params); // 重大危险源修改
export const getMajorHazardManagementView = (params) =>
post("/majordangersource/goEdit", params); // 重大危险源查看
export const getMajorHazardManagementChangeRecordList = (params) =>
post("/majordangersourcelog/list", params); // 重大危险源变更记录列表
export const getMajorHazardManagementChangeRecordView = (params) =>
post("/majordangersourcelog/goCompare", params); // 重大危险源变更记录查看
export const getMonitoringTypeManagementList = (params) =>
post("/dictionariesCorp/list", params); // 监测类型管理列表
export const setMonitoringTypeManagementDelete = (params) =>
post("/dictionariesCorp/delete", params); // 监测类型管理删除
export const setMonitoringTypeManagementDeleteMultiple = (params) =>
post("/dictionariesCorp/deleteAll", params); // 监测类型管理删除多选
export const setMonitoringTypeManagementAdd = (params) =>
post("/dictionariesCorp/add", params); // 监测类型管理添加
export const setMonitoringTypeManagementEdit = (params) =>
post("/dictionariesCorp/edit", params); // 监测类型管理修改
export const getDataCollectionThresholdSettingList = (params) =>
post("/majordangersource/list", params); // 数据采集阈值设定列表
export const setDataCollectionThresholdSettingDeactivate = (params) =>
post("/monitoringdevicedisable/add", params); // 数据采集阈值设定停用
export const setDataCollectionThresholdSettingEnable = (params) =>
post("/majordangersource/enable", params); // 数据采集阈值设定启用
export const getDataCollectionThresholdSettingThresholdSettingList = (params) =>
post("/monitoringdevicesensor/list", params); // 数据采集阈值设定阈值设定列表
export const setDataCollectionThresholdSettingThresholdSettingDelete = (
params
) => post("/monitoringdevicesensor/delete", params); // 数据采集阈值设定阈值设定删除
export const setDataCollectionThresholdSettingThresholdSettingDeleteMultiple = (
params
) => post("/monitoringdevicesensor/deleteAll", params); // 数据采集阈值设定阈值设定删除多选
export const setDataCollectionThresholdSettingThresholdSettingAdd = (params) =>
post("/monitoringdevicesensor/add", params); // 数据采集阈值设定阈值设定添加
export const setDataCollectionThresholdSettingThresholdSettingEdit = (params) =>
post("/monitoringdevicesensor/edit", params); // 数据采集阈值设定阈值设定修改
export const getDataCollectionThresholdSettingThresholdSettingView = (params) =>
post("/monitoringdevicesensor/goEdit", params); // 数据采集阈值设定阈值设定查看
export const getDataCollectionThresholdSettingView = (params) =>
post("/majordangersource/goShow", params); // 数据采集阈值设定查看
export const getRealTimeDataMonitoringEquipment = (params) =>
post("/majordangersource/findRealTimeMonitoringListAll", params); // 实时数据监测设备
export const getRealTimeDataMonitoringEquipmentInfo = (params) =>
post("/majordangersource/goShow", params); // 实时数据监测设备信息
export const getRealTimeDataMonitoringEquipmentDisposal = (params) =>
post("/majordangersourcedisposal/findValidateData", params); // 实时数据监测设备获取最新的有效报警数据
export const getRealTimeDataMonitoringEquipmentData = (params) =>
post("/storagetank/goEdit", params); // 实时数据监测设备获取监测数据实时数据
export const getRealTimeDataMonitoringEquipmentLogList = (params) =>
post("/storagetanklog/list", params); // 实时数据监测设备获取监测数据对接记录
export const setRealTimeDataMonitoringEquipmentEdit = (params) =>
post("/majordangersourcedisposal/edit", params); // 实时数据监测设备应急处置修改
export const getEmergencyHandlingRecordList = (params) =>
post("/majordangersourcedisposal/list", params); // 应急处理记录列表
export const setEmergencyHandlingRecordFalseAlarm = (params) =>
post("/majordangersourcedisposal/editAlarmFalse", params); // 应急处理记录设置成误报
export const getEmergencyHandlingRecordView = (params) =>
post("/majordangersourcedisposal/goShow", params); // 应急处理记录查看

View File

@ -75,7 +75,14 @@ const fnMapInit = async () => {
styleId: "6f501abeb2a0cc0d961d110b9407b127",
});
loading.value = false;
const point = new window.BMapGL.Point(props.longitude, props.latitude);
const marker = new window.BMapGL.Marker(point);
mapInstance.addOverlay(marker);
mapInstance.addEventListener("click", function (event) {
mapInstance.clearOverlays();
const point = new window.BMapGL.Point(event.latlng.lng, event.latlng.lat);
const marker = new window.BMapGL.Marker(point);
mapInstance.addOverlay(marker);
currentLatitude.value = event.latlng.lat;
currentLongitude.value = event.latlng.lng;
});

View File

@ -0,0 +1,330 @@
<template>
<div>
<el-card>
<el-form
:model="data.searchForm"
label-width="120px"
@submit.prevent="fnResetPagination"
>
<el-row>
<el-col :span="5">
<el-form-item label="重大危险源名称" prop="KEYWORDS">
<el-input v-model="data.searchForm.KEYWORDS" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="重大危险源类型" prop="MAJORDANGERSOURCE_TYPE">
<el-select v-model="data.searchForm.MAJORDANGERSOURCE_TYPE">
<el-option
v-for="item in majorHazardSourceTypeList"
:key="item.BIANMA"
:label="item.NAME"
:value="item.BIANMA"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item
label="重大危险源状态"
prop="MAJORDANGERSOURCE_STATUS"
>
<el-select v-model="data.searchForm.MAJORDANGERSOURCE_STATUS">
<el-option
v-for="item in majorHazardSourceStateList"
:key="item.ID"
:label="item.NAME"
:value="item.ID"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item
label="责任人"
prop="RESPONSIBLE_PERSON_NAME"
label-width="70px"
>
<el-input v-model="data.searchForm.RESPONSIBLE_PERSON_NAME" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label-width="10px">
<el-button type="primary" native-type="submit">搜索</el-button>
<el-button native-type="reset" @click="fnResetPagination">
重置
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<layout-card>
<layout-table
:data="data.list"
@get-data="fnGetData"
v-model:pagination="data.pagination"
>
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(data.pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="MAJORDANGERSOURCE_NAME" label="重大危险源名称" />
<el-table-column
prop="MAJORDANGERSOURCE_NUMBER"
label="重大危险源编号"
/>
<el-table-column
prop="MAJORDANGERSOURCE_TYPE_NAME"
label="重大危险源类型"
/>
<el-table-column
prop="MAJORDANGERSOURCE_ADDRESS"
label="重大危险源地址"
/>
<el-table-column prop="RESPONSIBLE_PERSON" label="责任人" />
<el-table-column label="状态">
<template v-slot="{ row }">
{{
fnTranslationStatus(
row.MAJORDANGERSOURCE_STATUS,
majorHazardSourceStateList
)
}}
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template v-slot="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: '/major_hazard_sources/data_collection_threshold_setting/view',
query: { MAJORDANGERSOURCE_ID: row.MAJORDANGERSOURCE_ID },
})
"
>
查看
</el-button>
<el-button
v-if="
buttonJurisdiction.edit && row.MAJORDANGERSOURCE_STATUS === '1'
"
type="primary"
text
link
@click="
router.push({
path: '/major_hazard_sources/data_collection_threshold_setting/threshold_setting',
query: { MAJORDANGERSOURCE_ID: row.MAJORDANGERSOURCE_ID },
})
"
>
阈值设定
</el-button>
<el-button
v-if="
buttonJurisdiction.edit && row.MAJORDANGERSOURCE_STATUS === '1'
"
type="primary"
text
link
@click="fnDeactivate(row.MAJORDANGERSOURCE_ID)"
>
停用
</el-button>
<el-button
v-if="
buttonJurisdiction.edit && row.MAJORDANGERSOURCE_STATUS !== '1'
"
type="primary"
text
link
@click="fnEnable(row.MAJORDANGERSOURCE_ID)"
>
启用
</el-button>
</template>
</el-table-column>
</layout-table>
</layout-card>
<el-dialog v-model="data.deactivateDialog.visible" title="设备停用">
<el-form
ref="deactivateDialogFormRef"
:rules="data.deactivateDialog.rules"
:model="data.deactivateDialog.form"
label-width="150px"
>
<el-form-item label="停用状态" prop="DISABLE_STATUS">
<el-select v-model="data.deactivateDialog.form.DISABLE_STATUS">
<el-option
v-for="item in [
{ ID: '2', NAME: '停用' },
{ ID: '3', NAME: '检修' },
]"
:key="item.ID"
:label="item.NAME"
:value="item.ID"
/>
</el-select>
</el-form-item>
<el-form-item label="停用开始时间" prop="DISABLE_TIME_START">
<el-date-picker
v-model="data.deactivateDialog.form.DISABLE_TIME_START"
format="YYYY-MM-DD HH:mm"
value-format="YYYY-MM-DD HH:mm"
type="datetime"
/>
</el-form-item>
<el-form-item label="停用结束时间" prop="DISABLE_TIME_END">
<el-date-picker
v-model="data.deactivateDialog.form.DISABLE_TIME_END"
format="YYYY-MM-DD HH:mm"
value-format="YYYY-MM-DD HH:mm"
type="datetime"
/>
</el-form-item>
<el-form-item label="停用原因" prop="DISABLE_REASON">
<el-input
v-model="data.deactivateDialog.form.DISABLE_REASON"
autosize
type="textarea"
/>
</el-form-item>
<el-form-item label="停用人" prop="DISABLE_USER">
<el-input v-model="data.deactivateDialog.form.DISABLE_USER" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="fnDeactivateDialogChangeShow"></el-button>
<el-button type="primary" @click="fnDeactivateDialogSubmit">
确定
</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { nextTick, reactive, ref } from "vue";
import { fnTranslationStatus, serialNumber } from "@/assets/js/utils";
import {
getDataCollectionThresholdSettingList,
setDataCollectionThresholdSettingDeactivate,
setDataCollectionThresholdSettingEnable,
} from "@/request/major_hazard_sources";
import { layoutFnButtonJurisdiction } from "@/assets/js/button_jurisdiction";
import { layoutFnGetMajorHazardSourceType } from "@/assets/js/data_dictionary.js";
import { debounce } from "throttle-debounce";
import { useUserStore } from "@/pinia/user.js";
import { ElMessage, ElMessageBox } from "element-plus";
import { useRouter } from "vue-router";
import useFormValidate from "@/assets/js/useFormValidate.js";
const userStore = useUserStore();
const router = useRouter();
const deactivateDialogFormRef = ref(null);
const data = reactive({
list: [],
pagination: {
currentPage: 1,
pageSize: 10,
total: 0,
},
searchForm: {},
deactivateDialog: {
visible: false,
MAJORDANGERSOURCE_ID: "",
form: {
DISABLE_STATUS: "",
DISABLE_TIME_START: "",
DISABLE_TIME_END: "",
DISABLE_REASON: "",
DISABLE_USER: userStore.getUserInfo.NAME,
},
rules: {
DISABLE_STATUS: [
{ required: true, message: "停用状态不能为空", trigger: "blur" },
],
DISABLE_TIME_START: [
{ required: true, message: "请选择停用开始时间", trigger: "blur" },
],
DISABLE_TIME_END: [
{ required: true, message: "请选择停用结束时间", trigger: "blur" },
],
DISABLE_REASON: [
{ required: true, message: "停用原因不能为空", trigger: "blur" },
],
DISABLE_USER: [
{ required: true, message: "停用人不能为空", trigger: "blur" },
],
},
},
});
const fnGetData = async () => {
const resData = await getDataCollectionThresholdSettingList({
currentPage: data.pagination.currentPage,
showCount: data.pagination.pageSize,
...data.searchForm,
});
data.list = resData.varList;
data.pagination.total = resData.page.totalResult;
};
fnGetData();
const buttonJurisdiction = await layoutFnButtonJurisdiction(
"majordangersource"
);
const majorHazardSourceTypeList = await layoutFnGetMajorHazardSourceType();
const majorHazardSourceStateList = [
{ ID: "1", NAME: "正常" },
{ ID: "2", NAME: "停用" },
{ ID: "3", NAME: "检修" },
];
const fnResetPagination = () => {
data.pagination = {
currentPage: 1,
pageSize: 10,
total: 0,
};
fnGetData();
};
const fnDeactivateDialogChangeShow = () => {
data.deactivateDialog.visible = !data.deactivateDialog.visible;
};
const fnDeactivate = async (MAJORDANGERSOURCE_ID) => {
fnDeactivateDialogChangeShow();
data.deactivateDialog.MAJORDANGERSOURCE_ID = MAJORDANGERSOURCE_ID;
await nextTick();
deactivateDialogFormRef.value.resetFields();
};
const fnDeactivateDialogSubmit = debounce(
1000,
async () => {
await useFormValidate(deactivateDialogFormRef);
const { form, MAJORDANGERSOURCE_ID } = data.deactivateDialog;
await setDataCollectionThresholdSettingDeactivate({
...form,
MAJORDANGERSOURCE_ID,
});
fnDeactivateDialogChangeShow();
ElMessage.success("停用成功");
fnResetPagination();
},
{ atBegin: true }
);
const fnEnable = debounce(
1000,
async (MAJORDANGERSOURCE_ID) => {
await ElMessageBox.confirm("确定要启用危险源吗?", { type: "warning" });
await setDataCollectionThresholdSettingEnable({ MAJORDANGERSOURCE_ID });
ElMessage.success("启用成功");
fnResetPagination();
},
{ atBegin: true }
);
</script>
<style scoped></style>

View File

@ -0,0 +1,476 @@
<template>
<div>
<layout-card>
<layout-table
ref="tableRef"
row-key="MONITORINGDEVICESENSOR_ID"
:data="data.list"
@get-data="fnGetData"
v-model:pagination="data.pagination"
>
<el-table-column reserve-selection type="selection" width="55" />
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(data.pagination, $index) }}
</template>
</el-table-column>
<el-table-column
prop="MONITORINGDEVICESENSOR_TYPE_NAME"
label="监测数据类型"
/>
<el-table-column label="量程">
<el-table-column prop="RANGE_MIN" label="下限" />
<el-table-column prop="RANGE_MAX" label="上限" />
</el-table-column>
<el-table-column label="一级预警">
<el-table-column prop="RANGE1_MIN" label="下限" />
<el-table-column prop="RANGE1_MAX" label="上限" />
</el-table-column>
<el-table-column label="二级预警">
<el-table-column prop="RANGE2_MIN" label="下限" />
<el-table-column prop="RANGE2_MAX" label="上限" />
</el-table-column>
<el-table-column label="三级预警">
<el-table-column prop="RANGE3_MIN" label="下限" />
<el-table-column prop="RANGE3_MAX" label="上限" />
</el-table-column>
<el-table-column label="四级预警">
<el-table-column prop="RANGE4_MIN" label="下限" />
<el-table-column prop="RANGE4_MAX" label="上限" />
</el-table-column>
<el-table-column label="操作" width="200">
<template v-slot="{ row }">
<el-button
v-if="buttonJurisdiction.edit"
type="primary"
text
link
@click="fnAddOrEdit(row.MONITORINGDEVICESENSOR_ID, 'edit')"
>
编辑
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="primary"
text
link
@click="fnDelete(row.MONITORINGDEVICESENSOR_ID)"
>
删除
</el-button>
</template>
</el-table-column>
<template #button>
<el-button
v-if="buttonJurisdiction.add"
type="primary"
@click="fnAddOrEdit('', 'add')"
>
新增
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="danger"
@click="fnDeleteAll"
>
删除
</el-button>
</template>
</layout-table>
</layout-card>
<el-dialog
v-model="data.addOrEditDialog.visible"
:title="data.addOrEditDialog.type === 'add' ? '添加' : '修改'"
>
<el-form
ref="addOrEditDialogFormRef"
:rules="data.addOrEditDialog.rules"
:model="data.addOrEditDialog.form"
label-width="110px"
>
<el-row>
<el-col :span="24">
<el-form-item
label="监测数据类型"
prop="MONITORINGDEVICESENSOR_TYPE"
>
<el-select
v-model="data.addOrEditDialog.form.MONITORINGDEVICESENSOR_TYPE"
:disabled="data.addOrEditDialog.type === 'edit'"
>
<el-option
v-for="item in data.addOrEditDialog.equipmentTypeList"
:key="item.BIANMA"
:label="item.NAME"
:value="item.BIANMA"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="量程下限" prop="RANGE_MIN">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE_MIN"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="量程上限" prop="RANGE_MAX">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE_MAX"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="一级预警下限" prop="RANGE1_MIN">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE1_MIN"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="一级预警上限" prop="RANGE1_MAX">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE1_MAX"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="二级预警下限" prop="RANGE2_MIN">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE2_MIN"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="二级预警上限" prop="RANGE2_MAX">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE2_MAX"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="三级预警下限" prop="RANGE3_MIN">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE3_MIN"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="三级预警上限" prop="RANGE3_MAX">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE3_MAX"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="四级预警下限" prop="RANGE4_MIN">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE4_MIN"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="四级预警上限" prop="RANGE4_MAX">
<el-input-number
v-model="data.addOrEditDialog.form.RANGE4_MAX"
:precision="2"
:step="0.01"
:mix="0"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="fnAddOrEditDialogChangeShow"></el-button>
<el-button type="primary" @click="fnAddOrEditDialogSubmit">
确定
</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { nextTick, reactive, ref } from "vue";
import { serialNumber } from "@/assets/js/utils";
import {
getDataCollectionThresholdSettingThresholdSettingList,
getDataCollectionThresholdSettingThresholdSettingView,
setDataCollectionThresholdSettingThresholdSettingAdd,
setDataCollectionThresholdSettingThresholdSettingDelete,
setDataCollectionThresholdSettingThresholdSettingDeleteMultiple,
setDataCollectionThresholdSettingThresholdSettingEdit,
} from "@/request/major_hazard_sources";
import { debounce } from "throttle-debounce";
import { ElMessage, ElMessageBox } from "element-plus";
import { layoutFnButtonJurisdiction } from "@/assets/js/button_jurisdiction.js";
import { useRoute } from "vue-router";
import { layoutFnGetEquipmentTypeCorp } from "@/assets/js/data_dictionary.js";
import CloneDeep from "lodash-es/cloneDeep.js";
import useFormValidate from "@/assets/js/useFormValidate.js";
const route = useRoute();
const { MAJORDANGERSOURCE_ID } = route.query;
const tableRef = ref(null);
const addOrEditDialogFormRef = ref(null);
const data = reactive({
list: [],
pagination: {
currentPage: 1,
pageSize: 10,
total: 0,
},
addOrEditDialog: {
visible: false,
type: "",
equipmentTypeList: [],
form: {
MONITORINGDEVICESENSOR_TYPE: "",
RANGE_MIN: 0,
RANGE_MAX: 0,
RANGE1_MIN: 0,
RANGE1_MAX: 0,
RANGE2_MIN: 0,
RANGE2_MAX: 0,
RANGE3_MIN: 0,
RANGE3_MAX: 0,
RANGE4_MIN: 0,
RANGE4_MAX: 0,
},
rules: {
MONITORINGDEVICESENSOR_TYPE: [
{ required: true, message: "监测数据类型不能为空", trigger: "blur" },
],
RANGE_MIN: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
RANGE_MAX: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
RANGE1_MIN: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
RANGE1_MAX: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
RANGE2_MIN: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
RANGE2_MAX: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
RANGE3_MIN: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
RANGE3_MAX: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
RANGE4_MIN: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
RANGE4_MAX: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
},
},
});
const fnGetData = async () => {
const resData = await getDataCollectionThresholdSettingThresholdSettingList({
currentPage: data.pagination.currentPage,
showCount: data.pagination.pageSize,
MAJORDANGERSOURCE_ID,
});
data.list = resData.varList;
data.pagination.total = resData.page.totalResult;
};
fnGetData();
const buttonJurisdiction = await layoutFnButtonJurisdiction(
"majordangersource"
);
const equipmentTypeList = await layoutFnGetEquipmentTypeCorp();
const fnResetPagination = () => {
data.pagination = {
currentPage: 1,
pageSize: 10,
total: 0,
};
tableRef.value.clearSelection();
fnGetData();
};
const fnAddOrEditDialogChangeShow = () => {
data.addOrEditDialog.visible = !data.addOrEditDialog.visible;
};
const fnAddOrEdit = async (MONITORINGDEVICESENSOR_ID, type) => {
fnAddOrEditDialogChangeShow();
fnEquipmentTypeListDeduplication();
data.addOrEditDialog.type = type;
await nextTick();
addOrEditDialogFormRef.value.resetFields();
if (type === "edit") {
const resData = await getDataCollectionThresholdSettingThresholdSettingView(
{ MONITORINGDEVICESENSOR_ID }
);
data.addOrEditDialog.form = resData.pd;
}
};
const fnEquipmentTypeListDeduplication = () => {
const cloneEquipmentTypeList = CloneDeep(equipmentTypeList.value);
for (let i = 0; i < cloneEquipmentTypeList.length; i++) {
for (let j = 0; j < data.list.length; j++) {
if (
cloneEquipmentTypeList[i].BIANMA ===
data.list[j].MONITORINGDEVICESENSOR_TYPE
) {
cloneEquipmentTypeList[i] = "";
break;
}
}
}
data.addOrEditDialog.equipmentTypeList =
cloneEquipmentTypeList.filter(Boolean);
};
const fnAddOrEditDialogSubmit = debounce(
1000,
async () => {
await useFormValidate(addOrEditDialogFormRef);
const { form, type } = data.addOrEditDialog;
if (type === "add")
await setDataCollectionThresholdSettingThresholdSettingAdd({
...form,
MAJORDANGERSOURCE_ID,
});
if (type === "edit")
await setDataCollectionThresholdSettingThresholdSettingEdit({
...form,
MAJORDANGERSOURCE_ID,
});
fnAddOrEditDialogChangeShow();
ElMessage.success("保存成功");
fnResetPagination();
},
{ atBegin: true }
);
const fnDelete = debounce(
1000,
async (MONITORINGDEVICESENSOR_ID) => {
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
await setDataCollectionThresholdSettingThresholdSettingDelete({
MONITORINGDEVICESENSOR_ID,
});
ElMessage.success("删除成功");
fnResetPagination();
},
{ atBegin: true }
);
const fnDeleteAll = debounce(
1000,
async () => {
const selectionData = tableRef.value.getSelectionRows();
if (selectionData.length === 0) {
ElMessage.warning("请选中要删除的项");
return;
}
const DATA_IDS = selectionData
.map((item) => item.MONITORINGDEVICESENSOR_ID)
.join(",");
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
await setDataCollectionThresholdSettingThresholdSettingDeleteMultiple({
DATA_IDS,
});
ElMessage.success("删除成功");
fnResetPagination();
},
{ atBegin: true }
);
</script>
<style scoped></style>

View File

@ -0,0 +1,146 @@
<template>
<layout-card>
<el-divider content-position="left">设备信息</el-divider>
<el-descriptions :column="2" border>
<el-descriptions-item label="重大危险源名称">
{{ data.info.MAJORDANGERSOURCE_NAME }}
</el-descriptions-item>
<el-descriptions-item label="重大危险源编号">
{{ data.info.MAJORDANGERSOURCE_NUMBER }}
</el-descriptions-item>
<el-descriptions-item label="重大危险源类型">
{{ data.info.MAJORDANGERSOURCE_TYPE_NAME }}
</el-descriptions-item>
<el-descriptions-item label="申报等级">
{{ data.info.DECLARATION_LEVEL_NAME }}
</el-descriptions-item>
<el-descriptions-item label="投入使用日期">
{{ data.info.USE_DATE }}
</el-descriptions-item>
<el-descriptions-item label="重大危险源地址">
{{ data.info.MAJORDANGERSOURCE_ADDRESS }}
</el-descriptions-item>
<el-descriptions-item label="实际储存量">
{{ data.info.STORAGE_ACTUAL }}
</el-descriptions-item>
<el-descriptions-item label="最大储量">
{{ data.info.STORAGE_MAX }}
</el-descriptions-item>
<el-descriptions-item label="管控措施" :span="2">
{{ data.info.CONTROL_MEASURES }}
</el-descriptions-item>
<el-descriptions-item label="误报审核人">
{{ data.info.ALARM_REVIEWER_NAME }}
</el-descriptions-item>
<el-descriptions-item label="联系方式">
{{ data.info.ALARM_REVIEWER_PHONE }}
</el-descriptions-item>
<template
v-for="item in data.info.responsibleList"
:key="item.MAJORDANGERSOURCE_RESPONSIBLE_ID"
>
<el-descriptions-item label="责任人">
{{ item.RESPONSIBLE_USER_NAME }}
</el-descriptions-item>
<el-descriptions-item label="联系方式">
{{ item.RESPONSIBLE_PERSON_PHONE }}
</el-descriptions-item>
</template>
<el-descriptions-item
label="分公司应急预案"
v-if="data.info.BRANCHEMERGENCYPLAN_FILEPATH"
>
{{ data.info.BRANCHEMERGENCYPLAN_NAME }}
<el-button
class="ml"
type="primary"
@click="fnDownloadFile(data.info.MAJORDANGERSOURCE_ID)"
>
下载
</el-button>
</el-descriptions-item>
<el-descriptions-item label="重大危险源位置">
<el-button circle @click="data.mapDialogVisible = true">
<el-icon>
<Place />
</el-icon>
</el-button>
经度:{{ data.info.MAJORDANGERSOURCE_LONGITUDE }} , 纬度:{{
data.info.MAJORDANGERSOURCE_LATITUDE
}}
</el-descriptions-item>
</el-descriptions>
<el-divider content-position="left">阈值设定信息</el-divider>
<layout-table :data="data.info.SENSORLIST" :show-pagination="false">
<el-table-column label="序号" width="60" type="index">
<el-table-column
prop="MONITORINGDEVICESENSOR_TYPE_NAME"
label="监测数据类型"
/>
<el-table-column label="量程">
<el-table-column prop="RANGE_MIN" label="下限" />
<el-table-column prop="RANGE_MAX" label="上限" />
</el-table-column>
<el-table-column label="一级预警">
<el-table-column prop="RANGE1_MIN" label="下限" />
<el-table-column prop="RANGE1_MAX" label="上限" />
</el-table-column>
<el-table-column label="二级预警">
<el-table-column prop="RANGE2_MIN" label="下限" />
<el-table-column prop="RANGE2_MAX" label="上限" />
</el-table-column>
<el-table-column label="三级预警">
<el-table-column prop="RANGE3_MIN" label="下限" />
<el-table-column prop="RANGE3_MAX" label="上限" />
</el-table-column>
<el-table-column label="四级预警">
<el-table-column prop="RANGE4_MIN" label="下限" />
<el-table-column prop="RANGE4_MAX" label="上限" />
</el-table-column>
</el-table-column>
</layout-table>
<layout-map
:latitude="data.info.MAJORDANGERSOURCE_LATITUDE"
:longitude="data.info.MAJORDANGERSOURCE_LONGITUDE"
v-model:visible="data.mapDialogVisible"
type="view"
/>
</layout-card>
</template>
<script setup>
import { useRoute } from "vue-router";
import { reactive } from "vue";
import { getDataCollectionThresholdSettingView } from "@/request/major_hazard_sources";
import { ElMessageBox } from "element-plus";
import { Place } from "@element-plus/icons-vue";
import LayoutMap from "@/components/map/index.vue";
const route = useRoute();
const MAJORDANGERSOURCE_ID = route.query.MAJORDANGERSOURCE_ID;
const data = reactive({
info: {},
mapDialogVisible: false,
});
const fnGetData = async () => {
const resData = await getDataCollectionThresholdSettingView({
MAJORDANGERSOURCE_ID,
});
data.info = resData.pd;
};
fnGetData();
const fnDownloadFile = async (MAJORDANGERSOURCE_ID) => {
await ElMessageBox.confirm("确定要下载此文件吗?", { type: "warning" });
window.open(
"/api/majordangersource/download?MAJORDANGERSOURCE_ID=" +
MAJORDANGERSOURCE_ID
);
};
</script>
<style scoped lang="scss">
#map_container {
width: 100%;
height: 500px;
}
</style>

View File

@ -0,0 +1,195 @@
<template>
<div>
<el-card>
<el-form
:model="data.searchForm"
label-width="90px"
@submit.prevent="fnResetPagination"
>
<el-row>
<el-col :span="6">
<el-form-item label="报警级别" prop="ALARM_LEVEL">
<el-select v-model="data.searchForm.ALARM_LEVEL">
<el-option
v-for="item in [
{ VALUE: '1', NAME: '一级' },
{ VALUE: '2', NAME: '二级' },
{ VALUE: '3', NAME: '三级' },
{ VALUE: '4', NAME: '四级' },
]"
:key="item.VALUE"
:label="item.NAME"
:value="item.VALUE"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="处置状态" prop="DISPOSAL_STATUS">
<el-select v-model="data.searchForm.DISPOSAL_STATUS">
<el-option
v-for="item in stateList"
:key="item.ID"
:label="item.NAME"
:value="item.ID"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="10px">
<el-button type="primary" native-type="submit">搜索</el-button>
<el-button native-type="reset" @click="fnResetPagination">
重置
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<layout-card>
<layout-table
:data="data.list"
@get-data="fnGetData"
v-model:pagination="data.pagination"
>
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(data.pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="MAJORDANGERSOURCE_NUMBER" label="危险源编号" />
<el-table-column prop="ALARM_TYPE_NAME" label="报警类型" width="80" />
<el-table-column prop="ALARM_VALUE" label="报警值" />
<el-table-column label="报警级别" width="100">
<template v-slot="{ row }">
<span v-if="row.ALARM_LEVEL === '1'"></span>
<span v-else-if="row.ALARM_LEVEL === '2'">二级</span>
<span v-else-if="row.ALARM_LEVEL === '3'">三级</span>
<span v-else-if="row.ALARM_LEVEL === '4'">四级</span>
</template>
</el-table-column>
<el-table-column
prop="ALARM_RANGE_MIN"
label="报警阈值下限"
width="120"
/>
<el-table-column
prop="ALARM_RANGE_MAX"
label="报警阈值上限"
width="120"
/>
<el-table-column label="处置状态">
<template v-slot="{ row }">
{{ fnTranslationStatus(row.ALARM_LEVEL, stateList) }}
</template>
</el-table-column>
<el-table-column prop="DISPOSAL_TIME" label="时间" />
<el-table-column prop="DISPOSAL_PERSON" label="处置人" />
<el-table-column prop="DISPOSAL_METHOD" label="处置方式" />
<el-table-column label="操作" width="150">
<template v-slot="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: MAJORDANGERSOURCE_ID
? '/major_hazard_sources/real_time_data_monitoring/view/emergency_handling_record/view'
: '/major_hazard_sources/emergency_handling_record/view',
query: {
MAJORDANGERSOURCE_DISPOSAL_ID:
row.MAJORDANGERSOURCE_DISPOSAL_ID,
},
})
"
>
查看
</el-button>
<el-button
type="primary"
text
link
v-if="
row.ALARM_REVIEWER_ID === userStore.getUserInfo.USER_ID &&
row.DISPOSAL_STATUS === '-1'
"
@click="fnFalseAlarmHandling(row.MAJORDANGERSOURCE_DISPOSAL_ID)"
>
误报处置
</el-button>
</template>
</el-table-column>
</layout-table>
</layout-card>
</div>
</template>
<script setup>
import { reactive } from "vue";
import { fnTranslationStatus, serialNumber } from "@/assets/js/utils";
import {
getEmergencyHandlingRecordList,
setEmergencyHandlingRecordFalseAlarm,
} from "@/request/major_hazard_sources";
import { useRouter, useRoute } from "vue-router";
import { useUserStore } from "@/pinia/user.js";
import { debounce } from "throttle-debounce";
import { ElMessage, ElMessageBox } from "element-plus";
const router = useRouter();
const route = useRoute();
const { MAJORDANGERSOURCE_ID } = route.query;
const userStore = useUserStore();
const stateList = [
{ ID: "-2", NAME: "误报" },
{ ID: "-1", NAME: "未处置" },
{ ID: "0", NAME: "报警升级" },
{ ID: "1", NAME: "处置完成" },
];
const data = reactive({
list: [],
pagination: {
currentPage: 1,
pageSize: 10,
total: 0,
},
searchForm: {},
});
const fnGetData = async () => {
const resData = await getEmergencyHandlingRecordList({
currentPage: data.pagination.currentPage,
showCount: data.pagination.pageSize,
...data.searchForm,
MAJORDANGERSOURCE_ID,
});
data.list = resData.varList;
data.pagination.total = resData.page.totalResult;
};
fnGetData();
const fnResetPagination = () => {
data.pagination = {
currentPage: 1,
pageSize: 10,
total: 0,
};
fnGetData();
};
const fnFalseAlarmHandling = debounce(
1000,
async (MAJORDANGERSOURCE_DISPOSAL_ID) => {
await ElMessageBox.confirm("确定要将此报警记录设置成误报吗?", {
type: "warning",
});
await setEmergencyHandlingRecordFalseAlarm({
MAJORDANGERSOURCE_DISPOSAL_ID,
});
ElMessage.success("设置成功");
fnResetPagination();
},
{ atBegin: true }
);
</script>
<style scoped></style>

View File

@ -0,0 +1,92 @@
<template>
<layout-card>
<el-divider content-position="left">重大危险源信息</el-divider>
<el-descriptions :column="2" border>
<el-descriptions-item label="危险源编号">
{{ data.info.MAJORDANGERSOURCE_NUMBER }}
</el-descriptions-item>
<el-descriptions-item label="报警类型">
{{ data.info.ALARM_TYPE_NAME }}
</el-descriptions-item>
<el-descriptions-item label="报警值">
{{ data.info.ALARM_VALUE }}
</el-descriptions-item>
<el-descriptions-item label="报警级别">
<span v-if="data.info.ALARM_LEVEL === '1'"></span>
<span v-else-if="data.info.ALARM_LEVEL === '2'">二级</span>
<span v-else-if="data.info.ALARM_LEVEL === '3'">三级</span>
<span v-else-if="data.info.ALARM_LEVEL === '4'">四级</span>
</el-descriptions-item>
<el-descriptions-item label="阈值下限">
{{ data.info.ALARM_RANGE_MIN }}
</el-descriptions-item>
<el-descriptions-item label="阈值上限">
{{ data.info.ALARM_RANGE_MAX }}
</el-descriptions-item>
<el-descriptions-item label="处置人">
{{ data.info.DISPOSAL_PERSON }}
</el-descriptions-item>
<el-descriptions-item label="处置方式">
{{ data.info.DISPOSAL_METHOD }}
</el-descriptions-item>
<el-descriptions-item label="处置描述" :span="2">
{{ data.info.DISPOSAL_DESC }}
</el-descriptions-item>
<el-descriptions-item label="处置前图片" :span="2">
<img
v-viewer
v-for="item in data.info.disposalBeforeFile"
:key="item.FILEPATH"
:src="item.url"
alt=""
class="ml"
/>
</el-descriptions-item>
<el-descriptions-item label="处置后图片" :span="2">
<img
v-viewer
v-for="item in data.info.disposalAfterFile"
:key="item.FILEPATH"
:src="item.url"
alt=""
class="ml"
/>
</el-descriptions-item>
<el-descriptions-item label="处置完成时间" :span="2">
{{ data.info.DISPOSAL_TIME_OVER }}
</el-descriptions-item>
</el-descriptions>
</layout-card>
</template>
<script setup>
import { reactive } from "vue";
import { getEmergencyHandlingRecordView } from "@/request/major_hazard_sources.js";
import { useRoute } from "vue-router";
import { fnAddingPrefixToFile } from "@/assets/js/utils.js";
const route = useRoute();
const { MAJORDANGERSOURCE_DISPOSAL_ID } = route.query;
const data = reactive({
info: {},
});
const fnGetData = async () => {
const resData = await getEmergencyHandlingRecordView({
MAJORDANGERSOURCE_DISPOSAL_ID,
});
data.info = resData.pd;
data.info.disposalBeforeFile = fnAddingPrefixToFile(
resData.pd.disposalBeforeFile
);
data.info.disposalAfterFile = fnAddingPrefixToFile(
resData.pd.disposalAfterFile
);
};
fnGetData();
</script>
<style lang="scss" scoped>
.ml:first-child {
margin-left: 0;
}
</style>

View File

@ -0,0 +1,275 @@
<template>
<layout-card>
<el-form ref="formRef" :rules="rules" :model="form" label-width="200px">
<el-row>
<el-col :span="12">
<el-form-item label="重大危险源名称" prop="MAJORDANGERSOURCE_NAME">
<el-input v-model="form.MAJORDANGERSOURCE_NAME" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="重大危险源编号" prop="MAJORDANGERSOURCE_NUMBER">
<el-input v-model="form.MAJORDANGERSOURCE_NUMBER" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="重大危险源类型" prop="MAJORDANGERSOURCE_TYPE">
<el-select v-model="form.MAJORDANGERSOURCE_TYPE">
<el-option
v-for="item in majorHazardSourceTypeList"
:key="item.BIANMA"
:label="item.NAME"
:value="item.BIANMA"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="申报等级" prop="DECLARATION_LEVEL">
<el-select v-model="form.DECLARATION_LEVEL">
<el-option
v-for="item in declarationGradeList"
:key="item.BIANMA"
:label="item.NAME"
:value="item.BIANMA"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投入使用日期" prop="USE_DATE">
<el-date-picker
v-model="form.USE_DATE"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="date"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="重大危险源位置"
prop="MAJORDANGERSOURCE_LONGITUDE"
>
<el-row style="flex: 1">
<el-col :span="10" class="pr-2">
<el-input
v-model="form.MAJORDANGERSOURCE_LONGITUDE"
:readonly="true"
@click="fnOpenMap"
/>
</el-col>
<el-col :span="10" class="pl-2">
<el-input
v-model="form.MAJORDANGERSOURCE_LATITUDE"
:readonly="true"
@click="fnOpenMap"
/>
</el-col>
<el-col :span="4">
<el-button type="primary" class="ml-10" @click="fnOpenMap">
位置定位
</el-button>
</el-col>
</el-row>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="重大危险源地址" prop="MAJORDANGERSOURCE_ADDRESS">
<el-input v-model="form.MAJORDANGERSOURCE_ADDRESS" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实际储存量" prop="STORAGE_ACTUAL">
<el-input v-model="form.STORAGE_ACTUAL" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="最大储量" prop="STORAGE_MAX">
<el-input v-model="form.STORAGE_MAX" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="责任人姓名" prop="RESPONSIBLE_PERSON_NAME">
<el-input v-model="form.RESPONSIBLE_PERSON_NAME" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系方式" prop="RESPONSIBLE_PERSON_PHONE">
<el-input v-model="form.RESPONSIBLE_PERSON_PHONE" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="管控措施" prop="CONTROL_MEASURES">
<el-input
v-model="form.CONTROL_MEASURES"
:autosize="{ minRows: 3 }"
type="textarea"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="分公司应急预案(附件)" prop="file">
<layout-upload v-model:file-list="form.file" accept=".pdf" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="tc mt-10">
<el-button type="primary" @click="fnSubmit"> </el-button>
</div>
<map-dialog
v-model:visible="mapDialogVisible"
v-model:latitude="form.MAJORDANGERSOURCE_LATITUDE"
v-model:longitude="form.MAJORDANGERSOURCE_LONGITUDE"
type="add"
/>
</layout-card>
</template>
<script setup>
import { ref } from "vue";
import LayoutUpload from "@/components/upload/index";
import { useRoute, useRouter } from "vue-router";
import { debounce } from "throttle-debounce";
import {
layoutFnGetDeclarationGrade,
layoutFnGetMajorHazardSourceType,
} from "@/assets/js/data_dictionary";
import { ElMessage } from "element-plus";
import {
getMajorHazardManagementView,
setMajorHazardManagementAdd,
setMajorHazardManagementEdit,
} from "@/request/major_hazard_sources";
import useFormValidate from "@/assets/js/useFormValidate.js";
import MapDialog from "@/views/major_hazard_sources/major_hazard_management/components/map.vue";
const FILE_URL = import.meta.env.VITE_FILE_URL;
const router = useRouter();
const route = useRoute();
const { MAJORDANGERSOURCE_ID } = route.query;
const rules = {
MAJORDANGERSOURCE_NAME: [
{ required: true, message: "重大危险源名称不能为空", trigger: "blur" },
],
MAJORDANGERSOURCE_TYPE: [
{ required: true, message: "请选择重大危险源类型", trigger: "blur" },
],
MAJORDANGERSOURCE_ADDRESS: [
{ required: true, message: "重大危险源地址不能为空", trigger: "blur" },
],
MAJORDANGERSOURCE_LONGITUDE: [
{
required: true,
message: "重大危险源位置不能为空",
trigger: "blur",
},
],
MAJORDANGERSOURCE_NUMBER: [
{ required: true, message: "重大危险源编号不能为空", trigger: "blur" },
],
USE_DATE: [
{ required: true, message: "请选择投入使用日期", trigger: "blur" },
],
DECLARATION_LEVEL: [
{ required: true, message: "请选择申报等级", trigger: "blur" },
],
STORAGE_ACTUAL: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
STORAGE_MAX: [
{
required: true,
pattern:
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message: "请输入正确格式,可保留两位小数",
trigger: "blur",
},
],
CONTROL_MEASURES: [
{ required: true, message: "管控措施不能为空", trigger: "blur" },
],
file: [
{
required: true,
message: "分公司应急预案(附件)不能为空",
trigger: "blur",
},
],
RESPONSIBLE_PERSON_NAME: [
{ required: true, message: "责任人姓名不能为空", trigger: "blur" },
],
RESPONSIBLE_PERSON_PHONE: [
{ required: true, message: "联系方式不能为空", trigger: "blur" },
{
pattern:
/^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/,
message: "请输入正确的手机号码",
},
],
};
const formRef = ref(null);
const form = ref({
MAJORDANGERSOURCE_NAME: "",
MAJORDANGERSOURCE_TYPE: "",
MAJORDANGERSOURCE_ADDRESS: "",
MAJORDANGERSOURCE_LONGITUDE: "",
MAJORDANGERSOURCE_LATITUDE: "",
MAJORDANGERSOURCE_NUMBER: "",
USE_DATE: "",
DECLARATION_LEVEL: "",
STORAGE_ACTUAL: "",
STORAGE_MAX: "",
CONTROL_MEASURES: "",
RESPONSIBLE_PERSON_NAME: "",
RESPONSIBLE_PERSON_PHONE: "",
file: [],
});
const mapDialogVisible = ref(false);
const fnGetData = async () => {
if (!MAJORDANGERSOURCE_ID) return;
const resData = await getMajorHazardManagementView({ MAJORDANGERSOURCE_ID });
form.value = resData.pd;
form.value.file = [
{
url: FILE_URL + form.value.BRANCHEMERGENCYPLAN_FILEPATH,
name: form.value.BRANCHEMERGENCYPLAN_NAME,
},
];
};
fnGetData();
const majorHazardSourceTypeList = await layoutFnGetMajorHazardSourceType();
const declarationGradeList = await layoutFnGetDeclarationGrade();
const fnOpenMap = () => {
mapDialogVisible.value = true;
};
const fnSubmit = debounce(
1000,
async () => {
await useFormValidate(formRef);
const formData = new FormData();
Object.keys(form.value).forEach((key) => {
formData.append(key, form.value[key]);
});
formData.delete("file");
if (form.value.file[0].raw) {
formData.append("file", form.value.file[0].raw);
formData.append("BRANCHEMERGENCYPLAN_NAME", form.value.file[0].name);
}
if (!MAJORDANGERSOURCE_ID) await setMajorHazardManagementAdd(formData);
else await setMajorHazardManagementEdit(formData);
ElMessage.success("保存成功");
router.back();
},
{ atBegin: true }
);
</script>
<style scoped></style>

View File

@ -0,0 +1,74 @@
<template>
<layout-card>
<layout-table
:data="data.list"
@get-data="fnGetData"
v-model:pagination="data.pagination"
>
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(data.pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="MAJORDANGERSOURCE_NAME" label="重大危险源名称" />
<el-table-column
prop="MAJORDANGERSOURCE_TYPE_NAME"
label="重大危险源类型"
/>
<el-table-column
prop="MAJORDANGERSOURCE_ADDRESS"
label="重大危险源地址"
/>
<el-table-column prop="USER_NAME" label="变更人" />
<el-table-column prop="CREATTIME" label="变更时间" />
<el-table-column label="操作" width="80">
<template v-slot="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: '/major_hazard_sources/major_hazard_management/change_record/view',
query: { CREATTIME: row.CREATTIME, MAJORDANGERSOURCE_ID },
})
"
>
查看
</el-button>
</template>
</el-table-column>
</layout-table>
</layout-card>
</template>
<script setup>
import { reactive } from "vue";
import { serialNumber } from "@/assets/js/utils";
import { getMajorHazardManagementChangeRecordList } from "@/request/major_hazard_sources";
import { useRouter, useRoute } from "vue-router";
const router = useRouter();
const route = useRoute();
const { MAJORDANGERSOURCE_ID } = route.query;
const data = reactive({
list: [],
pagination: {
currentPage: 1,
pageSize: 10,
total: 0,
},
});
const fnGetData = async () => {
const resData = await getMajorHazardManagementChangeRecordList({
currentPage: data.pagination.currentPage,
showCount: data.pagination.pageSize,
MAJORDANGERSOURCE_ID,
});
data.list = resData.varList;
data.pagination.total = resData.page.totalResult;
};
fnGetData();
</script>
<style scoped></style>

View File

@ -0,0 +1,314 @@
<template>
<layout-card>
<div class="top">
<span class="title">变更人</span>
<span>{{ data.info.OPERATOR }}</span>
<span class="title">变更时间</span>
<span>{{ data.info.OPERATTIME }}</span>
</div>
<table class="mt">
<tr>
<td class="title" />
<td
class="title"
style="text-align: center; background-color: #4db555; color: #fff"
>
变更后
</td>
<td
class="title"
style="text-align: center; background-color: #4581e9; color: #fff"
>
变更前
</td>
</tr>
<tr>
<td class="title">重大危险源名称</td>
<td>
{{
data.info.MAJORDANGERSOURCE_NAME !==
data.oldInfo.MAJORDANGERSOURCE_NAME
? data.info.MAJORDANGERSOURCE_NAME
: ""
}}
</td>
<td>{{ data.oldInfo.MAJORDANGERSOURCE_NAME }}</td>
</tr>
<tr>
<td class="title">重大危险源编号</td>
<td>
{{
data.info.MAJORDANGERSOURCE_NUMBER !==
data.oldInfo.MAJORDANGERSOURCE_NUMBER
? data.info.MAJORDANGERSOURCE_NUMBER
: ""
}}
</td>
<td>{{ data.oldInfo.MAJORDANGERSOURCE_NUMBER }}</td>
</tr>
<tr>
<td class="title">重大危险源地址</td>
<td>
{{
data.info.MAJORDANGERSOURCE_ADDRESS !==
data.oldInfo.MAJORDANGERSOURCE_ADDRESS
? data.info.MAJORDANGERSOURCE_ADDRESS
: ""
}}
</td>
<td>{{ data.oldInfo.MAJORDANGERSOURCE_ADDRESS }}</td>
</tr>
<tr>
<td class="title">重大危险源位置</td>
<td>
<div
v-show="
data.info.MAJORDANGERSOURCE_LONGITUDE !==
data.oldInfo.MAJORDANGERSOURCE_LONGITUDE ||
data.info.MAJORDANGERSOURCE_LATITUDE !==
data.oldInfo.MAJORDANGERSOURCE_LATITUDE
"
>
经度:{{ data.info.MAJORDANGERSOURCE_LONGITUDE }} 纬度:{{
data.info.MAJORDANGERSOURCE_LATITUDE
}}
<el-button class="ml" circle @click="data.mapDialogVisible = true">
<el-icon>
<Place />
</el-icon>
</el-button>
</div>
</td>
<td>
<div>
经度:{{ data.oldInfo.MAJORDANGERSOURCE_LONGITUDE }} 纬度:{{
data.oldInfo.MAJORDANGERSOURCE_LATITUDE
}}
<el-button
class="ml"
circle
@click="data.oldMapDialogVisible = true"
>
<el-icon>
<Place />
</el-icon>
</el-button>
</div>
</td>
</tr>
<tr>
<td class="title">重大危险源类型</td>
<td>
{{
data.info.MAJORDANGERSOURCE_TYPE_NAME !==
data.oldInfo.MAJORDANGERSOURCE_TYPE_NAME
? data.info.MAJORDANGERSOURCE_TYPE_NAME
: ""
}}
</td>
<td>{{ data.oldInfo.MAJORDANGERSOURCE_TYPE_NAME }}</td>
</tr>
<tr>
<td class="title">投入使用日期</td>
<td>
{{
data.info.USE_DATE !== data.oldInfo.USE_DATE
? data.info.USE_DATE
: ""
}}
</td>
<td>{{ data.oldInfo.USE_DATE }}</td>
</tr>
<tr>
<td class="title">申报等级</td>
<td>
{{
data.info.DECLARATION_LEVEL_NAME !==
data.oldInfo.DECLARATION_LEVEL_NAME
? data.info.DECLARATION_LEVEL_NAME
: ""
}}
</td>
<td>{{ data.oldInfo.DECLARATION_LEVEL_NAME }}</td>
</tr>
<tr>
<td class="title">实际储存量</td>
<td>
{{
data.info.STORAGE_ACTUAL !== data.oldInfo.STORAGE_ACTUAL
? data.info.STORAGE_ACTUAL
: ""
}}
</td>
<td>{{ data.oldInfo.STORAGE_ACTUAL }}</td>
</tr>
<tr>
<td class="title">最大储量</td>
<td>
{{
data.info.STORAGE_MAX !== data.oldInfo.STORAGE_MAX
? data.info.STORAGE_MAX
: ""
}}
</td>
<td>{{ data.oldInfo.STORAGE_MAX }}</td>
</tr>
<tr>
<td class="title">管控措施</td>
<td>
{{
data.info.CONTROL_MEASURES !== data.oldInfo.CONTROL_MEASURES
? data.info.CONTROL_MEASURES
: ""
}}
</td>
<td>{{ data.oldInfo.CONTROL_MEASURES }}</td>
</tr>
<tr>
<td class="title">责任人</td>
<td>
{{
data.info.RESPONSIBLE_PERSON_NAME !==
data.oldInfo.RESPONSIBLE_PERSON_NAME
? data.info.RESPONSIBLE_PERSON_NAME
: ""
}}
</td>
<td>{{ data.oldInfo.RESPONSIBLE_PERSON_NAME }}</td>
</tr>
<tr>
<td class="title">联系方式</td>
<td>
{{
data.info.RESPONSIBLE_PERSON_PHONE !==
data.oldInfo.RESPONSIBLE_PERSON_PHONE
? data.info.RESPONSIBLE_PERSON_PHONE
: ""
}}
</td>
<td>{{ data.oldInfo.RESPONSIBLE_PERSON_PHONE }}</td>
</tr>
<tr>
<td class="title">分公司应急预案</td>
<td>
<template
v-if="
data.info.BRANCHEMERGENCYPLAN_FILEPATH !==
data.oldInfo.BRANCHEMERGENCYPLAN_FILEPATH
"
>
<span>
{{ data.info.BRANCHEMERGENCYPLAN_NAME }}
</span>
<el-button
class="ml"
type="primary"
@click="fnDownloadFile(data.info.MAJORDANGERSOURCELOG_ID)"
>
下载
</el-button>
</template>
</td>
<td>
<span>{{ data.oldInfo.BRANCHEMERGENCYPLAN_NAME }}</span>
<el-button
class="ml"
type="primary"
@click="fnDownloadFile(data.oldInfo.MAJORDANGERSOURCELOG_ID)"
>
下载
</el-button>
</td>
</tr>
</table>
<layout-map
:latitude="data.info.MAJORDANGERSOURCE_LATITUDE"
:longitude="data.info.MAJORDANGERSOURCE_LONGITUDE"
v-model:visible="data.mapDialogVisible"
type="view"
/>
<layout-map
:latitude="data.oldInfo.MAJORDANGERSOURCE_LATITUDE"
:longitude="data.oldInfo.MAJORDANGERSOURCE_LONGITUDE"
v-model:visible="data.oldMapDialogVisible"
type="view"
/>
</layout-card>
</template>
<script setup>
import { reactive } from "vue";
import { ElMessageBox } from "element-plus";
import { getMajorHazardManagementChangeRecordView } from "@/request/major_hazard_sources.js";
import { useRoute } from "vue-router";
import LayoutMap from "@/components/map/index.vue";
import { Place } from "@element-plus/icons-vue";
const route = useRoute();
const { MAJORDANGERSOURCE_ID, CREATTIME } = route.query;
const data = reactive({
info: {},
oldInfo: {},
mapDialogVisible: false,
oldMapDialogVisible: false,
});
const fnGetData = async () => {
const resData = await getMajorHazardManagementChangeRecordView({
MAJORDANGERSOURCE_ID,
CREATTIME,
showCount: 2,
currentPage: 1,
});
if (resData.varList.length > 0) data.info = resData.varList[0];
if (resData.varList.length > 1) data.oldInfo = resData.varList[1];
};
fnGetData();
const fnDownloadFile = async (MAJORDANGERSOURCELOG_ID) => {
await ElMessageBox.confirm("确定要下载此文件吗?", { type: "warning" });
window.open(
"/api/majordangersourcelog/download?MAJORDANGERSOURCELOG_ID=" +
MAJORDANGERSOURCELOG_ID
);
};
</script>
<style lang="scss" scoped>
.top {
display: flex;
width: 100%;
.title {
background: var(--el-fill-color-light);
}
span {
border: 1px solid var(--el-border-color);
padding: 8px 12px;
font-size: 14px;
line-height: 1.6;
display: block;
flex: 1;
}
}
table {
border-collapse: collapse;
width: 100%;
td,
th {
border: 1px solid var(--el-border-color);
padding: 8px 12px;
font-size: 14px;
line-height: 1.6;
}
td:not(.title) {
width: 40%;
}
.title {
background: var(--el-fill-color-light);
}
}
</style>

View File

@ -0,0 +1,126 @@
<template>
<el-dialog title="重大危险源位置" v-model="visible">
<el-form label-position="right" label-width="50px" v-if="type === 'add'">
<el-row>
<el-col :span="12">
<el-form-item label="坐标">
<el-input disabled :model-value="currentLongitude || longitude" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label-width="10px">
<el-input disabled :model-value="currentLatitude || latitude" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div
v-loading="loading"
element-loading-text="地图正在加载中..."
element-loading-background="rgba(0, 0, 0, 0.5)"
>
<div style="width: 100%; height: 500px" id="map_container" />
</div>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnConfirm" v-if="type === 'add'">
确定
</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { useVModels } from "@vueuse/core";
import { nextTick, onBeforeUnmount, ref, watch } from "vue";
let mapInstance;
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
longitude: {
type: [Number, String],
default: "",
},
latitude: {
type: [Number, String],
default: "",
},
type: {
type: String,
required: true,
default: "",
},
});
const emits = defineEmits([
"update:visible",
"update:longitude",
"update:latitude",
]);
const { visible, longitude, latitude } = useVModels(props, emits);
const loading = ref(false);
const currentLongitude = ref("");
const currentLatitude = ref("");
const fnMapInit = async () => {
loading.value = true;
await nextTick();
mapInstance = new window.BMapGL.Map("map_container");
mapInstance.centerAndZoom(
new window.BMapGL.Point(
props.longitude || "116.3972282409668",
props.latitude || "39.90960456049752"
),
16
);
mapInstance.enableScrollWheelZoom(true);
mapInstance.setMapStyleV2({
styleId: "6f501abeb2a0cc0d961d110b9407b127",
});
loading.value = false;
if (props.longitude && props.latitude) {
const point = new window.BMapGL.Point(props.longitude, props.latitude);
const marker = new window.BMapGL.Marker(point);
mapInstance.addOverlay(marker);
}
props.type === "add" &&
mapInstance.addEventListener("click", function (event) {
mapInstance.clearOverlays();
const point = new window.BMapGL.Point(event.latlng.lng, event.latlng.lat);
const marker = new window.BMapGL.Marker(point);
mapInstance.addOverlay(marker);
currentLatitude.value = event.latlng.lat;
currentLongitude.value = event.latlng.lng;
});
};
const fnClose = () => {
visible.value = false;
};
const fnConfirm = () => {
latitude.value = currentLatitude.value;
longitude.value = currentLongitude.value;
fnClose();
};
const stop = watch(
() => props.visible,
(val) => {
if (val && !mapInstance) {
fnMapInit();
stop && stop();
}
},
{
immediate: true,
}
);
onBeforeUnmount(() => {
if (mapInstance) {
mapInstance.destroy();
mapInstance = null;
}
});
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,185 @@
<template>
<div>
<el-card>
<el-form
:model="searchForm"
label-width="80px"
@submit.prevent="fnResetPagination"
>
<el-row>
<el-col :span="6">
<el-form-item
label="重大危险源名称"
prop="MAJORDANGERSOURCE_NAME"
label-width="130px"
>
<el-input v-model="searchForm.MAJORDANGERSOURCE_NAME" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="责任人" prop="RESPONSIBLE_PERSON_NAME">
<el-input v-model="searchForm.RESPONSIBLE_PERSON_NAME" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="10px">
<el-button type="primary" native-type="submit">搜索</el-button>
<el-button native-type="reset" @click="fnResetPagination">
重置
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<layout-card>
<layout-table
ref="tableRef"
row-key="MAJORDANGERSOURCE_ID"
:data="list"
@get-data="fnGetData"
v-model:pagination="pagination"
>
<el-table-column reserve-selection type="selection" width="55" />
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="MAJORDANGERSOURCE_NAME" label="重大危险源名称" />
<el-table-column
prop="MAJORDANGERSOURCE_TYPE_NAME"
label="重大危险源类型"
/>
<el-table-column
prop="MAJORDANGERSOURCE_ADDRESS"
label="重大危险源地址"
/>
<el-table-column prop="USE_DATE" label="投入使用日期" />
<el-table-column prop="RESPONSIBLE_PERSON_NAME" label="责任人" />
<el-table-column label="操作" width="250">
<template v-slot="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: '/major_hazard_sources/major_hazard_management/view',
query: { MAJORDANGERSOURCE_ID: row.MAJORDANGERSOURCE_ID },
})
"
>
查看
</el-button>
<el-button
v-if="buttonJurisdiction.edit"
type="primary"
text
link
@click="
router.push({
path: '/major_hazard_sources/major_hazard_management/edit',
query: { MAJORDANGERSOURCE_ID: row.MAJORDANGERSOURCE_ID },
})
"
>
变更
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="primary"
text
link
@click="fnDelete(row.MAJORDANGERSOURCE_ID)"
>
删除
</el-button>
<el-button
type="primary"
text
link
@click="
router.push({
path: '/major_hazard_sources/major_hazard_management/change_record',
query: { MAJORDANGERSOURCE_ID: row.MAJORDANGERSOURCE_ID },
})
"
>
变更记录
</el-button>
</template>
</el-table-column>
<template #button>
<el-button
v-if="buttonJurisdiction.add"
type="primary"
@click="
router.push({
path: '/major_hazard_sources/major_hazard_management/add',
})
"
>
新增
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="danger"
@click="fnDeleteAll"
>
删除
</el-button>
</template>
</layout-table>
</layout-card>
</div>
</template>
<script setup>
import { serialNumber } from "@/assets/js/utils";
import {
getMajorHazardManagementList,
setMajorHazardManagementDelete,
setMajorHazardManagementDeleteMultiple,
} from "@/request/major_hazard_sources";
import useButtonJurisdiction from "@/assets/js/useButtonJurisdiction.js";
import { debounce } from "throttle-debounce";
import { ElMessage, ElMessageBox } from "element-plus";
import { useRouter } from "vue-router";
import useListData from "@/assets/js/useListData.js";
const router = useRouter();
const { list, pagination, searchForm, fnGetData, fnResetPagination, tableRef } =
useListData(getMajorHazardManagementList);
const buttonJurisdiction = await useButtonJurisdiction("majordangersource");
const fnDelete = debounce(
1000,
async (MAJORDANGERSOURCE_ID) => {
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
await setMajorHazardManagementDelete({ MAJORDANGERSOURCE_ID });
ElMessage.success("删除成功");
fnResetPagination();
},
{ atBegin: true }
);
const fnDeleteAll = debounce(
1000,
async () => {
const selectionData = tableRef.value.getSelectionRows();
if (selectionData.length === 0) {
ElMessage.warning("请选中要删除的项");
return;
}
const DATA_IDS = selectionData
.map((item) => item.MAJORDANGERSOURCE_ID)
.join(",");
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
await setMajorHazardManagementDeleteMultiple({ DATA_IDS });
ElMessage.success("删除成功");
fnResetPagination();
},
{ atBegin: true }
);
</script>
<style scoped></style>

View File

@ -0,0 +1,100 @@
<template>
<layout-card>
<el-divider content-position="left">重大危险源信息</el-divider>
<el-descriptions :column="2" border>
<el-descriptions-item label="重大危险源名称">
{{ info.MAJORDANGERSOURCE_NAME }}
</el-descriptions-item>
<el-descriptions-item label="重大危险源编号">
{{ info.MAJORDANGERSOURCE_NUMBER }}
</el-descriptions-item>
<el-descriptions-item label="重大危险源地址">
{{ info.MAJORDANGERSOURCE_ADDRESS }}
</el-descriptions-item>
<el-descriptions-item label="重大危险源类型">
{{ info.MAJORDANGERSOURCE_TYPE_NAME }}
</el-descriptions-item>
<el-descriptions-item label="投入使用日期">
{{ info.USE_DATE }}
</el-descriptions-item>
<el-descriptions-item label="申报等级">
{{ info.DECLARATION_LEVEL_NAME }}
</el-descriptions-item>
<el-descriptions-item label="实际储存量">
{{ info.STORAGE_ACTUAL }}
</el-descriptions-item>
<el-descriptions-item label="最大储量">
{{ info.STORAGE_MAX }}
</el-descriptions-item>
<el-descriptions-item label="管控措施" :span="2">
{{ info.CONTROL_MEASURES }}
</el-descriptions-item>
<el-descriptions-item label="责任人">
{{ info.RESPONSIBLE_PERSON_NAME }}
</el-descriptions-item>
<el-descriptions-item label="联系方式">
{{ info.RESPONSIBLE_PERSON_PHONE }}
</el-descriptions-item>
<el-descriptions-item
label="分公司应急预案"
v-if="info.BRANCHEMERGENCYPLAN_FILEPATH"
>
{{ info.BRANCHEMERGENCYPLAN_NAME }}
<el-button
class="ml-10"
type="primary"
@click="
useDownloadFile(
info.BRANCHEMERGENCYPLAN_FILEPATH,
info.BRANCHEMERGENCYPLAN_NAME
)
"
>
下载
</el-button>
</el-descriptions-item>
<el-descriptions-item label="重大危险源位置">
<el-button circle @click="mapDialogVisible = true">
<el-icon>
<Place />
</el-icon>
</el-button>
经度:{{ info.MAJORDANGERSOURCE_LONGITUDE }} , 纬度:{{
info.MAJORDANGERSOURCE_LATITUDE
}}
</el-descriptions-item>
</el-descriptions>
<map-dialog
v-model:visible="mapDialogVisible"
:latitude="info.MAJORDANGERSOURCE_LATITUDE"
:longitude="info.MAJORDANGERSOURCE_LONGITUDE"
type="view"
/>
</layout-card>
</template>
<script setup>
import { useRoute } from "vue-router";
import { ref } from "vue";
import { getMajorHazardManagementView } from "@/request/major_hazard_sources";
import { Place } from "@element-plus/icons-vue";
import useDownloadFile from "@/assets/js/useDownloadFile.js";
import MapDialog from "./components/map.vue";
const route = useRoute();
const { MAJORDANGERSOURCE_ID } = route.query;
const info = ref({});
const mapDialogVisible = ref(false);
const fnGetData = async () => {
const resData = await getMajorHazardManagementView({ MAJORDANGERSOURCE_ID });
info.value = resData.pd;
};
fnGetData();
</script>
<style scoped lang="scss">
#map_container {
width: 100%;
height: 500px;
}
</style>

View File

@ -0,0 +1,243 @@
<template>
<div>
<el-card>
<el-form
:model="data.searchForm"
label-width="100px"
@submit.prevent="fnResetPagination"
>
<el-row>
<el-col :span="6">
<el-form-item label="监测类型名称" prop="KEYWORDS">
<el-input v-model="data.searchForm.KEYWORDS" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="10px">
<el-button type="primary" native-type="submit">搜索</el-button>
<el-button native-type="reset" @click="fnResetPagination">
重置
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<layout-card>
<layout-table
ref="tableRef"
row-key="DICTIONARIES_ID"
:data="data.list"
@get-data="fnGetData"
v-model:pagination="data.pagination"
>
<el-table-column reserve-selection type="selection" width="55" />
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(data.pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="NAME" label="监测类型名称" />
<el-table-column prop="BZ" label="备注" />
<el-table-column prop="ORDER_BY" label="排序" width="60" />
<el-table-column label="操作" width="100">
<template v-slot="{ row }">
<el-button
v-if="buttonJurisdiction.edit"
type="primary"
text
link
@click="fnAddOrEdit(row, 'edit')"
>
编辑
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="primary"
text
link
@click="fnDelete(row.DICTIONARIES_ID)"
>
删除
</el-button>
</template>
</el-table-column>
<template #button>
<el-button
v-if="buttonJurisdiction.add"
type="primary"
@click="fnAddOrEdit({}, 'add')"
>
新增
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="danger"
@click="fnDeleteAll"
>
删除
</el-button>
</template>
</layout-table>
</layout-card>
<el-dialog
v-model="data.addOrEditDialog.visible"
:title="data.addOrEditDialog.type === 'edit' ? '修改' : '新增'"
>
<el-form
ref="addOrEditDialogFormRef"
:model="data.addOrEditDialog.form"
:rules="data.addOrEditDialog.rules"
label-width="120px"
>
<el-form-item label="监测类型名称" prop="NAME">
<el-input v-model="data.addOrEditDialog.form.NAME" />
</el-form-item>
<el-form-item label="排序" prop="ORDER_BY">
<el-input v-model.number="data.addOrEditDialog.form.ORDER_BY" />
</el-form-item>
<el-form-item label="备注" prop="BZ">
<el-input
v-model="data.addOrEditDialog.form.BZ"
type="textarea"
autosize
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="fnAddOrEditDialogChangeShow"></el-button>
<el-button type="primary" @click="fnAddOrEditDialogSubmit">
确定
</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { nextTick, reactive, ref } from "vue";
import { serialNumber } from "@/assets/js/utils";
import {
getMonitoringTypeManagementList,
setMonitoringTypeManagementAdd,
setMonitoringTypeManagementDelete,
setMonitoringTypeManagementDeleteMultiple,
setMonitoringTypeManagementEdit,
} from "@/request/major_hazard_sources";
import { layoutFnButtonJurisdiction } from "@/assets/js/button_jurisdiction";
import { debounce } from "throttle-debounce";
import { ElMessage, ElMessageBox } from "element-plus";
import { cloneDeep } from "lodash-es";
import useFormValidate from "@/assets/js/useFormValidate.js";
const tableRef = ref(null);
const addOrEditDialogFormRef = ref(null);
const data = reactive({
list: [],
pagination: {
currentPage: 1,
pageSize: 10,
total: 0,
},
searchForm: {},
addOrEditDialog: {
visible: false,
type: "",
form: {
NAME: "",
ORDER_BY: "",
BZ: "",
},
rules: {
NAME: [
{ required: true, message: "字典名称不能为空", trigger: "change" },
{ min: 2, max: 30, message: "长度在 2 到 30 个字符", trigger: "blur" },
],
ORDER_BY: [
{ required: true, message: "字典序号名称不能为空", trigger: "change" },
{ type: "number", message: "字典序号必须为数字" },
],
},
},
});
const fnGetData = async () => {
const resData = await getMonitoringTypeManagementList({
currentPage: data.pagination.currentPage,
showCount: data.pagination.pageSize,
...data.searchForm,
DICTIONARIES_ID: "6a724d36c3ad416fad22049d932c1987",
});
data.list = resData.varList;
data.pagination.total = resData.page.totalResult;
};
fnGetData();
const buttonJurisdiction = await layoutFnButtonJurisdiction("dictionaries");
const fnResetPagination = () => {
data.pagination = {
currentPage: 1,
pageSize: 10,
total: 0,
};
tableRef.value.clearSelection();
fnGetData();
};
const fnDelete = debounce(
1000,
async (DICTIONARIES_ID) => {
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
await setMonitoringTypeManagementDelete({ DICTIONARIES_ID });
ElMessage.success("删除成功");
fnResetPagination();
},
{ atBegin: true }
);
const fnDeleteAll = debounce(
1000,
async () => {
const selectionData = tableRef.value.getSelectionRows();
if (selectionData.length === 0) {
ElMessage.warning("请选中要删除的项");
return;
}
const DATA_IDS = selectionData
.map((item) => item.DICTIONARIES_ID)
.join(",");
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
await setMonitoringTypeManagementDeleteMultiple({ DATA_IDS });
ElMessage.success("删除成功");
fnResetPagination();
},
{ atBegin: true }
);
const fnAddOrEditDialogChangeShow = () => {
data.addOrEditDialog.visible = !data.addOrEditDialog.visible;
};
const fnAddOrEdit = async (row, type) => {
data.addOrEditDialog.type = type;
fnAddOrEditDialogChangeShow();
await nextTick();
addOrEditDialogFormRef.value.resetFields();
if (type === "edit") data.addOrEditDialog.form = cloneDeep(row);
};
const fnAddOrEditDialogSubmit = debounce(
1000,
async () => {
await useFormValidate(addOrEditDialogFormRef);
const { type, form } = data.addOrEditDialog;
const params = {
...form,
BIANMA: "MONITORINGEQUIPMENTTYPE",
YNDEL: "no",
PARENT_ID: "6a724d36c3ad416fad22049d932c1987",
};
if (type === "add") await setMonitoringTypeManagementAdd(params);
if (type === "edit") await setMonitoringTypeManagementEdit(params);
ElMessage.success("保存成功");
fnAddOrEditDialogChangeShow();
fnResetPagination();
},
{ atBegin: true }
);
</script>
<style scoped></style>

View File

@ -0,0 +1,9 @@
<template>
<emergency-handling-record />
</template>
<script setup>
import EmergencyHandlingRecord from "../emergency_handling_record/index.vue";
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,9 @@
<template>
<emergency-handling-record-view />
</template>
<script setup>
import EmergencyHandlingRecordView from "../emergency_handling_record/view.vue";
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,83 @@
<template>
<layout-card>
<div class="container">
<div
v-for="(item, index) in data.list"
:key="index"
class="item"
@click="
router.push({
path: '/major_hazard_sources/real_time_data_monitoring/view',
query: { MAJORDANGERSOURCE_ID: item.MAJORDANGERSOURCE_ID },
})
"
>
<div class="title">
<div>
{{ item.MAJORDANGERSOURCE_NUMBER }}{{ item.MAJORDANGERSOURCE_NAME }}
</div>
<div>{{ item.MAJORDANGERSOURCE_TYPE_NAME }}</div>
</div>
<div class="img">
<img src="/src/assets/images/tanks.png" alt="" />
</div>
<div class="info">
<div class="label">液位</div>
<div class="value">{{ item.STORAGETANK_LIQUIDLEVEL }}</div>
</div>
<div class="info">
<div class="label">温度</div>
<div class="value">{{ item.STORAGETANK_TEMPERATURE }}</div>
</div>
</div>
</div>
</layout-card>
</template>
<script setup>
import { reactive } from "vue";
import { getRealTimeDataMonitoringEquipment } from "@/request/major_hazard_sources.js";
import { useRouter } from "vue-router";
const router = useRouter();
const data = reactive({
list: [],
});
const fnGetData = async () => {
const resData = await getRealTimeDataMonitoringEquipment();
data.list = resData.varList;
};
fnGetData();
</script>
<style lang="scss" scoped>
.container {
display: flex;
flex-wrap: wrap;
.item {
flex-basis: 20%;
text-align: center;
cursor: pointer;
.img {
margin-top: 10px;
margin-bottom: 10px;
}
.info {
div {
display: inline-block;
border: 1px solid var(--el-border-color);
padding: 8px 20px;
font-size: 14px;
line-height: 1.6;
}
.label {
background: var(--el-fill-color-light);
}
}
}
}
</style>

View File

@ -0,0 +1,860 @@
<template>
<div>
<layout-card>
<el-divider content-position="left">设备信息</el-divider>
<div class="liquid-warp">
<div class="liquid-item">
<div class="liquid-title">
<div>
{{ data.info.MAJORDANGERSOURCE_NUMBER }}
{{ data.info.MAJORDANGERSOURCE_NAME }}
</div>
<div>{{ data.info.MAJORDANGERSOURCE_TYPE_NAME }}</div>
</div>
<div class="tanks-img">
<img
src="/src/assets/images/tanks.png"
width="86"
height="74"
alt=""
/>
</div>
</div>
<div class="liquid-table">
<table class="table-mini">
<tr>
<td class="bg" />
<td class="bg">当前值</td>
<td class="bg">低预警值</td>
<td class="bg">高预警值</td>
</tr>
<tr>
<td class="bg">液位</td>
<td :class="data.info.LIQUIDLEVELCLASS">
{{ data.info.STORAGETANK_LIQUIDLEVEL }}
</td>
<td class="red">{{ data.info.LIQUIDLEVEL_RANGEMIN }}</td>
<td class="red">{{ data.info.LIQUIDLEVEL_RANGEMAX }}</td>
</tr>
<tr>
<td class="bg">温度</td>
<td :class="data.info.TEMPERATURECLASS">
{{ data.info.STORAGETANK_TEMPERATURE }}
</td>
<td class="red">{{ data.info.TEMPERATURE_RANGEMIN }}</td>
<td class="red">{{ data.info.TEMPERATURE_RANGEMAX }}</td>
</tr>
</table>
</div>
<div class="liquid-btns">
<el-button
type="primary"
v-if="data.hasDisposal"
@click="fnEmergencyResponse"
>
应急处置
</el-button>
<div style="margin-top: 14px">
<el-button
type="primary"
@click="
$router.push({
path: '/major_hazard_sources/real_time_data_monitoring/view/emergency_handling_record',
query: { MAJORDANGERSOURCE_ID },
})
"
>
应急处理记录
</el-button>
</div>
</div>
</div>
<div class="liquid-center">
<el-row :gutter="20">
<el-col :span="12">
<div id="echarts1" style="width: 100%; height: 220px" />
</el-col>
<el-col :span="12">
<div id="echarts2" style="width: 100%; height: 220px" />
</el-col>
</el-row>
</div>
<div>
<el-tabs v-model="tabsActive">
<el-tab-pane label="液位" name="first">
<layout-table :data="data.logList" :show-pagination="false">
<el-table-column type="index" label="序号" width="50" />
<el-table-column label="储罐编号">
{{ data.info.MAJORDANGERSOURCE_NUMBER }}
</el-table-column>
<el-table-column label="数据日期">
<template v-slot="{ row }">
{{
row[
"STORAGETANK" +
data.info.MAJORDANGERSOURCE_STORAGETANK +
"_OPERATTIME"
].substring(0, 10)
}}
</template>
</el-table-column>
<el-table-column label="数据时间">
<template v-slot="{ row }">
{{
row[
"STORAGETANK" +
data.info.MAJORDANGERSOURCE_STORAGETANK +
"_OPERATTIME"
].substring(11)
}}
</template>
</el-table-column>
<el-table-column label="数据">
<template v-slot="{ row }">
{{
row[
"STORAGETANK" +
data.info.MAJORDANGERSOURCE_STORAGETANK +
"_LIQUIDLEVEL"
]
}}
</template>
</el-table-column>
</layout-table>
</el-tab-pane>
<el-tab-pane label="温度" name="second">
<layout-table :data="data.logList" :show-pagination="false">
<el-table-column type="index" label="序号" width="50" />
<el-table-column label="储罐编号">
{{ data.info.MAJORDANGERSOURCE_NUMBER }}
</el-table-column>
<el-table-column label="数据日期">
<template v-slot="{ row }">
{{
row[
"STORAGETANK" +
data.info.MAJORDANGERSOURCE_STORAGETANK +
"_OPERATTIME"
].substring(0, 10)
}}
</template>
</el-table-column>
<el-table-column label="数据时间">
<template v-slot="{ row }">
{{
row[
"STORAGETANK" +
data.info.MAJORDANGERSOURCE_STORAGETANK +
"_OPERATTIME"
].substring(11)
}}
</template>
</el-table-column>
<el-table-column label="数据">
<template v-slot="{ row }">
{{
row[
"STORAGETANK" +
data.info.MAJORDANGERSOURCE_STORAGETANK +
"_TEMPERATURE"
]
}}
</template>
</el-table-column>
</layout-table>
</el-tab-pane>
</el-tabs>
</div>
</layout-card>
<el-dialog v-model="data.emergencyResponseDialog.visible" title="应急处置">
<el-form
ref="emergencyResponseDialogFormRef"
:rules="data.emergencyResponseDialog.rules"
:model="data.emergencyResponseDialog.form"
label-width="110px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="储罐编号" prop="MAJORDANGERSOURCE_NUMBER">
<el-input v-model="data.info.MAJORDANGERSOURCE_NUMBER" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报警类型" prop="ALARM_TYPE">
<el-select
v-model="data.emergencyResponseDialog.form.ALARM_TYPE"
disabled
>
<el-option
v-for="item in equipmentTypeList"
:key="item.BIANMA"
:label="item.NAME"
:value="item.BIANMA"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报警级别" prop="ALARM_LEVEL">
<el-select
v-model="data.emergencyResponseDialog.form.ALARM_LEVEL"
disabled
>
<el-option
v-for="item in equipmentLevelList"
:key="item.VALUE"
:label="item.NAME"
:value="item.VALUE"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报警值" prop="ALARM_VALUE">
<el-input
v-model="data.emergencyResponseDialog.form.ALARM_VALUE"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="阈值下限" prop="ALARM_RANGE_MIN">
<el-input
v-model="data.emergencyResponseDialog.form.ALARM_RANGE_MIN"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="阈值上限" prop="ALARM_RANGE_MAX">
<el-input
v-model="data.emergencyResponseDialog.form.ALARM_RANGE_MAX"
disabled
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="处置人" prop="DISPOSAL_PERSON">
<el-input
v-model="data.emergencyResponseDialog.form.DISPOSAL_PERSON"
/>
</el-form-item>
<el-form-item label="处置方式" prop="DISPOSAL_METHOD">
<el-input
v-model="data.emergencyResponseDialog.form.DISPOSAL_METHOD"
/>
</el-form-item>
<el-form-item label="处置描述" prop="DISPOSAL_DESC">
<el-input
v-model="data.emergencyResponseDialog.form.DISPOSAL_DESC"
autosize
type="textarea"
/>
</el-form-item>
<el-form-item label="处置前图片" prop="disposalBeforeFile">
<layout-upload
v-model:file-list="
data.emergencyResponseDialog.form.disposalBeforeFile
"
accept=".jpg,.jpeg,.png"
list-type="picture-card"
:limit="99"
/>
</el-form-item>
<el-form-item label="处置后图片" prop="disposalAfterFile">
<layout-upload
v-model:file-list="
data.emergencyResponseDialog.form.disposalAfterFile
"
accept=".jpg,.jpeg,.png"
list-type="picture-card"
:limit="99"
/>
</el-form-item>
<el-form-item label="处置完成时间" prop="DISPOSAL_TIME_OVER">
<el-date-picker
v-model="data.emergencyResponseDialog.form.DISPOSAL_TIME_OVER"
format="YYYY-MM-DD HH:mm"
value-format="YYYY-MM-DD HH:mm"
type="datetime"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="fnEmergencyResponseDialogChangeShow"></el-button>
<el-button type="primary" @click="fnEmergencyResponseDialogSubmit">
确定
</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { useRoute } from "vue-router";
import { nextTick, onBeforeUnmount, reactive, ref } from "vue";
import {
getRealTimeDataMonitoringEquipmentInfo,
getRealTimeDataMonitoringEquipmentDisposal,
getRealTimeDataMonitoringEquipmentData,
getRealTimeDataMonitoringEquipmentLogList,
setRealTimeDataMonitoringEquipmentEdit,
} from "@/request/major_hazard_sources.js";
import { ElMessage } from "element-plus";
import * as echarts from "echarts";
import LayoutUpload from "@/components/upload/index.vue";
import { cloneDeep } from "lodash-es";
import { layoutFnGetEquipmentTypeCorp } from "@/assets/js/data_dictionary.js";
import { debounce } from "throttle-debounce";
import { setUploadImg } from "@/request/api.js";
import useFormValidate from "@/assets/js/useFormValidate.js";
const route = useRoute();
const { MAJORDANGERSOURCE_ID } = route.query;
let messageExample = null;
const Echarts1 = null;
const Echarts2 = null;
let timer = null;
const tabsActive = ref("first");
const emergencyResponseDialogFormRef = ref(null);
const data = reactive({
info: {},
disposalNew: {},
disposal: {},
logList: [],
chartData: {
LIQUIDLEVEL: {
dataX: ["15:14:00", "15:14:05", "15:14:10", "15:14:15", "15:14:20"],
legend: ["液位"],
color: ["#3888FA"],
dataY: [[13.172, 13.171, 13.173, 13.171, 13.175]],
},
TEMPERATURE: {
dataX: ["15:14:00", "15:14:05", "15:14:10", "15:14:15", "15:14:20"],
legend: ["温度"],
color: ["#3888FA"],
dataY: [[26.6, 26.3, 26.5, 26.6, 26.2]],
},
},
hasDisposal: false,
emergencyResponseDialog: {
visible: false,
form: {
ALARM_TYPE: "",
ALARM_VALUE: "",
ALARM_LEVEL: "",
ALARM_RANGE_MIN: "",
ALARM_RANGE_MAX: "",
DISPOSAL_TIME: "",
DISPOSAL_PERSON: "",
DISPOSAL_METHOD: "",
DISPOSAL_DESC: "",
DISPOSAL_TIME_OVER: "",
disposalBeforeFile: [],
disposalAfterFile: [],
},
rules: {
ALARM_TYPE: [
{ required: true, message: "请选择报警类型", trigger: "blur" },
],
ALARM_VALUE: [
{ required: true, message: "报警值不能为空", trigger: "blur" },
],
ALARM_LEVEL: [
{ required: true, message: "报警级别不能为空", trigger: "blur" },
],
ALARM_RANGE_MIN: [
{ required: true, message: "报警阈值下限不能为空", trigger: "blur" },
],
ALARM_RANGE_MAX: [
{ required: true, message: "报警阈值上限不能为空", trigger: "blur" },
],
disposalBeforeFile: [
{ required: true, message: "处置前图片不能为空", trigger: "blur" },
],
disposalAfterFile: [
{ required: true, message: "处置后图片不能为空", trigger: "blur" },
],
DISPOSAL_PERSON: [
{ required: true, message: "处置人不能为空", trigger: "blur" },
],
DISPOSAL_METHOD: [
{ required: true, message: "处置方式不能为空", trigger: "blur" },
],
DISPOSAL_DESC: [
{ required: true, message: "处置描述不能为空", trigger: "blur" },
],
DISPOSAL_TIME_OVER: [
{ required: true, message: "请选择处置完成时间", trigger: "blur" },
],
},
},
});
const fnGetDisposal = async () => {
const resData = await getRealTimeDataMonitoringEquipmentDisposal({
MAJORDANGERSOURCE_ID,
});
data.disposal = resData.varList.length > 0 ? resData.varList[0] : {};
let message = "";
let type = "";
//
if (
data.disposal.MAJORDANGERSOURCE_DISPOSAL_ID &&
Number(data.disposal.ALARM_LEVEL) >
Number(
data.disposalNew.ALARM_LEVEL === ""
? "10"
: data.disposalNew.ALARM_LEVEL
)
) {
data.disposal = { ...data.disposal, ...data.disposalNew };
message =
data.info.MAJORDANGERSOURCE_NAME +
"【" +
(data.disposalNew.ALARM_TYPE === "MONITORINGEQUIPMENTTYPE001"
? "液位"
: "温度") +
"】已升级为";
if (data.disposalNew.ALARM_LEVEL === "1") {
message += "一级";
type = "error";
} else if (data.disposalNew.ALARM_LEVEL === "2") {
message += "二级";
type = "warning";
} else if (data.disposalNew.ALARM_LEVEL === "3") {
message += "三级";
type = "warning";
} else if (data.disposalNew.ALARM_LEVEL === "4") {
message += "四级";
type = "info";
}
message += "预警,请尽快处理";
} else {
//
data.disposal = { ...data.disposal, ...data.disposalNew };
message =
data.info.MAJORDANGERSOURCE_NAME +
"【" +
(data.disposalNew.ALARM_TYPE === "MONITORINGEQUIPMENTTYPE001"
? "液位"
: "温度") +
"】已达";
if (data.disposalNew.ALARM_LEVEL === "1") {
message += "一级";
type = "error";
} else if (data.disposalNew.ALARM_LEVEL === "2") {
message += "二级";
type = "warning";
} else if (data.disposalNew.ALARM_LEVEL === "3") {
message += "三级";
type = "warning";
} else if (data.disposalNew.ALARM_LEVEL === "4") {
message += "四级";
type = "info";
}
message += "预警,请尽快处理";
}
if (type) {
data.hasDisposal = true;
messageExample && messageExample.close();
messageExample = null;
messageExample = ElMessage({
message,
type,
showClose: false,
duration: 0,
});
}
};
const fnGetStorageTankData = async () => {
const resData = await getRealTimeDataMonitoringEquipmentData({
MAJORDANGERSOURCE_STORAGETANK_ID: "1",
});
const liquidLevel =
resData.pd[
"STORAGETANK" + data.info.MAJORDANGERSOURCE_STORAGETANK + "_LIQUIDLEVEL"
];
const temperature =
resData.pd[
"STORAGETANK" + data.info.MAJORDANGERSOURCE_STORAGETANK + "_TEMPERATURE"
];
data.info.STORAGETANK_LIQUIDLEVEL = liquidLevel;
data.info.STORAGETANK_TEMPERATURE = temperature;
let ALARM_LEVEL = 10;
data.info.SENSORLIST.forEach((item) => {
if (item.MONITORINGDEVICESENSOR_TYPE === "MONITORINGEQUIPMENTTYPE001") {
//
if (
Number(item.RANGE1_MIN) <= Number(liquidLevel) &&
Number(liquidLevel) <= Number(item.RANGE1_MAX)
) {
data.info.LIQUIDLEVELCLASS = "red";
data.info.LIQUIDLEVEL_RANGEMIN = item.RANGE1_MIN;
data.info.LIQUIDLEVEL_RANGEMAX = item.RANGE1_MAX;
if (ALARM_LEVEL > 1) {
ALARM_LEVEL = 1;
data.disposalNew.ALARM_TYPE = item.MONITORINGDEVICESENSOR_TYPE;
data.disposalNew.ALARM_LEVEL = "1";
}
} else if (
Number(item.RANGE2_MIN) <= Number(liquidLevel) &&
Number(liquidLevel) <= Number(item.RANGE2_MAX)
) {
data.info.LIQUIDLEVELCLASS = "orange";
data.info.LIQUIDLEVEL_RANGEMIN = item.RANGE2_MIN;
data.info.LIQUIDLEVEL_RANGEMAX = item.RANGE2_MAX;
if (ALARM_LEVEL > 2) {
ALARM_LEVEL = 2;
data.disposalNew.ALARM_TYPE = item.MONITORINGDEVICESENSOR_TYPE;
data.disposalNew.ALARM_LEVEL = "2";
}
} else if (
Number(item.RANGE3_MIN) <= Number(liquidLevel) &&
Number(liquidLevel) <= Number(item.RANGE3_MAX)
) {
data.info.LIQUIDLEVELCLASS = "yellow";
data.info.LIQUIDLEVEL_RANGEMIN = item.RANGE3_MIN;
data.info.LIQUIDLEVEL_RANGEMAX = item.RANGE3_MAX;
if (ALARM_LEVEL > 3) {
ALARM_LEVEL = 3;
data.disposalNew.ALARM_TYPE = item.MONITORINGDEVICESENSOR_TYPE;
data.disposalNew.ALARM_LEVEL = "3";
}
} else if (
Number(item.RANGE4_MIN) <= Number(liquidLevel) &&
Number(liquidLevel) <= Number(item.RANGE4_MAX)
) {
data.info.LIQUIDLEVELCLASS = "blue";
data.info.LIQUIDLEVEL_RANGEMIN = item.RANGE4_MIN;
data.info.LIQUIDLEVEL_RANGEMAX = item.RANGE4_MAX;
if (ALARM_LEVEL > 4) {
ALARM_LEVEL = 4;
data.disposalNew.ALARM_TYPE = item.MONITORINGDEVICESENSOR_TYPE;
data.disposalNew.ALARM_LEVEL = "4";
}
} else {
data.info.LIQUIDLEVELCLASS = "green";
data.info.LIQUIDLEVEL_RANGEMIN = "-";
data.info.LIQUIDLEVEL_RANGEMAX = "-";
}
if (
ALARM_LEVEL < 10 &&
data.disposalNew.ALARM_TYPE === item.MONITORINGDEVICESENSOR_TYPE
) {
data.disposalNew.ALARM_VALUE = liquidLevel;
data.disposalNew.ALARM_RANGE_MIN = data.info.LIQUIDLEVEL_RANGEMIN;
data.disposalNew.ALARM_RANGE_MAX = data.info.LIQUIDLEVEL_RANGEMAX;
}
} else if (
item.MONITORINGDEVICESENSOR_TYPE === "MONITORINGEQUIPMENTTYPE002"
) {
//
if (
Number(item.RANGE1_MIN) <= Number(temperature) &&
Number(temperature) <= Number(item.RANGE1_MAX)
) {
data.info.TEMPERATURECLASS = "red";
data.info.TEMPERATURE_RANGEMIN = item.RANGE1_MIN;
data.info.TEMPERATURE_RANGEMAX = item.RANGE1_MAX;
if (ALARM_LEVEL > 1) {
ALARM_LEVEL = 1;
data.disposalNew.ALARM_TYPE = item.MONITORINGDEVICESENSOR_TYPE;
data.disposalNew.ALARM_LEVEL = "1";
}
} else if (
Number(item.RANGE2_MIN) <= Number(temperature) &&
Number(temperature) <= Number(item.RANGE2_MAX)
) {
data.info.TEMPERATURECLASS = "orange";
data.info.TEMPERATURE_RANGEMIN = item.RANGE2_MIN;
data.info.TEMPERATURE_RANGEMAX = item.RANGE2_MAX;
if (ALARM_LEVEL > 2) {
ALARM_LEVEL = 2;
data.disposalNew.ALARM_TYPE = item.MONITORINGDEVICESENSOR_TYPE;
data.disposalNew.ALARM_LEVEL = "2";
}
} else if (
Number(item.RANGE3_MIN) <= Number(temperature) &&
Number(temperature) <= Number(item.RANGE3_MAX)
) {
data.info.TEMPERATURECLASS = "yellow";
data.info.TEMPERATURE_RANGEMIN = item.RANGE3_MIN;
data.info.TEMPERATURE_RANGEMAX = item.RANGE3_MAX;
if (ALARM_LEVEL > 3) {
ALARM_LEVEL = 3;
data.disposalNew.ALARM_TYPE = item.MONITORINGDEVICESENSOR_TYPE;
data.disposalNew.ALARM_LEVEL = "3";
}
} else if (
Number(item.RANGE4_MIN) <= Number(temperature) &&
Number(temperature) <= Number(item.RANGE4_MAX)
) {
data.info.TEMPERATURECLASS = "blue";
data.info.TEMPERATURE_RANGEMIN = item.RANGE4_MIN;
data.info.TEMPERATURE_RANGEMAX = item.RANGE4_MAX;
if (ALARM_LEVEL > 4) {
ALARM_LEVEL = 4;
data.disposalNew.ALARM_TYPE = item.MONITORINGDEVICESENSOR_TYPE;
data.disposalNew.ALARM_LEVEL = "4";
}
} else {
data.info.TEMPERATURECLASS = "green";
data.info.TEMPERATURE_RANGEMIN = "-";
data.info.TEMPERATURE_RANGEMAX = "-";
}
if (
ALARM_LEVEL < 10 &&
data.disposalNew.ALARM_TYPE === item.MONITORINGDEVICESENSOR_TYPE
) {
data.disposalNew.ALARM_VALUE = temperature;
data.disposalNew.ALARM_RANGE_MIN = data.info.TEMPERATURE_RANGEMIN;
data.disposalNew.ALARM_RANGE_MAX = data.info.TEMPERATURE_RANGEMAX;
}
}
});
await fnGetDisposal();
};
const fnInitEcharts = (echartsData, example, id) => {
example = echarts.init(document.querySelector(id));
const option = {
xAxis: {
data: echartsData.dataX,
axisTick: {
show: false,
},
axisLine: {
lineStyle: {
color: "#fff",
},
},
axisLabel: {
interval: 0,
},
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true,
},
tooltip: {
trigger: "axis",
padding: [5, 10],
},
yAxis: {
axisTick: {
show: false,
},
axisLine: {
lineStyle: {
color: "#fff",
},
},
},
legend: {
data: echartsData.legend,
textStyle: {
color: "#fff",
},
},
series: [
{
name: echartsData.legend[0],
itemStyle: {
normal: {
color: echartsData.color[0],
lineStyle: {
color: echartsData.color[0],
width: 2,
},
},
},
smooth: true,
type: "line",
data: echartsData.dataY[0],
animationDuration: 2800,
animationEasing: "cubicInOut",
},
],
};
example.setOption(option);
};
const fnGetStorageTankLogList = async () => {
const resData = await getRealTimeDataMonitoringEquipmentLogList({
showCount: 5,
currentPage: 1,
STORAGETANK_OPERATTIME:
"STORAGETANK" + data.info.MAJORDANGERSOURCE_STORAGETANK + "_OPERATTIME",
});
data.logList = resData.varList;
data.logList.forEach((item, i) => {
const j = data.logList.length - 1 - i;
const datatime =
item[
"STORAGETANK" + data.info.MAJORDANGERSOURCE_STORAGETANK + "_OPERATTIME"
];
data.chartData.LIQUIDLEVEL.dataX[j] =
datatime.length > 11 ? datatime.substring(11) : datatime;
data.chartData.TEMPERATURE.dataX[j] =
datatime.length > 11 ? datatime.substring(11) : datatime;
data.chartData.LIQUIDLEVEL.dataY[0][j] =
item[
"STORAGETANK" + data.info.MAJORDANGERSOURCE_STORAGETANK + "_LIQUIDLEVEL"
];
data.chartData.TEMPERATURE.dataY[0][j] =
item[
"STORAGETANK" + data.info.MAJORDANGERSOURCE_STORAGETANK + "_TEMPERATURE"
];
});
fnInitEcharts(data.chartData.LIQUIDLEVEL, Echarts1, "#echarts1");
fnInitEcharts(data.chartData.TEMPERATURE, Echarts2, "#echarts2");
};
const fnGetData = async () => {
const resData = await getRealTimeDataMonitoringEquipmentInfo({
MAJORDANGERSOURCE_ID,
});
data.info = resData.pd;
await fnGetStorageTankData();
await fnGetStorageTankLogList();
timer = setInterval(async () => {
await fnGetStorageTankData();
await fnGetStorageTankLogList();
}, 5000);
};
fnGetData();
const equipmentTypeList = await layoutFnGetEquipmentTypeCorp();
const equipmentLevelList = [
{ VALUE: "1", NAME: "一级" },
{ VALUE: "2", NAME: "二级" },
{ VALUE: "3", NAME: "三级" },
{ VALUE: "4", NAME: "四级" },
];
const fnEmergencyResponseDialogChangeShow = () => {
data.emergencyResponseDialog.visible = !data.emergencyResponseDialog.visible;
};
const fnEmergencyResponse = async () => {
fnEmergencyResponseDialogChangeShow();
await nextTick();
emergencyResponseDialogFormRef.value.resetFields();
data.emergencyResponseDialog.form = cloneDeep(data.disposal);
};
const fnEmergencyResponseDialogSubmit = debounce(
1000,
async () => {
await useFormValidate(emergencyResponseDialogFormRef);
const { form } = data.emergencyResponseDialog;
await fnUploadImg("disposalBeforeFile", 20);
await fnUploadImg("disposalAfterFile", 21);
await setRealTimeDataMonitoringEquipmentEdit({
...form,
DISPOSAL_STATUS: "1",
MAJORDANGERSOURCE_ID,
MAJORDANGERSOURCE_DISPOSAL_ID:
data.disposal.MAJORDANGERSOURCE_DISPOSAL_ID,
});
fnEmergencyResponseDialogChangeShow();
ElMessage.success("保存成功");
},
{ atBegin: true }
);
const fnUploadImg = async (file, TYPE) => {
const { form } = data.emergencyResponseDialog;
for (let i = 0; i < form[file].length; i++) {
const formData = new FormData();
formData.append("FFILE", form[file][i].raw);
formData.append("FOREIGN_KEY", data.disposal.MAJORDANGERSOURCE_DISPOSAL_ID);
formData.append("TYPE", TYPE);
await setUploadImg(formData);
}
};
onBeforeUnmount(() => {
messageExample && messageExample.close();
messageExample = null;
timer && clearInterval(timer);
timer = null;
});
</script>
<style scoped lang="scss">
.liquid-warp {
display: flex;
align-items: center;
padding-bottom: 20px;
border-bottom: 1px solid #273868;
.liquid-item {
display: flex;
flex-direction: column;
padding: 18px 100px;
text-align: center;
.liquid-title {
font-size: 14px;
margin-bottom: 10px;
}
.liquid-img {
margin: 10px 0;
cursor: pointer;
}
}
.liquid-table {
width: 500px;
.table-mini {
width: 100%;
border-collapse: collapse;
font-size: 14px;
tr {
.bg {
background: var(--el-fill-color-light);
color: #fff;
}
.red {
color: #e72626;
}
.orange {
color: orange;
}
.yellow {
color: #eec722;
}
.blue {
color: dodgerblue;
}
.green {
color: #2dcf25;
}
td {
padding: 4px 8px;
border: 1px solid var(--el-border-color);
text-align: center;
}
}
}
}
.liquid-btns {
margin-left: 40px;
display: flex;
flex-direction: column;
.el-button {
width: 140px;
}
}
}
.liquid-center {
height: 240px;
}
</style>