feat: 初始化构建节点设备模块
parent
bc48347bb1
commit
49bfe975bc
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-25 15:45:17
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-28 17:15:19
|
||||
* @FilePath: \general-ai-platform-web\mock\device.ts
|
||||
* @Description: mock设备数据
|
||||
*/
|
||||
import { mockGetDeviceListByGroup } from './pools/deviceData';
|
||||
|
||||
import { successMockApiProps } from './typing';
|
||||
import { fetchCurrPageByList } from './utils/apiMock';
|
||||
|
||||
export default {
|
||||
// 设备列表
|
||||
'GET /api/device/listByGroup': async (req: Request, res: Response) => {
|
||||
const { page, pageSize } = req.query;
|
||||
const resData: successMockApiProps = {
|
||||
...fetchCurrPageByList({
|
||||
...mockGetDeviceListByGroup,
|
||||
data: { ...mockGetDeviceListByGroup.data, page, pageSize: pageSize || 10 },
|
||||
}),
|
||||
};
|
||||
res.json(resData);
|
||||
},
|
||||
// // 设备分类
|
||||
// 'GET /api/dict/deviceType': async (req: Request, res: Response) => {
|
||||
// const resData: successMockApiProps = {
|
||||
// ...fetchMockSuccessFullByOther(mockGetDeviceTypeDictData),
|
||||
// };
|
||||
// res.json(resData);
|
||||
// },
|
||||
};
|
@ -0,0 +1,35 @@
|
||||
// 节点下设备列表数据
|
||||
// 节点设备列表
|
||||
export const mockGetDeviceListByGroup = {
|
||||
data: {
|
||||
count: 2,
|
||||
results: [
|
||||
{
|
||||
id: '10001',
|
||||
name: '海康威视环球摄像头', // 设备名称
|
||||
deviceType: '摄像头', // 设备类型
|
||||
isEnable: true, // 是否部署
|
||||
createTime: '2023-12-17T13:37:31.758471+08:00',
|
||||
updateTime: '2024-04-25T15:22:16.530494+08:00',
|
||||
deviceSite: '东区左侧', // 设备位置
|
||||
deviceModel: 'haikang_video_2024', // 设备型号
|
||||
deviceParams: '627663_aduh237298', // 设备参数
|
||||
remark: '', // 备注
|
||||
},
|
||||
{
|
||||
id: '10002',
|
||||
name: '海康威视环球摄像头',
|
||||
deviceType: '控制器',
|
||||
isEnable: false,
|
||||
createTime: '2023-12-17T13:37:31.758471+08:00',
|
||||
updateTime: '2024-04-25T15:22:16.530494+08:00',
|
||||
deviceSite: '南区前侧',
|
||||
deviceModel: 'haikang_video_2024',
|
||||
deviceParams: '627663_aduh237298',
|
||||
remark: '',
|
||||
},
|
||||
],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
<svg t="1714117834638" class="icon" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" p-id="3262" width="200" height="200">
|
||||
<path d="M320 0 192 128l384 384-384 384 128 128 512-512L320 0z" p-id="3263" fill="#154DDD"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 260 B |
@ -0,0 +1 @@
|
||||
<svg t="1714117834638" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3262" width="200" height="200"><path d="M320 0 192 128l384 384-384 384 128 128 512-512L320 0z" p-id="3263" fill="#999999"></path></svg>
|
After Width: | Height: | Size: 250 B |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
@ -0,0 +1,3 @@
|
||||
import deviceGroupTree from './src/deviceGroupTree';
|
||||
|
||||
export const DeviceGroupTree = deviceGroupTree;
|
@ -0,0 +1,47 @@
|
||||
.base_tree_wrap {
|
||||
font-size: 14px;
|
||||
}
|
||||
.base_tree_wrap > .ant-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.base_tree_wrap > .ant-form-item .ant-input-outlined {
|
||||
border: none;
|
||||
}
|
||||
.base_tree_wrap > .ant-form-item .ant-input:focus,
|
||||
.base_tree_wrap > .ant-form-item .ant-input-focused {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
/* 去掉聚焦时的阴影效果 */
|
||||
/* 如果需要,你也可以调整其他聚焦时的样式 */
|
||||
}
|
||||
.base_tree_wrap > .ant-form-item .ant-input-outlined:focus,
|
||||
.base_tree_wrap > .ant-form-item .ant-input-outlined:focus-within {
|
||||
box-shadow: none;
|
||||
/* 去掉聚焦时的阴影效果 */
|
||||
}
|
||||
.base_tree_wrap .tree_node_1 {
|
||||
width: 100%;
|
||||
margin: 12px 0;
|
||||
padding: 8px 17px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.base_tree_wrap .tree_node_1 .ant-tree-switcher-noop {
|
||||
opacity: 0;
|
||||
}
|
||||
.base_tree_wrap .tree_node_item .action_list {
|
||||
display: none;
|
||||
}
|
||||
.base_tree_wrap .tree_node_1:hover,
|
||||
.base_tree_wrap .ant-tree-treenode-selected {
|
||||
color: #154ddd;
|
||||
background: rgba(21, 77, 221, 0.1);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.base_tree_wrap .tree_node_item:hover .action_list {
|
||||
display: block;
|
||||
}
|
||||
.base_tree_wrap .tree_node_item:hover .action_list .anticon-delete {
|
||||
color: #e80d0d;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
.base_tree_wrap {
|
||||
font-size: 14px;
|
||||
& > .ant-form-item {
|
||||
margin-bottom: 0;
|
||||
.ant-input-outlined {
|
||||
border: none;
|
||||
}
|
||||
.ant-input:focus,
|
||||
.ant-input-focused {
|
||||
border: none;
|
||||
box-shadow: none; /* 去掉聚焦时的阴影效果 */
|
||||
/* 如果需要,你也可以调整其他聚焦时的样式 */
|
||||
}
|
||||
.ant-input-outlined:focus,
|
||||
.ant-input-outlined:focus-within {
|
||||
box-shadow: none; /* 去掉聚焦时的阴影效果 */
|
||||
}
|
||||
}
|
||||
|
||||
.tree_node_1 {
|
||||
width: 100%;
|
||||
margin: 12px 0;
|
||||
padding: 8px 17px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
.ant-tree-switcher-noop {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.tree_node_item {
|
||||
.action_list {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.tree_node_1:hover,
|
||||
.ant-tree-treenode-selected {
|
||||
color: #154ddd;
|
||||
background: rgba(21, 77, 221, 0.1);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.tree_node_item:hover {
|
||||
// color: #154ddd;
|
||||
// background: rgba(21, 77, 221, 0.1);
|
||||
// border-radius: 8px;
|
||||
.action_list {
|
||||
display: block;
|
||||
.anticon-delete {
|
||||
color: #e80d0d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-26 11:11:05
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-29 16:26:05
|
||||
* @FilePath: \general-ai-manage\src\components\Tree\src\deviceGroupTree.tsx
|
||||
* @Description: 设备节点树
|
||||
* @交互说明
|
||||
* 1、树形展示
|
||||
* 2、可新增、删除
|
||||
* 3、可编辑
|
||||
* 4、可拖拽
|
||||
*/
|
||||
import { PlusCircleOutlined } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
|
||||
import { theme } from 'antd';
|
||||
import { DeviceGroupTreeProps } from '../typing';
|
||||
import BaseTree from './baseTree';
|
||||
const DeviceGroupTree: React.FC<DeviceGroupTreeProps> = (props) => {
|
||||
const { token } = theme.useToken();
|
||||
console.log('token', token);
|
||||
|
||||
// async function loadTree() {
|
||||
// const resp = await getDeviceGroupSettingTree()
|
||||
// setDeviceGroupList(resp.data)
|
||||
// }
|
||||
|
||||
// useEffect(()=>{
|
||||
// loadTree()
|
||||
// },[])
|
||||
|
||||
// const [expandedKeys] = useState(['0-0', '0-0-0', '0-0-0-0']);
|
||||
function handleAdd(node) {
|
||||
// 当前节点的父节点 可以添加数据
|
||||
console.log(node, 'handleAdd_node');
|
||||
props.addTreeNode(node);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="deviceGroup_tree_wrap">
|
||||
<BaseTree
|
||||
treeData={props.dataSource}
|
||||
fieldNames={{ title: 'name', key: 'id', children: 'children' }}
|
||||
addRender={(node) => {
|
||||
return (
|
||||
<div
|
||||
onClick={() => {
|
||||
handleAdd(node);
|
||||
}}
|
||||
style={{ color: token.colorPrimary }}
|
||||
key={node?.key || 'add'}
|
||||
>
|
||||
<PlusCircleOutlined />
|
||||
<span className="pl-[10px]"> {node?.key ? '添加子节点' : '添加节点'} </span>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
handleDelete={(node) => {
|
||||
// 提示删除
|
||||
console.log('handleDelete_node', node);
|
||||
}}
|
||||
selectTree={(selectedKeys, info) => {
|
||||
props.selectTree(selectedKeys, info);
|
||||
}}
|
||||
></BaseTree>
|
||||
{/* 新增节点 修改节点 */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DeviceGroupTree;
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-26 11:09:49
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-29 16:24:05
|
||||
* @FilePath: \general-ai-platform-web\src\components\Tree\typing.ts
|
||||
* @Description: 树的类型文件
|
||||
*/
|
||||
|
||||
// 增删改查基础树
|
||||
export interface BaseTreeProps extends TreeProps {
|
||||
hideInAdd?: boolean; // 是否隐藏新增节点
|
||||
// hideInEdit?: boolean // 是否隐藏编辑节点
|
||||
hideInDelete?: boolean; // 是否隐藏删除节点
|
||||
hideInSearch?: boolean; // 是否隐藏筛选节点
|
||||
addRender?: React.ReactNode; // 新增操作自定义
|
||||
addText?: string | React.ReactNode; // 新增按钮文案自定义
|
||||
deleteRender?: React.ReactNode; // 删除操作自定义
|
||||
deleteText?: string | React.ReactNode; // 删除按钮文案自定义
|
||||
}
|
||||
// 节点树
|
||||
export interface DeviceGroupTreeProps extends BaseTreeProps {
|
||||
addTreeNode?: (arg1: Record<string, any>) => void;
|
||||
selectTree: (arg1: any, arg2: any) => void;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-28 15:30:31
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-28 15:32:43
|
||||
* @FilePath: \general-ai-platform-web\src\enums\device.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
// 告警规则
|
||||
export const deviceGroupEnums: Record<string, any>[] = [
|
||||
{
|
||||
label: '设备列表',
|
||||
key: '1',
|
||||
},
|
||||
{
|
||||
label: '业务模型部署',
|
||||
key: '2',
|
||||
},
|
||||
{
|
||||
label: '告警设置',
|
||||
key: '3',
|
||||
},
|
||||
];
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-23 17:00:00
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-28 17:55:58
|
||||
* @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\components\baseInfo.tsx
|
||||
* @Description: 基本信息展示
|
||||
*
|
||||
*/
|
||||
|
||||
import { ProDescriptions } from '@ant-design/pro-components';
|
||||
import { FormattedMessage } from '@umijs/max';
|
||||
|
||||
type BaseInfoProps = {
|
||||
info: Record<string, any>;
|
||||
};
|
||||
|
||||
const BaseInfo: React.FC<BaseInfoProps> = ({ info }) => {
|
||||
// 设备基本信息
|
||||
const DeviceDetailColumns = [
|
||||
{
|
||||
title: <FormattedMessage id="device_group.tree_node.name" defaultMessage="节点名称" />,
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />,
|
||||
dataIndex: 'fatherName',
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="device_group.tree_node.address" defaultMessage="地址" />,
|
||||
dataIndex: 'address',
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="device_group.tree_node.lonlat" defaultMessage="经纬度" />,
|
||||
dataIndex: 'lonlat',
|
||||
render: (_, record) => {
|
||||
return record?.lon + ',' + record?.lat;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="device_group.tree_node.managerName" defaultMessage="负责人" />,
|
||||
dataIndex: 'managerName',
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage id="device_group.tree_node.managerPhone" defaultMessage="联系方式" />
|
||||
),
|
||||
dataIndex: 'managerPhone',
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="device_group.tree_node.remark" defaultMessage="简介" />,
|
||||
dataIndex: 'remark',
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div className="gn_table_descriptions bg_active_1">
|
||||
<ProDescriptions column={3} columns={DeviceDetailColumns} dataSource={info}></ProDescriptions>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BaseInfo;
|
@ -0,0 +1,175 @@
|
||||
// import { postModelCategoryCreateModelCategory } from '@/services/resource/ModelCategory';
|
||||
import { ModalForm, ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
|
||||
import { FormattedMessage, useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import React from 'react';
|
||||
import {
|
||||
proFormSmallItemStyleProps,
|
||||
proFormSmallModelWidth,
|
||||
} from '../../../../../config/defaultForm';
|
||||
// @ts-ignore
|
||||
|
||||
export type CreateDeviceFormProps = {
|
||||
createModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
reload: any;
|
||||
};
|
||||
const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
// const [isAuto, setIsAuto] = useState(true);
|
||||
const [form] = Form.useForm<API.ModelCategory>();
|
||||
|
||||
return (
|
||||
<ModalForm<API.ModelCategory>
|
||||
className="gn_modal_form gn_form"
|
||||
width={proFormSmallModelWidth}
|
||||
title={intl.formatMessage({
|
||||
id: 'device_group.tree_node.CreateDeviceForm.add',
|
||||
defaultMessage: '新建',
|
||||
})}
|
||||
open={props.createModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => props.handleModal(),
|
||||
}}
|
||||
submitTimeout={2000}
|
||||
onFinish={async (values) => {
|
||||
console.log(values, 'add_finish_values');
|
||||
// TODO 对接新增接口
|
||||
// postModelCategoryCreateModelCategory(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={proFormSmallItemStyleProps.column2Width}
|
||||
name="name"
|
||||
label={<FormattedMessage id="device_group.tree_node.name" defaultMessage="名称" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.name',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
required={true}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="device_group.tree_node.rule.required.name"
|
||||
defaultMessage="名称必填"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="fatherName"
|
||||
label={
|
||||
<FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.fatherName',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
disabled
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="address"
|
||||
label={<FormattedMessage id="device_group.tree_node.address" defaultMessage="地址" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.address',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="lon"
|
||||
label={<FormattedMessage id="device_group.tree_node.lon" defaultMessage="经度" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.lon',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="lat"
|
||||
label={<FormattedMessage id="device_group.tree_node.lat" defaultMessage="纬度" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.lat',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="managerName"
|
||||
label={
|
||||
<FormattedMessage id="device_group.tree_node.managerName" defaultMessage="负责人" />
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.managerName',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="managerPhone"
|
||||
label={
|
||||
<FormattedMessage id="device_group.tree_node.managerPhone" defaultMessage="联系方式" />
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.managerPhone',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
<ProFormTextArea
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="remark"
|
||||
label={<FormattedMessage id="device_group.tree_node.remark" defaultMessage="简介" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.remark',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
</ProForm.Group>
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default CreateDeviceForm;
|
@ -0,0 +1,176 @@
|
||||
// import { postModelCategoryCreateModelCategory } from '@/services/resource/ModelCategory';
|
||||
import { ModalForm, ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
|
||||
import { FormattedMessage, useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import React from 'react';
|
||||
import {
|
||||
proFormSmallItemStyleProps,
|
||||
proFormSmallModelWidth,
|
||||
} from '../../../../../config/defaultForm';
|
||||
// @ts-ignore
|
||||
|
||||
export type CreateFormProps = {
|
||||
createModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
parentInfo?: Record<string, any>;
|
||||
reload: any;
|
||||
};
|
||||
const CreateForm: React.FC<CreateFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
// const [isAuto, setIsAuto] = useState(true);
|
||||
const [form] = Form.useForm<API.ModelCategory>();
|
||||
|
||||
return (
|
||||
<ModalForm<API.ModelCategory>
|
||||
className="gn_modal_form gn_form"
|
||||
width={proFormSmallModelWidth}
|
||||
title={intl.formatMessage({
|
||||
id: 'device_group.tree_node.createForm.add',
|
||||
defaultMessage: '新建',
|
||||
})}
|
||||
open={props.createModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => props.handleModal(),
|
||||
}}
|
||||
submitTimeout={2000}
|
||||
onFinish={async (values) => {
|
||||
console.log(values, 'add_finish_values');
|
||||
// TODO 对接新增接口
|
||||
// postModelCategoryCreateModelCategory(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={proFormSmallItemStyleProps.column2Width}
|
||||
name="name"
|
||||
label={<FormattedMessage id="device_group.tree_node.name" defaultMessage="名称" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.name',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
required={true}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="device_group.tree_node.rule.required.name"
|
||||
defaultMessage="名称必填"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="fatherName"
|
||||
label={
|
||||
<FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.fatherName',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
disabled
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="address"
|
||||
label={<FormattedMessage id="device_group.tree_node.address" defaultMessage="地址" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.address',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="lon"
|
||||
label={<FormattedMessage id="device_group.tree_node.lon" defaultMessage="经度" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.lon',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="lat"
|
||||
label={<FormattedMessage id="device_group.tree_node.lat" defaultMessage="纬度" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.lat',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="managerName"
|
||||
label={
|
||||
<FormattedMessage id="device_group.tree_node.managerName" defaultMessage="负责人" />
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.managerName',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.column2Width}
|
||||
name="managerPhone"
|
||||
label={
|
||||
<FormattedMessage id="device_group.tree_node.managerPhone" defaultMessage="联系方式" />
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.managerPhone',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
<ProFormTextArea
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="remark"
|
||||
label={<FormattedMessage id="device_group.tree_node.remark" defaultMessage="简介" />}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '$$$',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device_group.tree_node.remark',
|
||||
defaultMessage: '$$$',
|
||||
})}`}
|
||||
/>
|
||||
</ProForm.Group>
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default CreateForm;
|
@ -0,0 +1,246 @@
|
||||
import TableActionCard from '@/components/TableActionCard';
|
||||
import { getDeviceListByGroup } from '@/services/testApi/device';
|
||||
import { ProTable } from '@ant-design/pro-components';
|
||||
import { Access, FormattedMessage, history, useAccess } from '@umijs/max';
|
||||
import { Button } from 'antd';
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
import { proTablePaginationOptions } from '../../../../../config/defaultTable';
|
||||
|
||||
import IsDelete from '@/components/TableActionCard/isDelete';
|
||||
import CreateDeviceForm from './createDeviceForm';
|
||||
|
||||
type DeviceListProps = {
|
||||
info: Record<string, any>;
|
||||
};
|
||||
|
||||
const DeviceList: React.FC<DeviceListProps> = () => {
|
||||
const access = useAccess();
|
||||
// const intl = useIntl();
|
||||
const actionRef = useRef<ActionType>();
|
||||
|
||||
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false);
|
||||
// const [categoryFkIdIds, setCategoryFkIdIds] = useState([]);
|
||||
// 动态设置每页数量
|
||||
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
|
||||
|
||||
/**新增 编辑 删除 */
|
||||
// 新增
|
||||
const handleCreateModal = () => {
|
||||
setCreateModalOpen(!createModalOpen);
|
||||
};
|
||||
|
||||
function reloadList() {
|
||||
actionRef.current?.reload();
|
||||
}
|
||||
|
||||
const columns: ProColumns<Record<string, any>>[] = [
|
||||
{
|
||||
title: <FormattedMessage id="device_group_list.table.list.name" defaultMessage="设备名称" />,
|
||||
dataIndex: 'name',
|
||||
hideInSearch: true,
|
||||
// width: 80,
|
||||
// key: 'fixedName',
|
||||
// fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage id="device_group_list.table.list.deviceType" defaultMessage="设备类型" />
|
||||
),
|
||||
dataIndex: 'deviceType',
|
||||
hideInSearch: true,
|
||||
// width: 120,
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage id="device_group_list.table.list.isEnable" defaultMessage="模型部署" />
|
||||
),
|
||||
dataIndex: 'isEnable',
|
||||
hideInSearch: true,
|
||||
// width: 80,
|
||||
render: (dom, record) => {
|
||||
return (
|
||||
<div
|
||||
className={`model_index_type_tag flex items-center justify-center ${
|
||||
record.isEnable ? 'active1' : 'active2'
|
||||
}`}
|
||||
>
|
||||
<span className="dot"></span>
|
||||
<span>
|
||||
{record.isEnable ? (
|
||||
<FormattedMessage
|
||||
id="device_group_list.table.list.deployed.isEnable"
|
||||
defaultMessage="已部署"
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="device_group_list.table.list.undeployed.isEnable"
|
||||
defaultMessage="未部署"
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />,
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
fixed: 'right',
|
||||
key: 'option',
|
||||
render: (_, record) => [
|
||||
<TableActionCard
|
||||
key="TableActionCardRef"
|
||||
renderActions={[
|
||||
// TODO 设为默认交互补充
|
||||
{
|
||||
key: 'setModel',
|
||||
renderDom: (
|
||||
<Button
|
||||
key="setModel"
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
// setCurrentRow(record);
|
||||
// history.push('/home/model-detail');
|
||||
// doToDetail(record);
|
||||
// setShowDetail(true);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="device_group_list.table.list.action.setModel"
|
||||
defaultMessage="基础模型配置"
|
||||
/>
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'updateDetail',
|
||||
renderDom: (
|
||||
<Button
|
||||
key="update"
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
// TODO 编辑在新增联调后实现
|
||||
// setCurrentRow(record);
|
||||
// history.push('/home/model-detail');
|
||||
// doToDetail(record);
|
||||
// setShowDetail(true);
|
||||
// setUpdateModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage id="pages.searchTable.update" defaultMessage="编辑" />
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'destroy',
|
||||
renderDom: (
|
||||
<IsDelete
|
||||
deleteApi={() => {
|
||||
handleDestroy(record).then(() => {});
|
||||
}}
|
||||
></IsDelete>
|
||||
),
|
||||
},
|
||||
]}
|
||||
></TableActionCard>,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="dg_deviceList_wrap">
|
||||
<ProTable
|
||||
className="gn_pro_table"
|
||||
cardProps={{
|
||||
bodyStyle: { padding: 0 },
|
||||
}}
|
||||
// 标题栏
|
||||
toolBarRender={() => [
|
||||
<Access
|
||||
accessible={access.canUpdate(history.location.pathname)}
|
||||
key={`${history.location.pathname}-add`}
|
||||
>
|
||||
<div className="mb-[16px] ">
|
||||
<Button
|
||||
className="mr-[12px]"
|
||||
type="primary"
|
||||
key="add"
|
||||
onClick={() => {
|
||||
setCreateModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="device_group_list.table.list.action.new"
|
||||
defaultMessage="新建"
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
key="modelType"
|
||||
onClick={() => {
|
||||
setCreateModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="device_group_list.table.list.action.modelType"
|
||||
defaultMessage="设备分类"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
</Access>,
|
||||
]}
|
||||
search={false}
|
||||
// scroll={{ y: proTableCommonOptions.commscrollY, x: proTableCommonOptions.commscrollX }}
|
||||
options={{ fullScreen: false, setting: false, density: false, reload: false }}
|
||||
actionRef={actionRef}
|
||||
rowKey="key"
|
||||
onDataSourceChange={(data) => {
|
||||
console.log(data, 'onDataSourceChange_data');
|
||||
// let CategoryFkIdIds: any = data.map((v) => {
|
||||
// return v.categoryFkId;
|
||||
// });
|
||||
// setCategoryFkIdIds(CategoryFkIdIds);
|
||||
}}
|
||||
pagination={{
|
||||
...proTablePaginationOptions,
|
||||
pageSize: currentPageSize,
|
||||
onChange: (page, pageSize) => setCurrentPageSize(pageSize),
|
||||
}}
|
||||
columnsState={{
|
||||
persistenceKey: 'algorithm_model_list',
|
||||
persistenceType: 'localStorage',
|
||||
}}
|
||||
request={async (params = {}) => {
|
||||
const { current, ...rest } = params;
|
||||
const reqParams = {
|
||||
page: current,
|
||||
...rest,
|
||||
};
|
||||
let resp = await getDeviceListByGroup({ ...reqParams });
|
||||
console.log(resp, 'getDeviceListByGroup_resp');
|
||||
return {
|
||||
data: resp.data?.results.map((v: Record<string, any>) => {
|
||||
return { ...v, key: v.id };
|
||||
}),
|
||||
success: resp.success,
|
||||
total: resp.data.count,
|
||||
current: current,
|
||||
pageSize: currentPageSize,
|
||||
};
|
||||
}}
|
||||
columns={columns}
|
||||
/>
|
||||
<CreateDeviceForm
|
||||
createModalOpen={createModalOpen}
|
||||
handleModal={handleCreateModal}
|
||||
reload={reloadList}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DeviceList;
|
@ -0,0 +1,37 @@
|
||||
.deviceGroup_page {
|
||||
height: calc(100vh - 92px);
|
||||
/* 节点列表 */
|
||||
/* 节点信息 */
|
||||
}
|
||||
.deviceGroup_page .dg_content .gn_card {
|
||||
height: calc(100% - 8px);
|
||||
}
|
||||
.deviceGroup_page .node_list > .gn_card {
|
||||
box-shadow: 0px 2px 8px 0px rgba(0, 79, 178, 0.15);
|
||||
}
|
||||
.deviceGroup_page .node_info {
|
||||
padding-left: 0;
|
||||
}
|
||||
.dg_deviceList_wrap .model_index_type_tag {
|
||||
width: 82px;
|
||||
height: 24px;
|
||||
color: #52C41A;
|
||||
background: #E8F7E6;
|
||||
border: 1px solid #BAEEA1;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.dg_deviceList_wrap .model_index_type_tag .dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-right: 4px;
|
||||
background: #52C41A;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.dg_deviceList_wrap .model_index_type_tag.active2 {
|
||||
color: #E80D0D;
|
||||
background: #FEEFEE;
|
||||
border: 1px solid #F9B2AE;
|
||||
}
|
||||
.dg_deviceList_wrap .model_index_type_tag.active2 .dot {
|
||||
background: #E80D0D;
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
.deviceGroup_page {
|
||||
height: calc(100vh - 92px);
|
||||
.dg_content {
|
||||
.gn_card {
|
||||
height: calc(100% - 8px);
|
||||
}
|
||||
}
|
||||
/* 节点列表 */
|
||||
.node_list {
|
||||
& > .gn_card {
|
||||
box-shadow: 0px 2px 8px 0px rgba(0, 79, 178, 0.15);
|
||||
}
|
||||
}
|
||||
/* 节点信息 */
|
||||
.node_info {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dg_deviceList_wrap {
|
||||
.model_index_type_tag {
|
||||
width: 82px;
|
||||
height: 24px;
|
||||
color: #52c41a;
|
||||
background: #e8f7e6;
|
||||
border: 1px solid #baeea1;
|
||||
border-radius: 12px;
|
||||
|
||||
.dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-right: 4px;
|
||||
background: #52c41a;
|
||||
border-radius: 50%;
|
||||
}
|
||||
&.active2 {
|
||||
color: #e80d0d;
|
||||
background: #feefee;
|
||||
border: 1px solid #f9b2ae;
|
||||
.dot {
|
||||
background: #e80d0d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-22 15:23:36
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-22 15:34:36
|
||||
* @FilePath: \general-ai-platform-web\src\pages\Node\NodeSetting\index.tsx
|
||||
* @Description: 节点设置
|
||||
* @交互说明
|
||||
*/
|
||||
const NodeSetting: React.FC = () => {
|
||||
return <div className="nodeSetting_page">节点设置</div>;
|
||||
};
|
||||
|
||||
export default NodeSetting;
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-25 15:39:42
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-28 17:14:06
|
||||
* @FilePath: \general-ai-platform-web\src\services\testApi\device.ts
|
||||
* @Description: 设备api
|
||||
*/
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
/** 节点下设备分页列表 */
|
||||
export async function getDeviceListByGroup(
|
||||
body: Record<string, any>, //
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<API.Response & { data?: API.PageResult; msg?: string }>(
|
||||
`/api/device/listByGroup`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
params: {
|
||||
...body,
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
export const formatTreeValByKey = (
|
||||
key: string,
|
||||
node: Record<string, any>,
|
||||
fieldNames?: string,
|
||||
): any => {
|
||||
if (fieldNames && Object.keys(fieldNames).includes(key)) {
|
||||
return node[fieldNames[key]];
|
||||
}
|
||||
if (Object.keys(node).includes(key)) {
|
||||
return node[key];
|
||||
}
|
||||
return null;
|
||||
};
|
Loading…
Reference in New Issue