feat: 节点设备树、节点设备模块的联调完成

develop2
donghao 12 months ago
parent c825f53982
commit cd816525b7

@ -2,22 +2,25 @@
* @Author: zhoux zhouxia@supervision.ltd * @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-12-27 10:30:10 * @Date: 2023-12-27 10:30:10
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-17 13:19:01 * @LastEditTime: 2024-05-28 16:34:50
* @FilePath: \general-ai-platform-web\src\components\TableActionCard\isConfirmModal.tsx * @FilePath: \general-ai-platform-web\src\components\TableActionCard\isConfirmModal.tsx
* @Description: * @Description:
*/ */
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import modal from 'antd/es/modal'; import modal from 'antd/es/modal';
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
import './isConfirmModal.less'; import './isConfirmModal.less';
import { ReactComponent as QuestionIcon } from '/public/icons/questionIcon.svg'; import { ReactComponent as QuestionIcon } from '/public/icons/questionIcon.svg';
type IsConfirmModalProps = { type IsConfirmModalProps = {
modalProps: ModalType; modalProps: ModalType;
confirmButton: string | React.ReactNode; confirmButton: string | React.ReactNode;
}; };
const IsConfirmModal: React.FC<IsConfirmModalProps> = (props) => { const IsConfirmModal: React.FC<IsConfirmModalProps> = forwardRef((props, ref) => {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
const intl = useIntl(); const intl = useIntl();
const confirmRef = useRef(null);
const confirm = () => { const confirm = () => {
modal.confirm({ modal.confirm({
width: 560, width: 560,
@ -37,8 +40,13 @@ const IsConfirmModal: React.FC<IsConfirmModalProps> = (props) => {
}); });
}; };
// 使用 useImperativeHandle 来定义父组件可以调用的方法
useImperativeHandle(ref, () => ({
confirm,
}));
return ( return (
<div className="isConfirmModal_wrap"> <div className="isConfirmModal_wrap" ref={confirmRef}>
<span <span
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
@ -49,6 +57,6 @@ const IsConfirmModal: React.FC<IsConfirmModalProps> = (props) => {
</span> </span>
</div> </div>
); );
}; });
export default IsConfirmModal; export default IsConfirmModal;

@ -22,7 +22,7 @@
.base_tree_wrap .ant-tree .ant-tree-switcher .ant-tree-switcher-icon { .base_tree_wrap .ant-tree .ant-tree-switcher .ant-tree-switcher-icon {
font-size: 12px; font-size: 12px;
} }
.base_tree_wrap .tree_node_1 { .base_tree_wrap .tree_node_0 {
width: 100%; width: 100%;
margin: 12px 0; margin: 12px 0;
padding: 8px 17px; padding: 8px 17px;
@ -30,16 +30,16 @@
border-radius: 4px; border-radius: 4px;
cursor: pointer; cursor: pointer;
} }
.base_tree_wrap .tree_node_1 .ant-tree-switcher-noop { .base_tree_wrap .tree_node_0 .ant-tree-switcher-noop {
opacity: 0; opacity: 0;
} }
.base_tree_wrap .tree_node_item .action_list { .base_tree_wrap .tree_node_item .action_list {
display: none; display: none;
} }
.base_tree_wrap .tree_node_1:hover, .base_tree_wrap .tree_node_0:hover,
.base_tree_wrap .ant-tree-treenode-selected { .base_tree_wrap .ant-tree-treenode-selected {
font-weight: bold;
color: #154ddd; color: #154ddd;
font-weight: bold;
background: rgba(21, 77, 221, 0.1); background: rgba(21, 77, 221, 0.1);
border-radius: 8px; border-radius: 8px;
} }

@ -20,7 +20,7 @@
font-size: 12px; font-size: 12px;
} }
.tree_node_1 { .tree_node_0 {
width: 100%; width: 100%;
margin: 12px 0; margin: 12px 0;
padding: 8px 17px; padding: 8px 17px;
@ -36,7 +36,7 @@
display: none; display: none;
} }
} }
.tree_node_1:hover, .tree_node_0:hover,
.ant-tree-treenode-selected { .ant-tree-treenode-selected {
color: #154ddd; color: #154ddd;
font-weight: bold; font-weight: bold;

@ -1,6 +1,6 @@
import { formatTreeValByKey } from '@/utils/baseTree'; import { formatTreeValByKey } from '@/utils/baseTree';
import { SearchOutlined } from '@ant-design/icons'; import { SearchOutlined } from '@ant-design/icons';
import { Button, Form, Input, Modal, Tree } from 'antd'; import { Button, Tree } from 'antd';
import _debounce from 'lodash/debounce'; import _debounce from 'lodash/debounce';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { BaseTreeProps } from '../typing'; import { BaseTreeProps } from '../typing';
@ -13,16 +13,18 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
/**state */ /**state */
// const { token } = theme.useToken(); // const { token } = theme.useToken();
const { treeData, ...defaultProps } = props; const { treeData, searchChange, ...defaultProps } = props;
const [currSeleted, setCurrSeleted] = useState<any[]>([]);
console.log(treeData, 'treeData', defaultProps); console.log(treeData, 'treeData', defaultProps);
const [currTreeData, setCurrTreeData] = useState([ const [currTreeData, setCurrTreeData] = useState([
// { title: '节点1', key: '1' }, // { title: '节点1', key: '1' },
// { title: '节点2', key: '2', children: [{ title: '子节点1', key: '3' }] }, // { title: '节点2', key: '2', children: [{ title: '子节点1', key: '3' }] },
]); ]);
const [visible, setVisible] = useState(false); // const [visible, setVisible] = useState(false);
const [editNodeKey, setEditNodeKey] = useState(null); // const [editNodeKey, setEditNodeKey] = useState(null);
const [form] = Form.useForm(); // const [form] = Form.useForm();
const action_add_key = ''; const action_add_key = '';
/**工具方法集 */ /**工具方法集 */
@ -37,19 +39,14 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
/**查询树节点 */ /**查询树节点 */
// 定义一个防抖处理函数500ms 后执行 handleChange 函数 // 定义一个防抖处理函数500ms 后执行 handleChange 函数
const debouncedHandleChange = _debounce((value) => { const debouncedHandleChange = _debounce((value) => {
// TODO 查询所有匹配的节点 searchChange(value);
console.log('debouncedHandleChange_value:', value); console.log('debouncedHandleChange_value:', value);
}, 500); }, 1000);
// 搜索节点 // 搜索节点
function handleSearch(val) { function handleSearch(val) {
debouncedHandleChange(val); debouncedHandleChange(val);
} }
const handleAddNode = () => {
// setVisible(true);
// form.resetFields();
};
// const getNodeByKey = (key) => { // const getNodeByKey = (key) => {
// return currTreeData.find((node) => node.key === key); // return currTreeData.find((node) => node.key === key);
// }; // };
@ -84,47 +81,47 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
// }; // };
// 组装节点数据 // 组装节点数据
const handleModalOk = () => { // const handleModalOk = () => {
form.validateFields().then((values) => { // form.validateFields().then((values) => {
const { nodeTitle } = values; // const { nodeTitle } = values;
let newData; // let newData;
if (editNodeKey) { // if (editNodeKey) {
// 编辑节点标题 // // 编辑节点标题
newData = currTreeData.map((node) => { // newData = currTreeData.map((node) => {
if (node.key === editNodeKey) { // if (node.key === editNodeKey) {
return { ...node, title: nodeTitle }; // return { ...node, title: nodeTitle };
} // }
return node; // return node;
}); // });
} else if (editNodeKey === null) { // } else if (editNodeKey === null) {
// 新增根节点 // // 新增根节点
newData = [...currTreeData, { title: nodeTitle, key: Date.now().toString() }]; // newData = [...currTreeData, { title: nodeTitle, key: Date.now().toString() }];
} else { // } else {
// 新增子节点 // // 新增子节点
newData = currTreeData.map((node) => { // newData = currTreeData.map((node) => {
if (node.key === editNodeKey) { // if (node.key === editNodeKey) {
return { // return {
...node, // ...node,
children: [ // children: [
...(node.children || []), // ...(node.children || []),
{ title: nodeTitle, key: Date.now().toString() }, // { title: nodeTitle, key: Date.now().toString() },
], // ],
}; // };
} // }
return node; // return node;
}); // });
} // }
console.log('handleModalOk_newData', newData); // console.log('handleModalOk_newData', newData);
setCurrTreeData(newData); // setCurrTreeData(newData);
setVisible(false); // // setVisible(false);
setEditNodeKey(''); // setEditNodeKey('');
}); // });
}; // };
const handleModalCancel = () => { // const handleModalCancel = () => {
setVisible(false); // // setVisible(false);
setEditNodeKey(''); // setEditNodeKey('');
}; // };
// render 新增节点操作 // render 新增节点操作
const renderAddAction = (node?: Record<string, any>) => { const renderAddAction = (node?: Record<string, any>) => {
@ -132,7 +129,7 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
return props?.addRender ? ( return props?.addRender ? (
props?.addRender(node) props?.addRender(node)
) : ( ) : (
<div onClick={handleAddNode}> <div>
<Button></Button> <Button></Button>
</div> </div>
); );
@ -141,18 +138,24 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
// 定义每个节点内容 递归操作 // 定义每个节点内容 递归操作
const renderTreeNodes = (data) => { const renderTreeNodes = (data) => {
if (Array.isArray(data) && data.length) { if (Array.isArray(data) && data.length) {
return data.map((node, index) => { return data.map((node) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { id, children, ...restData } = node;
console.log('restData', restData);
return ( return (
<TreeNode <TreeNode
{...node} {...node}
title={formatTreeValByNodeKey('title', node)} title={formatTreeValByNodeKey('title', node)}
key={formatTreeValByNodeKey('key', node) + index} key={formatTreeValByNodeKey('key', node)}
className={`tree_node_item tree_node_${node.level}`} className={`tree_node_item tree_node_${!node?.parent ? 0 : 1}`}
> >
{formatTreeValByNodeKey('children', node) && {formatTreeValByNodeKey('children', node) &&
renderTreeNodes(formatTreeValByNodeKey('children', node))} renderTreeNodes(formatTreeValByNodeKey('children', node))}
{/* 此处不可以赋值id、children */}
<TreeNode key={formatTreeValByNodeKey('key', node) + action_add_key}></TreeNode> <TreeNode
{...restData}
key={formatTreeValByNodeKey('key', node) + action_add_key}
></TreeNode>
</TreeNode> </TreeNode>
); );
}); });
@ -163,11 +166,12 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
const renderTreeItem = (node) => { const renderTreeItem = (node) => {
return ( return (
<div className="flex w-full"> <div className="flex w-full">
<span className="w-[140px]">{node.title}</span> <span className="w-[130px]">{node.title}</span>
{!props?.hideInDelete ? ( {!props?.hideInDelete ? (
<span <span
className="action_list" className="action_list"
onClick={() => { onClick={(e) => {
e.stopPropagation();
props.handleDelete(node); props.handleDelete(node);
}} }}
> >
@ -183,6 +187,8 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
useEffect(() => { useEffect(() => {
setCurrTreeData(props.treeData); setCurrTreeData(props.treeData);
// TODO 后续改从业务层获取 默认选项
setCurrSeleted([props?.treeData[0]?.id]);
console.log(props.treeData, 'props_treeData'); console.log(props.treeData, 'props_treeData');
}, [props.treeData]); }, [props.treeData]);
@ -209,8 +215,10 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
)} )}
<div style={{ maxHeight: 'calc(100vh - 210px)', overflowY: 'auto', overflowX: 'hidden' }}> <div style={{ maxHeight: 'calc(100vh - 210px)', overflowY: 'auto', overflowX: 'hidden' }}>
<Tree <Tree
selectedKeys={currSeleted}
defaultExpandAll defaultExpandAll
onSelect={(selectedKeys, info) => { onSelect={(selectedKeys, info) => {
setCurrSeleted(selectedKeys);
console.log('selected', selectedKeys); console.log('selected', selectedKeys);
props.selectTree(selectedKeys, info); props.selectTree(selectedKeys, info);
}} }}
@ -224,12 +232,12 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
> >
{renderTreeNodes(currTreeData)} {renderTreeNodes(currTreeData)}
</Tree> </Tree>
<div className="tree_node_1">{renderAddAction()}</div> <div className="tree_node_0">{renderAddAction()}</div>
</div> </div>
{/* <div onClick={handleAddNode}>添加一级节点</div> */} {/* <div onClick={handleAddNode}>添加一级节点</div> */}
{/* TODO 使用ProForm */} {/* TODO 使用ProForm */}
<Modal {/* <Modal
title={editNodeKey ? '编辑节点' : '新增节点'} title={editNodeKey ? '编辑节点' : '新增节点'}
open={visible} open={visible}
onOk={handleModalOk} onOk={handleModalOk}
@ -244,7 +252,7 @@ const BaseTree: React.FC<BaseTreeProps> = (props) => {
<Input /> <Input />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal> */}
</div> </div>
); );
}; };

@ -2,14 +2,15 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-26 11:11:05 * @Date: 2024-04-26 11:11:05
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-16 13:36:53 * @LastEditTime: 2024-05-29 14:19:24
* @FilePath: \general-ai-manage\src\components\Tree\src\deviceGroupTree.tsx * @FilePath: \general-ai-manage\src\components\Tree\src\deviceGroupTree.tsx
* @Description: * @Description:
* @ * @
* 1 * 1
* 2 * 2
* 3 * 3
* 4 *
*
*/ */
import { PlusCircleOutlined } from '@ant-design/icons'; import { PlusCircleOutlined } from '@ant-design/icons';
import { theme } from 'antd'; import { theme } from 'antd';
@ -33,15 +34,22 @@ const DeviceGroupTree: React.FC<DeviceGroupTreeProps> = (props) => {
props.addTreeNode(node); props.addTreeNode(node);
} }
// function handleDelete(node) {
// // 当前节点的父节点 可以添加数据
// console.log(node, 'handleAdd_node');
// }
return ( return (
<div className="deviceGroup_tree_wrap"> <div className="deviceGroup_tree_wrap">
<BaseTree <BaseTree
searchChange={props.searchChange}
treeData={props.dataSource} treeData={props.dataSource}
fieldNames={{ title: 'name', key: 'id', children: 'children' }} fieldNames={{ title: 'name', key: 'id', children: 'children' }}
addRender={(node) => { addRender={(node) => {
return ( return (
<div <div
onClick={() => { onClick={(e) => {
e.stopPropagation();
handleAdd(node); handleAdd(node);
}} }}
style={{ color: token.colorPrimary }} style={{ color: token.colorPrimary }}
@ -54,6 +62,7 @@ const DeviceGroupTree: React.FC<DeviceGroupTreeProps> = (props) => {
}} }}
handleDelete={(node) => { handleDelete={(node) => {
// 提示删除 // 提示删除
props.deleteTreeNode(node);
console.log('handleDelete_node', node); console.log('handleDelete_node', node);
}} }}
selectTree={(selectedKeys, info) => { selectTree={(selectedKeys, info) => {

@ -2,7 +2,7 @@
* @Author: zhoux zhouxia@supervision.ltd * @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-11-01 13:56:33 * @Date: 2023-11-01 13:56:33
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-10 15:34:33 * @LastEditTime: 2024-05-29 16:06:49
* @FilePath: \general-ai-platform-web\src\locales\zh-CN\device.ts * @FilePath: \general-ai-platform-web\src\locales\zh-CN\device.ts
* @Description: * @Description:
*/ */
@ -18,7 +18,9 @@ export const device_group: { [key: string]: string } = {
'device_group.tree_node.managerName': '负责人', 'device_group.tree_node.managerName': '负责人',
'device_group.tree_node.managerPhone': '联系方式', 'device_group.tree_node.managerPhone': '联系方式',
'device_group.tree_node.remark': '简介', 'device_group.tree_node.remark': '简介',
'device_group.tree_node.createForm.add': '新建节点', 'device_group.tree_node.form.action.add': '新建节点',
'device_group.tree_node.form.action.update': '编辑节点',
// 未启用 // 未启用
'device_group.table.list.id': 'ID', 'device_group.table.list.id': 'ID',
'device_group.table.list.name': '分组名称', 'device_group.table.list.name': '分组名称',
@ -49,6 +51,8 @@ export const device_group_list: { [key: string]: string } = {
'device_group_list.table.list.rule.required.name': '请填写设备名称', 'device_group_list.table.list.rule.required.name': '请填写设备名称',
'device_group_list.table.list.deviceSite': '设备位置', 'device_group_list.table.list.deviceSite': '设备位置',
'device_group_list.table.list.deviceType': '设备分类', 'device_group_list.table.list.deviceType': '设备分类',
'device_group_list.table.list.rule.required.deviceType': '请选择设备分类',
'device_group_list.table.list.deviceModel': '设备型号', 'device_group_list.table.list.deviceModel': '设备型号',
'device_group_list.table.list.deviceParams': '设备参数', 'device_group_list.table.list.deviceParams': '设备参数',
'device_group_list.table.list.remark': '备注', 'device_group_list.table.list.remark': '备注',
@ -58,7 +62,8 @@ export const device_group_list: { [key: string]: string } = {
'device_group_list.table.list.action.setModel': '基础模型配置', 'device_group_list.table.list.action.setModel': '基础模型配置',
'device_group_list.table.list.action.new': '新建设备', 'device_group_list.table.list.action.new': '新建设备',
'device_group_list.table.list.action.deviceType': '设备分类', 'device_group_list.table.list.action.deviceType': '设备分类',
'device_group_list.table.list.add': '新建设备', 'device_group_list.form.action.add': '新建设备',
'device_group_list.form.action.edit': '编辑设备',
'device_group_list.table.list.action.setDeviceType': '新建设备分类', 'device_group_list.table.list.action.setDeviceType': '新建设备分类',
// 未启用 // 未启用
'device_group_list.table.list.code': '设备代码', 'device_group_list.table.list.code': '设备代码',

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-30 10:02:29 * @Date: 2024-04-30 10:02:29
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-24 14:37:22 * @LastEditTime: 2024-05-29 17:04:34
* @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\components\alarmSetForm.tsx * @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\components\alarmSetForm.tsx
* @Description: * @Description:
* @ * @

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-23 17:00:00 * @Date: 2024-04-23 17:00:00
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-04-28 17:55:58 * @LastEditTime: 2024-05-28 16:45:52
* @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\components\baseInfo.tsx * @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\components\baseInfo.tsx
* @Description: * @Description:
* *
@ -24,32 +24,37 @@ const BaseInfo: React.FC<BaseInfoProps> = ({ info }) => {
}, },
{ {
title: <FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />, title: <FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />,
dataIndex: 'fatherName', dataIndex: 'parent_name',
// TODO 需要接口返回上级节点的名称
// render: (_, record) => {
// if(record?.lon && record?.lat){
// return record?.lon + ',' + record?.lat;
// }
// return '-'
// },
}, },
{ {
title: <FormattedMessage id="device_group.tree_node.address" defaultMessage="地址" />, title: <FormattedMessage id="device_group.tree_node.address" defaultMessage="地址" />,
dataIndex: 'address', dataIndex: 'addr',
}, },
{ {
title: <FormattedMessage id="device_group.tree_node.lonlat" defaultMessage="经纬度" />, title: <FormattedMessage id="device_group.tree_node.lonlat" defaultMessage="经纬度" />,
dataIndex: 'lonlat', dataIndex: 'lola',
render: (_, record) => {
return record?.lon + ',' + record?.lat;
},
}, },
{ {
title: <FormattedMessage id="device_group.tree_node.managerName" defaultMessage="负责人" />, title: <FormattedMessage id="device_group.tree_node.managerName" defaultMessage="负责人" />,
dataIndex: 'managerName', dataIndex: 'contact',
}, },
{ {
title: ( title: (
<FormattedMessage id="device_group.tree_node.managerPhone" defaultMessage="联系方式" /> <FormattedMessage id="device_group.tree_node.managerPhone" defaultMessage="联系方式" />
), ),
dataIndex: 'managerPhone', dataIndex: 'phone',
}, },
{ {
title: <FormattedMessage id="device_group.tree_node.remark" defaultMessage="简介" />, title: <FormattedMessage id="device_group.tree_node.remark" defaultMessage="简介" />,
dataIndex: 'remark', dataIndex: 'comment',
}, },
]; ];
return ( return (

@ -1,4 +1,6 @@
import { getDictDeviceType } from '@/services/testApi/dict'; import { apiDeviceClassification } from '@/services/business/device';
import { apiEntityNodesDeviceAdd } from '@/services/business/entity';
import { isSuccessApi } from '@/utils/forApi';
import { import {
ModalForm, ModalForm,
ProForm, ProForm,
@ -7,8 +9,8 @@ import {
ProFormTextArea, ProFormTextArea,
} from '@ant-design/pro-components'; } from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max'; import { FormattedMessage, useIntl } from '@umijs/max';
import { Form } from 'antd'; import { Form, message } from 'antd';
import React from 'react'; import React, { useEffect } from 'react';
import { import {
proFormSmallItemStyleProps, proFormSmallItemStyleProps,
proFormSmallModelWidth, proFormSmallModelWidth,
@ -18,6 +20,8 @@ import {
export type CreateDeviceFormProps = { export type CreateDeviceFormProps = {
createModalOpen: boolean; createModalOpen: boolean;
handleModal: () => void; handleModal: () => void;
commInfo: Record<string, any>;
nodeInfo: Record<string, any>;
reload: any; reload: any;
}; };
const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => { const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => {
@ -25,12 +29,26 @@ const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => {
// const [isAuto, setIsAuto] = useState(true); // const [isAuto, setIsAuto] = useState(true);
const [form] = Form.useForm<API.ModelCategory>(); const [form] = Form.useForm<API.ModelCategory>();
// test 测试数据
useEffect(() => {
if (props.createModalOpen) {
form.setFieldsValue({
name: 'video_2024_000',
addr: '江苏省南京市雨花台区新华汇B4栋',
// classification: null, // 设备分类的suid
device_model: '设备型号2024_001', // 设备型号
param: 'device_2024_05_24', // 设备参数
comment:
'测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注',
});
}
}, [props.createModalOpen]);
return ( return (
<ModalForm<API.ModelCategory> <ModalForm<API.ModelCategory>
className="gn_modal_form gn_form" className="gn_modal_form gn_form"
width={proFormSmallModelWidth} width={proFormSmallModelWidth}
title={intl.formatMessage({ title={intl.formatMessage({
id: 'device_group_list.table.list.add', id: 'device_group_list.form.action.add',
defaultMessage: '新建', defaultMessage: '新建',
})} })}
open={props.createModalOpen} open={props.createModalOpen}
@ -44,15 +62,23 @@ const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => {
onFinish={async (values) => { onFinish={async (values) => {
console.log(values, 'add_finish_values'); console.log(values, 'add_finish_values');
// TODO 对接新增接口 // TODO 对接新增接口
// postModelCategoryCreateModelCategory(values) let resp = await apiEntityNodesDeviceAdd({
// .then(() => { ...values,
// message.success(intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' })); entity_id: props.commInfo.id,
// props.reload(); node_id: props.nodeInfo.id,
// }) });
// .catch(() => { if (isSuccessApi(resp)) {
// message.error(intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' })); message.success(
// }); intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }),
);
props.reload();
props.handleModal(); props.handleModal();
} else {
message.error(
resp?.meta?.message ||
intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }),
);
}
return true; return true;
}} }}
> >
@ -85,7 +111,7 @@ const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => {
/> />
<ProFormText <ProFormText
width={proFormSmallItemStyleProps.column2Width} width={proFormSmallItemStyleProps.column2Width}
name="deviceSite" name="addr"
label={ label={
<FormattedMessage <FormattedMessage
id="device_group_list.table.list.deviceSite" id="device_group_list.table.list.deviceSite"
@ -103,7 +129,7 @@ const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => {
<ProFormSelect <ProFormSelect
width={proFormSmallItemStyleProps.column2Width} width={proFormSmallItemStyleProps.column2Width}
name="deviceType" name="classification"
label={ label={
<FormattedMessage <FormattedMessage
id="device_group_list.table.list.deviceType" id="device_group_list.table.list.deviceType"
@ -120,15 +146,27 @@ const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => {
showSearch showSearch
debounceTime={500} debounceTime={500}
request={async () => { request={async () => {
const { data } = await getDictDeviceType(); const { data } = await apiDeviceClassification();
return data?.data?.map((v: Record<string, any>) => { return data?.data?.map((v: Record<string, any>) => {
return { ...v, label: v.name, value: v.id }; return { ...v, label: v.name, value: v.suid };
}); });
}} }}
required={true}
rules={[
{
required: true,
message: (
<FormattedMessage
id="device_group_list.table.list.rule.required.deviceType"
defaultMessage="必选"
/>
),
},
]}
/> />
<ProFormText <ProFormText
width={proFormSmallItemStyleProps.column2Width} width={proFormSmallItemStyleProps.column2Width}
name="deviceModel" name="device_model"
label={ label={
<FormattedMessage <FormattedMessage
id="device_group_list.table.list.deviceModel" id="device_group_list.table.list.deviceModel"
@ -146,7 +184,7 @@ const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => {
<ProFormText <ProFormText
width={proFormSmallItemStyleProps.width} width={proFormSmallItemStyleProps.width}
name="deviceParams" name="param"
label={ label={
<FormattedMessage <FormattedMessage
id="device_group_list.table.list.deviceParams" id="device_group_list.table.list.deviceParams"
@ -164,7 +202,7 @@ const CreateDeviceForm: React.FC<CreateDeviceFormProps> = (props) => {
<ProFormTextArea <ProFormTextArea
width={proFormSmallItemStyleProps.width} width={proFormSmallItemStyleProps.width}
name="remark" name="comment"
label={ label={
<FormattedMessage id="device_group_list.table.list.remark" defaultMessage="备注" /> <FormattedMessage id="device_group_list.table.list.remark" defaultMessage="备注" />
} }

@ -1,7 +1,9 @@
// import { postModelCategoryCreateModelCategory } from '@/services/resource/ModelCategory'; import { apiEntityNodesAdd } from '@/services/business/entity';
import { isSuccessApi } from '@/utils/forApi';
import { ModalForm, ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components'; import { ModalForm, ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max'; import { FormattedMessage, useIntl } from '@umijs/max';
import { Form } from 'antd'; import { Form, message } from 'antd';
import React from 'react'; import React from 'react';
import { import {
proFormSmallItemStyleProps, proFormSmallItemStyleProps,
@ -13,6 +15,7 @@ export type CreateFormProps = {
createModalOpen: boolean; createModalOpen: boolean;
handleModal: () => void; handleModal: () => void;
parentInfo?: Record<string, any>; parentInfo?: Record<string, any>;
commInfo: Record<string, any>;
reload: any; reload: any;
}; };
const CreateForm: React.FC<CreateFormProps> = (props) => { const CreateForm: React.FC<CreateFormProps> = (props) => {
@ -20,12 +23,28 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
// const [isAuto, setIsAuto] = useState(true); // const [isAuto, setIsAuto] = useState(true);
const [form] = Form.useForm<API.ModelCategory>(); const [form] = Form.useForm<API.ModelCategory>();
// test 测试数据
// useEffect(() => {
// if (props.createModalOpen) {
// form.setFieldsValue({
// // parent: '',
// addr: '江苏省南京市雨花台区新华汇B4栋',
// lon: '108.39829462',
// lat: '32.10234761',
// contact: ' 负责人',
// phone: '18716394627',
// comment:
// '测试一下简介测试一下简介测试一下简介测试一下简介测试一下简介测试一下简介测试一下简介测试一下简介测试一下简介测试一下简介测试一下简介测试一下简介',
// });
// }
// }, [props.createModalOpen]);
return ( return (
<ModalForm<API.ModelCategory> <ModalForm<API.ModelCategory>
className="gn_modal_form gn_form" className="gn_modal_form gn_form"
width={proFormSmallModelWidth} width={proFormSmallModelWidth}
title={intl.formatMessage({ title={intl.formatMessage({
id: 'device_group.tree_node.createForm.add', id: 'device_group.tree_node.form.action.add',
defaultMessage: '新建', defaultMessage: '新建',
})} })}
open={props.createModalOpen} open={props.createModalOpen}
@ -37,17 +56,24 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
}} }}
submitTimeout={2000} submitTimeout={2000}
onFinish={async (values) => { onFinish={async (values) => {
console.log(values, 'add_finish_values'); let resp = await apiEntityNodesAdd({
// TODO 对接新增接口 ...values,
// postModelCategoryCreateModelCategory(values) entity_id: props.commInfo.id,
// .then(() => { lola: values.lon + ',' + values.lat,
// message.success(intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' })); parent: props.parentInfo?.id,
// props.reload(); });
// }) if (isSuccessApi(resp)) {
// .catch(() => { message.success(
// message.error(intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' })); intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }),
// }); );
props.reload();
props.handleModal(); props.handleModal();
} else {
message.error(
resp?.meta?.message ||
intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }),
);
}
return true; return true;
}} }}
> >
@ -78,13 +104,13 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
/> />
<ProFormText <ProFormText
width={proFormSmallItemStyleProps.column2Width} width={proFormSmallItemStyleProps.column2Width}
name="fatherName" name="parent_name"
label={ label={
<FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" /> <FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />
} }
// TODO 此处在联调时确定下上级节点数据获取来源 // TODO 此处在联调时确定下上级节点数据获取来源
placeholder={ placeholder={
!props.parentInfo?.fatherId !props.parentInfo?.name
? `${intl.formatMessage({ ? `${intl.formatMessage({
id: 'common.empty', id: 'common.empty',
defaultMessage: '$$$', defaultMessage: '$$$',
@ -97,12 +123,12 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
defaultMessage: '$$$', defaultMessage: '$$$',
})}` })}`
} }
initialValue={props?.parentInfo?.fatherName} initialValue={props?.parentInfo?.name}
disabled disabled
/> />
<ProFormText <ProFormText
width={proFormSmallItemStyleProps.width} width={proFormSmallItemStyleProps.width}
name="address" name="addr"
label={<FormattedMessage id="device_group.tree_node.address" defaultMessage="地址" />} label={<FormattedMessage id="device_group.tree_node.address" defaultMessage="地址" />}
placeholder={`${intl.formatMessage({ placeholder={`${intl.formatMessage({
id: 'common.please_input', id: 'common.please_input',
@ -140,7 +166,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
<ProFormText <ProFormText
width={proFormSmallItemStyleProps.column2Width} width={proFormSmallItemStyleProps.column2Width}
name="managerName" name="contact"
label={ label={
<FormattedMessage id="device_group.tree_node.managerName" defaultMessage="负责人" /> <FormattedMessage id="device_group.tree_node.managerName" defaultMessage="负责人" />
} }
@ -154,7 +180,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
/> />
<ProFormText <ProFormText
width={proFormSmallItemStyleProps.column2Width} width={proFormSmallItemStyleProps.column2Width}
name="managerPhone" name="phone"
label={ label={
<FormattedMessage id="device_group.tree_node.managerPhone" defaultMessage="联系方式" /> <FormattedMessage id="device_group.tree_node.managerPhone" defaultMessage="联系方式" />
} }
@ -168,7 +194,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
/> />
<ProFormTextArea <ProFormTextArea
width={proFormSmallItemStyleProps.width} width={proFormSmallItemStyleProps.width}
name="remark" name="comment"
label={<FormattedMessage id="device_group.tree_node.remark" defaultMessage="简介" />} label={<FormattedMessage id="device_group.tree_node.remark" defaultMessage="简介" />}
placeholder={`${intl.formatMessage({ placeholder={`${intl.formatMessage({
id: 'common.please_input', id: 'common.please_input',

@ -2,45 +2,49 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-22 15:23:36 * @Date: 2024-04-22 15:23:36
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-28 11:45:44 * @LastEditTime: 2024-05-29 16:35:16
* @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\components\deviceList.tsx * @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\components\deviceList.tsx
* @Description: deviceGroupdg * @Description: deviceGroupdg
* @ * @
* 1 * 1
* 2 * 2
* 3 * 3
* 4 *
*
* *
*/ */
import InnerPageBack from '@/components/Back/innerPageBack'; import InnerPageBack from '@/components/Back/innerPageBack';
import { isSuccessApi } from '@/utils/forApi'; import TableActionCard from '@/components/TableActionCard';
import { import {
apiDeviceClassification, apiDeviceClassification,
apiDeviceClassificationAdd, apiDeviceClassificationAdd,
apiDeviceClassificationDelete, apiDeviceClassificationDelete,
} from '@/services/business/device'; } from '@/services/business/device';
import {
import TableActionCard from '@/components/TableActionCard'; apiEntityNodesDeviceDelete,
import { getDeviceListByGroup } from '@/services/testApi/device'; apiEntityNodesDeviceInfo,
apiEntityNodesDeviceList,
} from '@/services/business/entity';
import { isSuccessApi } from '@/utils/forApi';
import { ProTable } from '@ant-design/pro-components'; import { ProTable } from '@ant-design/pro-components';
import { Access, FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; import { Access, FormattedMessage, history, useAccess, useIntl } from '@umijs/max';
import { Button, message } from 'antd'; import { Button, message } from 'antd';
import { useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { proTablePaginationOptions } from '../../../../../config/defaultTable'; import { proTablePaginationOptions } from '../../../../../config/defaultTable';
import CategorizeUpdate from '@/components/CategorizeUpdate'; import CategorizeUpdate from '@/components/CategorizeUpdate';
import IsDelete from '@/components/TableActionCard/isDelete'; import IsDelete from '@/components/TableActionCard/isDelete';
import CreateDeviceForm from './createDeviceForm'; import CreateDeviceForm from './createDeviceForm';
import UpdateDeviceForm from './updateDeviceForm';
import ModelSetting from './modelSetting'; import ModelSetting from './modelSetting';
type DeviceListProps = { type DeviceListProps = {
info: Record<string, any>; commInfo: Record<string, any>;
nodeInfo: Record<string, any>;
}; };
const DeviceList: React.FC<DeviceListProps> = () => { const DeviceList: React.FC<DeviceListProps> = (props) => {
/**state */ /**state */
const access = useAccess(); const access = useAccess();
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
@ -48,6 +52,8 @@ const DeviceList: React.FC<DeviceListProps> = () => {
const actionRef = useRef<ActionType>(); const actionRef = useRef<ActionType>();
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false); const [createModalOpen, setCreateModalOpen] = useState<boolean>(false);
const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false); // 编辑窗口是否打开
const [currentRow, setCurrentRow] = useState<Record<string, any>>({}); const [currentRow, setCurrentRow] = useState<Record<string, any>>({});
// 动态设置每页数量 // 动态设置每页数量
@ -68,11 +74,30 @@ const DeviceList: React.FC<DeviceListProps> = () => {
const handleCreateModal = () => { const handleCreateModal = () => {
setCreateModalOpen(!createModalOpen); setCreateModalOpen(!createModalOpen);
}; };
// 编辑
const handleUpdateModal = () => {
setUpdateModalOpen(!updateModalOpen);
};
// 设备节点信息
async function loadDetail(record) {
const resp = await apiEntityNodesDeviceInfo({ device_id: record?.id });
if (isSuccessApi(resp) && resp?.data) {
setCurrentRow({ ...resp?.data, device_id: record?.id });
}
}
function reloadList() { function reloadList() {
actionRef.current?.reload(); actionRef.current?.reload();
} }
// 筛选查询
useEffect(() => {
if (actionRef && props?.nodeInfo) {
reloadList();
}
}, [actionRef, props.nodeInfo]);
const columns: ProColumns<Record<string, any>>[] = [ const columns: ProColumns<Record<string, any>>[] = [
{ {
title: <FormattedMessage id="device_group_list.table.list.name" defaultMessage="设备名称" />, title: <FormattedMessage id="device_group_list.table.list.name" defaultMessage="设备名称" />,
@ -86,10 +111,11 @@ const DeviceList: React.FC<DeviceListProps> = () => {
title: ( title: (
<FormattedMessage id="device_group_list.table.list.deviceType" defaultMessage="设备类型" /> <FormattedMessage id="device_group_list.table.list.deviceType" defaultMessage="设备类型" />
), ),
dataIndex: 'deviceType', dataIndex: 'classification',
hideInSearch: true, hideInSearch: true,
// width: 120, // width: 120,
}, },
// TODO 待定模型部署使用什么字段
{ {
title: ( title: (
<FormattedMessage id="device_group_list.table.list.isEnable" defaultMessage="模型部署" /> <FormattedMessage id="device_group_list.table.list.isEnable" defaultMessage="模型部署" />
@ -144,9 +170,6 @@ const DeviceList: React.FC<DeviceListProps> = () => {
onClick={() => { onClick={() => {
setCurrentRow(record); setCurrentRow(record);
setIsSettingOpen(true); setIsSettingOpen(true);
// history.push('/home/model-detail');
// doToDetail(record);
// setShowDetail(true);
}} }}
> >
<FormattedMessage <FormattedMessage
@ -164,12 +187,8 @@ const DeviceList: React.FC<DeviceListProps> = () => {
type="link" type="link"
size="small" size="small"
onClick={() => { onClick={() => {
// TODO 编辑在新增联调后实现 loadDetail(record);
// setCurrentRow(record); setUpdateModalOpen(true);
// history.push('/home/model-detail');
// doToDetail(record);
// setShowDetail(true);
// setUpdateModalOpen(true);
}} }}
> >
<FormattedMessage id="pages.searchTable.update" defaultMessage="编辑" /> <FormattedMessage id="pages.searchTable.update" defaultMessage="编辑" />
@ -181,7 +200,16 @@ const DeviceList: React.FC<DeviceListProps> = () => {
renderDom: ( renderDom: (
<IsDelete <IsDelete
deleteApi={() => { deleteApi={() => {
handleDestroy(record).then(() => {}); console.log('删除成功');
apiEntityNodesDeviceDelete({ device_id: record.id }).then(() => {
message.success(
intl.formatMessage({
id: 'common.action.success',
defaultMessage: '$$$',
}),
);
reloadList();
});
}} }}
></IsDelete> ></IsDelete>
), ),
@ -244,10 +272,6 @@ const DeviceList: React.FC<DeviceListProps> = () => {
rowKey="id" rowKey="id"
onDataSourceChange={(data) => { onDataSourceChange={(data) => {
console.log(data, 'onDataSourceChange_data'); console.log(data, 'onDataSourceChange_data');
// let CategoryFkIdIds: any = data.map((v) => {
// return v.categoryFkId;
// });
// setCategoryFkIdIds(CategoryFkIdIds);
}} }}
pagination={{ pagination={{
...proTablePaginationOptions, ...proTablePaginationOptions,
@ -262,9 +286,13 @@ const DeviceList: React.FC<DeviceListProps> = () => {
const { current, ...rest } = params; const { current, ...rest } = params;
const reqParams = { const reqParams = {
pageNo: current, pageNo: current,
node_id: props.nodeInfo.id,
...rest, ...rest,
}; };
let resp = await getDeviceListByGroup({ ...reqParams }); if (!reqParams.node_id) {
return { data: [], success: true };
}
let resp = await apiEntityNodesDeviceList({ ...reqParams });
console.log(resp, 'getDeviceListByGroup_resp'); console.log(resp, 'getDeviceListByGroup_resp');
return { return {
data: resp.data?.data, data: resp.data?.data,
@ -295,6 +323,17 @@ const DeviceList: React.FC<DeviceListProps> = () => {
<CreateDeviceForm <CreateDeviceForm
createModalOpen={createModalOpen} createModalOpen={createModalOpen}
handleModal={handleCreateModal} handleModal={handleCreateModal}
commInfo={props.commInfo}
nodeInfo={props.nodeInfo}
reload={reloadList}
/>
<UpdateDeviceForm
updateModalOpen={updateModalOpen}
handleModal={handleUpdateModal}
values={currentRow}
commInfo={props.commInfo}
nodeInfo={props.nodeInfo}
reload={reloadList} reload={reloadList}
/> />
<CategorizeUpdate <CategorizeUpdate

@ -0,0 +1,216 @@
import { apiDeviceClassification } from '@/services/business/device';
import { apiEntityNodesDeviceEdit } from '@/services/business/entity';
import { isSuccessApi } from '@/utils/forApi';
import {
ModalForm,
ProForm,
ProFormSelect,
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Form, message } from 'antd';
import React from 'react';
import {
proFormSmallItemStyleProps,
proFormSmallModelWidth,
} from '../../../../../config/defaultForm';
// @ts-ignore
export type UpdateDeviceFormProps = {
updateModalOpen: boolean;
handleModal: () => void;
commInfo: Record<string, any>;
nodeInfo: Record<string, any>;
values: Record<string, any>;
reload: any;
};
const UpdateDeviceForm: React.FC<UpdateDeviceFormProps> = (props) => {
const intl = useIntl();
// const [isAuto, setIsAuto] = useState(true);
const [form] = Form.useForm<Record<string, any>>({});
// function resetForm() {
// form.resetFields();
// }
// useEffect(() => {
// // if (props.updateModalOpen && props.values?.id) {
// // } else {
// // resetForm();
// // }
// }, [props.updateModalOpen, props.values]);
return (
<ModalForm<API.ModelCategory>
className="gn_modal_form gn_form"
width={proFormSmallModelWidth}
title={intl.formatMessage({
id: 'device_group_list.form.action.edit',
defaultMessage: '编辑',
})}
open={props.updateModalOpen}
form={form}
autoFocusFirstInput
modalProps={{
destroyOnClose: true,
onCancel: () => props.handleModal(),
}}
submitTimeout={2000}
onFinish={async (values) => {
console.log(values, 'update_finish_values');
let resp = await apiEntityNodesDeviceEdit({
...values,
entity_id: props.commInfo.id,
node_id: props.nodeInfo.id,
});
if (isSuccessApi(resp)) {
message.success(
intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }),
);
props.reload();
props.handleModal();
} else {
message.error(
resp?.meta?.message ||
intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }),
);
}
return true;
}}
>
<ProForm.Group>
<ProFormText
width={proFormSmallItemStyleProps.column2Width}
name="name"
label={
<FormattedMessage id="device_group_list.table.list.name" defaultMessage="设备名称" />
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.name',
defaultMessage: '$$$',
})}`}
required={true}
rules={[
{
required: true,
message: (
<FormattedMessage
id="device_group_list.table.list.rule.required.name"
defaultMessage="名称必填"
/>
),
},
]}
/>
<ProFormText
width={proFormSmallItemStyleProps.column2Width}
name="addr"
label={
<FormattedMessage
id="device_group_list.table.list.deviceSite"
defaultMessage="设备位置"
/>
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.deviceSite',
defaultMessage: '$$$',
})}`}
/>
<ProFormSelect
width={proFormSmallItemStyleProps.column2Width}
name="classification"
label={
<FormattedMessage
id="device_group_list.table.list.deviceType"
defaultMessage="设备分类"
/>
}
placeholder={`${intl.formatMessage({
id: 'common.please_select',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.deviceType',
defaultMessage: '$$$',
})}`}
showSearch
debounceTime={500}
request={async () => {
const { data } = await apiDeviceClassification();
return data?.data?.map((v: Record<string, any>) => {
return { ...v, label: v.name, value: v.suid };
});
}}
required={true}
rules={[
{
required: true,
message: (
<FormattedMessage
id="device_group_list.table.list.rule.required.deviceType"
defaultMessage="必选"
/>
),
},
]}
/>
<ProFormText
width={proFormSmallItemStyleProps.column2Width}
name="device_model"
label={
<FormattedMessage
id="device_group_list.table.list.deviceModel"
defaultMessage="设备型号"
/>
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.deviceModel',
defaultMessage: '$$$',
})}`}
/>
<ProFormText
width={proFormSmallItemStyleProps.width}
name="param"
label={
<FormattedMessage
id="device_group_list.table.list.deviceParams"
defaultMessage="设备参数"
/>
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.deviceParams',
defaultMessage: '$$$',
})}`}
/>
<ProFormTextArea
width={proFormSmallItemStyleProps.width}
name="comment"
label={
<FormattedMessage id="device_group_list.table.list.remark" defaultMessage="备注" />
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.remark',
defaultMessage: '$$$',
})}`}
/>
</ProForm.Group>
</ModalForm>
);
};
export default UpdateDeviceForm;

@ -0,0 +1,233 @@
import { apiDeviceClassification } from '@/services/business/device';
import { apiEntityNodesDeviceEdit } from '@/services/business/entity';
import { isSuccessApi } from '@/utils/forApi';
import {
ModalForm,
ProForm,
ProFormSelect,
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Form, message } from 'antd';
import React, { useEffect } from 'react';
import {
proFormSmallItemStyleProps,
proFormSmallModelWidth,
} from '../../../../../config/defaultForm';
// @ts-ignore
export type UpdateDeviceFormProps = {
updateModalOpen: boolean;
handleModal: () => void;
commInfo: Record<string, any>;
nodeInfo: Record<string, any>;
values: Record<string, any>;
reload: any;
};
const UpdateDeviceForm: React.FC<UpdateDeviceFormProps> = (props) => {
const intl = useIntl();
// const [isAuto, setIsAuto] = useState(true);
const [form] = Form.useForm<API.ModelCategory>();
function resetForm() {
form.resetFields();
}
useEffect(() => {
if (props.updateModalOpen && props.values?.device_id) {
form.setFieldsValue({ ...props.values });
console.log(props.values, 'useEffect_values');
} else {
resetForm();
}
}, [props.updateModalOpen, props.values]);
// test 测试数据
// useEffect(() => {
// if (props.updateModalOpen) {
// form.setFieldsValue({
// name: 'video_2024_000',
// addr: '江苏省南京市雨花台区新华汇B4栋',
// // classification: null, // 设备分类的suid
// device_model: '设备型号2024_001', // 设备型号
// param: 'device_2024_05_24', // 设备参数
// comment:
// '测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注',
// });
// }
// }, [props.updateModalOpen]);
return (
<ModalForm<API.ModelCategory>
className="gn_modal_form gn_form"
width={proFormSmallModelWidth}
title={intl.formatMessage({
id: 'device_group_list.form.action.edit',
defaultMessage: '编辑',
})}
open={props.updateModalOpen}
form={form}
autoFocusFirstInput
modalProps={{
destroyOnClose: true,
onCancel: () => props.handleModal(),
}}
submitTimeout={2000}
onFinish={async (values) => {
console.log(values, 'add_finish_values');
// TODO 对接新增接口
let resp = await apiEntityNodesDeviceEdit({
...values,
device_id: props.values.device_id,
entity_id: props.commInfo.id,
node_id: props.nodeInfo.id,
});
if (isSuccessApi(resp)) {
message.success(
intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }),
);
props.reload();
props.handleModal();
} else {
message.error(
resp?.meta?.message ||
intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }),
);
}
return true;
}}
>
<ProForm.Group>
<ProFormText
width={proFormSmallItemStyleProps.column2Width}
name="name"
label={
<FormattedMessage id="device_group_list.table.list.name" defaultMessage="设备名称" />
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.name',
defaultMessage: '$$$',
})}`}
required={true}
rules={[
{
required: true,
message: (
<FormattedMessage
id="device_group_list.table.list.rule.required.name"
defaultMessage="名称必填"
/>
),
},
]}
/>
<ProFormText
width={proFormSmallItemStyleProps.column2Width}
name="addr"
label={
<FormattedMessage
id="device_group_list.table.list.deviceSite"
defaultMessage="设备位置"
/>
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.deviceSite',
defaultMessage: '$$$',
})}`}
/>
<ProFormSelect
width={proFormSmallItemStyleProps.column2Width}
name="classification"
label={
<FormattedMessage
id="device_group_list.table.list.deviceType"
defaultMessage="设备分类"
/>
}
placeholder={`${intl.formatMessage({
id: 'common.please_select',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.deviceType',
defaultMessage: '$$$',
})}`}
showSearch
debounceTime={500}
request={async () => {
const { data } = await apiDeviceClassification();
return data?.data?.map((v: Record<string, any>) => {
return { ...v, label: v.name, value: v.suid };
});
}}
required={true}
rules={[
{
required: true,
message: (
<FormattedMessage
id="device_group_list.table.list.rule.required.deviceType"
defaultMessage="必选"
/>
),
},
]}
/>
<ProFormText
width={proFormSmallItemStyleProps.column2Width}
name="device_model"
label={
<FormattedMessage
id="device_group_list.table.list.deviceModel"
defaultMessage="设备型号"
/>
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.deviceModel',
defaultMessage: '$$$',
})}`}
/>
<ProFormText
width={proFormSmallItemStyleProps.width}
name="param"
label={
<FormattedMessage
id="device_group_list.table.list.deviceParams"
defaultMessage="设备参数"
/>
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.deviceParams',
defaultMessage: '$$$',
})}`}
/>
<ProFormTextArea
width={proFormSmallItemStyleProps.width}
name="comment"
label={
<FormattedMessage id="device_group_list.table.list.remark" defaultMessage="备注" />
}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group_list.table.list.remark',
defaultMessage: '$$$',
})}`}
/>
</ProForm.Group>
</ModalForm>
);
};
export default UpdateDeviceForm;

@ -0,0 +1,214 @@
import { apiEntityNodesEdit } from '@/services/business/entity';
import { isSuccessApi } from '@/utils/forApi';
import { ModalForm, ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Form, message } from 'antd';
import React, { useEffect } from 'react';
import {
proFormSmallItemStyleProps,
proFormSmallModelWidth,
} from '../../../../../config/defaultForm';
// @ts-ignore
export type UpdateFormProps = {
updateModalOpen: boolean;
handleModal: () => void;
commInfo: Record<string, any>;
values: Record<string, any>;
reload: any;
};
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const intl = useIntl();
// const [isAuto, setIsAuto] = useState(true);
const [form] = Form.useForm<API.ModelCategory>();
function resetForm() {
form.resetFields();
}
useEffect(() => {
if (props.updateModalOpen && props.values?.id) {
const { lola } = props.values;
let lon, lat;
if (lola) {
const lolaArr = lola.split(',');
lon = lolaArr[0];
lat = lolaArr[1];
}
form.setFieldsValue({ ...props.values, lon, lat });
console.log(props.values, 'useEffect_values');
} else {
resetForm();
}
}, [props.updateModalOpen, props.values]);
return (
<ModalForm<API.ModelCategory>
className="gn_modal_form gn_form"
width={proFormSmallModelWidth}
title={intl.formatMessage({
id: 'device_group.tree_node.form.action.update',
defaultMessage: '编辑',
})}
initialValues={props.values}
open={props.updateModalOpen}
form={form}
autoFocusFirstInput
modalProps={{
destroyOnClose: true,
onCancel: () => props.handleModal(),
}}
submitTimeout={2000}
onFinish={async (values) => {
let resp = await apiEntityNodesEdit({
...values,
entity_id: props.commInfo.id,
lola: values.lon + ',' + values.lat,
parent: props.values.parent,
node_id: props.values.node_id,
});
if (isSuccessApi(resp)) {
message.success(
intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }),
);
props.reload();
props.handleModal();
} else {
message.error(
resp?.meta?.message ||
intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }),
);
}
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="parent_name"
label={
<FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />
}
// TODO 此处在联调时确定下上级节点数据获取来源
placeholder={
!props.values?.parent_name
? `${intl.formatMessage({
id: 'common.empty',
defaultMessage: '$$$',
})}`
: `${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'device_group.tree_node.fatherName',
defaultMessage: '$$$',
})}`
}
disabled
/>
<ProFormText
width={proFormSmallItemStyleProps.width}
name="addr"
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="contact"
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="phone"
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="comment"
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 UpdateForm;

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-22 15:23:36 * @Date: 2024-04-22 15:23:36
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-27 13:47:38 * @LastEditTime: 2024-05-29 15:15:23
* @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\index.tsx * @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\index.tsx
* @Description: deviceGroupdg * @Description: deviceGroupdg
* @ * @
@ -12,29 +12,47 @@
* 4 * 4
* 5 * 5
*/ */
import { DeviceGroupTree } from '@/components/Tree'; import { DeviceGroupTree } from '@/components/Tree';
import { deviceGroupEnums } from '@/enums/device'; import { deviceGroupEnums } from '@/enums/device';
import { useBusinessInfo } from '@/hooks/useBusinessInfo';
import { isSuccessApi } from '@/utils/forApi'; import { isSuccessApi } from '@/utils/forApi';
import { getDeviceGroupList } from '@/services/testApi/deviceGroup'; import IsConfirmModal from '@/components/TableActionCard/isConfirmModal';
import {
apiEntityNodes,
apiEntityNodesDelete,
apiEntityNodesInfo,
} from '@/services/business/entity';
import { ProCard } from '@ant-design/pro-components'; import { ProCard } from '@ant-design/pro-components';
import { Button, Tabs } from 'antd'; import { useIntl } from '@umijs/max';
import { useEffect, useState } from 'react'; import { Button, Tabs, message } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import AlarmSetForm from './components/alarmSetForm'; import AlarmSetForm from './components/alarmSetForm';
import BaseInfo from './components/baseInfo'; import BaseInfo from './components/baseInfo';
import CreateForm from './components/createForm'; import CreateForm from './components/createForm';
import DeviceList from './components/deviceList'; import DeviceList from './components/deviceList';
import ModelDeploy from './components/modelDeploy'; import ModelDeploy from './components/modelDeploy';
import UpdateForm from './components/updateForm';
import './index.less'; import './index.less';
const DeviceGroup: React.FC = () => { const DeviceGroup: React.FC = () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const intl = useIntl();
const { getStoreBusinessInfo } = useBusinessInfo();
/**state */ /**state */
// 节点信息 // 节点信息
const [deviceTreeList, setDeviceTreeList] = useState<Record<string, any>[]>([]); const [deviceTreeList, setDeviceTreeList] = useState<Record<string, any>[]>([]);
const [nodeInfo, setNodeInfo] = useState<Record<string, any>>({}); // 当前节点信息 const [nodeInfo, setNodeInfo] = useState<Record<string, any>>({}); // 当前节点信息
const [commInfo] = useState<Record<string, any>>({ ...getStoreBusinessInfo() }); // 通用信息
// const [parentInfo, setParentInfo] = useState<Record<string, any>>({}); // 通用信息
const [currTreeInfo, setCurrTreeInfo] = useState<Record<string, any>>({});
const [actionType, setActionType] = useState<string>('');
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false); // 创建新增窗口是否打开 const [createModalOpen, setCreateModalOpen] = useState<boolean>(false); // 创建新增窗口是否打开
const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false); // 编辑窗口是否打开
const comfirmModalRef = useRef(null);
// 切换模块 // 切换模块
const [tabKey, setTabKey] = useState<string>(deviceGroupEnums[0].key); const [tabKey, setTabKey] = useState<string>(deviceGroupEnums[0].key);
const [tabs] = useState<any>([...deviceGroupEnums]); const [tabs] = useState<any>([...deviceGroupEnums]);
@ -44,14 +62,37 @@ const DeviceGroup: React.FC = () => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define // eslint-disable-next-line @typescript-eslint/no-use-before-define
// initList(key); // initList(key);
}; };
/**节点列表 */ /**节点设置 */
// 设备节点信息
async function loadDeviceDetail(record, isParent = false) {
const resp = await apiEntityNodesInfo({ node_id: record?.id });
if (isSuccessApi(resp) && resp?.data) {
// console.log(resp.data, 'loadDeviceDetail_resp');
if (isParent) {
// setParentInfo(resp?.data);
} else {
setNodeInfo({ ...resp?.data, node_id: record?.id });
}
}
}
// 设备节点树 // 设备节点树
async function loadDeviceTree() { async function loadDeviceTree(otherParams = {}) {
const resp = await getDeviceGroupList({ pageNo: 1, pageSize: 100 }); console.log('loadDeviceTree_commInfo', commInfo);
const resp = await apiEntityNodes({ entity_id: commInfo.id, ...otherParams });
console.log(resp.data, 'loadDeviceTree'); console.log(resp.data, 'loadDeviceTree');
if (isSuccessApi(resp)) { if (isSuccessApi(resp)) {
setDeviceTreeList(resp?.data.data); setDeviceTreeList(resp?.data.data);
setNodeInfo(resp?.data.data[0]); }
if (
isSuccessApi(resp) &&
resp?.data &&
resp?.data?.data &&
Array.isArray(resp?.data.data) &&
resp?.data.data.length
) {
const currNodeInfo = resp?.data.data[0];
loadDeviceDetail(currNodeInfo);
} }
} }
@ -59,6 +100,10 @@ const DeviceGroup: React.FC = () => {
const handleCreateModal = () => { const handleCreateModal = () => {
setCreateModalOpen(!createModalOpen); setCreateModalOpen(!createModalOpen);
}; };
// 编辑
const handleUpdateModal = () => {
setUpdateModalOpen(!updateModalOpen);
};
// 节点信息展示 // 节点信息展示
// 切换 // 切换
@ -68,6 +113,19 @@ const DeviceGroup: React.FC = () => {
loadDeviceTree(); loadDeviceTree();
}, []); }, []);
useEffect(() => {
switch (actionType) {
case 'deleteNode':
if (currTreeInfo) {
comfirmModalRef?.current?.confirm();
}
break;
case 'addNode':
handleCreateModal();
break;
}
}, [currTreeInfo, actionType]);
return ( return (
<div className="flex deviceGroup_page"> <div className="flex deviceGroup_page">
{/* 节点列表 */} {/* 节点列表 */}
@ -76,19 +134,30 @@ const DeviceGroup: React.FC = () => {
<div className="dg_tree_box"> <div className="dg_tree_box">
<DeviceGroupTree <DeviceGroupTree
dataSource={deviceTreeList} dataSource={deviceTreeList}
changeNode={(record) => { searchChange={(record) => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions console.log(record, 'searchChange');
record?.id && setNodeInfo(record); loadDeviceTree({ name: record });
}} }}
addTreeNode={(node) => { addTreeNode={(node) => {
//TODO 判断是根节点还是子节点 调用新增接口 // 判断是根节点还是子节点
console.log('addTreeNode_node', node); console.log(node, 'addTreeNode');
handleCreateModal(); if (node) {
setCurrTreeInfo({ ...node, id: Number(node.key) });
} else {
setCurrTreeInfo({});
}
setActionType('addNode');
}}
deleteTreeNode={(node) => {
// 是否确认删除
setCurrTreeInfo(node);
setActionType('deleteNode');
console.log('deleteTreeNode_node', node, comfirmModalRef);
}} }}
selectTree={(selectedKeys, info) => { selectTree={(selectedKeys, info) => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions if (selectedKeys && Array.isArray(selectedKeys) && selectedKeys.length) {
info?.node && info?.node?.id && setNodeInfo(info?.node); loadDeviceDetail({ id: selectedKeys[0] });
// handleSelectNode(selectedKeys, info) }
console.log('selectTree_selected', selectedKeys, info); console.log('selectTree_selected', selectedKeys, info);
}} }}
></DeviceGroupTree> ></DeviceGroupTree>
@ -105,8 +174,7 @@ const DeviceGroup: React.FC = () => {
<Button <Button
type="primary" type="primary"
onClick={() => { onClick={() => {
//TODO 打开修改节点信息弹窗 handleUpdateModal();
// handleUpdateModal();
}} }}
> >
@ -123,7 +191,7 @@ const DeviceGroup: React.FC = () => {
changeTabMode(key); changeTabMode(key);
}} }}
></Tabs> ></Tabs>
{tabKey === '1' && <DeviceList info={nodeInfo}></DeviceList>} {tabKey === '1' && <DeviceList commInfo={commInfo} nodeInfo={nodeInfo}></DeviceList>}
{tabKey === '2' && <ModelDeploy info={nodeInfo}></ModelDeploy>} {tabKey === '2' && <ModelDeploy info={nodeInfo}></ModelDeploy>}
{tabKey === '3' && ( {tabKey === '3' && (
<AlarmSetForm <AlarmSetForm
@ -151,11 +219,52 @@ const DeviceGroup: React.FC = () => {
<CreateForm <CreateForm
createModalOpen={createModalOpen} createModalOpen={createModalOpen}
handleModal={handleCreateModal} handleModal={handleCreateModal}
parentInfo={nodeInfo} parentInfo={currTreeInfo}
commInfo={commInfo}
reload={() => {
loadDeviceTree();
}}
/>
<UpdateForm
values={nodeInfo}
updateModalOpen={updateModalOpen}
handleModal={handleUpdateModal}
commInfo={commInfo}
reload={() => { reload={() => {
// TODO 调用获取节点列表的接口 loadDeviceTree();
}} }}
/> />
{/* UpdateForm */}
{/* 是否删除节点 */}
<IsConfirmModal
ref={comfirmModalRef}
modalProps={{
content: `确定删除${currTreeInfo.name}及相关信息吗?删除后将无法找回,请谨慎
.`,
onOk: () => {
console.log('删除成功');
apiEntityNodesDelete({ node_id: currTreeInfo.id })
.then(() => {
message.success(
intl.formatMessage({
id: 'common.action.success',
defaultMessage: '$$$',
}),
);
// eslint-disable-next-line @typescript-eslint/no-use-before-define
loadDeviceTree();
})
.catch(() => {
message.error(
intl.formatMessage({
id: 'common.action.failure',
defaultMessage: '$$$',
}),
);
});
},
}}
></IsConfirmModal>
</div> </div>
); );
}; };

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-07 14:02:00 * @Date: 2024-04-07 14:02:00
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-28 11:10:35 * @LastEditTime: 2024-05-28 14:30:32
* @FilePath: \general-ai-manage\src\pages\ModelIndex\ModelIndex.tsx * @FilePath: \general-ai-manage\src\pages\ModelIndex\ModelIndex.tsx
* @Description: * @Description:
* @ * @
@ -45,7 +45,6 @@ const ModelIndex: React.FC = () => {
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false); const [createModalOpen, setCreateModalOpen] = useState<boolean>(false);
// 设置分类 // 设置分类
const [industryOpen, setIndustryOpen] = useState<boolean>(false); const [industryOpen, setIndustryOpen] = useState<boolean>(false);
// const [categoryFkIdIds, setCategoryFkIdIds] = useState([]); // const [categoryFkIdIds, setCategoryFkIdIds] = useState([]);
// 动态设置每页数量 // 动态设置每页数量
const [currentPageSize, setCurrentPageSize] = useState<number>(10); const [currentPageSize, setCurrentPageSize] = useState<number>(10);

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-05-23 13:50:50 * @Date: 2024-05-23 13:50:50
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-28 10:09:31 * @LastEditTime: 2024-05-28 14:16:29
* @FilePath: \general-ai-platform-web\src\services\Business\entity.ts * @FilePath: \general-ai-platform-web\src\services\Business\entity.ts
* @Description: api * @Description: api
*/ */
@ -202,3 +202,84 @@ export async function apiEntityNodesInfo(body: any, options?: { [key: string]: a
}, },
); );
} }
/** 节点企业设备 */
// 添加企业设备
export async function apiEntityNodesDeviceAdd(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.ENTITY_INDEX_DATA; msg?: string }>(
`/api/v1/enterprise/entity/nodes/device/add`,
{
method: 'POST',
headers: {
// 'Content-Type': 'application/json',
// "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
data: body,
...(options || {}),
},
);
}
// 修改企业设备
export async function apiEntityNodesDeviceEdit(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.ENTITY_INDEX_DATA; msg?: string }>(
`/api/v1/enterprise/entity/nodes/device/edit`,
{
method: 'POST',
headers: {
// 'Content-Type': 'application/json',
// "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
data: body,
...(options || {}),
},
);
}
// 企业设备信息
export async function apiEntityNodesDeviceInfo(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.ENTITY_INDEX_DATA; msg?: string }>(
`/api/v1/enterprise/entity/nodes/device/info`,
{
method: 'POST',
headers: {
// 'Content-Type': 'application/json',
// "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
data: body,
...(options || {}),
},
);
}
// 删除企业设备
export async function apiEntityNodesDeviceDelete(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.ENTITY_INDEX_DATA; msg?: string }>(
`/api/v1/enterprise/entity/nodes/device/delete`,
{
method: 'POST',
headers: {
// 'Content-Type': 'application/json',
// "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
data: body,
...(options || {}),
},
);
}
// 企业设备列表
export async function apiEntityNodesDeviceList(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.ENTITY_INDEX_DATA; msg?: string }>(
`/api/v1/enterprise/entity/nodes/device/list`,
{
method: 'POST',
headers: {
// 'Content-Type': 'application/json',
// "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
data: body,
...(options || {}),
},
);
}

Loading…
Cancel
Save