From c4c145100bc6c0a1cf795ee42f2b6db1ae3e6ae6 Mon Sep 17 00:00:00 2001 From: zhoux Date: Fri, 8 Dec 2023 10:30:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9D=E5=A7=8B=E5=8C=96=E5=88=86?= =?UTF-8?q?=E5=B8=83=E5=BC=8F=E8=AE=BE=E5=A4=87=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/routes.ts | 16 + src/locales/zh-CN/DCSDevice.ts | 20 + src/locales/zh-CN/menu.ts | 6 +- .../DeviceList/components/ColumnDrawer.tsx | 41 + .../DeviceList/components/Columns.tsx | 62 ++ .../DeviceList/components/CreateForm.tsx | 233 ++++++ .../DeviceList/components/UpdateForm.tsx | 272 +++++++ .../DeviceList/components/VideoModal.tsx | 53 ++ src/pages/DCSDevice/DeviceList/index.tsx | 706 ++++++++++++++++++ .../DeviceStatus/components/ColumnDrawer.tsx | 41 + .../DeviceStatus/components/Columns.tsx | 62 ++ .../DeviceStatus/components/CreateForm.tsx | 233 ++++++ .../DeviceStatus/components/UpdateForm.tsx | 272 +++++++ .../DeviceStatus/components/VideoModal.tsx | 53 ++ src/pages/DCSDevice/DeviceStatus/index.tsx | 706 ++++++++++++++++++ 15 files changed, 2774 insertions(+), 2 deletions(-) create mode 100644 src/locales/zh-CN/DCSDevice.ts create mode 100644 src/pages/DCSDevice/DeviceList/components/ColumnDrawer.tsx create mode 100644 src/pages/DCSDevice/DeviceList/components/Columns.tsx create mode 100644 src/pages/DCSDevice/DeviceList/components/CreateForm.tsx create mode 100644 src/pages/DCSDevice/DeviceList/components/UpdateForm.tsx create mode 100644 src/pages/DCSDevice/DeviceList/components/VideoModal.tsx create mode 100644 src/pages/DCSDevice/DeviceList/index.tsx create mode 100644 src/pages/DCSDevice/DeviceStatus/components/ColumnDrawer.tsx create mode 100644 src/pages/DCSDevice/DeviceStatus/components/Columns.tsx create mode 100644 src/pages/DCSDevice/DeviceStatus/components/CreateForm.tsx create mode 100644 src/pages/DCSDevice/DeviceStatus/components/UpdateForm.tsx create mode 100644 src/pages/DCSDevice/DeviceStatus/components/VideoModal.tsx create mode 100644 src/pages/DCSDevice/DeviceStatus/index.tsx diff --git a/config/routes.ts b/config/routes.ts index 52fb10c..91bafa4 100644 --- a/config/routes.ts +++ b/config/routes.ts @@ -121,6 +121,22 @@ export default [ 'access': 'canReadMenu' }], + }, + { + name: 'DCSDevice', + path: '/DCSDevice', + routes: [{ + 'name': 'DCSDevice-device-list', + 'path': '/DCSDevice/device-list', + 'component': 'DCSDevice/DeviceList', + 'access': 'canReadMenu' + }, { + 'name': 'DCSDevice-device-status', + 'path': '/DCSDevice/device-status', + 'component': 'DCSDevice/DeviceStatus', + 'access': 'canReadMenu' + }], + }, { name: 'resource', diff --git a/src/locales/zh-CN/DCSDevice.ts b/src/locales/zh-CN/DCSDevice.ts new file mode 100644 index 0000000..bd9921a --- /dev/null +++ b/src/locales/zh-CN/DCSDevice.ts @@ -0,0 +1,20 @@ +/* + * @Author: zhoux zhouxia@supervision.ltd + * @Date: 2023-12-08 10:26:34 + * @LastEditors: zhoux zhouxia@supervision.ltd + * @LastEditTime: 2023-12-08 10:27:48 + * @FilePath: \general-ai-platform-web\src\locales\zh-CN\DCSDevice.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ + + +// 设备列表 +export const DCSDevice_list: { [key: string]: string } = { + 'DCSDeviceList.device.table.list.name': '设备名称' +} + + +export const DCSDevice_status: { [key: string]: string } = { + + +} \ No newline at end of file diff --git a/src/locales/zh-CN/menu.ts b/src/locales/zh-CN/menu.ts index 3be078d..8c231ec 100644 --- a/src/locales/zh-CN/menu.ts +++ b/src/locales/zh-CN/menu.ts @@ -2,7 +2,7 @@ * @Author: zhoux zhouxia@supervision.ltd * @Date: 2023-11-01 13:56:33 * @LastEditors: zhoux zhouxia@supervision.ltd - * @LastEditTime: 2023-11-10 14:44:54 + * @LastEditTime: 2023-12-08 10:30:11 * @FilePath: \general-ai-platform-web\src\locales\zh-CN\menu.ts * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ @@ -70,5 +70,7 @@ export default { 'menu.list.staff': '人力资源', 'menu.list.staff.employee-list': '员工列表', 'menu.device.device-relation-list': '设备版本列表', - 'menu.resource.algorithm-model-detail': '模型详情' + 'menu.resource.algorithm-model-detail': '模型详情', + 'menu.DCSDevice.DCSDevice-device-status': '设备状态', + 'menu.DCSDevice.DCSDevice-device-list': '设备列表' }; diff --git a/src/pages/DCSDevice/DeviceList/components/ColumnDrawer.tsx b/src/pages/DCSDevice/DeviceList/components/ColumnDrawer.tsx new file mode 100644 index 0000000..9561cd6 --- /dev/null +++ b/src/pages/DCSDevice/DeviceList/components/ColumnDrawer.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import {Drawer} from "antd"; +import {ProColumns, ProDescriptions, ProDescriptionsItemProps} from "@ant-design/pro-components"; + +export type ColumnDrawProps = { + handleDrawer: (id?: any)=>void; + isShowDetail: boolean; + columns: ProColumns[]; + currentRow: API.Device | undefined; +}; + + +const ColumnDrawer: React.FC = (props) => { + + return ( + { + props.handleDrawer(); + }} + closable={true} + > + {props.currentRow?.id && ( + + column={2} + title={props.currentRow?.id} + request={async () => ({ + data: props.currentRow || {}, + })} + params={{ + id: props.currentRow?.id, + }} + columns={props.columns as ProDescriptionsItemProps[]} + /> + )} + + ) +} +export {ColumnDrawer} + diff --git a/src/pages/DCSDevice/DeviceList/components/Columns.tsx b/src/pages/DCSDevice/DeviceList/components/Columns.tsx new file mode 100644 index 0000000..028dcf7 --- /dev/null +++ b/src/pages/DCSDevice/DeviceList/components/Columns.tsx @@ -0,0 +1,62 @@ +import { FormattedMessage} from '@umijs/max'; +export const DeviceColumns = [{ + title: (), + dataIndex: "id", + },{ + title: (), + dataIndex: "name", + },{ + title: (), + dataIndex: "code", + },{ + title: (), + dataIndex: "position", + },{ + title: (), + dataIndex: "param", + },{ + title: (), + dataIndex: "spec", + },{ + title: (), + dataIndex: "category_fk_id", + },{ + title: (), + dataIndex: "group_fk_id", + },{ + title: (), + dataIndex: "is_enable", + },{ + title: (), + dataIndex: "remark", + },{ + title: (), + dataIndex: "create_time", + },{ + title: (), + dataIndex: "update_time", + },] diff --git a/src/pages/DCSDevice/DeviceList/components/CreateForm.tsx b/src/pages/DCSDevice/DeviceList/components/CreateForm.tsx new file mode 100644 index 0000000..f4d8289 --- /dev/null +++ b/src/pages/DCSDevice/DeviceList/components/CreateForm.tsx @@ -0,0 +1,233 @@ +import { postDeviceCreateDevice } from '@/services/device/Device'; +import { postDeviceCategoryGetDeviceCategoryFkSelect } from '@/services/device/DeviceCategory'; +import { postDeviceGroupGetDeviceGroupFkSelect } from '@/services/device/DeviceGroup'; +import { + ModalForm, + ProForm, + ProFormSelect, + ProFormSwitch, + ProFormText, +} from '@ant-design/pro-components'; +import { FormattedMessage, useIntl } from '@umijs/max'; +import { Form, Switch, message } from 'antd'; +import React, { useState } from 'react'; +import { proFormItemStyleProps, proFormModelWidth } from '../../../../../config/defaultForm'; +export type FormValueType = { + target?: string; + template?: string; + type?: string; + time?: string; + frequency?: string; +} & Partial; + +export type CreateFormProps = { + createModalOpen: boolean; + handleModal: () => void; + values: Partial; + reload: any; +}; +const CreateForm: React.FC = (props) => { + const intl = useIntl(); + const [isAuto, setIsAuto] = useState(true); + const [form] = Form.useForm(); + + return ( + + width={proFormModelWidth} + title={intl.formatMessage({ + id: 'device.device.table.list.add', + defaultMessage: '$$$', + })} + open={props.createModalOpen} + form={form} + autoFocusFirstInput + modalProps={{ + destroyOnClose: true, + onCancel: () => props.handleModal(), + }} + submitTimeout={2000} + onFinish={async (values) => { + postDeviceCreateDevice(values) + .then(() => { + message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); + props.reload(); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + props.handleModal(); + return true; + }} + > + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.name', defaultMessage: '$$$' })}`} + required={true} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_select', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.groupFkId', + defaultMessage: '$$$', + })}`} + required={false} + showSearch + debounceTime={1000} + request={async (keyWord) => { + const resp = await postDeviceGroupGetDeviceGroupFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.code', defaultMessage: '$$$' })}`} + required={!isAuto} + initialValue="" + disabled={isAuto} + rules={ + isAuto + ? [] + : [ + { + required: true, + message: ( + + ), + }, + ] + } + addonAfter={ + } + unCheckedChildren={} + onChange={setIsAuto} + /> + } + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.position', + defaultMessage: '$$$', + })}`} + required={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.param', + defaultMessage: '$$$', + })}`} + required={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.spec', defaultMessage: '$$$' })}`} + required={false} + /> + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_select', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.categoryFkId', + defaultMessage: '$$$', + })}`} + required={false} + showSearch + debounceTime={1000} + request={async (keyWord) => { + const resp = await postDeviceCategoryGetDeviceCategoryFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.remark', + defaultMessage: '$$$', + })}`} + required={false} + /> + } + initialValue={true} + /> + + + ); +}; +export default CreateForm; diff --git a/src/pages/DCSDevice/DeviceList/components/UpdateForm.tsx b/src/pages/DCSDevice/DeviceList/components/UpdateForm.tsx new file mode 100644 index 0000000..c386ae9 --- /dev/null +++ b/src/pages/DCSDevice/DeviceList/components/UpdateForm.tsx @@ -0,0 +1,272 @@ +import { putDeviceUpdateDevice } from '@/services/device/Device'; +import { postDeviceCategoryGetDeviceCategoryFkSelect } from '@/services/device/DeviceCategory'; +import { postDeviceGroupGetDeviceGroupFkSelect } from '@/services/device/DeviceGroup'; +import { + ModalForm, + ProForm, + ProFormDateTimePicker, + ProFormSelect, + ProFormSwitch, + ProFormText, +} from '@ant-design/pro-components'; +import { FormattedMessage, useIntl } from '@umijs/max'; +import { Form, message } from 'antd'; +import React from 'react'; +import { proFormItemStyleProps, proFormModelWidth } from '../../../../../config/defaultForm'; +export type FormValueType = { + target?: string; + template?: string; + type?: string; + time?: string; + frequency?: string; +} & Partial; + +export type UpdateFormProps = { + updateModalOpen: boolean; + handleModal: () => void; + values: Partial; + reload: any; +}; +const UpdateForm: React.FC = (props) => { + const intl = useIntl(); + const [form] = Form.useForm(); + + return ( + + width={proFormModelWidth} + title={intl.formatMessage({ + id: 'device.device.table.list.update', + defaultMessage: '$$$', + })} + open={props.updateModalOpen} + form={form} + autoFocusFirstInput + modalProps={{ + destroyOnClose: true, + onCancel: () => props.handleModal(), + }} + submitTimeout={2000} + onFinish={async (values) => { + putDeviceUpdateDevice(values) + .then(() => { + message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); + props.reload(); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + + props.handleModal(); + return true; + }} + > + + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.name', defaultMessage: '$$$' })}`} + required={true} + initialValue={props.values.name} + disabled={false} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.code', defaultMessage: '$$$' })}`} + required={true} + initialValue={props.values.code} + disabled={false} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.position', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.position} + disabled={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.param', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.param} + disabled={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.spec', defaultMessage: '$$$' })}`} + required={false} + initialValue={props.values.spec} + disabled={false} + /> + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_select', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.categoryFkId', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.categoryFkId} + showSearch + debounceTime={1000} + request={async (keyWord) => { + const resp = await postDeviceCategoryGetDeviceCategoryFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_select', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.groupFkId', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.groupFkId} + showSearch + debounceTime={1000} + request={async (keyWord) => { + const resp = await postDeviceGroupGetDeviceGroupFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.remark', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.remark} + disabled={false} + /> + } + initialValue={props.values.isEnable} + disabled={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.createTime', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.createTime} + disabled={true} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.updateTime', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.updateTime} + disabled={true} + /> + + + ); +}; +export default UpdateForm; diff --git a/src/pages/DCSDevice/DeviceList/components/VideoModal.tsx b/src/pages/DCSDevice/DeviceList/components/VideoModal.tsx new file mode 100644 index 0000000..b1bcd83 --- /dev/null +++ b/src/pages/DCSDevice/DeviceList/components/VideoModal.tsx @@ -0,0 +1,53 @@ +import {useIntl} from '@umijs/max'; +import React, {useState, useRef, useCallback, useEffect} from 'react'; +import {Form, Modal} from 'antd'; + +import WebRTCStreamer from "@/components/WebRtcPlayer"; +export type FormValueType = { + target?: string; + template?: string; + type?: string; + time?: string; + frequency?: string; +} & Partial; + +export type VideoModalProps = { + modalOpen: boolean; + handleModal: () => void; + values: Partial; + reload: any; + videoServerParam: API.RtspRes; +}; + +const VideoModal: React.FC = (props) => { + + const intl = useIntl(); + const [form] = Form.useForm(); + + const [videoInit, setVideoInit] = useState(false); + + + useEffect(()=>{ + setVideoInit(false) + if (props.modalOpen) { + setVideoInit(true) + + } else { + console.log('***********') + setVideoInit(false) + } + + }, [props.modalOpen]) + + + return ( + + {videoInit && ()} + + + ) +} +export default VideoModal; diff --git a/src/pages/DCSDevice/DeviceList/index.tsx b/src/pages/DCSDevice/DeviceList/index.tsx new file mode 100644 index 0000000..c55ff1a --- /dev/null +++ b/src/pages/DCSDevice/DeviceList/index.tsx @@ -0,0 +1,706 @@ +import IsBatchDelete from '@/components/BatchOperation/isBatchDelete'; +import TableActionCard from '@/components/TableActionCard'; +import IsDelete from '@/components/TableActionCard/isDelete'; +import TreeAndTableList, { ProCardTypeProps } from '@/layouts/treeAndTableList'; +import { ColumnDrawer as DeviceCategoryColumnDrawer } from '@/pages/Device/DeviceCategoryList/components/ColumnDrawer'; +import { DeviceCategoryColumns } from '@/pages/Device/DeviceCategoryList/components/Columns'; +import { ColumnDrawer as DeviceGroupColumnDrawer } from '@/pages/Device/DeviceGroupList/components/ColumnDrawer'; +import { DeviceGroupColumns } from '@/pages/Device/DeviceGroupList/components/Columns'; +import { + deleteDeviceDeleteDevice, + deleteDeviceDeleteDeviceByIds, + postDeviceCloseRtspCamera, + postDeviceGetDeviceList, + postDeviceOpenRtspCamera, +} from '@/services/device/Device'; +import { + postDeviceCategoryGetDeviceCategoryById, + postDeviceCategoryGetDeviceCategoryFkSelect, + postDeviceCategoryGetDeviceCategoryNames, +} from '@/services/device/DeviceCategory'; +import { + postDeviceGroupGetDeviceGroupById, + postDeviceGroupGetDeviceGroupFkSelect, + postDeviceGroupGetDeviceGroupNames, + postDeviceGroupGetDeviceGroupTree, +} from '@/services/device/DeviceGroup'; +import { PlusOutlined, RedoOutlined } from '@ant-design/icons'; +import type { ActionType, ProColumns } from '@ant-design/pro-components'; +import { PageContainer, ProFormSelect, ProTable } from '@ant-design/pro-components'; +import { Access, FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; +import { Button, Tree, message } from 'antd'; +import { DataNode } from 'antd/es/tree'; +import React, { useEffect, useRef, useState } from 'react'; +import { proTableCommonOptions, proTablePaginationOptions } from '../../../../config/defaultTable'; +import { ColumnDrawer } from './components/ColumnDrawer'; +import CreateForm from './components/CreateForm'; +import UpdateForm from './components/UpdateForm'; +import VideoModal from './components/VideoModal'; + +const DeviceList: React.FC = () => { + /** + * @en-US Pop-up window of new window + * @zh-CN 新建窗口的弹窗 + * */ + const [videoModalOpen, setVideoModalOpen] = useState(false); + + const [createModalOpen, setCreateModalOpen] = useState(false); + /** + * @en-US The pop-up window of the distribution update window + * @zh-CN 分布更新窗口的弹窗 + * */ + const [updateModalOpen, setUpdateModalOpen] = useState(false); + const [showDetail, setShowDetail] = useState(false); + /** + * @en-US International configuration + * @zh-CN 国际化配置 + * */ + const access = useAccess(); + const intl = useIntl(); + const actionRef = useRef(); + // 动态设置每页数量 + const [currentPageSize, setCurrentPageSize] = useState(10); + const [currentRow, setCurrentRow] = useState(); + const [selectedRowsState, setSelectedRows] = useState([]); + const [category_fk_id_open, set_category_fk_id_open] = useState(false); + const [category_fk_id, set_category_fk_id] = useState(); + const [category_fk_id_column_open, set_category_fk_id_column_open] = useState(false); + const [categoryFkIdIds, setCategoryFkIdIds] = useState([]); + const [categoryFkIdMap, setCategoryFkIdMap] = useState<{ [key: number]: string }>({}); + const [group_fk_id_open, set_group_fk_id_open] = useState(false); + const [group_fk_id, set_group_fk_id] = useState(); + const [group_fk_id_column_open, set_group_fk_id_column_open] = useState(false); + const [groupFkIdIds, setGroupFkIdIds] = useState([]); + const [groupFkIdMap, setGroupFkIdMap] = useState<{ [key: number]: string }>({}); + + const [hasInit, setHasInit] = useState(false); + const [nodeTreeData, setNodeTreeData] = React.useState([]); + const [selectNodes, setSelectNodes] = React.useState([]); + const [videoOpening, setVideoOpening] = useState(false); + const [videoServerParam, setVideoServerParam] = useState({}); + useEffect(() => { + postDeviceGroupGetDeviceGroupTree() + .then((resp) => { + setNodeTreeData(resp.data.tree); + setHasInit(true); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + }, []); + const handleVideoModal = () => { + if (videoModalOpen) { + setVideoModalOpen(false); + if (videoServerParam?.pid || 0) { + postDeviceCloseRtspCamera({ pid: videoServerParam.pid }).then((resp) => { + console.log(resp); + }); + } + setCurrentRow(undefined); + setVideoServerParam({}); + } else { + setVideoModalOpen(true); + } + }; + const handle_category_fk_id = (id: any) => { + if (category_fk_id_open) { + set_category_fk_id(undefined); + set_category_fk_id_open(false); + } else { + postDeviceCategoryGetDeviceCategoryById({ id: id }).then((resp) => { + set_category_fk_id(resp.data.deviceCategory); + set_category_fk_id_open(true); + }); + } + }; + const handle_category_fk_id_column_open = () => { + if (category_fk_id_column_open) { + set_category_fk_id_column_open(false); + } else { + postDeviceCategoryGetDeviceCategoryNames({ ids: categoryFkIdIds }).then((resp) => { + let a: any = {}; + resp.data.list.forEach((v: any) => { + if (v.id) { + a[v.id] = v.name; + } + }); + setCategoryFkIdMap(a); + }); + set_category_fk_id_column_open(true); + } + }; + const handle_group_fk_id = (id: any) => { + if (group_fk_id_open) { + set_group_fk_id(undefined); + set_group_fk_id_open(false); + } else { + postDeviceGroupGetDeviceGroupById({ id: id }).then((resp) => { + set_group_fk_id(resp.data.deviceGroup); + set_group_fk_id_open(true); + }); + } + }; + const handle_group_fk_id_column_open = () => { + if (group_fk_id_column_open) { + set_group_fk_id_column_open(false); + } else { + postDeviceGroupGetDeviceGroupNames({ ids: groupFkIdIds }).then((resp) => { + let a: any = {}; + resp.data.list.forEach((v: any) => { + if (v.id) { + a[v.id] = v.name; + } + }); + setGroupFkIdMap(a); + }); + set_group_fk_id_column_open(true); + } + }; + + const handleUpdateModal = () => { + if (updateModalOpen) { + setUpdateModalOpen(false); + setCurrentRow(undefined); + } else { + setUpdateModalOpen(true); + } + }; + const handleCreateModal = () => { + if (createModalOpen) { + setCreateModalOpen(false); + setCurrentRow(undefined); + } else { + setCreateModalOpen(true); + } + }; + const handleColumnDrawer = () => { + if (showDetail) { + setShowDetail(false); + setCurrentRow(undefined); + } else { + setShowDetail(true); + } + }; + const handleDestroy = async (selectedRow: API.Device) => { + deleteDeviceDeleteDevice({ id: selectedRow.id }) + .then(() => { + message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); + actionRef.current?.reload(); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + }; + + const columns: ProColumns[] = [ + { + title: , + dataIndex: 'name', + width: '150', + sorter: true, + render: (dom, entity) => { + return ( + { + setCurrentRow(entity); + setShowDetail(true); + }} + > + {dom} + + ); + }, + // renderFormItem: () => { + // return ( + // <> + // + // + // ); + // }, + key: 'fixedName', + fixed: 'left', + }, + + // { + // title: , + // dataIndex: 'name', + // hideInSearch: true, + // }, + + { + title: , + dataIndex: 'code', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'position', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'param', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'spec', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'categoryFkId', + hideInSearch: false, + render: (text, record) => { + if (category_fk_id_column_open) { + return ( + { + handle_category_fk_id(record.categoryFkId); + }} + > + {record?.categoryFkId ? categoryFkIdMap[record.categoryFkId] : undefined} + + ); + } else { + return ( + { + handle_category_fk_id(record.categoryFkId); + }} + > + {record.categoryFkId} + + ); + } + }, + renderFormItem: () => { + return ( + // value 和 onchange 会通过 form 自动注入。 + { + const resp = await postDeviceCategoryGetDeviceCategoryFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + ); + }, + }, + + { + title: , + dataIndex: 'groupFkId', + hideInSearch: false, + render: (text, record) => { + if (group_fk_id_column_open) { + return ( + { + handle_group_fk_id(record.groupFkId); + }} + > + {record?.groupFkId ? groupFkIdMap[record.groupFkId] : undefined} + + ); + } else { + return ( + { + handle_group_fk_id(record.groupFkId); + }} + > + {record.groupFkId} + + ); + } + }, + renderFormItem: () => { + return ( + // value 和 onchange 会通过 form 自动注入。 + { + const resp = await postDeviceGroupGetDeviceGroupFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + ); + }, + }, + + { + title: , + dataIndex: 'isEnable', + filters: true, + onFilter: true, + hideInSearch: true, + valueType: 'switch', + }, + + { + title: , + dataIndex: 'remark', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'createTime', + sorter: true, + hideInSearch: true, + valueType: 'dateTime', + }, + + { + title: , + dataIndex: 'updateTime', + sorter: true, + hideInSearch: true, + valueType: 'dateTime', + }, + + { + title: , + dataIndex: 'option', + valueType: 'option', + fixed: 'right', + render: (_, record) => [ + { + setUpdateModalOpen(true); + setCurrentRow(record); + }} + > + + + ), + }, + { + key: 'destroy', + renderDom: ( + { + handleDestroy(record).then(() => {}); + }} + > + ), + }, + { + key: 'video', + renderDom: ( + + ), + }, + ]} + >, + ], + }, + ]; + return ( + + + + + ), + } as ProCardTypeProps + } + leftDom={ + hasInit && ( + { + setSelectNodes(selectKeys); + actionRef.current?.reload(); + }} + checkStrictly={false} + /> + ) + } + rightDom={ + + headerTitle={intl.formatMessage({ + id: 'pages.searchTable.title', + defaultMessage: '$$$', + })} + loading={{ + tip: intl.formatMessage({ + id: 'common.video_opening', + defaultMessage: '$$$', + }), + spinning: videoOpening, + }} + options={{ fullScreen: true, setting: true, density: true, reload: true }} + actionRef={actionRef} + rowKey="key" + scroll={{ x: 2000, y: proTableCommonOptions.commscrollY }} + search={{ + labelWidth: proTableCommonOptions.searchLabelWidth, + }} + onDataSourceChange={(data) => { + let CategoryFkIdIds: any = data.map((v) => { + return v.categoryFkId; + }); + setCategoryFkIdIds(CategoryFkIdIds); + + let GroupFkIdIds: any = data.map((v) => { + return v.groupFkId; + }); + setGroupFkIdIds(GroupFkIdIds); + }} + pagination={{ + ...proTablePaginationOptions, + pageSize: currentPageSize, + onChange: (page, pageSize) => setCurrentPageSize(pageSize), + }} + columnsState={{ + persistenceKey: 'device_list', + persistenceType: 'localStorage', + }} + tableAlertOptionRender={() => { + return ( + <> + {selectedRowsState?.length > 0 && ( + { + // TODO 需联调批量删除接口 + deleteDeviceDeleteDeviceByIds({ + ids: selectedRowsState.map((v: API.Device) => { + return v.id as number; + }), + }).then(() => { + actionRef.current?.reloadAndRest?.(); + }); + }} + /> + )} + + ); + }} + toolBarRender={() => [ + + + + + + + , + ]} + request={async (params = {}, sort) => { + const { current, ...rest } = params; + const reqParams: any = { + page: current, + desc: false, + orderKey: '', + ...rest, + }; + if (selectNodes.length) { + reqParams.groupFkId = selectNodes[0]; + } + if (sort && Object.keys(sort).length) { + reqParams.orderKey = Object.keys(sort)[0]; + let sort_select = sort[reqParams.orderKey]; + reqParams.desc = sort_select === 'descend'; + } + let resp = await postDeviceGetDeviceList({ ...reqParams }); + return { + data: resp.data.list.map((v: API.Device) => { + return { ...v, key: v.id }; + }), + success: resp.success, + total: resp.data.total, + current: resp.data.page, + pageSize: resp.data.pageSize, + }; + }} + columns={columns} + rowSelection={{ + onChange: (_, selectedRows) => { + setSelectedRows(selectedRows); + }, + }} + /> + } + > + + + + + + + + + ); +}; + +export default DeviceList; diff --git a/src/pages/DCSDevice/DeviceStatus/components/ColumnDrawer.tsx b/src/pages/DCSDevice/DeviceStatus/components/ColumnDrawer.tsx new file mode 100644 index 0000000..9561cd6 --- /dev/null +++ b/src/pages/DCSDevice/DeviceStatus/components/ColumnDrawer.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import {Drawer} from "antd"; +import {ProColumns, ProDescriptions, ProDescriptionsItemProps} from "@ant-design/pro-components"; + +export type ColumnDrawProps = { + handleDrawer: (id?: any)=>void; + isShowDetail: boolean; + columns: ProColumns[]; + currentRow: API.Device | undefined; +}; + + +const ColumnDrawer: React.FC = (props) => { + + return ( + { + props.handleDrawer(); + }} + closable={true} + > + {props.currentRow?.id && ( + + column={2} + title={props.currentRow?.id} + request={async () => ({ + data: props.currentRow || {}, + })} + params={{ + id: props.currentRow?.id, + }} + columns={props.columns as ProDescriptionsItemProps[]} + /> + )} + + ) +} +export {ColumnDrawer} + diff --git a/src/pages/DCSDevice/DeviceStatus/components/Columns.tsx b/src/pages/DCSDevice/DeviceStatus/components/Columns.tsx new file mode 100644 index 0000000..028dcf7 --- /dev/null +++ b/src/pages/DCSDevice/DeviceStatus/components/Columns.tsx @@ -0,0 +1,62 @@ +import { FormattedMessage} from '@umijs/max'; +export const DeviceColumns = [{ + title: (), + dataIndex: "id", + },{ + title: (), + dataIndex: "name", + },{ + title: (), + dataIndex: "code", + },{ + title: (), + dataIndex: "position", + },{ + title: (), + dataIndex: "param", + },{ + title: (), + dataIndex: "spec", + },{ + title: (), + dataIndex: "category_fk_id", + },{ + title: (), + dataIndex: "group_fk_id", + },{ + title: (), + dataIndex: "is_enable", + },{ + title: (), + dataIndex: "remark", + },{ + title: (), + dataIndex: "create_time", + },{ + title: (), + dataIndex: "update_time", + },] diff --git a/src/pages/DCSDevice/DeviceStatus/components/CreateForm.tsx b/src/pages/DCSDevice/DeviceStatus/components/CreateForm.tsx new file mode 100644 index 0000000..f4d8289 --- /dev/null +++ b/src/pages/DCSDevice/DeviceStatus/components/CreateForm.tsx @@ -0,0 +1,233 @@ +import { postDeviceCreateDevice } from '@/services/device/Device'; +import { postDeviceCategoryGetDeviceCategoryFkSelect } from '@/services/device/DeviceCategory'; +import { postDeviceGroupGetDeviceGroupFkSelect } from '@/services/device/DeviceGroup'; +import { + ModalForm, + ProForm, + ProFormSelect, + ProFormSwitch, + ProFormText, +} from '@ant-design/pro-components'; +import { FormattedMessage, useIntl } from '@umijs/max'; +import { Form, Switch, message } from 'antd'; +import React, { useState } from 'react'; +import { proFormItemStyleProps, proFormModelWidth } from '../../../../../config/defaultForm'; +export type FormValueType = { + target?: string; + template?: string; + type?: string; + time?: string; + frequency?: string; +} & Partial; + +export type CreateFormProps = { + createModalOpen: boolean; + handleModal: () => void; + values: Partial; + reload: any; +}; +const CreateForm: React.FC = (props) => { + const intl = useIntl(); + const [isAuto, setIsAuto] = useState(true); + const [form] = Form.useForm(); + + return ( + + width={proFormModelWidth} + title={intl.formatMessage({ + id: 'device.device.table.list.add', + defaultMessage: '$$$', + })} + open={props.createModalOpen} + form={form} + autoFocusFirstInput + modalProps={{ + destroyOnClose: true, + onCancel: () => props.handleModal(), + }} + submitTimeout={2000} + onFinish={async (values) => { + postDeviceCreateDevice(values) + .then(() => { + message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); + props.reload(); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + props.handleModal(); + return true; + }} + > + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.name', defaultMessage: '$$$' })}`} + required={true} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_select', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.groupFkId', + defaultMessage: '$$$', + })}`} + required={false} + showSearch + debounceTime={1000} + request={async (keyWord) => { + const resp = await postDeviceGroupGetDeviceGroupFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.code', defaultMessage: '$$$' })}`} + required={!isAuto} + initialValue="" + disabled={isAuto} + rules={ + isAuto + ? [] + : [ + { + required: true, + message: ( + + ), + }, + ] + } + addonAfter={ + } + unCheckedChildren={} + onChange={setIsAuto} + /> + } + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.position', + defaultMessage: '$$$', + })}`} + required={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.param', + defaultMessage: '$$$', + })}`} + required={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.spec', defaultMessage: '$$$' })}`} + required={false} + /> + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_select', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.categoryFkId', + defaultMessage: '$$$', + })}`} + required={false} + showSearch + debounceTime={1000} + request={async (keyWord) => { + const resp = await postDeviceCategoryGetDeviceCategoryFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.remark', + defaultMessage: '$$$', + })}`} + required={false} + /> + } + initialValue={true} + /> + + + ); +}; +export default CreateForm; diff --git a/src/pages/DCSDevice/DeviceStatus/components/UpdateForm.tsx b/src/pages/DCSDevice/DeviceStatus/components/UpdateForm.tsx new file mode 100644 index 0000000..c386ae9 --- /dev/null +++ b/src/pages/DCSDevice/DeviceStatus/components/UpdateForm.tsx @@ -0,0 +1,272 @@ +import { putDeviceUpdateDevice } from '@/services/device/Device'; +import { postDeviceCategoryGetDeviceCategoryFkSelect } from '@/services/device/DeviceCategory'; +import { postDeviceGroupGetDeviceGroupFkSelect } from '@/services/device/DeviceGroup'; +import { + ModalForm, + ProForm, + ProFormDateTimePicker, + ProFormSelect, + ProFormSwitch, + ProFormText, +} from '@ant-design/pro-components'; +import { FormattedMessage, useIntl } from '@umijs/max'; +import { Form, message } from 'antd'; +import React from 'react'; +import { proFormItemStyleProps, proFormModelWidth } from '../../../../../config/defaultForm'; +export type FormValueType = { + target?: string; + template?: string; + type?: string; + time?: string; + frequency?: string; +} & Partial; + +export type UpdateFormProps = { + updateModalOpen: boolean; + handleModal: () => void; + values: Partial; + reload: any; +}; +const UpdateForm: React.FC = (props) => { + const intl = useIntl(); + const [form] = Form.useForm(); + + return ( + + width={proFormModelWidth} + title={intl.formatMessage({ + id: 'device.device.table.list.update', + defaultMessage: '$$$', + })} + open={props.updateModalOpen} + form={form} + autoFocusFirstInput + modalProps={{ + destroyOnClose: true, + onCancel: () => props.handleModal(), + }} + submitTimeout={2000} + onFinish={async (values) => { + putDeviceUpdateDevice(values) + .then(() => { + message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); + props.reload(); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + + props.handleModal(); + return true; + }} + > + + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.name', defaultMessage: '$$$' })}`} + required={true} + initialValue={props.values.name} + disabled={false} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.code', defaultMessage: '$$$' })}`} + required={true} + initialValue={props.values.code} + disabled={false} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.position', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.position} + disabled={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.param', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.param} + disabled={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ id: 'device.device.table.list.spec', defaultMessage: '$$$' })}`} + required={false} + initialValue={props.values.spec} + disabled={false} + /> + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_select', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.categoryFkId', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.categoryFkId} + showSearch + debounceTime={1000} + request={async (keyWord) => { + const resp = await postDeviceCategoryGetDeviceCategoryFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_select', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.groupFkId', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.groupFkId} + showSearch + debounceTime={1000} + request={async (keyWord) => { + const resp = await postDeviceGroupGetDeviceGroupFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.remark', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.remark} + disabled={false} + /> + } + initialValue={props.values.isEnable} + disabled={false} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.createTime', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.createTime} + disabled={true} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'device.device.table.list.updateTime', + defaultMessage: '$$$', + })}`} + required={false} + initialValue={props.values.updateTime} + disabled={true} + /> + + + ); +}; +export default UpdateForm; diff --git a/src/pages/DCSDevice/DeviceStatus/components/VideoModal.tsx b/src/pages/DCSDevice/DeviceStatus/components/VideoModal.tsx new file mode 100644 index 0000000..b1bcd83 --- /dev/null +++ b/src/pages/DCSDevice/DeviceStatus/components/VideoModal.tsx @@ -0,0 +1,53 @@ +import {useIntl} from '@umijs/max'; +import React, {useState, useRef, useCallback, useEffect} from 'react'; +import {Form, Modal} from 'antd'; + +import WebRTCStreamer from "@/components/WebRtcPlayer"; +export type FormValueType = { + target?: string; + template?: string; + type?: string; + time?: string; + frequency?: string; +} & Partial; + +export type VideoModalProps = { + modalOpen: boolean; + handleModal: () => void; + values: Partial; + reload: any; + videoServerParam: API.RtspRes; +}; + +const VideoModal: React.FC = (props) => { + + const intl = useIntl(); + const [form] = Form.useForm(); + + const [videoInit, setVideoInit] = useState(false); + + + useEffect(()=>{ + setVideoInit(false) + if (props.modalOpen) { + setVideoInit(true) + + } else { + console.log('***********') + setVideoInit(false) + } + + }, [props.modalOpen]) + + + return ( + + {videoInit && ()} + + + ) +} +export default VideoModal; diff --git a/src/pages/DCSDevice/DeviceStatus/index.tsx b/src/pages/DCSDevice/DeviceStatus/index.tsx new file mode 100644 index 0000000..c55ff1a --- /dev/null +++ b/src/pages/DCSDevice/DeviceStatus/index.tsx @@ -0,0 +1,706 @@ +import IsBatchDelete from '@/components/BatchOperation/isBatchDelete'; +import TableActionCard from '@/components/TableActionCard'; +import IsDelete from '@/components/TableActionCard/isDelete'; +import TreeAndTableList, { ProCardTypeProps } from '@/layouts/treeAndTableList'; +import { ColumnDrawer as DeviceCategoryColumnDrawer } from '@/pages/Device/DeviceCategoryList/components/ColumnDrawer'; +import { DeviceCategoryColumns } from '@/pages/Device/DeviceCategoryList/components/Columns'; +import { ColumnDrawer as DeviceGroupColumnDrawer } from '@/pages/Device/DeviceGroupList/components/ColumnDrawer'; +import { DeviceGroupColumns } from '@/pages/Device/DeviceGroupList/components/Columns'; +import { + deleteDeviceDeleteDevice, + deleteDeviceDeleteDeviceByIds, + postDeviceCloseRtspCamera, + postDeviceGetDeviceList, + postDeviceOpenRtspCamera, +} from '@/services/device/Device'; +import { + postDeviceCategoryGetDeviceCategoryById, + postDeviceCategoryGetDeviceCategoryFkSelect, + postDeviceCategoryGetDeviceCategoryNames, +} from '@/services/device/DeviceCategory'; +import { + postDeviceGroupGetDeviceGroupById, + postDeviceGroupGetDeviceGroupFkSelect, + postDeviceGroupGetDeviceGroupNames, + postDeviceGroupGetDeviceGroupTree, +} from '@/services/device/DeviceGroup'; +import { PlusOutlined, RedoOutlined } from '@ant-design/icons'; +import type { ActionType, ProColumns } from '@ant-design/pro-components'; +import { PageContainer, ProFormSelect, ProTable } from '@ant-design/pro-components'; +import { Access, FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; +import { Button, Tree, message } from 'antd'; +import { DataNode } from 'antd/es/tree'; +import React, { useEffect, useRef, useState } from 'react'; +import { proTableCommonOptions, proTablePaginationOptions } from '../../../../config/defaultTable'; +import { ColumnDrawer } from './components/ColumnDrawer'; +import CreateForm from './components/CreateForm'; +import UpdateForm from './components/UpdateForm'; +import VideoModal from './components/VideoModal'; + +const DeviceList: React.FC = () => { + /** + * @en-US Pop-up window of new window + * @zh-CN 新建窗口的弹窗 + * */ + const [videoModalOpen, setVideoModalOpen] = useState(false); + + const [createModalOpen, setCreateModalOpen] = useState(false); + /** + * @en-US The pop-up window of the distribution update window + * @zh-CN 分布更新窗口的弹窗 + * */ + const [updateModalOpen, setUpdateModalOpen] = useState(false); + const [showDetail, setShowDetail] = useState(false); + /** + * @en-US International configuration + * @zh-CN 国际化配置 + * */ + const access = useAccess(); + const intl = useIntl(); + const actionRef = useRef(); + // 动态设置每页数量 + const [currentPageSize, setCurrentPageSize] = useState(10); + const [currentRow, setCurrentRow] = useState(); + const [selectedRowsState, setSelectedRows] = useState([]); + const [category_fk_id_open, set_category_fk_id_open] = useState(false); + const [category_fk_id, set_category_fk_id] = useState(); + const [category_fk_id_column_open, set_category_fk_id_column_open] = useState(false); + const [categoryFkIdIds, setCategoryFkIdIds] = useState([]); + const [categoryFkIdMap, setCategoryFkIdMap] = useState<{ [key: number]: string }>({}); + const [group_fk_id_open, set_group_fk_id_open] = useState(false); + const [group_fk_id, set_group_fk_id] = useState(); + const [group_fk_id_column_open, set_group_fk_id_column_open] = useState(false); + const [groupFkIdIds, setGroupFkIdIds] = useState([]); + const [groupFkIdMap, setGroupFkIdMap] = useState<{ [key: number]: string }>({}); + + const [hasInit, setHasInit] = useState(false); + const [nodeTreeData, setNodeTreeData] = React.useState([]); + const [selectNodes, setSelectNodes] = React.useState([]); + const [videoOpening, setVideoOpening] = useState(false); + const [videoServerParam, setVideoServerParam] = useState({}); + useEffect(() => { + postDeviceGroupGetDeviceGroupTree() + .then((resp) => { + setNodeTreeData(resp.data.tree); + setHasInit(true); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + }, []); + const handleVideoModal = () => { + if (videoModalOpen) { + setVideoModalOpen(false); + if (videoServerParam?.pid || 0) { + postDeviceCloseRtspCamera({ pid: videoServerParam.pid }).then((resp) => { + console.log(resp); + }); + } + setCurrentRow(undefined); + setVideoServerParam({}); + } else { + setVideoModalOpen(true); + } + }; + const handle_category_fk_id = (id: any) => { + if (category_fk_id_open) { + set_category_fk_id(undefined); + set_category_fk_id_open(false); + } else { + postDeviceCategoryGetDeviceCategoryById({ id: id }).then((resp) => { + set_category_fk_id(resp.data.deviceCategory); + set_category_fk_id_open(true); + }); + } + }; + const handle_category_fk_id_column_open = () => { + if (category_fk_id_column_open) { + set_category_fk_id_column_open(false); + } else { + postDeviceCategoryGetDeviceCategoryNames({ ids: categoryFkIdIds }).then((resp) => { + let a: any = {}; + resp.data.list.forEach((v: any) => { + if (v.id) { + a[v.id] = v.name; + } + }); + setCategoryFkIdMap(a); + }); + set_category_fk_id_column_open(true); + } + }; + const handle_group_fk_id = (id: any) => { + if (group_fk_id_open) { + set_group_fk_id(undefined); + set_group_fk_id_open(false); + } else { + postDeviceGroupGetDeviceGroupById({ id: id }).then((resp) => { + set_group_fk_id(resp.data.deviceGroup); + set_group_fk_id_open(true); + }); + } + }; + const handle_group_fk_id_column_open = () => { + if (group_fk_id_column_open) { + set_group_fk_id_column_open(false); + } else { + postDeviceGroupGetDeviceGroupNames({ ids: groupFkIdIds }).then((resp) => { + let a: any = {}; + resp.data.list.forEach((v: any) => { + if (v.id) { + a[v.id] = v.name; + } + }); + setGroupFkIdMap(a); + }); + set_group_fk_id_column_open(true); + } + }; + + const handleUpdateModal = () => { + if (updateModalOpen) { + setUpdateModalOpen(false); + setCurrentRow(undefined); + } else { + setUpdateModalOpen(true); + } + }; + const handleCreateModal = () => { + if (createModalOpen) { + setCreateModalOpen(false); + setCurrentRow(undefined); + } else { + setCreateModalOpen(true); + } + }; + const handleColumnDrawer = () => { + if (showDetail) { + setShowDetail(false); + setCurrentRow(undefined); + } else { + setShowDetail(true); + } + }; + const handleDestroy = async (selectedRow: API.Device) => { + deleteDeviceDeleteDevice({ id: selectedRow.id }) + .then(() => { + message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); + actionRef.current?.reload(); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + }; + + const columns: ProColumns[] = [ + { + title: , + dataIndex: 'name', + width: '150', + sorter: true, + render: (dom, entity) => { + return ( + { + setCurrentRow(entity); + setShowDetail(true); + }} + > + {dom} + + ); + }, + // renderFormItem: () => { + // return ( + // <> + // + // + // ); + // }, + key: 'fixedName', + fixed: 'left', + }, + + // { + // title: , + // dataIndex: 'name', + // hideInSearch: true, + // }, + + { + title: , + dataIndex: 'code', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'position', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'param', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'spec', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'categoryFkId', + hideInSearch: false, + render: (text, record) => { + if (category_fk_id_column_open) { + return ( + { + handle_category_fk_id(record.categoryFkId); + }} + > + {record?.categoryFkId ? categoryFkIdMap[record.categoryFkId] : undefined} + + ); + } else { + return ( + { + handle_category_fk_id(record.categoryFkId); + }} + > + {record.categoryFkId} + + ); + } + }, + renderFormItem: () => { + return ( + // value 和 onchange 会通过 form 自动注入。 + { + const resp = await postDeviceCategoryGetDeviceCategoryFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + ); + }, + }, + + { + title: , + dataIndex: 'groupFkId', + hideInSearch: false, + render: (text, record) => { + if (group_fk_id_column_open) { + return ( + { + handle_group_fk_id(record.groupFkId); + }} + > + {record?.groupFkId ? groupFkIdMap[record.groupFkId] : undefined} + + ); + } else { + return ( + { + handle_group_fk_id(record.groupFkId); + }} + > + {record.groupFkId} + + ); + } + }, + renderFormItem: () => { + return ( + // value 和 onchange 会通过 form 自动注入。 + { + const resp = await postDeviceGroupGetDeviceGroupFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + ); + }, + }, + + { + title: , + dataIndex: 'isEnable', + filters: true, + onFilter: true, + hideInSearch: true, + valueType: 'switch', + }, + + { + title: , + dataIndex: 'remark', + hideInSearch: true, + }, + + { + title: , + dataIndex: 'createTime', + sorter: true, + hideInSearch: true, + valueType: 'dateTime', + }, + + { + title: , + dataIndex: 'updateTime', + sorter: true, + hideInSearch: true, + valueType: 'dateTime', + }, + + { + title: , + dataIndex: 'option', + valueType: 'option', + fixed: 'right', + render: (_, record) => [ + { + setUpdateModalOpen(true); + setCurrentRow(record); + }} + > + + + ), + }, + { + key: 'destroy', + renderDom: ( + { + handleDestroy(record).then(() => {}); + }} + > + ), + }, + { + key: 'video', + renderDom: ( + + ), + }, + ]} + >, + ], + }, + ]; + return ( + + + + + ), + } as ProCardTypeProps + } + leftDom={ + hasInit && ( + { + setSelectNodes(selectKeys); + actionRef.current?.reload(); + }} + checkStrictly={false} + /> + ) + } + rightDom={ + + headerTitle={intl.formatMessage({ + id: 'pages.searchTable.title', + defaultMessage: '$$$', + })} + loading={{ + tip: intl.formatMessage({ + id: 'common.video_opening', + defaultMessage: '$$$', + }), + spinning: videoOpening, + }} + options={{ fullScreen: true, setting: true, density: true, reload: true }} + actionRef={actionRef} + rowKey="key" + scroll={{ x: 2000, y: proTableCommonOptions.commscrollY }} + search={{ + labelWidth: proTableCommonOptions.searchLabelWidth, + }} + onDataSourceChange={(data) => { + let CategoryFkIdIds: any = data.map((v) => { + return v.categoryFkId; + }); + setCategoryFkIdIds(CategoryFkIdIds); + + let GroupFkIdIds: any = data.map((v) => { + return v.groupFkId; + }); + setGroupFkIdIds(GroupFkIdIds); + }} + pagination={{ + ...proTablePaginationOptions, + pageSize: currentPageSize, + onChange: (page, pageSize) => setCurrentPageSize(pageSize), + }} + columnsState={{ + persistenceKey: 'device_list', + persistenceType: 'localStorage', + }} + tableAlertOptionRender={() => { + return ( + <> + {selectedRowsState?.length > 0 && ( + { + // TODO 需联调批量删除接口 + deleteDeviceDeleteDeviceByIds({ + ids: selectedRowsState.map((v: API.Device) => { + return v.id as number; + }), + }).then(() => { + actionRef.current?.reloadAndRest?.(); + }); + }} + /> + )} + + ); + }} + toolBarRender={() => [ + + + + + + + , + ]} + request={async (params = {}, sort) => { + const { current, ...rest } = params; + const reqParams: any = { + page: current, + desc: false, + orderKey: '', + ...rest, + }; + if (selectNodes.length) { + reqParams.groupFkId = selectNodes[0]; + } + if (sort && Object.keys(sort).length) { + reqParams.orderKey = Object.keys(sort)[0]; + let sort_select = sort[reqParams.orderKey]; + reqParams.desc = sort_select === 'descend'; + } + let resp = await postDeviceGetDeviceList({ ...reqParams }); + return { + data: resp.data.list.map((v: API.Device) => { + return { ...v, key: v.id }; + }), + success: resp.success, + total: resp.data.total, + current: resp.data.page, + pageSize: resp.data.pageSize, + }; + }} + columns={columns} + rowSelection={{ + onChange: (_, selectedRows) => { + setSelectedRows(selectedRows); + }, + }} + /> + } + > + + + + + + + + + ); +}; + +export default DeviceList;