feat: 初始化分布式设备状态模块

develop
zhoux 1 year ago
parent 5524a6aaec
commit 628daf4cd1

@ -0,0 +1,111 @@
import { Request, Response } from 'express';
import moment from 'moment';
import { parse } from 'url';
// mock tableListDataSource
const genList = (current: number, pageSize: number) => {
const tableListDataSource: API.RuleListItem[] = [];
for (let i = 0; i < pageSize; i += 1) {
const index = (current - 1) * 10 + i;
tableListDataSource.push({
key: index,
disabled: i % 6 === 0,
href: 'https://ant.design',
avatar: [
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
][i % 2],
name: `TradeCode ${index}`,
owner: '曲丽丽',
desc: '这是一段描述',
callNo: Math.floor(Math.random() * 1000),
status: Math.floor(Math.random() * 10) % 4,
updatedAt: moment().format('YYYY-MM-DD'),
createdAt: moment().format('YYYY-MM-DD'),
progress: Math.ceil(Math.random() * 100),
});
}
tableListDataSource.reverse();
return tableListDataSource;
};
let tableListDataSource = genList(1, 100);
function getDCSDeviceStatusList(req: Request, res: Response, u: string) {
let realUrl = u;
if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
realUrl = req.url;
}
const { current = 1, pageSize = 10 } = req.query;
const params = parse(realUrl, true).query as unknown as API.PageParams &
API.RuleListItem & {
sorter: any;
filter: any;
};
let dataSource = [...tableListDataSource].slice(
((current as number) - 1) * (pageSize as number),
(current as number) * (pageSize as number),
);
if (params.sorter) {
const sorter = JSON.parse(params.sorter);
dataSource = dataSource.sort((prev, next) => {
let sortNumber = 0;
(Object.keys(sorter) as Array<keyof API.RuleListItem>).forEach((key) => {
let nextSort = next?.[key] as number;
let preSort = prev?.[key] as number;
if (sorter[key] === 'descend') {
if (preSort - nextSort > 0) {
sortNumber += -1;
} else {
sortNumber += 1;
}
return;
}
if (preSort - nextSort > 0) {
sortNumber += 1;
} else {
sortNumber += -1;
}
});
return sortNumber;
});
}
if (params.filter) {
const filter = JSON.parse(params.filter as any) as {
[key: string]: string[];
};
if (Object.keys(filter).length > 0) {
dataSource = dataSource.filter((item) => {
return (Object.keys(filter) as Array<keyof API.RuleListItem>).some((key) => {
if (!filter[key]) {
return true;
}
if (filter[key].includes(`${item[key]}`)) {
return true;
}
return false;
});
});
}
}
if (params.name) {
dataSource = dataSource.filter((data) => data?.name?.includes(params.name || ''));
}
const result = {
data: dataSource,
total: tableListDataSource.length,
success: true,
pageSize,
current: parseInt(`${params.current}`, 10) || 1,
};
return res.json(result);
}
export default {
'GET /api/mock/getDCSDeviceStatusList': getDCSDeviceStatusList,
};

@ -0,0 +1,30 @@
export const deviceStatusEnums : Record<string,any> = {
'allStatus': {
miniName: '全部',
value: '',
color: ''
},
'onlineStatus': {
miniName: '在线',
value: '',
color: 'success'
},
'outlineStatus': {
miniName: '离线',
value: '',
color: 'default'
},
'processingStatus': {
miniName: '运行中',
value: '',
color: 'warning'
},
'errorStatus': {
miniName: '故障',
value: '',
color: 'error'
}
}

@ -2,10 +2,28 @@
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-11-01 13:56:33
* @LastEditors: zhoux zhouxia@supervision.ltd
* @LastEditTime: 2023-11-30 17:10:53
* @LastEditTime: 2023-12-08 16:03:40
* @FilePath: \general-ai-platform-web\src\locales\zh-CN.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import * as DCSDevice from '@/locales/zh-CN/DCSDevice';
import * as analysisZh from '@/locales/zh-CN/analysis';
import * as deviceZh from '@/locales/zh-CN/device';
import * as errorTypesZh from '@/locales/zh-CN/errorTypes';
import * as projectZh from '@/locales/zh-CN/project';
import * as resourceZh from '@/locales/zh-CN/resource';
import {
api,
department,
dynamic_menu,
interface_api,
operation_record,
post,
role,
user,
} from '@/locales/zh-CN/system';
import app from './zh-CN/app';
import common from './zh-CN/common';
import component from './zh-CN/component';
import globalHeader from './zh-CN/globalHeader';
import menu from './zh-CN/menu';
@ -13,14 +31,7 @@ import pages from './zh-CN/pages';
import pwa from './zh-CN/pwa';
import settingDrawer from './zh-CN/settingDrawer';
import settings from './zh-CN/settings';
import common from './zh-CN/common';
import app from './zh-CN/app';
import {interface_api, dynamic_menu, api, role, user, post, department, operation_record} from "@/locales/zh-CN/system";
import * as analysisZh from "@/locales/zh-CN/analysis";
import * as errorTypesZh from "@/locales/zh-CN/errorTypes";
import * as deviceZh from "@/locales/zh-CN/device";
import * as resourceZh from "@/locales/zh-CN/resource";
import * as projectZh from "@/locales/zh-CN/project";
export default {
'navBar.lang': '语言',
'layout.user.link.help': '帮助',
@ -38,7 +49,14 @@ export default {
...pwa,
...common,
...component,
...interface_api, ...dynamic_menu, ...api, ...role, ...user, ...post, ...department, ...operation_record,
...interface_api,
...dynamic_menu,
...api,
...role,
...user,
...post,
...department,
...operation_record,
...app,
...Object.assign({}, ...Object.values(analysisZh)),
@ -46,4 +64,5 @@ export default {
...Object.assign({}, ...Object.values(deviceZh)),
...Object.assign({}, ...Object.values(resourceZh)),
...Object.assign({}, ...Object.values(projectZh)),
...Object.assign({}, ...Object.values(DCSDevice)),
};

@ -2,7 +2,7 @@
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-12-08 10:26:34
* @LastEditors: zhoux zhouxia@supervision.ltd
* @LastEditTime: 2023-12-08 10:27:48
* @LastEditTime: 2023-12-08 17:59: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
*/
@ -22,8 +22,14 @@ export const DCSDevice_list: { [key: string]: string } = {
'DCSDeviceList.device.table.list.name': '设备名称'
}
// 设备状态
export const DCSDevice_status: { [key: string]: string } = {
}
'DCSDeviceList.deviceStatus.detailModel.name': '设备详情',
'DCSDeviceList.deviceStatus.detailModel.baseInfo': '设备信息',
'DCSDeviceList.deviceStatus.detailModel.log': '设备日志',
'DCSDeviceList.deviceStatus.detailModel.logTable.deviceName': '设备名称',
'DCSDeviceList.deviceStatus.detailModel.logTable.deviceID': '设备ID',
'DCSDeviceList.deviceStatus.detailModel.logTable.deviceCat': '设备类别',
'DCSDeviceList.deviceStatus.detailModel.logTable.deviceIP': '设备IP',
'DCSDeviceList.deviceStatus.detailModel.logTable.deviceTime': '运行时长',
}

@ -28,6 +28,7 @@ export default {
'pages.admin.subPage.alertMessage': 'umi ui 现已发布,欢迎使用 npm run ui 启动体验。',
'pages.searchTable.createForm.newRule': '新建规则',
'pages.searchTable.detail': '详情',
'pages.searchTable.reOpen': '重启',
'pages.searchTable.update': '更新',
'pages.searchTable.destroy': '删除',
'pages.searchTable.create_son_menu': '添加子菜单',

@ -1,41 +0,0 @@
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<API.Device>[];
currentRow: API.Device | undefined;
};
const ColumnDrawer: React.FC<ColumnDrawProps> = (props) => {
return (
<Drawer
width={500}
open={props.isShowDetail}
onClose={() => {
props.handleDrawer();
}}
closable={true}
>
{props.currentRow?.id && (
<ProDescriptions<API.Device>
column={2}
title={props.currentRow?.id}
request={async () => ({
data: props.currentRow || {},
})}
params={{
id: props.currentRow?.id,
}}
columns={props.columns as ProDescriptionsItemProps<API.Device>[]}
/>
)}
</Drawer>
)
}
export {ColumnDrawer}

@ -1,62 +0,0 @@
import { FormattedMessage} from '@umijs/max';
export const DeviceColumns = [{
title: (<FormattedMessage
id="device.device.table.list.id"
defaultMessage="$$$"/>),
dataIndex: "id",
},{
title: (<FormattedMessage
id="device.device.table.list.name"
defaultMessage="$$$"/>),
dataIndex: "name",
},{
title: (<FormattedMessage
id="device.device.table.list.code"
defaultMessage="$$$"/>),
dataIndex: "code",
},{
title: (<FormattedMessage
id="device.device.table.list.position"
defaultMessage="$$$"/>),
dataIndex: "position",
},{
title: (<FormattedMessage
id="device.device.table.list.param"
defaultMessage="$$$"/>),
dataIndex: "param",
},{
title: (<FormattedMessage
id="device.device.table.list.spec"
defaultMessage="$$$"/>),
dataIndex: "spec",
},{
title: (<FormattedMessage
id="device.device.table.list.categoryFkId"
defaultMessage="$$$"/>),
dataIndex: "category_fk_id",
},{
title: (<FormattedMessage
id="device.device.table.list.groupFkId"
defaultMessage="$$$"/>),
dataIndex: "group_fk_id",
},{
title: (<FormattedMessage
id="device.device.table.list.isEnable"
defaultMessage="$$$"/>),
dataIndex: "is_enable",
},{
title: (<FormattedMessage
id="device.device.table.list.remark"
defaultMessage="$$$"/>),
dataIndex: "remark",
},{
title: (<FormattedMessage
id="device.device.table.list.createTime"
defaultMessage="$$$"/>),
dataIndex: "create_time",
},{
title: (<FormattedMessage
id="device.device.table.list.updateTime"
defaultMessage="$$$"/>),
dataIndex: "update_time",
},]

@ -1,233 +0,0 @@
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<API.Device>;
export type CreateFormProps = {
createModalOpen: boolean;
handleModal: () => void;
values: Partial<API.Device>;
reload: any;
};
const CreateForm: React.FC<CreateFormProps> = (props) => {
const intl = useIntl();
const [isAuto, setIsAuto] = useState(true);
const [form] = Form.useForm<API.Device>();
return (
<ModalForm<API.Device>
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;
}}
>
<ProForm.Group>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="name"
label={<FormattedMessage id="device.device.table.list.name" defaultMessage="$$$" />}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({ id: 'device.device.table.list.name', defaultMessage: '$$$' })}`}
required={true}
rules={[
{
required: true,
message: (
<FormattedMessage
id="device.device.table.rule.required.name"
defaultMessage="name is required"
/>
),
},
]}
/>
<ProFormSelect
width={proFormItemStyleProps.column2Width}
name="groupFkId"
label={<FormattedMessage id="device.device.table.list.groupFkId" defaultMessage="$$$" />}
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,
};
});
}}
/>
<ProFormText
width={proFormItemStyleProps.width - 80}
name="code"
label={<FormattedMessage id="device.device.table.list.code" defaultMessage="$$$" />}
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: (
<FormattedMessage
id="device.device.table.rule.required.code"
defaultMessage="code is required"
/>
),
},
]
}
addonAfter={
<Switch
checked={isAuto}
checkedChildren={<FormattedMessage id="common.auto" defaultMessage="$$$" />}
unCheckedChildren={<FormattedMessage id="common.edit" defaultMessage="$$$" />}
onChange={setIsAuto}
/>
}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="position"
label={<FormattedMessage id="device.device.table.list.position" defaultMessage="$$$" />}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device.device.table.list.position',
defaultMessage: '$$$',
})}`}
required={false}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="param"
label={<FormattedMessage id="device.device.table.list.param" defaultMessage="$$$" />}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device.device.table.list.param',
defaultMessage: '$$$',
})}`}
required={false}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="spec"
label={<FormattedMessage id="device.device.table.list.spec" defaultMessage="$$$" />}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({ id: 'device.device.table.list.spec', defaultMessage: '$$$' })}`}
required={false}
/>
<ProFormSelect
width={proFormItemStyleProps.column2Width}
name="categoryFkId"
label={
<FormattedMessage id="device.device.table.list.categoryFkId" defaultMessage="$$$" />
}
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,
};
});
}}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="remark"
label={<FormattedMessage id="device.device.table.list.remark" defaultMessage="$$$" />}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device.device.table.list.remark',
defaultMessage: '$$$',
})}`}
required={false}
/>
<ProFormSwitch
width={proFormItemStyleProps.column2Width}
name="isEnable"
label={<FormattedMessage id="device.device.table.list.isEnable" defaultMessage="$$$" />}
initialValue={true}
/>
</ProForm.Group>
</ModalForm>
);
};
export default CreateForm;

@ -0,0 +1,175 @@
import { Modal, Tabs } from 'antd';
import { proFormMaxModelWidth } from '../../../../../config/defaultForm';
import { ProColumns, ProTable } from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import React, { useState } from 'react';
// 设备信息
const DeviceBaseInfo: React.FC = () => {
return (
<ul>
<li></li>
</ul>
);
};
// 设备信息
const DeviceLogInfo: React.FC = () => {
const columns: ProColumns<Record<string, any>[]> = [
{
title: (
<FormattedMessage
id="DCSDeviceList.deviceStatus.detailModel.logTable.deviceName"
defaultMessage="$$$"
/>
),
dataIndex: 'deviceName',
// width: 120,
hideInSearch: true,
},
{
title: (
<FormattedMessage
id="DCSDeviceList.deviceStatus.detailModel.logTable.deviceID"
defaultMessage="$$$"
/>
),
dataIndex: 'deviceID',
// width: 120,
hideInSearch: true,
},
{
title: (
<FormattedMessage
id="DCSDeviceList.deviceStatus.detailModel.logTable.deviceCat"
defaultMessage="$$$"
/>
),
dataIndex: 'deviceCat',
// width: 120,
hideInSearch: true,
},
{
title: (
<FormattedMessage
id="DCSDeviceList.deviceStatus.detailModel.logTable.deviceIP"
defaultMessage="$$$"
/>
),
dataIndex: 'deviceIP',
// width: 120,
hideInSearch: true,
},
{
title: (
<FormattedMessage
id="DCSDeviceList.deviceStatus.detailModel.logTable.deviceTime"
defaultMessage="$$$"
/>
),
dataIndex: 'deviceTime',
// width: 120,
hideInSearch: true,
},
];
let testData: Record<string, any>[] = [];
for (let i = 0; i < 8; i++) {
testData.push({
deviceName: '设备' + (i + 1),
deviceID: '123456',
deviceCat: '外围监控',
deviceIP: '192.168.1.10',
deviceTime: '22:00:00',
});
}
return (
<ProTable
cardProps={{
bodyStyle: { padding: 0, margin: 0 },
}}
search={false}
options={{ fullScreen: false, setting: false, density: false, reload: false }}
rowKey="key"
request={async () => {
// const {current, ...rest} = params
// const reqParams = {
// page: current,
// desc: false,
// orderKey: "",
// ...rest,
// }
// 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 getSysOperationRecordGetOperationRecordList({...reqParams})
let resp = {
success: true,
};
return {
data: testData,
success: resp.success,
// total: resp.data.total,
// current: resp.data.page,
// pageSize: resp.data.pageSize
};
}}
pagination={false}
columns={columns}
></ProTable>
);
};
export type DetailInfoCardProps = {
detailModalOpen: boolean;
handleDetailModal: () => void;
};
const DetailInfoCard: React.FC<DetailInfoCardProps> = (props) => {
const intl = useIntl();
const [type, setType] = useState<string>('deviceInfo');
return (
<Modal
width={proFormMaxModelWidth}
title={intl.formatMessage({
id: 'DCSDeviceList.deviceStatus.detailModel.name',
defaultMessage: '$$$',
})}
open={props.detailModalOpen}
footer={null}
onCancel={props.handleDetailModal}
destroyOnClose
>
<Tabs
activeKey={type}
onChange={(activeKey: string) => setType(activeKey)}
items={[
{
key: 'deviceInfo',
label: intl.formatMessage({
id: 'pages.login.accountLogin.tab',
defaultMessage: '设备信息',
}),
},
{
key: 'deviceLog',
label: intl.formatMessage({
id: 'DCSDeviceList.deviceStatus.detailModel.log',
defaultMessage: '设备日志',
}),
},
]}
></Tabs>
{type === 'deviceInfo' && <DeviceBaseInfo></DeviceBaseInfo>}
{type === 'deviceLog' && <DeviceLogInfo></DeviceLogInfo>}
</Modal>
);
};
export default DetailInfoCard;

@ -0,0 +1,115 @@
/*
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-11-06 16:12:17
* @LastEditors: zhoux zhouxia@supervision.ltd
* @LastEditTime: 2023-12-08 14:05:45
* @FilePath: \general-ai-platform-web\src\pages\Setting\components\ProjectCardList.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React from 'react';
import { Progress } from 'antd';
// import { postModelVersionGetModelVersionListByIds } from '@/services/resource/ModelVersion';
// const [tabs, setTabs] = useState([]);
// const [projectData, setProjectData] = useState<any>({});
// const [tab, setTab] = useState('');
// const [modelVersionData, setModelVersionData] = useState<any[]>([]);
/**styles */
const listItemStyle = {
display: 'flex',
fontSize: 14,
color: '#333333',
maxWidth: '22vh',
alignItems: 'center',
padding: '5px 0',
};
const listItemLabelStyle = {
fontSize: 14,
color: '#666666',
minWidth: 40,
};
const listItemTextStyle = {
fontSize: 14,
margin: 0,
};
// 卡片
export type UpdateProjectProps = {
info: Record<string, any>;
// reload: any;
};
type DeviceItemProgress = {
label: string;
percent: number;
};
// 进度条
const DeviceItemProgress: React.FC<DeviceItemProgress> = (props) => {
let strokeColor = 'rgb(243,48,5)';
switch (props.label) {
case 'CPU':
strokeColor = 'rgb(243,48,5)';
break;
case '内存':
strokeColor = 'rgb(33,169,122)';
break;
case '存储':
strokeColor = 'rgb(33,169,122)';
break;
case 'NPU':
strokeColor = 'rgb(250,173,20)';
break;
}
return (
<div style={{ width: '100%', display: 'flex' }}>
<span style={listItemLabelStyle}>{props.label}</span>
<Progress height={46} percent={props.percent * 100} strokeColor={strokeColor} showInfo={false} />
</div>
);
};
const DeviceStatusCard: React.FC<UpdateProjectProps> = ({
info,
}: {
info: Record<string, any>;
}) => {
return (
<div
style={{
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'left',
paddingLeft: 15,
paddingRight: 15,
}}
>
{/* <div style={{ display: 'flex', alignItems: 'center', paddingBottom: 10 }}>
<span style={{ fontWeight: 700, fontSize: 14, paddingRight: 10 }}></span>
<Tag color="#44AEF5"></Tag>
</div> */}
<ul>
<li style={listItemStyle}>
<DeviceItemProgress label="CPU" percent={0.79}></DeviceItemProgress>
</li>
<li style={listItemStyle}>
<DeviceItemProgress label="内存" percent={0.18}></DeviceItemProgress>
</li>
<li style={listItemStyle}>
<DeviceItemProgress label="存储" percent={0.16}></DeviceItemProgress>
</li>
<li style={listItemStyle}>
<DeviceItemProgress label="NPU" percent={0.58}></DeviceItemProgress>
</li>
</ul>
</div>
);
};
export default DeviceStatusCard;

@ -1,272 +0,0 @@
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<API.Device>;
export type UpdateFormProps = {
updateModalOpen: boolean;
handleModal: () => void;
values: Partial<API.Device>;
reload: any;
};
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const intl = useIntl();
const [form] = Form.useForm<API.Device>();
return (
<ModalForm<API.Device>
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;
}}
>
<ProForm.Group>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="id"
label="id"
disabled={true}
initialValue={props.values.id}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="name"
label={<FormattedMessage id="device.device.table.list.name" defaultMessage="$$$" />}
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: (
<FormattedMessage
id="device.device.table.rule.required.name"
defaultMessage="name is required"
/>
),
},
]}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="code"
label={<FormattedMessage id="device.device.table.list.code" defaultMessage="$$$" />}
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: (
<FormattedMessage
id="device.device.table.rule.required.code"
defaultMessage="code is required"
/>
),
},
]}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="position"
label={<FormattedMessage id="device.device.table.list.position" defaultMessage="$$$" />}
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}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="param"
label={<FormattedMessage id="device.device.table.list.param" defaultMessage="$$$" />}
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}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="spec"
label={<FormattedMessage id="device.device.table.list.spec" defaultMessage="$$$" />}
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}
/>
<ProFormSelect
width={proFormItemStyleProps.column2Width}
name="categoryFkId"
label={
<FormattedMessage id="device.device.table.list.categoryFkId" defaultMessage="$$$" />
}
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,
};
});
}}
/>
<ProFormSelect
width={proFormItemStyleProps.column2Width}
name="groupFkId"
label={<FormattedMessage id="device.device.table.list.groupFkId" defaultMessage="$$$" />}
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,
};
});
}}
/>
<ProFormText
width={proFormItemStyleProps.column2Width}
name="remark"
label={<FormattedMessage id="device.device.table.list.remark" defaultMessage="$$$" />}
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}
/>
<ProFormSwitch
width={proFormItemStyleProps.column2Width}
name="isEnable"
label={<FormattedMessage id="device.device.table.list.isEnable" defaultMessage="$$$" />}
initialValue={props.values.isEnable}
disabled={false}
/>
<ProFormDateTimePicker
width={proFormItemStyleProps.column2Width}
name="createTime"
label={<FormattedMessage id="device.device.table.list.createTime" defaultMessage="$$$" />}
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}
/>
<ProFormDateTimePicker
width={proFormItemStyleProps.column2Width}
name="updateTime"
label={<FormattedMessage id="device.device.table.list.updateTime" defaultMessage="$$$" />}
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}
/>
</ProForm.Group>
</ModalForm>
);
};
export default UpdateForm;

@ -1,53 +0,0 @@
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<API.Device>;
export type VideoModalProps = {
modalOpen: boolean;
handleModal: () => void;
values: Partial<API.Device>;
reload: any;
videoServerParam: API.RtspRes;
};
const VideoModal: React.FC<VideoModalProps> = (props) => {
const intl = useIntl();
const [form] = Form.useForm<API.ActionDetection>();
const [videoInit, setVideoInit] = useState(false);
useEffect(()=>{
setVideoInit(false)
if (props.modalOpen) {
setVideoInit(true)
} else {
console.log('***********')
setVideoInit(false)
}
}, [props.modalOpen])
return (
<Modal title="播放视频" open={props.modalOpen}
width={1280}
onOk={props.handleModal} onCancel={props.handleModal}
footer={null}>
{videoInit && (<WebRTCStreamer is_open={props.modalOpen} stream_url={props.values.param} server_url={props.videoServerParam.host || ''}></WebRTCStreamer>)}
</Modal>
)
}
export default VideoModal;

@ -1,706 +1,216 @@
import IsBatchDelete from '@/components/BatchOperation/isBatchDelete';
/*
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-12-08 10:11:54
* @LastEditors: zhoux zhouxia@supervision.ltd
* @LastEditTime: 2023-12-08 16:01:26
* @FilePath: \general-ai-platform-web\src\pages\DCSDevice\DeviceStatus\index.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
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';
import IsConfirmAction from '@/components/TableActionCard/isConfirmAction';
import { deviceStatusEnums } from '@/enums/status';
import { PageContainer, ProCard, ProList } from '@ant-design/pro-components';
import { FormattedMessage } from '@umijs/max';
import { Button, Tag } from 'antd';
import React, { useState } from 'react';
import DeviceStatusCard from './components/DeviceStatusCard';
import DetailInfoCard from './components/DetailInfoCard';
/**
* @
* 1
* 2UI
* 3
*/
const tabOptions: Record<string, any> = {
allStatus: 90,
onlineStatus: 20,
outlineStatus: 20,
processingStatus: 10,
errorStatus: 20,
};
const DeviceList: React.FC = () => {
/**
* @en-US Pop-up window of new window
* @zh-CN
* */
const [videoModalOpen, setVideoModalOpen] = useState<boolean>(false);
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false);
/**
* @en-US The pop-up window of the distribution update window
* @zh-CN
* */
const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false);
const [showDetail, setShowDetail] = useState<boolean>(false);
/**
* @en-US International configuration
* @zh-CN
* */
const access = useAccess();
const intl = useIntl();
const actionRef = useRef<ActionType>();
// 动态设置每页数量
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
const [currentRow, setCurrentRow] = useState<API.Device>();
const [selectedRowsState, setSelectedRows] = useState<API.Device[]>([]);
const [category_fk_id_open, set_category_fk_id_open] = useState(false);
const [category_fk_id, set_category_fk_id] = useState<API.DeviceCategory>();
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<API.DeviceGroup>();
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<boolean>(false);
const [nodeTreeData, setNodeTreeData] = React.useState<DataNode[]>([]);
const [selectNodes, setSelectNodes] = React.useState<any[]>([]);
const [videoOpening, setVideoOpening] = useState<boolean>(false);
const [videoServerParam, setVideoServerParam] = useState<API.RtspRes>({});
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 DeviceStatus: React.FC = () => {
const [cardActionProps, setCardActionProps] = useState<'actions' | 'extra'>('extra');
const [detailModalOpen, setDetailModalOpen] = useState<boolean>(false);
const [currentRow, setCurrentRow] = useState<Record<string,any>>({});
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<API.Device>[] = [
{
title: <FormattedMessage id="device.device.table.list.name" defaultMessage="$$$" />,
dataIndex: 'name',
width: '150',
sorter: true,
render: (dom, entity) => {
return (
<a
onClick={() => {
setCurrentRow(entity);
setShowDetail(true);
}}
>
{dom}
</a>
);
},
// renderFormItem: () => {
// return (
// <>
// <ProFormText
// width="md"
// labelCol={{ span: 4 }}
// wrapperCol={{ span: 22 }}
// name="name"
// placeholder={`${intl.formatMessage({
// id: 'common.please_input',
// defaultMessage: '$$$',
// })}`}
// required={false}
// />
// </>
// );
// },
key: 'fixedName',
fixed: 'left',
},
// {
// title: <FormattedMessage id="device.device.table.list.name" defaultMessage="$$$" />,
// dataIndex: 'name',
// hideInSearch: true,
// },
const [activeTabIndex, setActiveTabIndex] = useState<number>(0);
{
title: <FormattedMessage id="device.device.table.list.code" defaultMessage="$$$" />,
dataIndex: 'code',
hideInSearch: true,
},
{
title: <FormattedMessage id="device.device.table.list.position" defaultMessage="$$$" />,
dataIndex: 'position',
hideInSearch: true,
},
const [ghost, setGhost] = useState<boolean>(false);
{
title: <FormattedMessage id="device.device.table.list.param" defaultMessage="$$$" />,
dataIndex: 'param',
hideInSearch: true,
},
{
title: <FormattedMessage id="device.device.table.list.spec" defaultMessage="$$$" />,
dataIndex: 'spec',
hideInSearch: true,
},
const handleDetailModal = () => {
if (detailModalOpen) {
setDetailModalOpen(false);
setCurrentRow({});
} else {
setDetailModalOpen(true);
{
title: <FormattedMessage id="device.device.table.list.categoryFkId" defaultMessage="$$$" />,
dataIndex: 'categoryFkId',
hideInSearch: false,
render: (text, record) => {
if (category_fk_id_column_open) {
return (
<a
onClick={() => {
handle_category_fk_id(record.categoryFkId);
}}
>
{record?.categoryFkId ? categoryFkIdMap[record.categoryFkId] : undefined}
</a>
);
} else {
return (
<a
onClick={() => {
handle_category_fk_id(record.categoryFkId);
}}
>
{record.categoryFkId}
</a>
);
}
},
renderFormItem: () => {
return (
// value 和 onchange 会通过 form 自动注入。
<ProFormSelect
placeholder={`${intl.formatMessage({
id: 'common.please_select',
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,
};
});
}}
/>
);
},
},
}
};
{
title: <FormattedMessage id="device.device.table.list.groupFkId" defaultMessage="$$$" />,
dataIndex: 'groupFkId',
hideInSearch: false,
render: (text, record) => {
if (group_fk_id_column_open) {
return (
<a
onClick={() => {
handle_group_fk_id(record.groupFkId);
}}
>
{record?.groupFkId ? groupFkIdMap[record.groupFkId] : undefined}
</a>
);
} else {
return (
<a
onClick={() => {
handle_group_fk_id(record.groupFkId);
const data = [{status: '在线'},{status: '在线'}, {status: '故障'},{status: '故障'},{status: '运行中'},{status: '在线'},{status: '在线'}, {status: '离线'}].map(
(record, index) => {
let currColor = 'default';
switch (record.status) {
case '在线':
currColor = 'success';
break;
case '故障':
currColor = 'error';
break;
case '运行中':
currColor = 'warning';
break;
default:
currColor = 'default';
break;
}
return {
content: (
<ProCard style={{ backgroundColor: '#FAFAFA' }} bodyStyle={{ margin: 0, padding: 0 }}>
<div
style={{
display: 'flex',
alignItems: 'center',
padding: 15,
justifyContent: 'space-between',
}}
>
{record.groupFkId}
</a>
);
}
},
renderFormItem: () => {
return (
// value 和 onchange 会通过 form 自动注入。
<ProFormSelect
placeholder={`${intl.formatMessage({
id: 'common.please_select',
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,
};
});
}}
/>
);
},
},
{
title: <FormattedMessage id="device.device.table.list.isEnable" defaultMessage="$$$" />,
dataIndex: 'isEnable',
filters: true,
onFilter: true,
hideInSearch: true,
valueType: 'switch',
},
{
title: <FormattedMessage id="device.device.table.list.remark" defaultMessage="$$$" />,
dataIndex: 'remark',
hideInSearch: true,
},
{
title: <FormattedMessage id="device.device.table.list.createTime" defaultMessage="$$$" />,
dataIndex: 'createTime',
sorter: true,
hideInSearch: true,
valueType: 'dateTime',
},
{
title: <FormattedMessage id="device.device.table.list.updateTime" defaultMessage="$$$" />,
dataIndex: 'updateTime',
sorter: true,
hideInSearch: true,
valueType: 'dateTime',
},
{
title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="Operating" />,
dataIndex: 'option',
valueType: 'option',
fixed: 'right',
render: (_, record) => [
<TableActionCard
key="TableActionCardRef"
renderActions={[
{
key: 'update',
renderDom: (
<Button
key="update"
type="link"
size="small"
onClick={() => {
setUpdateModalOpen(true);
setCurrentRow(record);
}}
>
<FormattedMessage id="pages.searchTable.update" defaultMessage="Update" />
</Button>
),
},
{
key: 'destroy',
renderDom: (
<IsDelete
deleteApi={() => {
handleDestroy(record).then(() => {});
}}
></IsDelete>
),
},
{
key: 'video',
renderDom: (
<Button
key="video"
type="link"
size="small"
onClick={() => {
setVideoOpening(true);
if (record.param) {
postDeviceOpenRtspCamera({ url: record.param })
.then((resp) => {
setVideoServerParam(resp.data);
setVideoOpening(false);
setVideoModalOpen(true);
console.log(resp.data);
<div>
<Tag color={currColor}>{record.status}</Tag>
<span>{index + 1}</span>
</div>
<TableActionCard
key="TableActionCardRef"
renderActions={[
{
key: 'update',
renderDom: (
<IsConfirmAction
key="reOpen"
title={'重启'}
buttonFormatText={'pages.searchTable.reOpen'}
confirmAction={() => {
// setPublishModalOpen(true);
// putAlgorithmModelUpdateAlgorithmModel({
// id: record.modelFkId,
// defaultVersionFkId: record.id,
// })
// .then(() => {
// message.success(
// intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' }),
// );
// })
// .catch(() => {
// message.error(
// intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' }),
// );
// });
}}
></IsConfirmAction>
),
},
{
key: 'detail',
renderDom: (
<Button
key="detail"
type="link"
size="small"
onClick={() => {
handleDetailModal()
setCurrentRow(record);
})
.catch(() => {
setVideoOpening(false);
message.error(
intl.formatMessage({
id: 'common.open_failure',
defaultMessage: '$$$',
}),
);
});
} else {
setVideoOpening(false);
message.error(
intl.formatMessage({ id: 'common.open_failure', defaultMessage: '$$$' }),
);
}
}}
>
<FormattedMessage id="common.open_video" defaultMessage="$$$" />
</Button>
),
},
]}
></TableActionCard>,
],
// doToDetail(record);
// setShowDetail(true);
}}
>
<FormattedMessage id="pages.searchTable.detail" defaultMessage="Update" />
</Button>
),
},
]}
></TableActionCard>
</div>
<DeviceStatusCard info={record}></DeviceStatusCard>{' '}
</ProCard>
),
};
},
];
);
return (
<PageContainer>
<TreeAndTableList
leftCard={
{
title: '网点选择',
extra: (
<>
<Button
icon={<RedoOutlined />}
onClick={() => {
setSelectNodes([]);
actionRef.current?.reload();
}}
>
</Button>
</>
),
} as ProCardTypeProps
}
leftDom={
hasInit && (
<Tree
checkable={false}
defaultExpandAll={true}
selectedKeys={selectNodes}
treeData={nodeTreeData}
onSelect={(selectKeys) => {
setSelectNodes(selectKeys);
actionRef.current?.reload();
}}
checkStrictly={false}
/>
)
}
rightDom={
<ProTable<API.Device>
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 && (
<IsBatchDelete
deleteApi={() => {
// TODO 需联调批量删除接口
deleteDeviceDeleteDeviceByIds({
ids: selectedRowsState.map((v: API.Device) => {
return v.id as number;
}),
}).then(() => {
actionRef.current?.reloadAndRest?.();
});
}}
/>
)}
</>
);
}}
toolBarRender={() => [
<Access
accessible={access.canUpdate(history.location.pathname)}
key={`${history.location.pathname}-add`}
<ProCard bodyStyle={{ padding: 16, margin: 0 }}>
<div>
{Object.keys(tabOptions).map((item, index) => {
// eslint-disable-next-line react/jsx-key
return (
<Button
style={{ marginRight: 12 }}
type={activeTabIndex === index ? 'primary' : 'default'}
key={index}
onClick={() => {
setActiveTabIndex(index);
}}
>
<Button
type="primary"
key="category_fk_id_show"
onClick={() => {
handle_category_fk_id_column_open();
}}
>
{category_fk_id_column_open ? (
<FormattedMessage id="common.hide" defaultMessage="$$$" />
) : (
<FormattedMessage id="common.show" defaultMessage="$$$" />
)}
<FormattedMessage
id="device.device.table.list.categoryFkId"
defaultMessage="$$$"
/>
</Button>
<Button
type="primary"
key="group_fk_id_show"
onClick={() => {
handle_group_fk_id_column_open();
}}
>
{group_fk_id_column_open ? (
<FormattedMessage id="common.hide" defaultMessage="$$$" />
) : (
<FormattedMessage id="common.show" defaultMessage="$$$" />
)}
<FormattedMessage id="device.device.table.list.groupFkId" defaultMessage="$$$" />
</Button>
<Button
type="primary"
key="primary"
onClick={() => {
setCreateModalOpen(true);
}}
>
<PlusOutlined />{' '}
<FormattedMessage id="pages.searchTable.new" defaultMessage="New" />
</Button>
</Access>,
]}
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);
},
}}
/>
}
></TreeAndTableList>
<CreateForm
createModalOpen={createModalOpen}
values={currentRow || {}}
handleModal={handleCreateModal}
reload={actionRef.current?.reload}
/>
<UpdateForm
updateModalOpen={updateModalOpen}
values={currentRow || {}}
handleModal={handleUpdateModal}
reload={actionRef.current?.reload}
/>
<ColumnDrawer
handleDrawer={handleColumnDrawer}
isShowDetail={showDetail}
columns={columns}
currentRow={currentRow}
/>
<DeviceCategoryColumnDrawer
handleDrawer={handle_category_fk_id}
isShowDetail={category_fk_id_open}
columns={DeviceCategoryColumns}
currentRow={category_fk_id}
/>
<DeviceGroupColumnDrawer
handleDrawer={handle_group_fk_id}
isShowDetail={group_fk_id_open}
columns={DeviceGroupColumns}
currentRow={group_fk_id}
/>
<VideoModal
modalOpen={videoModalOpen}
handleModal={handleVideoModal}
values={currentRow || {}}
videoServerParam={videoServerParam}
reload={actionRef.current?.reload}
/>
{Object.keys(deviceStatusEnums).includes(item)
? deviceStatusEnums[item].miniName
: ''}
{tabOptions[item]}
</Button>
);
})}
</div>
<ProList<any>
className="gn"
ghost={true}
itemCardProps={{
ghost: true,
bodyStyle: { padding: 0, margin: 0 },
}}
pagination={{
defaultPageSize: 8,
showSizeChanger: false,
}}
showActions="hover"
rowSelection={false}
grid={{ gutter: 16, xs: 1, md: 2, lg: 3, xl: 4, xxl: 4 }}
metas={{
type: {},
content: {},
actions: {
cardActionProps,
},
}}
headerTitle=""
// toolBarRender={(action, rows) => {
// console.log(action, rows, 'toolBarRender');
// // TODO 需要对接接口
// const isProcess: boolean = false;
// return isProcess ? (
// <Button type="primary" danger>
// 结束运行
// </Button>
// ) : (
// <Button type="primary">
// 开始运行
// </Button>
// );
// }}
dataSource={data}
/>
</ProCard>
<DetailInfoCard detailModalOpen={detailModalOpen} handleDetailModal={handleDetailModal}>
</DetailInfoCard>
</PageContainer>
);
};
export default DeviceList;
export default DeviceStatus;

Loading…
Cancel
Save