refactor(api,components): 优化报警及设备区域相关接口与组件展示

- 调整报警信息API请求路径,统一使用 alarmRecord/list 接口
- 修正AlarmRecord接口请求路径前缀
- 更新DeviceRegion火灾区域列表接口路径为fireCheck/fireRegion/listAll
- 调整api模块导出顺序,确保AlarmInfo、AlarmRecord、DeviceRegion和SensorDevice正确导出
- 引入SensorDevice列表数据,优化AssignList、DcsList、ThresholdList、AlarmRecordList组件显示传感器名称
- 优化AssignList和相关组件中报警值显示,加入上下升降标识及单位显示逻辑
- 移除AssignModal中报警级别和报警类型字段,简化表单交互
- 修正DetailModal中报警详情显示,增加报警类型、报警描述和告警值展示
- DeviceRegion组件新增消防区域名称、编码及负责人名称展示逻辑
- 优化DeviceRegion绑定传感器Modal逻辑,使用循环逐个绑定/解绑,提升稳定性
- 修正DeviceRegion管理Modal部门和负责人表单字段名称及对应赋值处理
- 调整SensorDevice和SensorType组件导出顺序,保证默认导出顺序及命名规范
- 增加AlarmRecord和设备区域、传感器相关页面对传感器名称数据源依赖
- 修改常量文件中报警级别和类型定义,调整为紧急/一般及DCS报警/阈值报警
- 规范组件导出顺序和默认导出,增强代码可维护性
- 优化搜索表单字段及表格列定义,修复时间筛选字段匹配及展示展示一致性
- 修复若干UI细节,如Checkbox.Group样式调整、Message调用顺序及无障碍优化
- 调整pages导出组件顺序,确保Container模块中子模块有序且清晰
main
wangyan 2026-04-03 18:24:47 +08:00
parent 3b672c92aa
commit 72f65bc850
23 changed files with 311 additions and 160 deletions

View File

@ -1,4 +1,4 @@
import { declareRequest } from "@cqsjjb/jjb-dva-runtime"; import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
export const dcsAlarmInfoList = declareRequest("dcsAlarmInfoLoading", "Post > @/iotalarm/dcsAlarmInfo/list"); export const dcsAlarmInfoList = declareRequest("dcsAlarmInfoLoading", "Post > @/iotalarm/alarmRecord/list");
export const thresholdAlarmInfoList = declareRequest("thresholdAlarmInfoLoading", "Post > @/iotalarm/thresholdAlarmInfo/list"); export const thresholdAlarmInfoList = declareRequest("thresholdAlarmInfoLoading", "Post > @/iotalarm/alarmRecord/list");

View File

@ -6,5 +6,5 @@ export const alarmRecordList = declareRequest(
); );
export const alarmRecordInfo = declareRequest( export const alarmRecordInfo = declareRequest(
"alarmRecordLoading", "alarmRecordLoading",
`Get > /iotalarm/alarmRecord/{id}`, `Get > @/iotalarm/alarmRecord/{id}`,
); );

View File

@ -1,7 +1,7 @@
import { declareRequest } from "@cqsjjb/jjb-dva-runtime"; import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
export const deviceRegionList = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/list"); export const deviceRegionList = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/list");
export const deviceRegionFireRegionList = declareRequest("deviceRegionLoading", "Get > @/iotalarm/deviceRegion/fireRegionList"); export const deviceRegionFireRegionList = declareRequest("deviceRegionLoading", "Get > @/fireCheck/fireRegion/listAll");
export const deviceRegionSaveOrUpdate = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/saveOrUpdate"); export const deviceRegionSaveOrUpdate = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/saveOrUpdate");
export const deviceRegionBindSensor = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/bindSensor"); export const deviceRegionBindSensor = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/bindSensor");
export const deviceRegionUnbindSensor = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/unbindSensor"); export const deviceRegionUnbindSensor = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/unbindSensor");

View File

@ -1,6 +1,6 @@
export * from "./SensorType";
export * from "./SensorDevice";
export * from "./DeviceRegion";
export * from "./AlarmInfo";
export * from "./AlarmDispose"; export * from "./AlarmDispose";
export * from "./AlarmInfo";
export * from "./AlarmRecord"; export * from "./AlarmRecord";
export * from "./DeviceRegion";
export * from "./SensorDevice";
export * from "./SensorType";

View File

@ -1,7 +1,7 @@
import { Permission } from "@cqsjjb/jjb-common-decorator/permission"; import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Button, Form, message, Space, Modal } from "antd"; import { Button, Form, message, Space } from "antd";
import { useState } from "react"; import { useEffect, useState } from "react";
import Page from "zy-react-library/components/Page"; import Page from "zy-react-library/components/Page";
import Search from "zy-react-library/components/Search"; import Search from "zy-react-library/components/Search";
import Table from "zy-react-library/components/Table"; import Table from "zy-react-library/components/Table";
@ -9,8 +9,8 @@ import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
import useTable from "zy-react-library/hooks/useTable"; import useTable from "zy-react-library/hooks/useTable";
import { getLabelName } from "zy-react-library/utils"; import { getLabelName } from "zy-react-library/utils";
import AssignModal from "~/components/AlarmDispose/AssignModal"; import AssignModal from "~/components/AlarmDispose/AssignModal";
import { ALARM_STATUS_OPTIONS, ALARM_SOURCE_OPTIONS, ALARM_LEVEL_OPTIONS, ALARM_TYPE_OPTIONS } from "~/enumerate/constant"; import { ALARM_LEVEL_OPTIONS, ALARM_SOURCE_OPTIONS, ALARM_STATUS_OPTIONS, ALARM_TYPE_OPTIONS } from "~/enumerate/constant";
import { NS_ALARMDISPOSE } from "~/enumerate/namespace"; import { NS_ALARMDISPOSE, NS_SENSORDEVICE } from "~/enumerate/namespace";
function AssignList(props) { function AssignList(props) {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -18,11 +18,20 @@ function AssignList(props) {
const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [currentAlarmId, setCurrentAlarmId] = useState(null); const [currentAlarmId, setCurrentAlarmId] = useState(null);
const [isBatch, setIsBatch] = useState(false); const [isBatch, setIsBatch] = useState(false);
const [sensorNameMap, setSensorNameMap] = useState({});
const { tableProps, getData } = useTable(props["alarmAssignList"], { const { tableProps, getData } = useTable(props["alarmAssignList"], { form });
form,
defaultParams: { status: [10, 20] }, useEffect(() => {
props.sensorDeviceList({ pageIndex: 1, pageSize: 500 }).then((res) => {
if (!res?.success) {
return;
}
setSensorNameMap(
Object.fromEntries((res.data || []).map(item => [item.sensorCode, item.sensorName])),
);
}); });
}, [props.sensorDeviceList]);
const assignPermission = `${props.type}-iotalarm-alarm-assign`; const assignPermission = `${props.type}-iotalarm-alarm-assign`;
@ -47,14 +56,28 @@ function AssignList(props) {
onChange: setSelectedRowKeys, onChange: setSelectedRowKeys,
}; };
const dataSource = (tableProps.dataSource || []).map(item => ({
...item,
sensorName: sensorNameMap[item.sensorCode] || "-",
}));
const renderCurrentValue = (_, record) => {
if (record.currentValue == null || record.currentValue === "") {
return "-";
}
const suffix = record.compareFlag === "UP" ? " 上升" : record.compareFlag === "DOWN" ? " 下降" : "";
const unit = record.unitName ? ` ${record.unitName}` : "";
return `${record.currentValue}${unit}${suffix}`;
};
return ( return (
<Page isShowAllAction={false}> <Page isShowAllAction={false}>
<Search <Search
form={form} form={form}
onFinish={getData} onFinish={getData}
options={[ options={[
{ name: "alarmName", label: "报警名称" }, { name: "alarmNo", label: "报警编号" },
{ name: "deviceName", label: "设备名称" }, { name: "sensorCode", label: "传感器编码" },
{ {
name: "alarmSource", name: "alarmSource",
label: "报警来源", label: "报警来源",
@ -62,10 +85,16 @@ function AssignList(props) {
items: ALARM_SOURCE_OPTIONS, items: ALARM_SOURCE_OPTIONS,
}, },
{ {
name: "status", name: "alarmLevel",
label: "报警状态", label: "报警级别",
render: FORM_ITEM_RENDER_ENUM.SELECT, render: FORM_ITEM_RENDER_ENUM.SELECT,
items: ALARM_STATUS_OPTIONS.filter(item => item.bianma === 10 || item.bianma === 20), items: ALARM_LEVEL_OPTIONS,
},
{
name: "alarmType",
label: "报警类型",
render: FORM_ITEM_RENDER_ENUM.SELECT,
items: ALARM_TYPE_OPTIONS,
}, },
]} ]}
/> />
@ -82,14 +111,14 @@ function AssignList(props) {
</Space> </Space>
)} )}
columns={[ columns={[
{ title: "报警名称", dataIndex: "alarmName", ellipsis: true }, { title: "报警编号", dataIndex: "alarmNo" },
{ title: "设备名称", dataIndex: "deviceName", ellipsis: true },
{ title: "报警位置", dataIndex: "alarmLocation", ellipsis: true },
{ {
title: "报警来源", title: "报警来源",
dataIndex: "alarmSource", dataIndex: "alarmSource",
render: value => getLabelName({ status: value, list: ALARM_SOURCE_OPTIONS }) || value || "-", render: value => getLabelName({ status: value, list: ALARM_SOURCE_OPTIONS }) || value || "-",
}, },
{ title: "传感器编码", dataIndex: "sensorCode" },
{ title: "传感器名称", dataIndex: "sensorName", ellipsis: true },
{ {
title: "报警级别", title: "报警级别",
dataIndex: "alarmLevel", dataIndex: "alarmLevel",
@ -100,13 +129,14 @@ function AssignList(props) {
dataIndex: "alarmType", dataIndex: "alarmType",
render: value => getLabelName({ status: value, list: ALARM_TYPE_OPTIONS }) || value || "-", render: value => getLabelName({ status: value, list: ALARM_TYPE_OPTIONS }) || value || "-",
}, },
{ title: "报警描述", dataIndex: "alarmDesc", ellipsis: true },
{ {
title: "报警状态", title: "报警状态",
dataIndex: "status", dataIndex: "status",
render: value => getLabelName({ status: value, list: ALARM_STATUS_OPTIONS }) || value || "-", render: value => getLabelName({ status: value, list: ALARM_STATUS_OPTIONS }) || value || "-",
}, },
{ title: "报警时间", dataIndex: "alarmTime", width: 180 }, { title: "报警时间", dataIndex: "alarmTime", width: 180 },
{ title: "报警值", dataIndex: "alarmValue" }, { title: "告警值", render: renderCurrentValue },
{ {
title: "操作", title: "操作",
width: 120, width: 120,
@ -122,6 +152,7 @@ function AssignList(props) {
}, },
]} ]}
{...tableProps} {...tableProps}
dataSource={dataSource}
/> />
{modalOpen && ( {modalOpen && (
<AssignModal <AssignModal
@ -144,4 +175,4 @@ function AssignList(props) {
); );
} }
export default Connect([NS_ALARMDISPOSE], true)(Permission(AssignList)); export default Connect([NS_ALARMDISPOSE, NS_SENSORDEVICE], true)(Permission(AssignList));

View File

@ -1,7 +1,6 @@
import { Form, Modal, Select } from "antd"; import { Form, Modal } from "antd";
import { useEffect } from "react"; import { useEffect } from "react";
import PersonnelSelect from "zy-react-library/components/Select/Personnel/Gwj"; import PersonnelSelect from "zy-react-library/components/Select/Personnel/Gwj";
import { ALARM_LEVEL_OPTIONS, ALARM_TYPE_OPTIONS } from "~/enumerate/constant";
function AssignModal(props) { function AssignModal(props) {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -21,17 +20,14 @@ function AssignModal(props) {
const handleSubmit = async (values) => { const handleSubmit = async (values) => {
if (props.isBatch) { if (props.isBatch) {
await props.alarmBatchAssign({ await props.alarmBatchAssign({
alarmIds: props.alarmIds, ids: props.alarmIds,
disposeUserId: values.disposeUserId, disposeUserId: values.disposeUserId,
alarmLevel: values.alarmLevel,
alarmType: values.alarmType,
}); });
} else { }
else {
await props.alarmAssign({ await props.alarmAssign({
alarmId: props.alarmId, id: props.alarmId,
disposeUserId: values.disposeUserId, disposeUserId: values.disposeUserId,
alarmLevel: values.alarmLevel,
alarmType: values.alarmType,
}); });
} }
handleCancel(); handleCancel();
@ -56,32 +52,6 @@ function AssignModal(props) {
> >
<PersonnelSelect placeholder="请选择处置人" /> <PersonnelSelect placeholder="请选择处置人" />
</Form.Item> </Form.Item>
<Form.Item
label="报警级别"
name="alarmLevel"
rules={[{ required: true, message: "请选择报警级别" }]}
>
<Select placeholder="请选择报警级别">
{ALARM_LEVEL_OPTIONS.map(item => (
<Select.Option key={item.bianma} value={item.bianma}>
{item.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
label="报警类型"
name="alarmType"
rules={[{ required: true, message: "请选择报警类型" }]}
>
<Select placeholder="请选择报警类型">
{ALARM_TYPE_OPTIONS.map(item => (
<Select.Option key={item.bianma} value={item.bianma}>
{item.name}
</Select.Option>
))}
</Select>
</Form.Item>
</Form> </Form>
</Modal> </Modal>
); );

View File

@ -1,6 +1,7 @@
import { Permission } from "@cqsjjb/jjb-common-decorator/permission"; import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Form } from "antd"; import { Form } from "antd";
import { useEffect, useState } from "react";
import Page from "zy-react-library/components/Page"; import Page from "zy-react-library/components/Page";
import Search from "zy-react-library/components/Search"; import Search from "zy-react-library/components/Search";
import Table from "zy-react-library/components/Table"; import Table from "zy-react-library/components/Table";
@ -8,11 +9,40 @@ import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
import useTable from "zy-react-library/hooks/useTable"; import useTable from "zy-react-library/hooks/useTable";
import { getLabelName } from "zy-react-library/utils"; import { getLabelName } from "zy-react-library/utils";
import { ALARM_STATUS_OPTIONS } from "~/enumerate/constant"; import { ALARM_STATUS_OPTIONS } from "~/enumerate/constant";
import { NS_DCSALARMINFO } from "~/enumerate/namespace"; import { NS_DCSALARMINFO, NS_SENSORDEVICE } from "~/enumerate/namespace";
function DcsList(props) { function DcsList(props) {
const [form] = Form.useForm(); const [form] = Form.useForm();
const { tableProps, getData } = useTable(props["dcsAlarmInfoList"], { form }); const [sensorNameMap, setSensorNameMap] = useState({});
const { tableProps, getData } = useTable(props["dcsAlarmInfoList"], {
form,
defaultParams: { alarmSource: "DCS" },
});
useEffect(() => {
props.sensorDeviceList({ pageIndex: 1, pageSize: 500 }).then((res) => {
if (!res?.success) {
return;
}
setSensorNameMap(
Object.fromEntries((res.data || []).map(item => [item.sensorCode, item.sensorName])),
);
});
}, [props.sensorDeviceList]);
const dataSource = (tableProps.dataSource || []).map(item => ({
...item,
sensorName: sensorNameMap[item.sensorCode] || "-",
}));
const renderCurrentValue = (_, record) => {
if (record.currentValue == null || record.currentValue === "") {
return "-";
}
const suffix = record.compareFlag === "UP" ? " 上升" : record.compareFlag === "DOWN" ? " 下降" : "";
const unit = record.unitName ? ` ${record.unitName}` : "";
return `${record.currentValue}${unit}${suffix}`;
};
return ( return (
<Page isShowAllAction={false}> <Page isShowAllAction={false}>
@ -45,9 +75,11 @@ function DcsList(props) {
columns={[ columns={[
{ title: "报警编号", dataIndex: "alarmNo" }, { title: "报警编号", dataIndex: "alarmNo" },
{ title: "传感器编码", dataIndex: "sensorCode" }, { title: "传感器编码", dataIndex: "sensorCode" },
{ title: "传感器名称", dataIndex: "sensorName" },
{ title: "报警时间", dataIndex: "alarmTime" }, { title: "报警时间", dataIndex: "alarmTime" },
{ title: "报警级", dataIndex: "alarmLevel" }, { title: "报警", dataIndex: "alarmLevel" },
{ title: "报警描述", dataIndex: "alarmDesc", ellipsis: true }, { title: "报警描述", dataIndex: "alarmDesc", ellipsis: true },
{ title: "告警值", render: renderCurrentValue },
{ {
title: "报警状态", title: "报警状态",
dataIndex: "status", dataIndex: "status",
@ -56,9 +88,10 @@ function DcsList(props) {
{ title: "设备来源", dataIndex: "deviceSourceDesc" }, { title: "设备来源", dataIndex: "deviceSourceDesc" },
]} ]}
{...tableProps} {...tableProps}
dataSource={dataSource}
/> />
</Page> </Page>
); );
} }
export default Connect([NS_DCSALARMINFO], true)(Permission(DcsList)); export default Connect([NS_DCSALARMINFO, NS_SENSORDEVICE], true)(Permission(DcsList));

View File

@ -1,6 +1,7 @@
import { Permission } from "@cqsjjb/jjb-common-decorator/permission"; import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Form } from "antd"; import { Form } from "antd";
import { useEffect, useState } from "react";
import Page from "zy-react-library/components/Page"; import Page from "zy-react-library/components/Page";
import Search from "zy-react-library/components/Search"; import Search from "zy-react-library/components/Search";
import Table from "zy-react-library/components/Table"; import Table from "zy-react-library/components/Table";
@ -8,11 +9,40 @@ import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
import useTable from "zy-react-library/hooks/useTable"; import useTable from "zy-react-library/hooks/useTable";
import { getLabelName } from "zy-react-library/utils"; import { getLabelName } from "zy-react-library/utils";
import { ALARM_STATUS_OPTIONS } from "~/enumerate/constant"; import { ALARM_STATUS_OPTIONS } from "~/enumerate/constant";
import { NS_THRESHOLDALARMINFO } from "~/enumerate/namespace"; import { NS_SENSORDEVICE, NS_THRESHOLDALARMINFO } from "~/enumerate/namespace";
function ThresholdList(props) { function ThresholdList(props) {
const [form] = Form.useForm(); const [form] = Form.useForm();
const { tableProps, getData } = useTable(props["thresholdAlarmInfoList"], { form }); const [sensorNameMap, setSensorNameMap] = useState({});
const { tableProps, getData } = useTable(props["thresholdAlarmInfoList"], {
form,
defaultParams: { alarmSource: "THRESHOLD" },
});
useEffect(() => {
props.sensorDeviceList({ pageIndex: 1, pageSize: 500 }).then((res) => {
if (!res?.success) {
return;
}
setSensorNameMap(
Object.fromEntries((res.data || []).map(item => [item.sensorCode, item.sensorName])),
);
});
}, [props.sensorDeviceList]);
const dataSource = (tableProps.dataSource || []).map(item => ({
...item,
sensorName: sensorNameMap[item.sensorCode] || "-",
}));
const renderCurrentValue = (_, record) => {
if (record.currentValue == null || record.currentValue === "") {
return "-";
}
const suffix = record.compareFlag === "UP" ? " 上升" : record.compareFlag === "DOWN" ? " 下降" : "";
const unit = record.unitName ? ` ${record.unitName}` : "";
return `${record.currentValue}${unit}${suffix}`;
};
return ( return (
<Page isShowAllAction={false}> <Page isShowAllAction={false}>
@ -45,9 +75,11 @@ function ThresholdList(props) {
columns={[ columns={[
{ title: "报警编号", dataIndex: "alarmNo" }, { title: "报警编号", dataIndex: "alarmNo" },
{ title: "传感器编码", dataIndex: "sensorCode" }, { title: "传感器编码", dataIndex: "sensorCode" },
{ title: "传感器名称", dataIndex: "sensorName" },
{ title: "报警时间", dataIndex: "alarmTime" }, { title: "报警时间", dataIndex: "alarmTime" },
{ title: "报警级", dataIndex: "alarmLevel" }, { title: "报警", dataIndex: "alarmLevel" },
{ title: "报警描述", dataIndex: "alarmDesc", ellipsis: true }, { title: "报警描述", dataIndex: "alarmDesc", ellipsis: true },
{ title: "告警值", render: renderCurrentValue },
{ {
title: "报警状态", title: "报警状态",
dataIndex: "status", dataIndex: "status",
@ -56,9 +88,10 @@ function ThresholdList(props) {
{ title: "设备来源", dataIndex: "deviceSourceDesc" }, { title: "设备来源", dataIndex: "deviceSourceDesc" },
]} ]}
{...tableProps} {...tableProps}
dataSource={dataSource}
/> />
</Page> </Page>
); );
} }
export default Connect([NS_THRESHOLDALARMINFO], true)(Permission(ThresholdList)); export default Connect([NS_THRESHOLDALARMINFO, NS_SENSORDEVICE], true)(Permission(ThresholdList));

View File

@ -8,7 +8,6 @@ function DetailModal(props) {
useEffect(() => { useEffect(() => {
if (!props.open) { if (!props.open) {
setDetail(null);
return; return;
} }
props.alarmRecordInfo({ id: props.currentId }).then((res) => { props.alarmRecordInfo({ id: props.currentId }).then((res) => {
@ -18,6 +17,15 @@ function DetailModal(props) {
}); });
}, [props.open, props.currentId, props.alarmRecordInfo]); }, [props.open, props.currentId, props.alarmRecordInfo]);
const renderCurrentValue = () => {
if (!detail || detail.currentValue == null || detail.currentValue === "") {
return "-";
}
const suffix = detail.compareFlag === "UP" ? " 上升" : detail.compareFlag === "DOWN" ? " 下降" : "";
const unit = detail.unitName ? ` ${detail.unitName}` : "";
return `${detail.currentValue}${unit}${suffix}`;
};
return ( return (
<Modal <Modal
destroyOnClose destroyOnClose
@ -34,18 +42,23 @@ function DetailModal(props) {
{getLabelName({ status: detail.alarmSource, list: ALARM_SOURCE_OPTIONS }) || detail.alarmSource || "-"} {getLabelName({ status: detail.alarmSource, list: ALARM_SOURCE_OPTIONS }) || detail.alarmSource || "-"}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="传感器编码">{detail.sensorCode || "-"}</Descriptions.Item> <Descriptions.Item label="传感器编码">{detail.sensorCode || "-"}</Descriptions.Item>
<Descriptions.Item label="传感器名称">{detail.sensorName || "-"}</Descriptions.Item> <Descriptions.Item label="传感器名称">
{props.sensorNameMap?.[detail.sensorCode] || detail.sensorName || "-"}
</Descriptions.Item>
<Descriptions.Item label="报警时间">{detail.alarmTime || "-"}</Descriptions.Item> <Descriptions.Item label="报警时间">{detail.alarmTime || "-"}</Descriptions.Item>
<Descriptions.Item label="报警级别">{detail.alarmLevel || "-"}</Descriptions.Item> <Descriptions.Item label="报警级别">{detail.alarmLevel || "-"}</Descriptions.Item>
<Descriptions.Item label="报警类型">{detail.alarmType || "-"}</Descriptions.Item>
<Descriptions.Item label="报警描述">{detail.alarmDesc || "-"}</Descriptions.Item>
<Descriptions.Item label="状态"> <Descriptions.Item label="状态">
{getLabelName({ status: detail.status, list: ALARM_STATUS_OPTIONS }) || detail.status || "-"} {getLabelName({ status: detail.status, list: ALARM_STATUS_OPTIONS }) || detail.status || "-"}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="处置人">{detail.disposeUserName || "-"}</Descriptions.Item> <Descriptions.Item label="告警值">{renderCurrentValue()}</Descriptions.Item>
<Descriptions.Item label="设备来源描述" span={2}> <Descriptions.Item label="设备来源描述" span={2}>
{detail.deviceSourceDesc || "-"} {detail.deviceSourceDesc || "-"}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="处置人">{detail.disposeUserName || detail.disposeUserId || "-"}</Descriptions.Item>
<Descriptions.Item label="处置时间">{detail.disposeTime || "-"}</Descriptions.Item> <Descriptions.Item label="处置时间">{detail.disposeTime || "-"}</Descriptions.Item>
<Descriptions.Item label="处置备注">{detail.disposeRemark || "-"}</Descriptions.Item> <Descriptions.Item label="处置备注" span={2}>{detail.disposeRemark || "-"}</Descriptions.Item>
</Descriptions> </Descriptions>
)} )}
</Modal> </Modal>

View File

@ -1,7 +1,7 @@
import { Permission } from "@cqsjjb/jjb-common-decorator/permission"; import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Button, Form, Space } from "antd"; import { Button, Form, Space } from "antd";
import { useState } from "react"; import { useEffect, useState } from "react";
import Page from "zy-react-library/components/Page"; import Page from "zy-react-library/components/Page";
import Search from "zy-react-library/components/Search"; import Search from "zy-react-library/components/Search";
import Table from "zy-react-library/components/Table"; import Table from "zy-react-library/components/Table";
@ -10,19 +10,45 @@ import useTable from "zy-react-library/hooks/useTable";
import { getLabelName } from "zy-react-library/utils"; import { getLabelName } from "zy-react-library/utils";
import DetailModal from "~/components/AlarmRecord/DetailModal"; import DetailModal from "~/components/AlarmRecord/DetailModal";
import { ALARM_SOURCE_OPTIONS, ALARM_STATUS_OPTIONS } from "~/enumerate/constant"; import { ALARM_SOURCE_OPTIONS, ALARM_STATUS_OPTIONS } from "~/enumerate/constant";
import { NS_ALARMRECORD } from "~/enumerate/namespace"; import { NS_ALARMRECORD, NS_SENSORDEVICE } from "~/enumerate/namespace";
function AlarmRecordList(props) { function AlarmRecordList(props) {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [detailOpen, setDetailOpen] = useState(false); const [detailOpen, setDetailOpen] = useState(false);
const [currentId, setCurrentId] = useState(""); const [currentId, setCurrentId] = useState("");
const [sensorNameMap, setSensorNameMap] = useState({});
const { tableProps, getData } = useTable(props["alarmRecordList"], { form }); const { tableProps, getData } = useTable(props["alarmRecordList"], { form });
useEffect(() => {
props.sensorDeviceList({ pageIndex: 1, pageSize: 500 }).then((res) => {
if (!res?.success) {
return;
}
setSensorNameMap(
Object.fromEntries((res.data || []).map(item => [item.sensorCode, item.sensorName])),
);
});
}, [props.sensorDeviceList]);
const handleViewDetail = (record) => { const handleViewDetail = (record) => {
setCurrentId(record.id); setCurrentId(record.id);
setDetailOpen(true); setDetailOpen(true);
}; };
const dataSource = (tableProps.dataSource || []).map(item => ({
...item,
sensorName: sensorNameMap[item.sensorCode] || "-",
}));
const renderCurrentValue = (_, record) => {
if (record.currentValue == null || record.currentValue === "") {
return "-";
}
const suffix = record.compareFlag === "UP" ? " 上升" : record.compareFlag === "DOWN" ? " 下降" : "";
const unit = record.unitName ? ` ${record.unitName}` : "";
return `${record.currentValue}${unit}${suffix}`;
};
return ( return (
<Page isShowAllAction={false}> <Page isShowAllAction={false}>
<Search <Search
@ -30,7 +56,7 @@ function AlarmRecordList(props) {
onFinish={getData} onFinish={getData}
options={[ options={[
{ name: "alarmNo", label: "报警编号" }, { name: "alarmNo", label: "报警编号" },
{ name: "sensorName", label: "传感器名称" }, { name: "sensorCode", label: "传感器编码" },
{ {
name: "alarmSource", name: "alarmSource",
label: "报警来源", label: "报警来源",
@ -44,9 +70,14 @@ function AlarmRecordList(props) {
items: ALARM_STATUS_OPTIONS, items: ALARM_STATUS_OPTIONS,
}, },
{ {
name: "alarmTime", name: "alarmTimeStart",
label: "报警时间", label: "开始时间",
render: FORM_ITEM_RENDER_ENUM.DATETIME_RANGE, render: FORM_ITEM_RENDER_ENUM.DATE,
},
{
name: "alarmTimeEnd",
label: "结束时间",
render: FORM_ITEM_RENDER_ENUM.DATE,
}, },
]} ]}
/> />
@ -62,13 +93,20 @@ function AlarmRecordList(props) {
{ title: "传感器编码", dataIndex: "sensorCode" }, { title: "传感器编码", dataIndex: "sensorCode" },
{ title: "传感器名称", dataIndex: "sensorName" }, { title: "传感器名称", dataIndex: "sensorName" },
{ title: "报警时间", dataIndex: "alarmTime" }, { title: "报警时间", dataIndex: "alarmTime" },
{ title: "报警描述", dataIndex: "alarmDesc", ellipsis: true },
{ title: "告警值", render: renderCurrentValue },
{ title: "报警级别", dataIndex: "alarmLevel" }, { title: "报警级别", dataIndex: "alarmLevel" },
{ title: "报警类型", dataIndex: "alarmType" },
{ {
title: "状态", title: "状态",
dataIndex: "status", dataIndex: "status",
render: value => getLabelName({ status: value, list: ALARM_STATUS_OPTIONS }) || value || "-", render: value => getLabelName({ status: value, list: ALARM_STATUS_OPTIONS }) || value || "-",
}, },
{ title: "处置人", dataIndex: "disposeUserName" }, {
title: "处置人",
render: (_, record) => record.disposeUserName || record.disposeUserId || "-",
},
{ title: "处置时间", dataIndex: "disposeTime" },
{ title: "设备来源描述", dataIndex: "deviceSourceDesc", ellipsis: true }, { title: "设备来源描述", dataIndex: "deviceSourceDesc", ellipsis: true },
{ {
title: "操作", title: "操作",
@ -86,12 +124,14 @@ function AlarmRecordList(props) {
}, },
]} ]}
{...tableProps} {...tableProps}
dataSource={dataSource}
/> />
{detailOpen && ( {detailOpen && (
<DetailModal <DetailModal
open={detailOpen} open={detailOpen}
currentId={currentId} currentId={currentId}
alarmRecordInfo={props.alarmRecordInfo} alarmRecordInfo={props.alarmRecordInfo}
sensorNameMap={sensorNameMap}
onCancel={() => { onCancel={() => {
setDetailOpen(false); setDetailOpen(false);
setCurrentId(""); setCurrentId("");
@ -102,4 +142,4 @@ function AlarmRecordList(props) {
); );
} }
export default Connect([NS_ALARMRECORD], true)(Permission(AlarmRecordList)); export default Connect([NS_ALARMRECORD, NS_SENSORDEVICE], true)(Permission(AlarmRecordList));

View File

@ -1,4 +1,4 @@
import { Checkbox, Empty, Modal, Typography, message } from "antd"; import { Checkbox, Empty, message, Modal, Typography } from "antd";
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
function BindSensorModal(props) { function BindSensorModal(props) {
@ -51,17 +51,14 @@ function BindSensorModal(props) {
const handleSubmit = async () => { const handleSubmit = async () => {
setLoading(true); setLoading(true);
try { try {
if (changes.addIds.length) { for (const sensorId of changes.addIds) {
await props.deviceRegionBindSensor({ await props.deviceRegionBindSensor({
regionConfigId: props.currentId, regionConfigId: props.currentId,
sensorIds: changes.addIds, sensorId,
}); });
} }
if (changes.removeIds.length) { for (const sensorId of changes.removeIds) {
await props.deviceRegionUnbindSensor({ await props.deviceRegionUnbindSensor({ sensorId });
regionConfigId: props.currentId,
sensorIds: changes.removeIds,
});
} }
message.success("传感器绑定已更新"); message.success("传感器绑定已更新");
props.onCancel(); props.onCancel();
@ -83,9 +80,15 @@ function BindSensorModal(props) {
width={760} width={760}
> >
<Typography.Paragraph style={{ marginBottom: 16 }}> <Typography.Paragraph style={{ marginBottom: 16 }}>
当前区域{detail.fireRegionName || "-"} / {detail.fireRegionCode || "-"} 当前区域
{detail.fireRegionName || "-"}
{" "}
/
{" "}
{detail.fireRegionCode || "-"}
</Typography.Paragraph> </Typography.Paragraph>
{options.length ? ( {options.length
? (
<Checkbox.Group <Checkbox.Group
value={selectedSensorIds} value={selectedSensorIds}
onChange={setSelectedSensorIds} onChange={setSelectedSensorIds}
@ -107,7 +110,8 @@ function BindSensorModal(props) {
))} ))}
</div> </div>
</Checkbox.Group> </Checkbox.Group>
) : ( )
: (
<Empty description="暂无可绑定的传感器设备" /> <Empty description="暂无可绑定的传感器设备" />
)} )}
</Modal> </Modal>

View File

@ -1,7 +1,7 @@
import { Permission } from "@cqsjjb/jjb-common-decorator/permission"; import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Button, Form, Input, Modal, Select, Space, message } from "antd"; import { Button, Form, Input, message, Modal, Select, Space } from "antd";
import { useEffect, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import AddIcon from "zy-react-library/components/Icon/AddIcon"; import AddIcon from "zy-react-library/components/Icon/AddIcon";
import Page from "zy-react-library/components/Page"; import Page from "zy-react-library/components/Page";
import Search from "zy-react-library/components/Search"; import Search from "zy-react-library/components/Search";
@ -37,6 +37,11 @@ function DeviceRegionList(props) {
loadFireRegionOptions(); loadFireRegionOptions();
}, [props.deviceRegionFireRegionList]); }, [props.deviceRegionFireRegionList]);
const fireRegionMap = useMemo(
() => Object.fromEntries(fireRegionOptions.map(item => [item.id, item])),
[fireRegionOptions],
);
useEffect(() => { useEffect(() => {
if (!configOpen) { if (!configOpen) {
return; return;
@ -62,6 +67,7 @@ function DeviceRegionList(props) {
await props["deviceRegionSaveOrUpdate"]({ await props["deviceRegionSaveOrUpdate"]({
...values, ...values,
id: currentId || undefined, id: currentId || undefined,
fireRegionName: selectedFireRegion?.fireRegionName,
fireRegionCode: selectedFireRegion?.fireRegionCode, fireRegionCode: selectedFireRegion?.fireRegionCode,
}); });
message.success(currentId ? "设备区域配置已更新" : "设备区域配置已新增"); message.success(currentId ? "设备区域配置已更新" : "设备区域配置已新增");
@ -71,13 +77,28 @@ function DeviceRegionList(props) {
getData(); getData();
}; };
const handleSearch = (values) => {
getData(values);
};
const dataSource = (tableProps.dataSource || []).map((item) => {
const fireRegion = fireRegionMap[item.fireRegionId] || {};
return {
...item,
fireRegionName: fireRegion.fireRegionName || item.fireRegionName || "-",
fireRegionCode: fireRegion.fireRegionCode || item.fireRegionCode || "-",
deptName: item.deptName || item.departmentName || fireRegion.departmentName || item.departmentId || "-",
managerName: item.managerName || item.managerId || "-",
bindSensorCount: item.bindSensorCount ?? item.boundSensors?.length ?? 0,
};
});
return ( return (
<Page isShowAllAction={false}> <Page isShowAllAction={false}>
<Search <Search
form={form} form={form}
onFinish={getData} onFinish={handleSearch}
options={[ options={[
{ name: "fireRegionName", label: "消防区域名称" },
{ name: "fireRegionCode", label: "消防区域编码" }, { name: "fireRegionCode", label: "消防区域编码" },
{ {
name: "status", name: "status",
@ -160,6 +181,7 @@ function DeviceRegionList(props) {
}, },
]} ]}
{...tableProps} {...tableProps}
dataSource={dataSource}
/> />
<Modal <Modal
destroyOnClose destroyOnClose

View File

@ -16,10 +16,11 @@ function ManagerModal(props) {
return; return;
} }
const data = res.data || {}; const data = res.data || {};
setDepartmentId(data.deptId); setDepartmentId(data.departmentId);
form.setFieldsValue({ form.setFieldsValue({
deptId: data.deptId, departmentId: data.departmentId,
managerId: data.managerId, managerId: data.managerId,
managerName: data.managerName,
}); });
}); });
}, [form, props.currentId, props.deviceRegionInfo, props.open]); }, [form, props.currentId, props.deviceRegionInfo, props.open]);
@ -47,7 +48,7 @@ function ManagerModal(props) {
width={640} width={640}
> >
<Form form={form} layout="vertical" onFinish={handleSubmit}> <Form form={form} layout="vertical" onFinish={handleSubmit}>
<Form.Item label="负责部门" name="deptId"> <Form.Item label="负责部门" name="departmentId">
<DepartmentSelectTree <DepartmentSelectTree
onChange={(value) => { onChange={(value) => {
setDepartmentId(value); setDepartmentId(value);
@ -56,7 +57,13 @@ function ManagerModal(props) {
/> />
</Form.Item> </Form.Item>
<Form.Item label="负责人" name="managerId"> <Form.Item label="负责人" name="managerId">
<PersonnelSelect params={{ departmentId }} /> <PersonnelSelect
params={{ departmentId }}
onGetLabel={label => form.setFieldValue("managerName", label)}
/>
</Form.Item>
<Form.Item hidden name="managerName">
<input />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>

View File

@ -1,6 +1,6 @@
export { default as List } from "./List";
export { default as ManagerModal } from "./ManagerModal";
export { default as BindSensorModal } from "./BindSensorModal"; export { default as BindSensorModal } from "./BindSensorModal";
export { default as List } from "./List";
// 默认导出 List 作为主入口组件 // 默认导出 List 作为主入口组件
export { default } from "./List"; export { default } from "./List";
export { default as ManagerModal } from "./ManagerModal";

View File

@ -1,8 +1,8 @@
// 导出子组件 // 导出子组件
export { default as List } from "./List"; export { default as List } from "./List";
export { default as Modal } from "./Modal";
export { default as ThresholdModal } from "./ThresholdModal";
export { default as RealtimeModal } from "./RealtimeModal";
// 默认导出 List 作为主入口 // 默认导出 List 作为主入口
export { default } from "./List"; export { default } from "./List";
export { default as Modal } from "./Modal";
export { default as RealtimeModal } from "./RealtimeModal";
export { default as ThresholdModal } from "./ThresholdModal";

View File

@ -1,5 +1,5 @@
export { default as List } from "./List"; export { default as List } from "./List";
export { default as Modal } from "./Modal";
// 默认导出 List 作为主入口组件 // 默认导出 List 作为主入口组件
export { default } from "./List"; export { default } from "./List";
export { default as Modal } from "./Modal";

View File

@ -1,6 +1,6 @@
export { default as SensorType } from "./SensorType";
export { default as SensorDevice } from "./SensorDevice";
export { default as DeviceRegion } from "./DeviceRegion";
export { default as AlarmInfo } from "./AlarmInfo";
export { default as AlarmDispose } from "./AlarmDispose"; export { default as AlarmDispose } from "./AlarmDispose";
export { default as AlarmInfo } from "./AlarmInfo";
export { default as AlarmRecord } from "./AlarmRecord"; export { default as AlarmRecord } from "./AlarmRecord";
export { default as DeviceRegion } from "./DeviceRegion";
export { default as SensorDevice } from "./SensorDevice";
export { default as SensorType } from "./SensorType";

View File

@ -34,13 +34,11 @@ export const ALARM_SOURCE_OPTIONS = [
]; ];
export const ALARM_LEVEL_OPTIONS = [ export const ALARM_LEVEL_OPTIONS = [
{ bianma: "HIGH", name: "高" }, { bianma: "URGENT", name: "紧急" },
{ bianma: "MEDIUM", name: "中" }, { bianma: "NORMAL", name: "一般" },
{ bianma: "LOW", name: "低" },
]; ];
export const ALARM_TYPE_OPTIONS = [ export const ALARM_TYPE_OPTIONS = [
{ bianma: "FAULT", name: "故障报警" }, { bianma: "DCS_ALARM", name: "DCS 报警" },
{ bianma: "THRESHOLD", name: "阈值报警" }, { bianma: "THRESHOLD_ALARM", name: "阈值报警" },
{ bianma: "MANUAL", name: "人工报警" },
]; ];

View File

@ -1,3 +1,3 @@
export * from "./context";
export * from "./constant"; export * from "./constant";
export * from "./context";
export * from "./namespace"; export * from "./namespace";

View File

@ -1,22 +1,22 @@
export { default as Container } from "./Container"; export { default as Container } from "./Container";
export { default as BranchCompany } from "./Container/BranchCompany"; export { default as BranchCompany } from "./Container/BranchCompany";
export { default as BranchCompanyAlarmAssign } from "./Container/BranchCompany/AlarmAssign";
export { default as BranchCompanyAlarmRecord } from "./Container/BranchCompany/AlarmRecord";
export { default as BranchCompanyDcsAlarmInfo } from "./Container/BranchCompany/DcsAlarmInfo";
export { default as BranchCompanyDeviceRegion } from "./Container/BranchCompany/DeviceRegion";
export { default as BranchCompanySensorDevice } from "./Container/BranchCompany/SensorDevice";
export { default as BranchCompanySensorType } from "./Container/BranchCompany/SensorType";
export { default as BranchCompanyThresholdAlarmInfo } from "./Container/BranchCompany/ThresholdAlarmInfo";
export { default as Supervision } from "./Container/Supervision"; export { default as Supervision } from "./Container/Supervision";
export { default as BranchCompanySensorType } from "./Container/BranchCompany/SensorType";
export { default as BranchCompanySensorDevice } from "./Container/BranchCompany/SensorDevice";
export { default as BranchCompanyDeviceRegion } from "./Container/BranchCompany/DeviceRegion";
export { default as BranchCompanyDcsAlarmInfo } from "./Container/BranchCompany/DcsAlarmInfo";
export { default as BranchCompanyThresholdAlarmInfo } from "./Container/BranchCompany/ThresholdAlarmInfo";
export { default as BranchCompanyAlarmAssign } from "./Container/BranchCompany/AlarmAssign";
export { default as BranchCompanyAlarmRecord } from "./Container/BranchCompany/AlarmRecord";
export { default as SupervisionSensorType } from "./Container/Supervision/SensorType";
export { default as SupervisionSensorDevice } from "./Container/Supervision/SensorDevice";
export { default as SupervisionDeviceRegion } from "./Container/Supervision/DeviceRegion";
export { default as SupervisionDcsAlarmInfo } from "./Container/Supervision/DcsAlarmInfo";
export { default as SupervisionThresholdAlarmInfo } from "./Container/Supervision/ThresholdAlarmInfo";
export { default as SupervisionAlarmAssign } from "./Container/Supervision/AlarmAssign"; export { default as SupervisionAlarmAssign } from "./Container/Supervision/AlarmAssign";
export { default as SupervisionAlarmRecord } from "./Container/Supervision/AlarmRecord"; export { default as SupervisionAlarmRecord } from "./Container/Supervision/AlarmRecord";
export { default as SupervisionDcsAlarmInfo } from "./Container/Supervision/DcsAlarmInfo";
export { default as SupervisionDeviceRegion } from "./Container/Supervision/DeviceRegion";
export { default as SupervisionSensorDevice } from "./Container/Supervision/SensorDevice";
export { default as SupervisionSensorType } from "./Container/Supervision/SensorType";
export { default as SupervisionThresholdAlarmInfo } from "./Container/Supervision/ThresholdAlarmInfo";
export default function HomePage() { export default function HomePage() {
return <div style={{ padding: 24 }}>物联网消防报警模块前端骨架已完成</div>; return <div style={{ padding: 24 }}>物联网消防报警模块前端骨架已完成</div>;