feat(iotalarm): 初始化物联网消防报警模块前端骨架
- 新增多项公共常量配置,便于全局状态和状态选项管理 - 重构全局命名空间常量定义,支持传感器类型等多个领域管理 - 完善 Container 页面主题配置,初始化主题为默认算法和样式 - 新增业务模型组件统一导出,支持设备类型、区域及报警信息等模块 - 更新包依赖版本,确保依赖库兼容最新功能 - 设计并实现多个 API 请求声明,覆盖传感器、设备区域、报警信息及处置 - 新增报警处置分配相关组件,支持单条及批量分配功能 - 新增 Dcs 和 Threshold 两类报警列表组件,支持多维搜索和表格展示 - 实现报警记录组件,支持详情查看和状态管理 - 新增设备区域管理功能,包括绑定传感器和配置负责人模块 - 优化全局上下文定义,设置InjectContext默认值为null,避免潜在错误风险 - 重构首页展示,简化底座模板描述,突出消防报警模块状态提示main
parent
8259ec5b0f
commit
a18d61521e
|
|
@ -31,7 +31,7 @@
|
|||
"lodash-es": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"zy-react-library": "^1.2.19"
|
||||
"zy-react-library": "^1.2.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^5.4.1",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
|
||||
|
||||
export const alarmAssignList = declareRequest("alarmDisposeLoading", "Post > @/iotalarm/alarmDispose/assignList");
|
||||
export const alarmAssign = declareRequest("alarmDisposeLoading", "Post > @/iotalarm/alarmDispose/assign");
|
||||
export const alarmBatchAssign = declareRequest("alarmDisposeLoading", "Post > @/iotalarm/alarmDispose/batchAssign");
|
||||
export const alarmRecordList = declareRequest("alarmRecordLoading", "Post > @/iotalarm/alarmRecord/list");
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
|
||||
|
||||
export const dcsAlarmInfoList = declareRequest("dcsAlarmInfoLoading", "Post > @/iotalarm/dcsAlarmInfo/list");
|
||||
export const thresholdAlarmInfoList = declareRequest("thresholdAlarmInfoLoading", "Post > @/iotalarm/thresholdAlarmInfo/list");
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
|
||||
|
||||
export const alarmRecordList = declareRequest(
|
||||
"alarmRecordLoading",
|
||||
`Post > @/iotalarm/alarmRecord/list`,
|
||||
);
|
||||
export const alarmRecordInfo = declareRequest(
|
||||
"alarmRecordLoading",
|
||||
`Get > /iotalarm/alarmRecord/{id}`,
|
||||
);
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
|
||||
|
||||
export const deviceRegionList = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/list");
|
||||
export const deviceRegionFireRegionList = declareRequest("deviceRegionLoading", "Get > @/iotalarm/deviceRegion/fireRegionList");
|
||||
export const deviceRegionSaveOrUpdate = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/saveOrUpdate");
|
||||
export const deviceRegionBindSensor = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/bindSensor");
|
||||
export const deviceRegionUnbindSensor = declareRequest("deviceRegionLoading", "Post > @/iotalarm/deviceRegion/unbindSensor");
|
||||
export const deviceRegionManager = declareRequest("deviceRegionLoading", "Put > @/iotalarm/deviceRegion/manager");
|
||||
export const deviceRegionInfo = declareRequest("deviceRegionLoading", "Get > @/iotalarm/deviceRegion/{id}");
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
|
||||
|
||||
export const sensorDeviceList = declareRequest("sensorDeviceLoading", "Post > @/iotalarm/sensorDevice/list");
|
||||
export const sensorDeviceInfo = declareRequest("sensorDeviceLoading", "Get > @/iotalarm/sensorDevice/{id}");
|
||||
export const sensorDeviceSave = declareRequest("sensorDeviceLoading", "Post > @/iotalarm/sensorDevice/save");
|
||||
export const sensorDeviceEdit = declareRequest("sensorDeviceLoading", "Put > @/iotalarm/sensorDevice/edit");
|
||||
export const sensorDeviceStatus = declareRequest("sensorDeviceLoading", "Put > @/iotalarm/sensorDevice/status");
|
||||
export const sensorDeviceThreshold = declareRequest("sensorDeviceLoading", "Put > @/iotalarm/sensorDevice/threshold");
|
||||
export const sensorDeviceRemove = declareRequest("sensorDeviceLoading", "Delete > @/iotalarm/sensorDevice/{id}");
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
|
||||
|
||||
export const sensorTypeList = declareRequest("sensorTypeLoading", "Post > @/iotalarm/sensorType/list");
|
||||
export const sensorTypeInfo = declareRequest("sensorTypeLoading", "Get > @/iotalarm/sensorType/{id}");
|
||||
export const sensorTypeSave = declareRequest("sensorTypeLoading", "Post > @/iotalarm/sensorType/save");
|
||||
export const sensorTypeEdit = declareRequest("sensorTypeLoading", "Put > @/iotalarm/sensorType/edit");
|
||||
export const sensorTypeRemove = declareRequest("sensorTypeLoading", "Delete > @/iotalarm/sensorType/{id}");
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export * from "./SensorType";
|
||||
export * from "./SensorDevice";
|
||||
export * from "./DeviceRegion";
|
||||
export * from "./AlarmInfo";
|
||||
export * from "./AlarmDispose";
|
||||
export * from "./AlarmRecord";
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Form, message, Space, Modal } from "antd";
|
||||
import { useState } from "react";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
import Search from "zy-react-library/components/Search";
|
||||
import Table from "zy-react-library/components/Table";
|
||||
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
|
||||
import useTable from "zy-react-library/hooks/useTable";
|
||||
import { getLabelName } from "zy-react-library/utils";
|
||||
import AssignModal from "~/components/AlarmDispose/AssignModal";
|
||||
import { ALARM_STATUS_OPTIONS, ALARM_SOURCE_OPTIONS, ALARM_LEVEL_OPTIONS, ALARM_TYPE_OPTIONS } from "~/enumerate/constant";
|
||||
import { NS_ALARMDISPOSE } from "~/enumerate/namespace";
|
||||
|
||||
function AssignList(props) {
|
||||
const [form] = Form.useForm();
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
const [currentAlarmId, setCurrentAlarmId] = useState(null);
|
||||
const [isBatch, setIsBatch] = useState(false);
|
||||
|
||||
const { tableProps, getData } = useTable(props["alarmAssignList"], {
|
||||
form,
|
||||
defaultParams: { status: [10, 20] },
|
||||
});
|
||||
|
||||
const assignPermission = `${props.type}-iotalarm-alarm-assign`;
|
||||
|
||||
const handleBatchAssign = () => {
|
||||
if (selectedRowKeys.length === 0) {
|
||||
message.warning("请先选择要分配的报警记录");
|
||||
return;
|
||||
}
|
||||
setIsBatch(true);
|
||||
setCurrentAlarmId(null);
|
||||
setModalOpen(true);
|
||||
};
|
||||
|
||||
const handleSingleAssign = (record) => {
|
||||
setIsBatch(false);
|
||||
setCurrentAlarmId(record.id);
|
||||
setModalOpen(true);
|
||||
};
|
||||
|
||||
const rowSelection = {
|
||||
selectedRowKeys,
|
||||
onChange: setSelectedRowKeys,
|
||||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Search
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
options={[
|
||||
{ name: "alarmName", label: "报警名称" },
|
||||
{ name: "deviceName", label: "设备名称" },
|
||||
{
|
||||
name: "alarmSource",
|
||||
label: "报警来源",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: ALARM_SOURCE_OPTIONS,
|
||||
},
|
||||
{
|
||||
name: "status",
|
||||
label: "报警状态",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: ALARM_STATUS_OPTIONS.filter(item => item.bianma === 10 || item.bianma === 20),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Table
|
||||
rowKey="id"
|
||||
rowSelection={rowSelection}
|
||||
toolBarRender={() => (
|
||||
<Space>
|
||||
{props.permission(assignPermission) && (
|
||||
<Button type="primary" onClick={handleBatchAssign}>
|
||||
批量分配
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
)}
|
||||
columns={[
|
||||
{ title: "报警名称", dataIndex: "alarmName", ellipsis: true },
|
||||
{ title: "设备名称", dataIndex: "deviceName", ellipsis: true },
|
||||
{ title: "报警位置", dataIndex: "alarmLocation", ellipsis: true },
|
||||
{
|
||||
title: "报警来源",
|
||||
dataIndex: "alarmSource",
|
||||
render: value => getLabelName({ status: value, list: ALARM_SOURCE_OPTIONS }) || value || "-",
|
||||
},
|
||||
{
|
||||
title: "报警级别",
|
||||
dataIndex: "alarmLevel",
|
||||
render: value => getLabelName({ status: value, list: ALARM_LEVEL_OPTIONS }) || value || "-",
|
||||
},
|
||||
{
|
||||
title: "报警类型",
|
||||
dataIndex: "alarmType",
|
||||
render: value => getLabelName({ status: value, list: ALARM_TYPE_OPTIONS }) || value || "-",
|
||||
},
|
||||
{
|
||||
title: "报警状态",
|
||||
dataIndex: "status",
|
||||
render: value => getLabelName({ status: value, list: ALARM_STATUS_OPTIONS }) || value || "-",
|
||||
},
|
||||
{ title: "报警时间", dataIndex: "alarmTime", width: 180 },
|
||||
{ title: "报警值", dataIndex: "alarmValue" },
|
||||
{
|
||||
title: "操作",
|
||||
width: 120,
|
||||
render: (_, record) => (
|
||||
<Space>
|
||||
{props.permission(assignPermission) && (
|
||||
<Button type="link" onClick={() => handleSingleAssign(record)}>
|
||||
分配
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
{...tableProps}
|
||||
/>
|
||||
{modalOpen && (
|
||||
<AssignModal
|
||||
open={modalOpen}
|
||||
isBatch={isBatch}
|
||||
alarmId={currentAlarmId}
|
||||
alarmIds={selectedRowKeys}
|
||||
loading={props.alarmDisposeLoading}
|
||||
getData={getData}
|
||||
alarmAssign={props.alarmAssign}
|
||||
alarmBatchAssign={props.alarmBatchAssign}
|
||||
onCancel={() => {
|
||||
setModalOpen(false);
|
||||
setCurrentAlarmId(null);
|
||||
setSelectedRowKeys([]);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default Connect([NS_ALARMDISPOSE], true)(Permission(AssignList));
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
import { Form, Modal, Select } from "antd";
|
||||
import { useEffect } from "react";
|
||||
import PersonnelSelect from "zy-react-library/components/Select/Personnel/Gwj";
|
||||
import { ALARM_LEVEL_OPTIONS, ALARM_TYPE_OPTIONS } from "~/enumerate/constant";
|
||||
|
||||
function AssignModal(props) {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.open) {
|
||||
return;
|
||||
}
|
||||
form.resetFields();
|
||||
}, [form, props.open]);
|
||||
|
||||
const handleCancel = () => {
|
||||
form.resetFields();
|
||||
props.onCancel();
|
||||
};
|
||||
|
||||
const handleSubmit = async (values) => {
|
||||
if (props.isBatch) {
|
||||
await props.alarmBatchAssign({
|
||||
alarmIds: props.alarmIds,
|
||||
disposeUserId: values.disposeUserId,
|
||||
alarmLevel: values.alarmLevel,
|
||||
alarmType: values.alarmType,
|
||||
});
|
||||
} else {
|
||||
await props.alarmAssign({
|
||||
alarmId: props.alarmId,
|
||||
disposeUserId: values.disposeUserId,
|
||||
alarmLevel: values.alarmLevel,
|
||||
alarmType: values.alarmType,
|
||||
});
|
||||
}
|
||||
handleCancel();
|
||||
props.getData();
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
open={props.open}
|
||||
title={props.isBatch ? "批量分配" : "分配处置"}
|
||||
onCancel={handleCancel}
|
||||
onOk={form.submit}
|
||||
confirmLoading={props.loading}
|
||||
width={640}
|
||||
>
|
||||
<Form form={form} layout="vertical" onFinish={handleSubmit}>
|
||||
<Form.Item
|
||||
label="处置人"
|
||||
name="disposeUserId"
|
||||
rules={[{ required: true, message: "请选择处置人" }]}
|
||||
>
|
||||
<PersonnelSelect placeholder="请选择处置人" />
|
||||
</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>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default AssignModal;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export { default as AssignList } from "./AssignList";
|
||||
export { default as AssignModal } from "./AssignModal";
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Form } from "antd";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
import Search from "zy-react-library/components/Search";
|
||||
import Table from "zy-react-library/components/Table";
|
||||
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
|
||||
import useTable from "zy-react-library/hooks/useTable";
|
||||
import { getLabelName } from "zy-react-library/utils";
|
||||
import { ALARM_STATUS_OPTIONS } from "~/enumerate/constant";
|
||||
import { NS_DCSALARMINFO } from "~/enumerate/namespace";
|
||||
|
||||
function DcsList(props) {
|
||||
const [form] = Form.useForm();
|
||||
const { tableProps, getData } = useTable(props["dcsAlarmInfoList"], { form });
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Search
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
options={[
|
||||
{ name: "alarmNo", label: "报警编号" },
|
||||
{ name: "sensorCode", label: "传感器编码" },
|
||||
{
|
||||
name: "status",
|
||||
label: "报警状态",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: ALARM_STATUS_OPTIONS,
|
||||
},
|
||||
{
|
||||
name: "alarmTimeStart",
|
||||
label: "开始时间",
|
||||
render: FORM_ITEM_RENDER_ENUM.DATE,
|
||||
},
|
||||
{
|
||||
name: "alarmTimeEnd",
|
||||
label: "结束时间",
|
||||
render: FORM_ITEM_RENDER_ENUM.DATE,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={[
|
||||
{ title: "报警编号", dataIndex: "alarmNo" },
|
||||
{ title: "传感器编码", dataIndex: "sensorCode" },
|
||||
{ title: "报警时间", dataIndex: "alarmTime" },
|
||||
{ title: "报警等级", dataIndex: "alarmLevel" },
|
||||
{ title: "报警描述", dataIndex: "alarmDesc", ellipsis: true },
|
||||
{
|
||||
title: "报警状态",
|
||||
dataIndex: "status",
|
||||
render: value => getLabelName({ status: value, list: ALARM_STATUS_OPTIONS }) || value || "-",
|
||||
},
|
||||
{ title: "设备来源", dataIndex: "deviceSourceDesc" },
|
||||
]}
|
||||
{...tableProps}
|
||||
/>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default Connect([NS_DCSALARMINFO], true)(Permission(DcsList));
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Form } from "antd";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
import Search from "zy-react-library/components/Search";
|
||||
import Table from "zy-react-library/components/Table";
|
||||
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
|
||||
import useTable from "zy-react-library/hooks/useTable";
|
||||
import { getLabelName } from "zy-react-library/utils";
|
||||
import { ALARM_STATUS_OPTIONS } from "~/enumerate/constant";
|
||||
import { NS_THRESHOLDALARMINFO } from "~/enumerate/namespace";
|
||||
|
||||
function ThresholdList(props) {
|
||||
const [form] = Form.useForm();
|
||||
const { tableProps, getData } = useTable(props["thresholdAlarmInfoList"], { form });
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Search
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
options={[
|
||||
{ name: "alarmNo", label: "报警编号" },
|
||||
{ name: "sensorCode", label: "传感器编码" },
|
||||
{
|
||||
name: "status",
|
||||
label: "报警状态",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: ALARM_STATUS_OPTIONS,
|
||||
},
|
||||
{
|
||||
name: "alarmTimeStart",
|
||||
label: "开始时间",
|
||||
render: FORM_ITEM_RENDER_ENUM.DATE,
|
||||
},
|
||||
{
|
||||
name: "alarmTimeEnd",
|
||||
label: "结束时间",
|
||||
render: FORM_ITEM_RENDER_ENUM.DATE,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={[
|
||||
{ title: "报警编号", dataIndex: "alarmNo" },
|
||||
{ title: "传感器编码", dataIndex: "sensorCode" },
|
||||
{ title: "报警时间", dataIndex: "alarmTime" },
|
||||
{ title: "报警等级", dataIndex: "alarmLevel" },
|
||||
{ title: "报警描述", dataIndex: "alarmDesc", ellipsis: true },
|
||||
{
|
||||
title: "报警状态",
|
||||
dataIndex: "status",
|
||||
render: value => getLabelName({ status: value, list: ALARM_STATUS_OPTIONS }) || value || "-",
|
||||
},
|
||||
{ title: "设备来源", dataIndex: "deviceSourceDesc" },
|
||||
]}
|
||||
{...tableProps}
|
||||
/>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default Connect([NS_THRESHOLDALARMINFO], true)(Permission(ThresholdList));
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export { default as DcsList } from "./DcsList";
|
||||
export { default as ThresholdList } from "./ThresholdList";
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
import { Descriptions, Modal } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getLabelName } from "zy-react-library/utils";
|
||||
import { ALARM_SOURCE_OPTIONS, ALARM_STATUS_OPTIONS } from "~/enumerate/constant";
|
||||
|
||||
function DetailModal(props) {
|
||||
const [detail, setDetail] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.open) {
|
||||
setDetail(null);
|
||||
return;
|
||||
}
|
||||
props.alarmRecordInfo({ id: props.currentId }).then((res) => {
|
||||
if (res?.success) {
|
||||
setDetail(res.data || {});
|
||||
}
|
||||
});
|
||||
}, [props.open, props.currentId, props.alarmRecordInfo]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
open={props.open}
|
||||
title="报警详情"
|
||||
onCancel={props.onCancel}
|
||||
footer={null}
|
||||
width={720}
|
||||
>
|
||||
{detail && (
|
||||
<Descriptions column={2} bordered>
|
||||
<Descriptions.Item label="报警编号">{detail.alarmNo || "-"}</Descriptions.Item>
|
||||
<Descriptions.Item label="报警来源">
|
||||
{getLabelName({ status: detail.alarmSource, list: ALARM_SOURCE_OPTIONS }) || detail.alarmSource || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="传感器编码">{detail.sensorCode || "-"}</Descriptions.Item>
|
||||
<Descriptions.Item label="传感器名称">{detail.sensorName || "-"}</Descriptions.Item>
|
||||
<Descriptions.Item label="报警时间">{detail.alarmTime || "-"}</Descriptions.Item>
|
||||
<Descriptions.Item label="报警级别">{detail.alarmLevel || "-"}</Descriptions.Item>
|
||||
<Descriptions.Item label="状态">
|
||||
{getLabelName({ status: detail.status, list: ALARM_STATUS_OPTIONS }) || detail.status || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="处置人">{detail.disposeUserName || "-"}</Descriptions.Item>
|
||||
<Descriptions.Item label="设备来源描述" span={2}>
|
||||
{detail.deviceSourceDesc || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="处置时间">{detail.disposeTime || "-"}</Descriptions.Item>
|
||||
<Descriptions.Item label="处置备注">{detail.disposeRemark || "-"}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default DetailModal;
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Form, Space } from "antd";
|
||||
import { useState } from "react";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
import Search from "zy-react-library/components/Search";
|
||||
import Table from "zy-react-library/components/Table";
|
||||
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
|
||||
import useTable from "zy-react-library/hooks/useTable";
|
||||
import { getLabelName } from "zy-react-library/utils";
|
||||
import DetailModal from "~/components/AlarmRecord/DetailModal";
|
||||
import { ALARM_SOURCE_OPTIONS, ALARM_STATUS_OPTIONS } from "~/enumerate/constant";
|
||||
import { NS_ALARMRECORD } from "~/enumerate/namespace";
|
||||
|
||||
function AlarmRecordList(props) {
|
||||
const [form] = Form.useForm();
|
||||
const [detailOpen, setDetailOpen] = useState(false);
|
||||
const [currentId, setCurrentId] = useState("");
|
||||
const { tableProps, getData } = useTable(props["alarmRecordList"], { form });
|
||||
|
||||
const handleViewDetail = (record) => {
|
||||
setCurrentId(record.id);
|
||||
setDetailOpen(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Search
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
options={[
|
||||
{ name: "alarmNo", label: "报警编号" },
|
||||
{ name: "sensorName", label: "传感器名称" },
|
||||
{
|
||||
name: "alarmSource",
|
||||
label: "报警来源",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: ALARM_SOURCE_OPTIONS,
|
||||
},
|
||||
{
|
||||
name: "status",
|
||||
label: "状态",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: ALARM_STATUS_OPTIONS,
|
||||
},
|
||||
{
|
||||
name: "alarmTime",
|
||||
label: "报警时间",
|
||||
render: FORM_ITEM_RENDER_ENUM.DATETIME_RANGE,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={[
|
||||
{ title: "报警编号", dataIndex: "alarmNo" },
|
||||
{
|
||||
title: "报警来源",
|
||||
dataIndex: "alarmSource",
|
||||
render: value => getLabelName({ status: value, list: ALARM_SOURCE_OPTIONS }) || value || "-",
|
||||
},
|
||||
{ title: "传感器编码", dataIndex: "sensorCode" },
|
||||
{ title: "传感器名称", dataIndex: "sensorName" },
|
||||
{ title: "报警时间", dataIndex: "alarmTime" },
|
||||
{ title: "报警级别", dataIndex: "alarmLevel" },
|
||||
{
|
||||
title: "状态",
|
||||
dataIndex: "status",
|
||||
render: value => getLabelName({ status: value, list: ALARM_STATUS_OPTIONS }) || value || "-",
|
||||
},
|
||||
{ title: "处置人", dataIndex: "disposeUserName" },
|
||||
{ title: "设备来源描述", dataIndex: "deviceSourceDesc", ellipsis: true },
|
||||
{
|
||||
title: "操作",
|
||||
width: 100,
|
||||
render: (_, record) => (
|
||||
<Space>
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => handleViewDetail(record)}
|
||||
>
|
||||
详情
|
||||
</Button>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
{...tableProps}
|
||||
/>
|
||||
{detailOpen && (
|
||||
<DetailModal
|
||||
open={detailOpen}
|
||||
currentId={currentId}
|
||||
alarmRecordInfo={props.alarmRecordInfo}
|
||||
onCancel={() => {
|
||||
setDetailOpen(false);
|
||||
setCurrentId("");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default Connect([NS_ALARMRECORD], true)(Permission(AlarmRecordList));
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import AlarmRecordList from "~/components/AlarmRecord/List";
|
||||
|
||||
export default AlarmRecordList;
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
import { Checkbox, Empty, Modal, Typography, message } from "antd";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
function BindSensorModal(props) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [detail, setDetail] = useState({});
|
||||
const [options, setOptions] = useState([]);
|
||||
const [initialSensorIds, setInitialSensorIds] = useState([]);
|
||||
const [selectedSensorIds, setSelectedSensorIds] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.open || !props.currentId) {
|
||||
return;
|
||||
}
|
||||
const loadData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const [detailRes, deviceRes] = await Promise.all([
|
||||
props.deviceRegionInfo({ id: props.currentId }),
|
||||
props.sensorDeviceList({ pageIndex: 1, pageSize: 500 }),
|
||||
]);
|
||||
const regionDetail = detailRes?.data || {};
|
||||
const deviceList = deviceRes?.data || [];
|
||||
const boundIds = (regionDetail.boundSensors || []).map(item => item.id);
|
||||
setDetail(regionDetail);
|
||||
setInitialSensorIds(boundIds);
|
||||
setSelectedSensorIds(boundIds);
|
||||
setOptions(
|
||||
deviceList.map(item => ({
|
||||
value: item.id,
|
||||
label: `${item.sensorCode} - ${item.sensorName}${item.sensorTypeName ? `(${item.sensorTypeName})` : ""}`,
|
||||
})),
|
||||
);
|
||||
}
|
||||
finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
loadData();
|
||||
}, [props.currentId, props.deviceRegionInfo, props.open, props.sensorDeviceList]);
|
||||
|
||||
const changes = useMemo(() => {
|
||||
const initialSet = new Set(initialSensorIds);
|
||||
const selectedSet = new Set(selectedSensorIds);
|
||||
return {
|
||||
addIds: selectedSensorIds.filter(id => !initialSet.has(id)),
|
||||
removeIds: initialSensorIds.filter(id => !selectedSet.has(id)),
|
||||
};
|
||||
}, [initialSensorIds, selectedSensorIds]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
if (changes.addIds.length) {
|
||||
await props.deviceRegionBindSensor({
|
||||
regionConfigId: props.currentId,
|
||||
sensorIds: changes.addIds,
|
||||
});
|
||||
}
|
||||
if (changes.removeIds.length) {
|
||||
await props.deviceRegionUnbindSensor({
|
||||
regionConfigId: props.currentId,
|
||||
sensorIds: changes.removeIds,
|
||||
});
|
||||
}
|
||||
message.success("传感器绑定已更新");
|
||||
props.onCancel();
|
||||
props.getData();
|
||||
}
|
||||
finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
open={props.open}
|
||||
title="绑定传感器"
|
||||
onCancel={props.onCancel}
|
||||
onOk={handleSubmit}
|
||||
confirmLoading={loading || props.loading}
|
||||
width={760}
|
||||
>
|
||||
<Typography.Paragraph style={{ marginBottom: 16 }}>
|
||||
当前区域:{detail.fireRegionName || "-"} / {detail.fireRegionCode || "-"}
|
||||
</Typography.Paragraph>
|
||||
{options.length ? (
|
||||
<Checkbox.Group
|
||||
value={selectedSensorIds}
|
||||
onChange={setSelectedSensorIds}
|
||||
style={{ width: "100%" }}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
maxHeight: 420,
|
||||
overflowY: "auto",
|
||||
border: "1px solid #f0f0f0",
|
||||
borderRadius: 6,
|
||||
padding: 12,
|
||||
}}
|
||||
>
|
||||
{options.map(item => (
|
||||
<div key={item.value} style={{ padding: "6px 0" }}>
|
||||
<Checkbox value={item.value}>{item.label}</Checkbox>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Checkbox.Group>
|
||||
) : (
|
||||
<Empty description="暂无可绑定的传感器设备" />
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default BindSensorModal;
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Form, Input, Modal, Select, Space, message } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import AddIcon from "zy-react-library/components/Icon/AddIcon";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
import Search from "zy-react-library/components/Search";
|
||||
import Table from "zy-react-library/components/Table";
|
||||
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
|
||||
import useTable from "zy-react-library/hooks/useTable";
|
||||
import { getLabelName } from "zy-react-library/utils";
|
||||
import BindSensorModal from "~/components/DeviceRegion/BindSensorModal";
|
||||
import ManagerModal from "~/components/DeviceRegion/ManagerModal";
|
||||
import { ENABLE_STATUS_OPTIONS } from "~/enumerate/constant";
|
||||
import { NS_DEVICEREGION, NS_SENSORDEVICE } from "~/enumerate/namespace";
|
||||
|
||||
function DeviceRegionList(props) {
|
||||
const [form] = Form.useForm();
|
||||
const [configForm] = Form.useForm();
|
||||
const [configOpen, setConfigOpen] = useState(false);
|
||||
const [managerOpen, setManagerOpen] = useState(false);
|
||||
const [bindOpen, setBindOpen] = useState(false);
|
||||
const [currentId, setCurrentId] = useState("");
|
||||
const [fireRegionOptions, setFireRegionOptions] = useState([]);
|
||||
const { tableProps, getData } = useTable(props["deviceRegionList"], { form });
|
||||
|
||||
const editPermission = `${props.type}-iotalarm-device-region-edit`;
|
||||
|
||||
const loadFireRegionOptions = async () => {
|
||||
const res = await props["deviceRegionFireRegionList"]();
|
||||
if (res?.success) {
|
||||
setFireRegionOptions(res.data || []);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadFireRegionOptions();
|
||||
}, [props.deviceRegionFireRegionList]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!configOpen) {
|
||||
return;
|
||||
}
|
||||
if (!currentId) {
|
||||
configForm.resetFields();
|
||||
configForm.setFieldsValue({ status: 1 });
|
||||
return;
|
||||
}
|
||||
props["deviceRegionInfo"]({ id: currentId }).then((res) => {
|
||||
if (res?.success) {
|
||||
configForm.setFieldsValue({
|
||||
fireRegionId: res.data?.fireRegionId,
|
||||
status: res.data?.status,
|
||||
remarks: res.data?.remarks,
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [configForm, configOpen, currentId, props.deviceRegionInfo]);
|
||||
|
||||
const handleConfigSubmit = async (values) => {
|
||||
const selectedFireRegion = fireRegionOptions.find(item => item.id === values.fireRegionId);
|
||||
await props["deviceRegionSaveOrUpdate"]({
|
||||
...values,
|
||||
id: currentId || undefined,
|
||||
fireRegionCode: selectedFireRegion?.fireRegionCode,
|
||||
});
|
||||
message.success(currentId ? "设备区域配置已更新" : "设备区域配置已新增");
|
||||
setConfigOpen(false);
|
||||
setCurrentId("");
|
||||
configForm.resetFields();
|
||||
getData();
|
||||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Search
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
options={[
|
||||
{ name: "fireRegionName", label: "消防区域名称" },
|
||||
{ name: "fireRegionCode", label: "消防区域编码" },
|
||||
{
|
||||
name: "status",
|
||||
label: "状态",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: ENABLE_STATUS_OPTIONS,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Table
|
||||
rowKey="id"
|
||||
toolBarRender={() => (
|
||||
<Space>
|
||||
{props.permission(editPermission) && (
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<AddIcon />}
|
||||
onClick={() => {
|
||||
setCurrentId("");
|
||||
setConfigOpen(true);
|
||||
}}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
)}
|
||||
columns={[
|
||||
{ title: "消防区域名称", dataIndex: "fireRegionName" },
|
||||
{ title: "消防区域编码", dataIndex: "fireRegionCode" },
|
||||
{ title: "负责部门", dataIndex: "deptName" },
|
||||
{ title: "负责人", dataIndex: "managerName" },
|
||||
{ title: "已绑定传感器", dataIndex: "bindSensorCount" },
|
||||
{
|
||||
title: "状态",
|
||||
dataIndex: "status",
|
||||
render: value => getLabelName({ status: value, list: ENABLE_STATUS_OPTIONS }) || value || "-",
|
||||
},
|
||||
{ title: "备注", dataIndex: "remarks", ellipsis: true },
|
||||
{
|
||||
title: "操作",
|
||||
width: 280,
|
||||
render: (_, record) => (
|
||||
<Space>
|
||||
{props.permission(editPermission) && (
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => {
|
||||
setCurrentId(record.id);
|
||||
setConfigOpen(true);
|
||||
}}
|
||||
>
|
||||
编辑配置
|
||||
</Button>
|
||||
)}
|
||||
{props.permission(editPermission) && (
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => {
|
||||
setCurrentId(record.id);
|
||||
setManagerOpen(true);
|
||||
}}
|
||||
>
|
||||
负责人
|
||||
</Button>
|
||||
)}
|
||||
{props.permission(editPermission) && (
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => {
|
||||
setCurrentId(record.id);
|
||||
setBindOpen(true);
|
||||
}}
|
||||
>
|
||||
绑定传感器
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
{...tableProps}
|
||||
/>
|
||||
<Modal
|
||||
destroyOnClose
|
||||
open={configOpen}
|
||||
title={currentId ? "编辑设备区域配置" : "新增设备区域配置"}
|
||||
onCancel={() => {
|
||||
setConfigOpen(false);
|
||||
setCurrentId("");
|
||||
configForm.resetFields();
|
||||
}}
|
||||
onOk={configForm.submit}
|
||||
confirmLoading={props.deviceRegionLoading}
|
||||
width={680}
|
||||
>
|
||||
<Form form={configForm} layout="vertical" onFinish={handleConfigSubmit} initialValues={{ status: 1 }}>
|
||||
<Form.Item
|
||||
label="消防区域"
|
||||
name="fireRegionId"
|
||||
rules={[{ required: true, message: "请选择消防区域" }]}
|
||||
>
|
||||
<Select
|
||||
allowClear
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
disabled={!!currentId}
|
||||
placeholder="请选择消防区域"
|
||||
options={fireRegionOptions.map(item => ({
|
||||
value: item.id,
|
||||
label: `${item.fireRegionName}${item.fireRegionCode ? `(${item.fireRegionCode})` : ""}`,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="状态" name="status">
|
||||
<Select
|
||||
allowClear
|
||||
placeholder="请选择状态"
|
||||
options={ENABLE_STATUS_OPTIONS.map(item => ({
|
||||
value: item.bianma,
|
||||
label: item.name,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="备注" name="remarks">
|
||||
<Input.TextArea rows={4} maxLength={255} placeholder="请输入备注" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
{managerOpen && (
|
||||
<ManagerModal
|
||||
open={managerOpen}
|
||||
currentId={currentId}
|
||||
loading={props.deviceRegionLoading}
|
||||
getData={getData}
|
||||
deviceRegionInfo={props.deviceRegionInfo}
|
||||
deviceRegionManager={props.deviceRegionManager}
|
||||
onCancel={() => {
|
||||
setManagerOpen(false);
|
||||
setCurrentId("");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{bindOpen && (
|
||||
<BindSensorModal
|
||||
open={bindOpen}
|
||||
currentId={currentId}
|
||||
loading={props.deviceRegionLoading || props.sensorDeviceLoading}
|
||||
getData={getData}
|
||||
deviceRegionInfo={props.deviceRegionInfo}
|
||||
deviceRegionBindSensor={props.deviceRegionBindSensor}
|
||||
deviceRegionUnbindSensor={props.deviceRegionUnbindSensor}
|
||||
sensorDeviceList={props.sensorDeviceList}
|
||||
onCancel={() => {
|
||||
setBindOpen(false);
|
||||
setCurrentId("");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default Connect([NS_DEVICEREGION, NS_SENSORDEVICE], true)(Permission(DeviceRegionList));
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import { Form, Modal } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import PersonnelSelect from "zy-react-library/components/Select/Personnel/Gwj";
|
||||
import DepartmentSelectTree from "zy-react-library/components/SelectTree/Department/Gwj";
|
||||
|
||||
function ManagerModal(props) {
|
||||
const [form] = Form.useForm();
|
||||
const [departmentId, setDepartmentId] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.open || !props.currentId) {
|
||||
return;
|
||||
}
|
||||
props.deviceRegionInfo({ id: props.currentId }).then((res) => {
|
||||
if (!res?.success) {
|
||||
return;
|
||||
}
|
||||
const data = res.data || {};
|
||||
setDepartmentId(data.deptId);
|
||||
form.setFieldsValue({
|
||||
deptId: data.deptId,
|
||||
managerId: data.managerId,
|
||||
});
|
||||
});
|
||||
}, [form, props.currentId, props.deviceRegionInfo, props.open]);
|
||||
|
||||
const handleCancel = () => {
|
||||
form.resetFields();
|
||||
setDepartmentId(undefined);
|
||||
props.onCancel();
|
||||
};
|
||||
|
||||
const handleSubmit = async (values) => {
|
||||
await props.deviceRegionManager({ ...values, id: props.currentId });
|
||||
handleCancel();
|
||||
props.getData();
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
open={props.open}
|
||||
title="负责人配置"
|
||||
onCancel={handleCancel}
|
||||
onOk={form.submit}
|
||||
confirmLoading={props.loading}
|
||||
width={640}
|
||||
>
|
||||
<Form form={form} layout="vertical" onFinish={handleSubmit}>
|
||||
<Form.Item label="负责部门" name="deptId">
|
||||
<DepartmentSelectTree
|
||||
onChange={(value) => {
|
||||
setDepartmentId(value);
|
||||
form.setFieldValue("managerId", undefined);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="负责人" name="managerId">
|
||||
<PersonnelSelect params={{ departmentId }} />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default ManagerModal;
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export { default as List } from "./List";
|
||||
export { default as ManagerModal } from "./ManagerModal";
|
||||
export { default as BindSensorModal } from "./BindSensorModal";
|
||||
|
||||
// 默认导出 List 作为主入口组件
|
||||
export { default } from "./List";
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Form, message, Modal, Space, Switch } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import AddIcon from "zy-react-library/components/Icon/AddIcon";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
import Search from "zy-react-library/components/Search";
|
||||
import Table from "zy-react-library/components/Table";
|
||||
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
|
||||
import useTable from "zy-react-library/hooks/useTable";
|
||||
import { getLabelName } from "zy-react-library/utils";
|
||||
import SensorDeviceModal from "~/components/SensorDevice/Modal";
|
||||
import RealtimeModal from "~/components/SensorDevice/RealtimeModal";
|
||||
import ThresholdModal from "~/components/SensorDevice/ThresholdModal";
|
||||
import { ENABLE_STATUS_OPTIONS, SENSOR_STATUS_OPTIONS, YES_NO_OPTIONS } from "~/enumerate/constant";
|
||||
import { NS_SENSORDEVICE, NS_SENSORTYPE } from "~/enumerate/namespace";
|
||||
|
||||
function SensorDeviceList(props) {
|
||||
const [form] = Form.useForm();
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [thresholdOpen, setThresholdOpen] = useState(false);
|
||||
const [realtimeOpen, setRealtimeOpen] = useState(false);
|
||||
const [currentId, setCurrentId] = useState("");
|
||||
const [currentRecord, setCurrentRecord] = useState({});
|
||||
const [sensorTypeOptions, setSensorTypeOptions] = useState([]);
|
||||
const { tableProps, getData } = useTable(props["sensorDeviceList"], { form });
|
||||
|
||||
const editPermission = `${props.type}-iotalarm-sensor-device-edit`;
|
||||
|
||||
const loadSensorTypeOptions = async () => {
|
||||
const res = await props["sensorTypeList"]({
|
||||
pageIndex: 1,
|
||||
pageSize: 500,
|
||||
status: 1,
|
||||
});
|
||||
if (res?.success) {
|
||||
setSensorTypeOptions(res.data || []);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadSensorTypeOptions();
|
||||
}, [props.sensorTypeList]);
|
||||
|
||||
const sensorTypeSelectOptions = sensorTypeOptions.map(item => ({
|
||||
bianma: item.id,
|
||||
name: item.typeName,
|
||||
}));
|
||||
|
||||
const handleDelete = (record) => {
|
||||
Modal.confirm({
|
||||
title: "确定删除这条传感器设备吗?",
|
||||
onOk: async () => {
|
||||
await props["sensorDeviceRemove"]({ id: record.id });
|
||||
message.success("删除成功");
|
||||
getData();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleAlarmSwitch = async (record, checked) => {
|
||||
await props["sensorDeviceStatus"]({ id: record.id, alarmSwitch: checked ? 1 : 0 });
|
||||
message.success("报警开关更新成功");
|
||||
getData();
|
||||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Search
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
options={[
|
||||
{ name: "sensorCode", label: "传感器编码" },
|
||||
{ name: "sensorName", label: "传感器名称" },
|
||||
{
|
||||
name: "sensorTypeId",
|
||||
label: "传感器类型",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: sensorTypeSelectOptions,
|
||||
},
|
||||
{
|
||||
name: "alarmSwitch",
|
||||
label: "报警开关",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: ENABLE_STATUS_OPTIONS,
|
||||
},
|
||||
{
|
||||
name: "thresholdFlag",
|
||||
label: "阈值配置",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: YES_NO_OPTIONS,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Table
|
||||
rowKey="id"
|
||||
toolBarRender={() => (
|
||||
<Space>
|
||||
{props.permission(editPermission) && (
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<AddIcon />}
|
||||
onClick={() => {
|
||||
setCurrentId("");
|
||||
setModalOpen(true);
|
||||
}}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
)}
|
||||
columns={[
|
||||
{ title: "传感器编码", dataIndex: "sensorCode" },
|
||||
{ title: "传感器名称", dataIndex: "sensorName" },
|
||||
{ title: "传感器类型", dataIndex: "sensorTypeName" },
|
||||
{
|
||||
title: "传感器状态",
|
||||
dataIndex: "sensorStatus",
|
||||
render: value => getLabelName({ status: value, list: SENSOR_STATUS_OPTIONS }) || value || "-",
|
||||
},
|
||||
{
|
||||
title: "报警开关",
|
||||
dataIndex: "alarmSwitch",
|
||||
render: (_, record) => (
|
||||
<Switch
|
||||
checked={record.alarmSwitch === 1}
|
||||
checkedChildren="开"
|
||||
unCheckedChildren="关"
|
||||
disabled={!props.permission(editPermission)}
|
||||
onChange={checked => handleAlarmSwitch(record, checked)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "阈值配置",
|
||||
dataIndex: "thresholdFlag",
|
||||
render: value => getLabelName({ status: value, list: YES_NO_OPTIONS }) || value || "-",
|
||||
},
|
||||
{ title: "安装位置", dataIndex: "installPosition", ellipsis: true },
|
||||
{ title: "单位", dataIndex: "unitName" },
|
||||
{
|
||||
title: "量程",
|
||||
render: (_, record) => `${record.rangeMin ?? "-"} ~ ${record.rangeMax ?? "-"}`,
|
||||
},
|
||||
{ title: "备注", dataIndex: "remarks", ellipsis: true },
|
||||
{
|
||||
title: "操作",
|
||||
width: 260,
|
||||
render: (_, record) => (
|
||||
<Space>
|
||||
{props.permission(editPermission) && record.sensorAttr === "NUMBER" && (
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => {
|
||||
setCurrentId(record.id);
|
||||
setThresholdOpen(true);
|
||||
}}
|
||||
>
|
||||
阈值配置
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => {
|
||||
setCurrentRecord(record);
|
||||
setRealtimeOpen(true);
|
||||
}}
|
||||
>
|
||||
实时概览
|
||||
</Button>
|
||||
{props.permission(editPermission) && (
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => {
|
||||
setCurrentId(record.id);
|
||||
setModalOpen(true);
|
||||
}}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
)}
|
||||
{props.permission(editPermission) && (
|
||||
<Button danger type="link" onClick={() => handleDelete(record)}>
|
||||
删除
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
{...tableProps}
|
||||
/>
|
||||
{modalOpen && (
|
||||
<SensorDeviceModal
|
||||
open={modalOpen}
|
||||
currentId={currentId}
|
||||
loading={props.sensorDeviceLoading}
|
||||
getData={getData}
|
||||
sensorTypeOptions={sensorTypeOptions}
|
||||
sensorDeviceInfo={props.sensorDeviceInfo}
|
||||
sensorDeviceSave={props.sensorDeviceSave}
|
||||
sensorDeviceEdit={props.sensorDeviceEdit}
|
||||
onCancel={() => {
|
||||
setModalOpen(false);
|
||||
setCurrentId("");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{thresholdOpen && (
|
||||
<ThresholdModal
|
||||
open={thresholdOpen}
|
||||
currentId={currentId}
|
||||
loading={props.sensorDeviceLoading}
|
||||
getData={getData}
|
||||
sensorDeviceInfo={props.sensorDeviceInfo}
|
||||
sensorDeviceThreshold={props.sensorDeviceThreshold}
|
||||
onCancel={() => {
|
||||
setThresholdOpen(false);
|
||||
setCurrentId("");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{realtimeOpen && (
|
||||
<RealtimeModal
|
||||
open={realtimeOpen}
|
||||
record={currentRecord}
|
||||
onCancel={() => {
|
||||
setRealtimeOpen(false);
|
||||
setCurrentRecord({});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default Connect([NS_SENSORDEVICE, NS_SENSORTYPE], true)(Permission(SensorDeviceList));
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
import { DatePicker, Form, Input, InputNumber, Modal, Radio, Select } from "antd";
|
||||
import dayjs from "dayjs";
|
||||
import { useEffect } from "react";
|
||||
import { ENABLE_STATUS_OPTIONS, SENSOR_STATUS_OPTIONS, YES_NO_OPTIONS } from "~/enumerate/constant";
|
||||
|
||||
function SensorDeviceModal(props) {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.open) {
|
||||
return;
|
||||
}
|
||||
if (!props.currentId) {
|
||||
form.resetFields();
|
||||
form.setFieldsValue({
|
||||
sensorStatus: "NORMAL",
|
||||
positioningFlag: 0,
|
||||
alarmSwitch: 1,
|
||||
});
|
||||
return;
|
||||
}
|
||||
props.sensorDeviceInfo({ id: props.currentId }).then((res) => {
|
||||
if (!res?.success) {
|
||||
return;
|
||||
}
|
||||
const data = { ...(res.data || {}) };
|
||||
if (data.factoryDate) {
|
||||
data.factoryDate = dayjs(data.factoryDate);
|
||||
}
|
||||
form.setFieldsValue(data);
|
||||
});
|
||||
}, [form, props.currentId, props.open, props.sensorDeviceInfo]);
|
||||
|
||||
const handleCancel = () => {
|
||||
form.resetFields();
|
||||
props.onCancel();
|
||||
};
|
||||
|
||||
const handleSubmit = async (values) => {
|
||||
const payload = {
|
||||
...values,
|
||||
factoryDate: values.factoryDate ? values.factoryDate.format("YYYY-MM-DD") : undefined,
|
||||
};
|
||||
if (props.currentId) {
|
||||
await props.sensorDeviceEdit({ ...payload, id: props.currentId });
|
||||
}
|
||||
else {
|
||||
await props.sensorDeviceSave(payload);
|
||||
}
|
||||
handleCancel();
|
||||
props.getData();
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
open={props.open}
|
||||
title={props.currentId ? "编辑传感器设备" : "新增传感器设备"}
|
||||
onCancel={handleCancel}
|
||||
onOk={form.submit}
|
||||
confirmLoading={props.loading}
|
||||
width={720}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
onFinish={handleSubmit}
|
||||
initialValues={{
|
||||
sensorStatus: "NORMAL",
|
||||
positioningFlag: 0,
|
||||
alarmSwitch: 1,
|
||||
}}
|
||||
>
|
||||
<Form.Item
|
||||
label="传感器编码"
|
||||
name="sensorCode"
|
||||
rules={[{ required: true, message: "请输入传感器编码" }]}
|
||||
>
|
||||
<Input maxLength={100} placeholder="请输入传感器编码" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="传感器名称"
|
||||
name="sensorName"
|
||||
rules={[{ required: true, message: "请输入传感器名称" }]}
|
||||
>
|
||||
<Input maxLength={200} placeholder="请输入传感器名称" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="传感器类型"
|
||||
name="sensorTypeId"
|
||||
rules={[{ required: true, message: "请选择传感器类型" }]}
|
||||
>
|
||||
<Select
|
||||
allowClear
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
placeholder="请选择传感器类型"
|
||||
options={props.sensorTypeOptions.map(item => ({
|
||||
value: item.id,
|
||||
label: `${item.typeName}${item.typeCode ? `(${item.typeCode})` : ""}`,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="安装位置" name="installPosition">
|
||||
<Input maxLength={255} placeholder="请输入安装位置" />
|
||||
</Form.Item>
|
||||
<Form.Item label="传感器状态" name="sensorStatus">
|
||||
<Radio.Group>
|
||||
{SENSOR_STATUS_OPTIONS.map(item => (
|
||||
<Radio key={item.bianma} value={item.bianma}>
|
||||
{item.name}
|
||||
</Radio>
|
||||
))}
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label="是否定位" name="positioningFlag">
|
||||
<Radio.Group>
|
||||
{YES_NO_OPTIONS.map(item => (
|
||||
<Radio key={item.bianma} value={item.bianma}>
|
||||
{item.name}
|
||||
</Radio>
|
||||
))}
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label="报警开关" name="alarmSwitch">
|
||||
<Radio.Group>
|
||||
{ENABLE_STATUS_OPTIONS.map(item => (
|
||||
<Radio key={item.bianma} value={item.bianma}>
|
||||
{item.name}
|
||||
</Radio>
|
||||
))}
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label="单位" name="unitName">
|
||||
<Input maxLength={50} placeholder="请输入单位" />
|
||||
</Form.Item>
|
||||
<Form.Item label="量程下限" name="rangeMin">
|
||||
<InputNumber style={{ width: "100%" }} placeholder="请输入量程下限" />
|
||||
</Form.Item>
|
||||
<Form.Item label="量程上限" name="rangeMax">
|
||||
<InputNumber style={{ width: "100%" }} placeholder="请输入量程上限" />
|
||||
</Form.Item>
|
||||
<Form.Item label="出厂日期" name="factoryDate">
|
||||
<DatePicker style={{ width: "100%" }} placeholder="请选择出厂日期" />
|
||||
</Form.Item>
|
||||
<Form.Item label="企业侧源编码" name="enterpriseSourceCode">
|
||||
<Input maxLength={100} placeholder="请输入企业侧源编码" />
|
||||
</Form.Item>
|
||||
<Form.Item label="备注" name="remarks">
|
||||
<Input.TextArea rows={4} maxLength={255} placeholder="请输入备注" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default SensorDeviceModal;
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import { Descriptions, Modal } from "antd";
|
||||
import { getLabelName } from "zy-react-library/utils";
|
||||
import { ENABLE_STATUS_OPTIONS, SENSOR_STATUS_OPTIONS, YES_NO_OPTIONS } from "~/enumerate/constant";
|
||||
|
||||
function RealtimeModal(props) {
|
||||
const record = props.record || {};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={props.open}
|
||||
title="实时概览"
|
||||
onCancel={props.onCancel}
|
||||
footer={null}
|
||||
width={720}
|
||||
>
|
||||
<Descriptions
|
||||
bordered
|
||||
column={2}
|
||||
items={[
|
||||
{ label: "传感器编码", children: record.sensorCode || "-" },
|
||||
{ label: "传感器名称", children: record.sensorName || "-" },
|
||||
{ label: "传感器类型", children: record.sensorTypeName || "-" },
|
||||
{
|
||||
label: "传感器状态",
|
||||
children: getLabelName({ status: record.sensorStatus, list: SENSOR_STATUS_OPTIONS }) || record.sensorStatus || "-",
|
||||
},
|
||||
{
|
||||
label: "报警开关",
|
||||
children: getLabelName({ status: record.alarmSwitch, list: ENABLE_STATUS_OPTIONS }) || record.alarmSwitch || "-",
|
||||
},
|
||||
{
|
||||
label: "是否定位",
|
||||
children: getLabelName({ status: record.positioningFlag, list: YES_NO_OPTIONS }) || record.positioningFlag || "-",
|
||||
},
|
||||
{ label: "当前量程", children: `${record.rangeMin ?? "-"} ~ ${record.rangeMax ?? "-"}` },
|
||||
{ label: "单位", children: record.unitName || "-" },
|
||||
{ label: "安装位置", children: record.installPosition || "-" },
|
||||
{ label: "低低报", children: record.thresholdLowLow ?? "-" },
|
||||
{ label: "低报", children: record.thresholdLow ?? "-" },
|
||||
{ label: "高报", children: record.thresholdHigh ?? "-" },
|
||||
{ label: "高高报", children: record.thresholdHighHigh ?? "-" },
|
||||
{ label: "企业侧源编码", children: record.enterpriseSourceCode || "-" },
|
||||
{ label: "备注", children: record.remarks || "-" },
|
||||
]}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default RealtimeModal;
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
import { Alert, Form, InputNumber, Modal } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
function ThresholdModal(props) {
|
||||
const [form] = Form.useForm();
|
||||
const [sensorAttr, setSensorAttr] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.open || !props.currentId) {
|
||||
return;
|
||||
}
|
||||
props.sensorDeviceInfo({ id: props.currentId }).then((res) => {
|
||||
if (res?.success) {
|
||||
form.setFieldsValue(res.data || {});
|
||||
setSensorAttr(res.data?.sensorAttr || "");
|
||||
}
|
||||
});
|
||||
}, [form, props.currentId, props.open, props.sensorDeviceInfo]);
|
||||
|
||||
const handleCancel = () => {
|
||||
form.resetFields();
|
||||
setSensorAttr("");
|
||||
props.onCancel();
|
||||
};
|
||||
|
||||
const handleSubmit = async (values) => {
|
||||
await props.sensorDeviceThreshold({ ...values, id: props.currentId });
|
||||
handleCancel();
|
||||
props.getData();
|
||||
};
|
||||
|
||||
const isNumberType = sensorAttr === "NUMBER";
|
||||
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
open={props.open}
|
||||
title="阈值配置"
|
||||
onCancel={handleCancel}
|
||||
onOk={isNumberType ? form.submit : undefined}
|
||||
confirmLoading={props.loading}
|
||||
width={560}
|
||||
footer={isNumberType ? undefined : null}
|
||||
>
|
||||
{!isNumberType && sensorAttr && (
|
||||
<Alert
|
||||
type="warning"
|
||||
message="仅数值型传感器支持阈值配置"
|
||||
description="当前传感器属性为开关量,无需配置四级阈值。"
|
||||
showIcon
|
||||
style={{ marginBottom: 16 }}
|
||||
/>
|
||||
)}
|
||||
{isNumberType && (
|
||||
<Form form={form} layout="vertical" onFinish={handleSubmit}>
|
||||
<Form.Item label="低低报阈值" name="thresholdLowLow">
|
||||
<InputNumber style={{ width: "100%" }} placeholder="请输入低低报阈值" />
|
||||
</Form.Item>
|
||||
<Form.Item label="低报阈值" name="thresholdLow">
|
||||
<InputNumber style={{ width: "100%" }} placeholder="请输入低报阈值" />
|
||||
</Form.Item>
|
||||
<Form.Item label="高报阈值" name="thresholdHigh">
|
||||
<InputNumber style={{ width: "100%" }} placeholder="请输入高报阈值" />
|
||||
</Form.Item>
|
||||
<Form.Item label="高高报阈值" name="thresholdHighHigh">
|
||||
<InputNumber style={{ width: "100%" }} placeholder="请输入高高报阈值" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default ThresholdModal;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// 导出子组件
|
||||
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 作为主入口
|
||||
export { default } from "./List";
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Form, message, Modal, Space } from "antd";
|
||||
import { useState } from "react";
|
||||
import AddIcon from "zy-react-library/components/Icon/AddIcon";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
import Search from "zy-react-library/components/Search";
|
||||
import Table from "zy-react-library/components/Table";
|
||||
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
|
||||
import useTable from "zy-react-library/hooks/useTable";
|
||||
import { getLabelName } from "zy-react-library/utils";
|
||||
import SensorTypeModal from "~/components/SensorType/Modal";
|
||||
import { ENABLE_STATUS_OPTIONS, SENSOR_ATTR_OPTIONS } from "~/enumerate/constant";
|
||||
import { NS_SENSORTYPE } from "~/enumerate/namespace";
|
||||
|
||||
function SensorTypeList(props) {
|
||||
const [form] = Form.useForm();
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [currentId, setCurrentId] = useState("");
|
||||
const { tableProps, getData } = useTable(props["sensorTypeList"], { form });
|
||||
|
||||
const editPermission = `${props.type}-iotalarm-sensor-type-edit`;
|
||||
|
||||
const handleDelete = (record) => {
|
||||
Modal.confirm({
|
||||
title: "确定删除这条传感器类型吗?",
|
||||
onOk: async () => {
|
||||
await props["sensorTypeRemove"]({ id: record.id });
|
||||
message.success("删除成功");
|
||||
getData();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Search
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
options={[
|
||||
{ name: "typeCode", label: "类型编码" },
|
||||
{ name: "typeName", label: "类型名称" },
|
||||
{
|
||||
name: "sensorAttr",
|
||||
label: "传感器属性",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: SENSOR_ATTR_OPTIONS,
|
||||
},
|
||||
{
|
||||
name: "status",
|
||||
label: "状态",
|
||||
render: FORM_ITEM_RENDER_ENUM.SELECT,
|
||||
items: ENABLE_STATUS_OPTIONS,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Table
|
||||
rowKey="id"
|
||||
toolBarRender={() => (
|
||||
<Space>
|
||||
{props.permission(editPermission) && (
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<AddIcon />}
|
||||
onClick={() => {
|
||||
setCurrentId("");
|
||||
setModalOpen(true);
|
||||
}}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
)}
|
||||
columns={[
|
||||
{ title: "类型编码", dataIndex: "typeCode" },
|
||||
{ title: "类型名称", dataIndex: "typeName" },
|
||||
{
|
||||
title: "传感器属性",
|
||||
dataIndex: "sensorAttr",
|
||||
render: value => getLabelName({ status: value, list: SENSOR_ATTR_OPTIONS }) || value || "-",
|
||||
},
|
||||
{ title: "排序", dataIndex: "sortNo" },
|
||||
{
|
||||
title: "状态",
|
||||
dataIndex: "status",
|
||||
render: value => getLabelName({ status: value, list: ENABLE_STATUS_OPTIONS }) || value || "-",
|
||||
},
|
||||
{ title: "备注", dataIndex: "remarks", ellipsis: true },
|
||||
{
|
||||
title: "操作",
|
||||
width: 180,
|
||||
render: (_, record) => (
|
||||
<Space>
|
||||
{props.permission(editPermission) && (
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => {
|
||||
setCurrentId(record.id);
|
||||
setModalOpen(true);
|
||||
}}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
)}
|
||||
{props.permission(editPermission) && (
|
||||
<Button danger type="link" onClick={() => handleDelete(record)}>
|
||||
删除
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
{...tableProps}
|
||||
/>
|
||||
{modalOpen && (
|
||||
<SensorTypeModal
|
||||
open={modalOpen}
|
||||
currentId={currentId}
|
||||
loading={props.sensorTypeLoading}
|
||||
getData={getData}
|
||||
sensorTypeInfo={props.sensorTypeInfo}
|
||||
sensorTypeSave={props.sensorTypeSave}
|
||||
sensorTypeEdit={props.sensorTypeEdit}
|
||||
onCancel={() => {
|
||||
setModalOpen(false);
|
||||
setCurrentId("");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default Connect([NS_SENSORTYPE], true)(Permission(SensorTypeList));
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
import { Form, Input, InputNumber, Modal, Radio } from "antd";
|
||||
import { useEffect } from "react";
|
||||
import { ENABLE_STATUS_OPTIONS, SENSOR_ATTR_OPTIONS } from "~/enumerate/constant";
|
||||
|
||||
function SensorTypeModal(props) {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.open) {
|
||||
return;
|
||||
}
|
||||
if (!props.currentId) {
|
||||
form.resetFields();
|
||||
form.setFieldsValue({
|
||||
sensorAttr: "NUMBER",
|
||||
status: 1,
|
||||
sortNo: 0,
|
||||
});
|
||||
return;
|
||||
}
|
||||
props.sensorTypeInfo({ id: props.currentId }).then((res) => {
|
||||
if (res?.success) {
|
||||
form.setFieldsValue(res.data || {});
|
||||
}
|
||||
});
|
||||
}, [form, props.currentId, props.open, props.sensorTypeInfo]);
|
||||
|
||||
const handleCancel = () => {
|
||||
form.resetFields();
|
||||
props.onCancel();
|
||||
};
|
||||
|
||||
const handleSubmit = async (values) => {
|
||||
if (props.currentId) {
|
||||
await props.sensorTypeEdit({ ...values, id: props.currentId });
|
||||
}
|
||||
else {
|
||||
await props.sensorTypeSave(values);
|
||||
}
|
||||
handleCancel();
|
||||
props.getData();
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
open={props.open}
|
||||
title={props.currentId ? "编辑传感器类型" : "新增传感器类型"}
|
||||
onCancel={handleCancel}
|
||||
onOk={form.submit}
|
||||
confirmLoading={props.loading}
|
||||
width={640}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
onFinish={handleSubmit}
|
||||
initialValues={{
|
||||
sensorAttr: "NUMBER",
|
||||
status: 1,
|
||||
sortNo: 0,
|
||||
}}
|
||||
>
|
||||
<Form.Item
|
||||
label="类型编码"
|
||||
name="typeCode"
|
||||
rules={[{ required: true, message: "请输入类型编码" }]}
|
||||
>
|
||||
<Input maxLength={64} placeholder="请输入类型编码" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="类型名称"
|
||||
name="typeName"
|
||||
rules={[{ required: true, message: "请输入类型名称" }]}
|
||||
>
|
||||
<Input maxLength={100} placeholder="请输入类型名称" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="传感器属性"
|
||||
name="sensorAttr"
|
||||
rules={[{ required: true, message: "请选择传感器属性" }]}
|
||||
>
|
||||
<Radio.Group>
|
||||
{SENSOR_ATTR_OPTIONS.map(item => (
|
||||
<Radio key={item.bianma} value={item.bianma}>
|
||||
{item.name}
|
||||
</Radio>
|
||||
))}
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label="排序" name="sortNo">
|
||||
<InputNumber min={0} precision={0} style={{ width: "100%" }} placeholder="请输入排序" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="状态"
|
||||
name="status"
|
||||
rules={[{ required: true, message: "请选择状态" }]}
|
||||
>
|
||||
<Radio.Group>
|
||||
{ENABLE_STATUS_OPTIONS.map(item => (
|
||||
<Radio key={item.bianma} value={item.bianma}>
|
||||
{item.name}
|
||||
</Radio>
|
||||
))}
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label="备注" name="remarks">
|
||||
<Input.TextArea rows={4} maxLength={255} placeholder="请输入备注" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default SensorTypeModal;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
export { default as List } from "./List";
|
||||
export { default as Modal } from "./Modal";
|
||||
|
||||
// 默认导出 List 作为主入口组件
|
||||
export { default } from "./List";
|
||||
|
|
@ -1 +1,6 @@
|
|||
export {};
|
||||
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 AlarmRecord } from "./AlarmRecord";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,46 @@
|
|||
/**
|
||||
* 全局常量定义
|
||||
*/
|
||||
export const APP_IDENTIFIER = "iotalarm";
|
||||
|
||||
export {};
|
||||
export const SENSOR_ATTR_OPTIONS = [
|
||||
{ bianma: "NUMBER", name: "数值型" },
|
||||
{ bianma: "SWITCH", name: "开关量" },
|
||||
];
|
||||
|
||||
export const ENABLE_STATUS_OPTIONS = [
|
||||
{ bianma: 1, name: "启用" },
|
||||
{ bianma: 0, name: "停用" },
|
||||
];
|
||||
|
||||
export const YES_NO_OPTIONS = [
|
||||
{ bianma: 1, name: "是" },
|
||||
{ bianma: 0, name: "否" },
|
||||
];
|
||||
|
||||
export const SENSOR_STATUS_OPTIONS = [
|
||||
{ bianma: "NORMAL", name: "正常" },
|
||||
{ bianma: "FAULT", name: "故障" },
|
||||
{ bianma: "OFFLINE", name: "离线" },
|
||||
];
|
||||
|
||||
export const ALARM_STATUS_OPTIONS = [
|
||||
{ bianma: 10, name: "报警中-待研判" },
|
||||
{ bianma: 20, name: "报警中-待处置" },
|
||||
{ bianma: 30, name: "已消警" },
|
||||
{ bianma: 40, name: "误报" },
|
||||
];
|
||||
|
||||
export const ALARM_SOURCE_OPTIONS = [
|
||||
{ bianma: "DCS", name: "DCS" },
|
||||
{ bianma: "THRESHOLD", name: "阈值报警" },
|
||||
];
|
||||
|
||||
export const ALARM_LEVEL_OPTIONS = [
|
||||
{ bianma: "HIGH", name: "高" },
|
||||
{ bianma: "MEDIUM", name: "中" },
|
||||
{ bianma: "LOW", name: "低" },
|
||||
];
|
||||
|
||||
export const ALARM_TYPE_OPTIONS = [
|
||||
{ bianma: "FAULT", name: "故障报警" },
|
||||
{ bianma: "THRESHOLD", name: "阈值报警" },
|
||||
{ bianma: "MANUAL", name: "人工报警" },
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
/**
|
||||
* 全局上下文定义
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
// 获取antd全局静态方法
|
||||
export const InjectContext = React.createContext({});
|
||||
export const InjectContext = React.createContext(null);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./context";
|
||||
export * from "./constant";
|
||||
export * from "./namespace";
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* 全局数据状态管理模块定义
|
||||
*/
|
||||
|
||||
import { defineNamespace } from "@cqsjjb/jjb-dva-runtime";
|
||||
|
||||
export const NS_GLOBAL = defineNamespace("global");
|
||||
export const NS_SENSORTYPE = "sensorType";
|
||||
export const NS_SENSORDEVICE = "sensorDevice";
|
||||
export const NS_DEVICEREGION = "deviceRegion";
|
||||
export const NS_DCSALARMINFO = "dcsAlarmInfo";
|
||||
export const NS_THRESHOLDALARMINFO = "thresholdAlarmInfo";
|
||||
export const NS_ALARMDISPOSE = "alarmDispose";
|
||||
export const NS_ALARMRECORD = "alarmRecord";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import AssignList from "~/components/AlarmDispose/AssignList";
|
||||
|
||||
function AlarmAssignPage(props) {
|
||||
return <AssignList {...props} type="fgs" />;
|
||||
}
|
||||
|
||||
export default Permission(AlarmAssignPage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import AlarmRecordList from "~/components/AlarmRecord/List";
|
||||
|
||||
function AlarmRecordPage(props) {
|
||||
return <AlarmRecordList {...props} type="fgs" />;
|
||||
}
|
||||
|
||||
export default Permission(AlarmRecordPage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import DcsList from "~/components/AlarmInfo/DcsList";
|
||||
|
||||
function DcsAlarmInfoPage(props) {
|
||||
return <DcsList {...props} type="fgs" />;
|
||||
}
|
||||
|
||||
export default Permission(DcsAlarmInfoPage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import DeviceRegionList from "~/components/DeviceRegion/List";
|
||||
|
||||
function DeviceRegionPage(props) {
|
||||
return <DeviceRegionList {...props} type="fgs" />;
|
||||
}
|
||||
|
||||
export default Permission(DeviceRegionPage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import SensorDeviceList from "~/components/SensorDevice/List";
|
||||
|
||||
function SensorDevicePage(props) {
|
||||
return <SensorDeviceList {...props} type="fgs" />;
|
||||
}
|
||||
|
||||
export default Permission(SensorDevicePage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import SensorTypeList from "~/components/SensorType/List";
|
||||
|
||||
function SensorTypePage(props) {
|
||||
return <SensorTypeList {...props} type="fgs" />;
|
||||
}
|
||||
|
||||
export default Permission(SensorTypePage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import ThresholdList from "~/components/AlarmInfo/ThresholdList";
|
||||
|
||||
function ThresholdAlarmInfoPage(props) {
|
||||
return <ThresholdList {...props} type="fgs" />;
|
||||
}
|
||||
|
||||
export default Permission(ThresholdAlarmInfoPage);
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export default function BranchCompany(props) {
|
||||
if (props.children) {
|
||||
return props.children;
|
||||
}
|
||||
|
||||
return <div style={{ padding: 24, border: "1px dashed #d9d9d9" }}>分公司端壳页面</div>;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import AssignList from "~/components/AlarmDispose/AssignList";
|
||||
|
||||
function AlarmAssignPage(props) {
|
||||
return <AssignList {...props} type="gfd" />;
|
||||
}
|
||||
|
||||
export default Permission(AlarmAssignPage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import AlarmRecordList from "~/components/AlarmRecord/List";
|
||||
|
||||
function AlarmRecordPage(props) {
|
||||
return <AlarmRecordList {...props} type="gfd" />;
|
||||
}
|
||||
|
||||
export default Permission(AlarmRecordPage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import DcsList from "~/components/AlarmInfo/DcsList";
|
||||
|
||||
function DcsAlarmInfoPage(props) {
|
||||
return <DcsList {...props} type="gfd" />;
|
||||
}
|
||||
|
||||
export default Permission(DcsAlarmInfoPage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import DeviceRegionList from "~/components/DeviceRegion/List";
|
||||
|
||||
function DeviceRegionPage(props) {
|
||||
return <DeviceRegionList {...props} type="gfd" />;
|
||||
}
|
||||
|
||||
export default Permission(DeviceRegionPage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import SensorDeviceList from "~/components/SensorDevice/List";
|
||||
|
||||
function SensorDevicePage(props) {
|
||||
return <SensorDeviceList {...props} type="gfd" />;
|
||||
}
|
||||
|
||||
export default Permission(SensorDevicePage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import SensorTypeList from "~/components/SensorType/List";
|
||||
|
||||
function SensorTypePage(props) {
|
||||
return <SensorTypeList {...props} type="gfd" />;
|
||||
}
|
||||
|
||||
export default Permission(SensorTypePage);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import ThresholdList from "~/components/AlarmInfo/ThresholdList";
|
||||
|
||||
function ThresholdAlarmInfoPage(props) {
|
||||
return <ThresholdList {...props} type="gfd" />;
|
||||
}
|
||||
|
||||
export default Permission(ThresholdAlarmInfoPage);
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export default function Supervision(props) {
|
||||
if (props.children) {
|
||||
return props.children;
|
||||
}
|
||||
|
||||
return <div style={{ padding: 24, border: "1px dashed #d9d9d9" }}>股份端壳页面</div>;
|
||||
}
|
||||
|
|
@ -7,25 +7,22 @@ import { InjectContext } from "~/enumerate/context";
|
|||
|
||||
export default class Container extends React.Component {
|
||||
state = window?.base?.themeConfig || {
|
||||
algorithm: window.process.env.app.antd.algorithm,
|
||||
borderRadius: window.process.env.app.antd.borderRadius,
|
||||
colorPrimary: window.process.env.app.antd.colorPrimary,
|
||||
algorithm: "defaultAlgorithm",
|
||||
borderRadius: 6,
|
||||
colorPrimary: "#0b6cff",
|
||||
};
|
||||
|
||||
get token() {
|
||||
const {
|
||||
colorPrimary,
|
||||
borderRadius,
|
||||
} = this.state;
|
||||
const { colorPrimary, borderRadius } = this.state;
|
||||
return {
|
||||
fontFamily: window.process.env.app.antd.fontFamily,
|
||||
colorPrimary,
|
||||
borderRadius,
|
||||
fontFamily: "Microsoft YaHei, PingFang SC, sans-serif",
|
||||
};
|
||||
}
|
||||
|
||||
get algorithm() {
|
||||
return antdTheme[this.state.algorithm];
|
||||
return antdTheme[this.state.algorithm] || antdTheme.defaultAlgorithm;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
|
@ -46,7 +43,6 @@ export default class Container extends React.Component {
|
|||
algorithm: this.algorithm,
|
||||
}}
|
||||
locale={language}
|
||||
prefixCls={window.process.env.app.antd["ant-prefix"]}
|
||||
>
|
||||
<App style={{ height: "100%" }}>
|
||||
<AppMiddle {...this.props} />
|
||||
|
|
|
|||
|
|
@ -1,8 +1,23 @@
|
|||
export default function () {
|
||||
return (
|
||||
<h1>
|
||||
底座微应用模板,技术文档:
|
||||
<a rel="noreferrer noopener" target="_blank" href="https://www.yuque.com/buhangjiecheshen-ymbtb/qc0093/gxdun1dphetcurko">https://www.yuque.com/buhangjiecheshen-ymbtb/qc0093/gxdun1dphetcurko</a>
|
||||
</h1>
|
||||
);
|
||||
export { default as Container } from "./Container";
|
||||
export { default as BranchCompany } from "./Container/BranchCompany";
|
||||
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 SupervisionAlarmRecord } from "./Container/Supervision/AlarmRecord";
|
||||
|
||||
export default function HomePage() {
|
||||
return <div style={{ padding: 24 }}>物联网消防报警模块前端骨架已完成</div>;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue