diff --git a/config/routes.ts b/config/routes.ts
index dc5c569..504786e 100644
--- a/config/routes.ts
+++ b/config/routes.ts
@@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-27 14:56:27
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-22 16:50:40
+ * @LastEditTime: 2024-04-26 09:33:39
* @FilePath: \general-ai-manage\config\routes.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@@ -103,9 +103,9 @@ export const innerMenuRoutes = [
menuIcon: 'TestIcon',
},
{
- name: 'business-node-setting',
- path: '/business/nodeSetting',
- component: './Business/NodeSetting',
+ name: 'business-device-group',
+ path: '/business/deviceGroup',
+ component: './Business/DeviceGroup',
access: 'canReadMenu',
key: '1002',
menuIcon: '',
diff --git a/mock/device.ts b/mock/device.ts
new file mode 100644
index 0000000..423c51c
--- /dev/null
+++ b/mock/device.ts
@@ -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);
+ // },
+};
diff --git a/mock/deviceGroup.ts b/mock/deviceGroup.ts
index d1eaf50..0da5dbb 100644
--- a/mock/deviceGroup.ts
+++ b/mock/deviceGroup.ts
@@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-25 16:53:15
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-25 15:50:16
+ * @LastEditTime: 2024-04-26 16:35:54
* @FilePath: \general-ai-platform-web\mock\deviceGroup.ts
* @Description: 节点设备设置 mock
*/
@@ -12,6 +12,7 @@ import {
mockGetDeviceGroupData3,
mockGetDeviceGroupFkSelectData,
mockGetDeviceGroupListData,
+ mockGetDeviceGroupSettingData,
mockGetDeviceGroupTreeData,
} from './pools/deviceGroupData';
import { successMockApiProps } from './typing';
@@ -29,6 +30,15 @@ export default {
res.json(resData);
},
+ // 设备组网点树列表
+ 'GET /api/device_group/setting_data': async (req: Request, res: Response) => {
+ const resData: successMockApiProps = {
+ ...fetchMockSuccessFullByOther(mockGetDeviceGroupSettingData),
+ };
+ res.json(resData);
+ },
+
+ /** 未启用 */
// 设备组网点选项列表
'GET /api/device_group/getDeviceGroupFkSelect': async (req: Request, res: Response) => {
const resData: successMockApiProps = {
@@ -43,6 +53,7 @@ export default {
};
res.json(resData);
},
+
// 设备组详情
'GET /api/device_group/getDeviceGroupById': async (req: Request, res: Response) => {
const { id } = req.query;
diff --git a/mock/dict.ts b/mock/dict.ts
index 66323f5..10ad869 100644
--- a/mock/dict.ts
+++ b/mock/dict.ts
@@ -2,21 +2,28 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-17 14:01:39
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-17 14:01:47
+ * @LastEditTime: 2024-04-28 14:08:45
* @FilePath: \general-ai-manage\mock\dict.ts
* @Description: 字典表mock数据处理
*/
-import { mockGetIndustryDictData } from './pools/dictData';
+import { mockGetDeviceTypeDictData, mockGetIndustryDictData } from './pools/dictData';
import { successMockApiProps } from './typing';
import { fetchMockSuccessFullByOther } from './utils/apiMock';
export default {
- // 实时分析告警列表分页
- 'GET /api/dict/industry/': async (req: Request, res: Response) => {
+ // 行业分类
+ 'GET /api/dict/industry': async (req: Request, res: Response) => {
const resData: successMockApiProps = {
...fetchMockSuccessFullByOther(mockGetIndustryDictData),
};
res.json(resData);
},
+ // 设备分类
+ 'GET /api/dict/deviceType': async (req: Request, res: Response) => {
+ const resData: successMockApiProps = {
+ ...fetchMockSuccessFullByOther(mockGetDeviceTypeDictData),
+ };
+ res.json(resData);
+ },
};
diff --git a/mock/pools/deviceData.ts b/mock/pools/deviceData.ts
new file mode 100644
index 0000000..e64e2c9
--- /dev/null
+++ b/mock/pools/deviceData.ts
@@ -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,
+ },
+};
diff --git a/mock/pools/deviceGroupData.ts b/mock/pools/deviceGroupData.ts
index b815405..6146b05 100644
--- a/mock/pools/deviceGroupData.ts
+++ b/mock/pools/deviceGroupData.ts
@@ -1,40 +1,257 @@
+/*
+ * @Author: donghao donghao@supervision.ltd
+ * @Date: 2024-04-25 15:45:31
+ * @LastEditors: donghao donghao@supervision.ltd
+ * @LastEditTime: 2024-04-29 14:44:39
+ * @FilePath: \general-ai-platform-web\mock\pools\deviceGroupData.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-25 16:32:31
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-25 15:51:57
+ * @LastEditTime: 2024-04-28 13:21:47
* @FilePath: \general-ai-platform-web\mock\pools\deviceGroupData.ts
* @Description: 节点设备设置
*/
-// 设备组节点选项列表
-export const mockGetDeviceGroupFkSelectData = {
- data: {
- list: [
- {
- name: '南京节点',
- id: 1,
- },
- {
- name: '秦淮节点',
- id: 2,
- },
- {
- name: '江宁节点',
- id: 3,
- },
- {
- name: '安徽节点',
- id: 4,
- },
- {
- name: '合肥节点',
- id: 5,
- },
- ],
- },
-};
// 设备组节点树
+export const mockGetDeviceGroupSettingData = {
+ data: [
+ {
+ name: '安徽省',
+ id: '340000',
+ groupList: [
+ {
+ name: '合肥市',
+ id: '340100',
+ groupList: [
+ { name: '瑶海区', id: '340102', groupList: [] },
+ { name: '庐阳区', id: '340103', groupList: [] },
+ { name: '蜀山区', id: '340104', groupList: [] },
+ { name: '包河区', id: '340111', groupList: [] },
+ { name: '长丰县', id: '340121', groupList: [] },
+ { name: '肥东县', id: '340122', groupList: [] },
+ { name: '肥西县', id: '340123', groupList: [] },
+ { name: '庐江县', id: '340124', groupList: [] },
+ { name: '巢湖市', id: '340181', groupList: [] },
+ ],
+ },
+ {
+ name: '芜湖市',
+ id: '340200',
+ groupList: [
+ { name: '镜湖区', id: '340202', groupList: [] },
+ { name: '弋江区', id: '340203', groupList: [] },
+ { name: '鸠江区', id: '340207', groupList: [] },
+ { name: '三山区', id: '340208', groupList: [] },
+ { name: '芜湖县', id: '340221', groupList: [] },
+ { name: '繁昌县', id: '340222', groupList: [] },
+ { name: '南陵县', id: '340223', groupList: [] },
+ { name: '无为县', id: '340225', groupList: [] },
+ ],
+ },
+ {
+ name: '蚌埠市',
+ id: '340300',
+ groupList: [
+ { name: '龙子湖区', id: '340302', groupList: [] },
+ { name: '蚌山区', id: '340303', groupList: [] },
+ { name: '禹会区', id: '340304', groupList: [] },
+ { name: '淮上区', id: '340311', groupList: [] },
+ { name: '怀远县', id: '340321', groupList: [] },
+ { name: '五河县', id: '340322', groupList: [] },
+ { name: '固镇县', id: '340323', groupList: [] },
+ ],
+ },
+ {
+ name: '淮南市',
+ id: '340400',
+ groupList: [
+ { name: '大通区', id: '340402', groupList: [] },
+ { name: '田家庵区', id: '340403', groupList: [] },
+ { name: '谢家集区', id: '340404', groupList: [] },
+ { name: '八公山区', id: '340405', groupList: [] },
+ { name: '潘集区', id: '340406', groupList: [] },
+ { name: '凤台县', id: '340421', groupList: [] },
+ { name: '寿县', id: '340422', groupList: [] },
+ ],
+ },
+ {
+ name: '马鞍山市',
+ id: '340500',
+ groupList: [
+ { name: '花山区', id: '340503', groupList: [] },
+ { name: '雨山区', id: '340504', groupList: [] },
+ { name: '博望区', id: '340506', groupList: [] },
+ { name: '当涂县', id: '340521', groupList: [] },
+ { name: '含山县', id: '340522', groupList: [] },
+ { name: '和县', id: '340523', groupList: [] },
+ ],
+ },
+ {
+ name: '淮北市',
+ id: '340600',
+ groupList: [
+ { name: '杜集区', id: '340602', groupList: [] },
+ { name: '相山区', id: '340603', groupList: [] },
+ { name: '烈山区', id: '340604', groupList: [] },
+ { name: '濉溪县', id: '340621', groupList: [] },
+ ],
+ },
+ {
+ name: '铜陵市',
+ id: '340700',
+ groupList: [
+ { name: '铜官区', id: '340705', groupList: [] },
+ { name: '义安区', id: '340706', groupList: [] },
+ { name: '郊区', id: '340711', groupList: [] },
+ { name: '枞阳县', id: '340722', groupList: [] },
+ ],
+ },
+ {
+ name: '安庆市',
+ id: '340800',
+ groupList: [
+ { name: '迎江区', id: '340802', groupList: [] },
+ { name: '大观区', id: '340803', groupList: [] },
+ { name: '宜秀区', id: '340811', groupList: [] },
+ { name: '怀宁县', id: '340822', groupList: [] },
+ { name: '潜山市', id: '340882', groupList: [] },
+ { name: '太湖县', id: '340825', groupList: [] },
+ { name: '宿松县', id: '340826', groupList: [] },
+ { name: '望江县', id: '340827', groupList: [] },
+ { name: '岳西县', id: '340828', groupList: [] },
+ { name: '桐城市', id: '340881', groupList: [] },
+ ],
+ },
+ {
+ name: '滁州市',
+ id: '341100',
+ groupList: [
+ { name: '琅琊区', id: '341102', groupList: [] },
+ { name: '南谯区', id: '341103', groupList: [] },
+ { name: '来安县', id: '341122', groupList: [] },
+ { name: '全椒县', id: '341124', groupList: [] },
+ { name: '定远县', id: '341125', groupList: [] },
+ { name: '凤阳县', id: '341126', groupList: [] },
+ { name: '天长市', id: '341181', groupList: [] },
+ { name: '明光市', id: '341182', groupList: [] },
+ ],
+ },
+ {
+ name: '阜阳市',
+ id: '341200',
+ groupList: [
+ { name: '颍州区', id: '341202', groupList: [] },
+ { name: '颍东区', id: '341203', groupList: [] },
+ { name: '颍泉区', id: '341204', groupList: [] },
+ { name: '临泉县', id: '341221', groupList: [] },
+ { name: '太和县', id: '341222', groupList: [] },
+ { name: '阜南县', id: '341225', groupList: [] },
+ { name: '颍上县', id: '341226', groupList: [] },
+ { name: '界首市', id: '341282', groupList: [] },
+ ],
+ },
+ {
+ name: '宿州市',
+ id: '341300',
+ groupList: [
+ { name: '埇桥区', id: '341302', groupList: [] },
+ { name: '砀山县', id: '341321', groupList: [] },
+ { name: '萧县', id: '341322', groupList: [] },
+ { name: '灵璧县', id: '341323', groupList: [] },
+ { name: '泗县', id: '341324', groupList: [] },
+ ],
+ },
+ {
+ name: '六安市',
+ id: '341500',
+ groupList: [
+ { name: '金安区', id: '341502', groupList: [] },
+ { name: '裕安区', id: '341503', groupList: [] },
+ { name: '叶集区', id: '341504', groupList: [] },
+ { name: '霍邱县', id: '341522', groupList: [] },
+ { name: '舒城县', id: '341523', groupList: [] },
+ { name: '金寨县', id: '341524', groupList: [] },
+ { name: '霍山县', id: '341525', groupList: [] },
+ ],
+ },
+ {
+ name: '亳州市',
+ id: '341600',
+ groupList: [
+ { name: '谯城区', id: '341602', groupList: [] },
+ { name: '涡阳县', id: '341621', groupList: [] },
+ { name: '蒙城县', id: '341622', groupList: [] },
+ { name: '利辛县', id: '341623', groupList: [] },
+ ],
+ },
+ {
+ name: '池州市',
+ id: '341700',
+ groupList: [
+ { name: '贵池区', id: '341702', groupList: [] },
+ { name: '东至县', id: '341721', groupList: [] },
+ { name: '石台县', id: '341722', groupList: [] },
+ { name: '青阳县', id: '341723', groupList: [] },
+ ],
+ },
+ {
+ name: '宣城市',
+ id: '341800',
+ groupList: [
+ { name: '宣州区', id: '341802', groupList: [] },
+ { name: '郎溪县', id: '341821', groupList: [] },
+ { name: '广德县', id: '341822', groupList: [] },
+ { name: '泾县', id: '341823', groupList: [] },
+ { name: '绩溪县', id: '341824', groupList: [] },
+ { name: '旌德县', id: '341825', groupList: [] },
+ { name: '宁国市', id: '341881', groupList: [] },
+ ],
+ },
+ {
+ name: '黄山市',
+ id: '341000',
+ groupList: [
+ { name: '屯溪区', id: '341002', groupList: [] },
+ { name: '黄山区', id: '341003', groupList: [] },
+ { name: '徽州区', id: '341004', groupList: [] },
+ { name: '歙县', id: '341021', groupList: [] },
+ { name: '休宁县', id: '341022', groupList: [] },
+ { name: '黟县', id: '341023', groupList: [] },
+ { name: '祁门县', id: '341024', groupList: [] },
+ ],
+ },
+ ],
+ },
+
+ {
+ name: '江苏省',
+ id: '320000',
+ groupList: [
+ {
+ name: '南京市',
+ id: '320100',
+ groupList: [
+ { name: '玄武区', id: '320102', groupList: [] },
+ { name: '秦淮区', id: '320104', groupList: [] },
+ { name: '建邺区', id: '320105', groupList: [] },
+ { name: '鼓楼区', id: '320106', groupList: [] },
+ { name: '浦口区', id: '320111', groupList: [] },
+ { name: '栖霞区', id: '320113', groupList: [] },
+ { name: '雨花台区', id: '320114', groupList: [] },
+ { name: '江宁区', id: '320115', groupList: [] },
+ { name: '六合区', id: '320116', groupList: [] },
+ { name: '溧水区', id: '320117', groupList: [] },
+ { name: '高淳区', id: '320118', groupList: [] },
+ ],
+ },
+ ],
+ },
+ ],
+};
+
export const mockGetDeviceGroupTreeData = {
data: {
tree: [
@@ -72,17 +289,34 @@ export const mockGetDeviceGroupTreeData = {
// 设备组列表分页
export const mockGetDeviceGroupListData = {
data: {
- list: [
+ results: [
{
- id: 1,
+ level: 1,
+ id: '0001',
+ createTime: '2023-10-17T10:43:31.254107+08:00',
+ updateTime: '2023-10-17T10:45:25.030034+08:00',
+ name: '上海节点',
+ address: '中国上海市浦东新区申迪北路',
+ fatherName: '无',
+ fatherId: '',
+ lon: 121.667987,
+ lat: 31.144417,
+ managerName: '刘芳',
+ managerPhone: '16526365632',
+ remark: '--',
+ // TODO 完成设备节点列表数据的构建
+ },
+ {
+ level: 1,
+ id: '0002',
createTime: '2023-10-17T10:43:31.254107+08:00',
updateTime: '2023-10-17T10:45:25.030034+08:00',
name: '南京节点',
code: 'DG00002',
- address: '江苏省南京市南京市栖霞区紫东路南京紫东国际创意园',
+ address: '江苏省南京市南京市栖霞区紫东路南京紫东国际创意园', // 地址
telephone: '12345',
- lon: '118.914349',
- lat: '32.086019',
+ lon: '118.914349', // 经度
+ lat: '32.086019', // 纬度
managerName: '张三',
managerPhone: '111111111',
isEnable: true,
@@ -90,7 +324,8 @@ export const mockGetDeviceGroupListData = {
remark: '',
children: [
{
- id: 2,
+ level: 2,
+ id: '20001',
createTime: '2023-10-17T13:37:31.758471+08:00',
updateTime: '2023-10-17T13:39:31.530494+08:00',
name: '秦淮节点',
@@ -105,10 +340,10 @@ export const mockGetDeviceGroupListData = {
parentFkId: 1,
remark: '',
children: null,
- key: '2',
},
{
- id: 3,
+ level: 2,
+ id: '20002',
createTime: '2023-10-17T13:40:28.823372+08:00',
updateTime: '2023-10-17T13:40:28.823372+08:00',
name: '江宁节点',
@@ -123,52 +358,42 @@ export const mockGetDeviceGroupListData = {
parentFkId: 1,
remark: '',
children: null,
- key: '3',
},
],
- key: '1',
+ },
+ ],
+ count: 2,
+ page: 1,
+ pageSize: 10,
+ },
+};
+
+/** 未启用 */
+// 设备组节点选项列表
+export const mockGetDeviceGroupFkSelectData = {
+ data: {
+ list: [
+ {
+ name: '南京节点',
+ id: 1,
+ },
+ {
+ name: '秦淮节点',
+ id: 2,
+ },
+ {
+ name: '江宁节点',
+ id: 3,
},
{
- id: 4,
- createTime: '2023-10-17T15:02:30.725705+08:00',
- updateTime: '2023-10-17T15:02:30.725705+08:00',
name: '安徽节点',
- code: 'DG00005',
- address: '',
- telephone: '',
- lon: '',
- lat: '',
- managerName: '',
- managerPhone: '',
- isEnable: true,
- parentFkId: 0,
- remark: '',
- children: [
- {
- id: 5,
- createTime: '2023-10-17T15:05:13.542992+08:00',
- updateTime: '2023-10-17T15:08:01.071315+08:00',
- name: '合肥节点',
- code: 'DG00006',
- address: '安徽省合肥市包河区马鞍山路130号',
- telephone: '',
- lon: '117.309214',
- lat: '31.862594',
- managerName: '',
- managerPhone: '',
- isEnable: true,
- parentFkId: 4,
- remark: '',
- children: null,
- key: '5',
- },
- ],
- key: '4',
+ id: 4,
+ },
+ {
+ name: '合肥节点',
+ id: 5,
},
],
- total: 0,
- page: 1,
- pageSize: 10,
},
};
@@ -239,3 +464,107 @@ export const mockGetDeviceGroupData3 = {
},
},
};
+
+// 节点信息
+export const mockGetNodeInfo = [
+ {
+ name: '南京中山陵',
+ address: '中国江苏省南京市玄武区明孝陵路1号',
+ fatherName: '南京',
+ fatherId: 'NJ002',
+ lon: 118.835383,
+ lat: 32.036853,
+ managerName: '赵刚',
+ managerPhone: '025-8443 5328',
+ remark: '中山陵是中国江苏省南京市的一处著名纪念建筑,是国父孙中山的陵墓。',
+ },
+ {
+ name: '南京总统府',
+ address: '中国江苏省南京市玄武区长江路292号',
+ fatherName: '南京',
+ fatherId: 'NJ003',
+ lon: 118.796492,
+ lat: 32.054979,
+ managerName: '陈霞',
+ managerPhone: '025-8462 3951',
+ remark:
+ '南京总统府是中国南京市玄武区长江路292号的一座历史建筑,是中华民国时期南京国民政府的办公地点。',
+ },
+ {
+ name: '东方明珠塔',
+ address: '中国上海市浦东新区陆家嘴环路1号',
+ fatherName: '上海',
+ fatherId: 'SH004',
+ lon: 121.506377,
+ lat: 31.239722,
+ managerName: '王静',
+ managerPhone: '021-5879 1888',
+ remark: '东方明珠塔是位于中国上海市浦东陆家嘴金融贸易区的一座电视塔,是上海的标志性建筑之一。',
+ },
+ {
+ name: '南京雨花台',
+ address: '中国江苏省南京市雨花台区雨花路78号',
+ fatherName: '南京',
+ fatherId: 'NJ004',
+ lon: 118.748754,
+ lat: 31.997532,
+ managerName: '张磊',
+ managerPhone: '025-5275 0088',
+ remark: '雨花台是中国江苏省南京市雨花台区的一个丘陵,也是南京市的一个知名旅游景点。',
+ },
+ {
+ name: '上海科技馆',
+ address: '中国上海市浦东新区世纪大道2000号',
+ fatherName: '上海',
+ fatherId: 'SH005',
+ lon: 121.537235,
+ lat: 31.216444,
+ managerName: '周洋',
+ managerPhone: '021-6854 6916',
+ remark: '上海科技馆是位于中国上海市浦东新区的一座科技展示馆,是上海市的科普教育基地之一。',
+ },
+ {
+ name: '南京中华门',
+ address: '中国江苏省南京市秦淮区中华门',
+ fatherName: '南京',
+ fatherId: 'NJ005',
+ lon: 118.790325,
+ lat: 32.046384,
+ managerName: '李明',
+ managerPhone: '025-8357 8845',
+ remark: '中华门是中国江苏省南京市秦淮区的一处历史古迹,是南京古城墙的门。',
+ },
+ {
+ name: '上海外滩观景台',
+ address: '中国上海市黄浦区中山东一路20号',
+ fatherName: '上海',
+ fatherId: 'SH006',
+ lon: 121.489562,
+ lat: 31.240737,
+ managerName: '王红',
+ managerPhone: '021-5879 8901',
+ remark: '上海外滩观景台位于上海市黄浦区外滩20号,是游览上海外滩天际线的最佳地点之一。',
+ },
+ {
+ name: '南京中山陵石象路',
+ address: '中国江苏省南京市玄武区石象路',
+ fatherName: '南京',
+ fatherId: 'NJ006',
+ lon: 118.835168,
+ lat: 32.041867,
+ managerName: '刘军',
+ managerPhone: '025-8463 2211',
+ remark: '南京中山陵石象路是中国江苏省南京市玄武区的一条道路,沿路有许多历史建筑和景点。',
+ },
+ {
+ name: '上海豫园',
+ address: '中国上海市黄浦区安仁街137号',
+ fatherName: '上海',
+ fatherId: 'SH007',
+ lon: 121.492783,
+ lat: 31.227565,
+ managerName: '张艳',
+ managerPhone: '021-6328 8888',
+ remark: '上海豫园是位于上海市黄浦区的一座古典式园林,是上海市的主要旅游景点之一。',
+ },
+];
diff --git a/mock/pools/dictData.ts b/mock/pools/dictData.ts
index 233bf66..c350347 100644
--- a/mock/pools/dictData.ts
+++ b/mock/pools/dictData.ts
@@ -2,10 +2,12 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-17 13:58:57
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-17 14:05:50
+ * @LastEditTime: 2024-04-28 14:03:58
* @FilePath: \general-ai-manage\mock\pools\dictData.ts
* @Description: 字典表mock数据
*/
+
+// 行业分类
export const mockGetIndustryDictData = {
data: {
results: [
@@ -186,3 +188,12 @@ export const mockGetIndustryDictData = {
],
},
};
+// 设备分类
+export const mockGetDeviceTypeDictData = {
+ data: {
+ results: [
+ { id: 1002000, name: '摄像头' },
+ { id: 1002002, name: '控制器' },
+ ],
+ },
+};
diff --git a/public/home/business_arrow.svg b/public/home/business_arrow.svg
new file mode 100644
index 0000000..81e46bd
--- /dev/null
+++ b/public/home/business_arrow.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/public/home/business_arrow_default.svg b/public/home/business_arrow_default.svg
new file mode 100644
index 0000000..1be62d1
--- /dev/null
+++ b/public/home/business_arrow_default.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/home/business_big_logo.svg b/public/home/business_big_logo.svg
new file mode 100644
index 0000000..abfc5bc
--- /dev/null
+++ b/public/home/business_big_logo.svg
@@ -0,0 +1,44 @@
+
diff --git a/public/home/menu_footer_bg.png b/public/home/menu_footer_bg.png
new file mode 100644
index 0000000..03d0aa5
Binary files /dev/null and b/public/home/menu_footer_bg.png differ
diff --git a/src/app.css b/src/app.css
index 28c310c..0058e65 100644
--- a/src/app.css
+++ b/src/app.css
@@ -12,6 +12,12 @@
background-color: transparent;
padding-inline: 0 !important;
}
+.app_page_wrap .page_menu .ant-menu {
+ background-image: url(../public/home/menu_footer_bg.png);
+ background-repeat: no-repeat;
+ background-position: left bottom;
+ background-size: cover;
+}
.app_page_wrap .page_body {
width: calc(100vw - 200px);
}
@@ -19,10 +25,10 @@
position: fixed;
top: 0;
right: 0;
+ z-index: 999;
width: calc(100vw - 200px);
min-width: 100px;
height: 50px;
- z-index: 999;
padding: 0 24px 0 20px;
background-color: #f8fafd;
}
diff --git a/src/app.less b/src/app.less
index 9eae460..f1c874d 100644
--- a/src/app.less
+++ b/src/app.less
@@ -12,6 +12,17 @@
background-color: transparent;
padding-inline: 0 !important;
}
+ .page_menu {
+ // menu_footer_bg.png
+
+ .ant-menu {
+ // background-color: red;
+ background-image: url(../public/home/menu_footer_bg.png);
+ background-repeat: no-repeat;
+ background-position: left bottom;
+ background-size: cover;
+ }
+ }
.page_body {
width: calc(100vw - 200px);
.body_nav_bar {
@@ -23,6 +34,7 @@
min-width: 100px;
height: 50px;
padding: 0 24px 0 20px;
+
background-color: #f8fafd;
.avatar_box {
& > img {
diff --git a/src/app.tsx b/src/app.tsx
index fc50d7a..44f72d4 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -145,7 +145,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) =
// if (initialState?.loading) return ;
return (
-
+
setCurrMenu(record)}
diff --git a/src/base.less b/src/base.less
index 6f5334b..9e293ff 100644
--- a/src/base.less
+++ b/src/base.less
@@ -39,6 +39,7 @@
text-align: left;
text-transform: none;
}
+
.head5 {
color: #333333;
font-weight: bold;
@@ -61,6 +62,3 @@
text-align: left;
text-transform: none;
}
-
-body {
-}
diff --git a/src/components/MenuBar/index.css b/src/components/MenuBar/index.css
index b3f42fd..22158f9 100644
--- a/src/components/MenuBar/index.css
+++ b/src/components/MenuBar/index.css
@@ -1,11 +1,11 @@
.menubar_wrap {
position: fixed;
- left: 0;
top: 0;
- height: 100vh;
- display: flex;
+ left: 0;
z-index: 999;
+ display: flex;
width: 200px;
+ height: 100vh;
padding: 0;
background-color: #fff;
border-radius: 0px 0px 32px 0px;
@@ -46,7 +46,6 @@
display: flex;
flex: 1;
width: 100%;
- padding-top: 10px;
}
.menubar_wrap .menu_bottom {
width: 96px;
diff --git a/src/components/MenuBar/index.less b/src/components/MenuBar/index.less
index 5cb0639..7cdd32f 100644
--- a/src/components/MenuBar/index.less
+++ b/src/components/MenuBar/index.less
@@ -52,7 +52,6 @@
display: flex;
flex: 1;
width: 100%;
- padding-top: 10px;
}
.menu_bottom {
width: 96px;
diff --git a/src/components/MenuBar/index.tsx b/src/components/MenuBar/index.tsx
index ded5dd3..8270ed9 100644
--- a/src/components/MenuBar/index.tsx
+++ b/src/components/MenuBar/index.tsx
@@ -2,19 +2,20 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-27 16:03:20
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-23 10:48:58
+ * @LastEditTime: 2024-04-28 09:44:23
* @FilePath: \general-ai-manage\src\components\Header\index.tsx
* @Description: 内层layout菜单配置
*/
import { useBusinessInfo } from '@/hooks/useBusinessInfo';
import { history, useIntl } from '@umijs/max';
+import { ReactComponent as BusinessLogoIcon } from '/public/home/business_logo.svg';
import type { MenuProps } from 'antd';
import { Menu } from 'antd';
import React, { useEffect, useState } from 'react';
-import { ReactComponent as BusinessLogoIcon } from '/public/home/business_logo.svg';
+import { ReactComponent as BusinessBigLogo } from '/public/home/business_big_logo.svg';
// import menuFooter from '/public/menuFooter.svg';
import './index.less';
@@ -104,10 +105,21 @@ const MenuBar: React.FC = ({ menuData, changeMenu }) => {
return (
-
-
-
{getStoreBusinessInfo()?.name}
+
+
{
+ history.replace('/');
+ }}
+ >
+
+
+
+
+ {getStoreBusinessInfo()?.name}
+
+
{/* // TODO 菜单需要补充路由聚焦状态 */}
- {/*
-

-
*/}
);
};
diff --git a/src/components/Tree/index.ts b/src/components/Tree/index.ts
new file mode 100644
index 0000000..53c59fd
--- /dev/null
+++ b/src/components/Tree/index.ts
@@ -0,0 +1,3 @@
+import deviceGroupTree from './src/deviceGroupTree';
+
+export const DeviceGroupTree = deviceGroupTree;
diff --git a/src/components/Tree/src/baseTree.css b/src/components/Tree/src/baseTree.css
new file mode 100644
index 0000000..e309232
--- /dev/null
+++ b/src/components/Tree/src/baseTree.css
@@ -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;
+}
diff --git a/src/components/Tree/src/baseTree.less b/src/components/Tree/src/baseTree.less
new file mode 100644
index 0000000..ddc6b68
--- /dev/null
+++ b/src/components/Tree/src/baseTree.less
@@ -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;
+ }
+ }
+ }
+}
diff --git a/src/components/Tree/src/baseTree.tsx b/src/components/Tree/src/baseTree.tsx
new file mode 100644
index 0000000..7712e38
--- /dev/null
+++ b/src/components/Tree/src/baseTree.tsx
@@ -0,0 +1,247 @@
+import { formatTreeValByKey } from '@/utils/baseTree';
+import { DeleteFilled, SearchOutlined } from '@ant-design/icons';
+import { Button, Form, Input, Modal, Tree } from 'antd';
+import _debounce from 'lodash/debounce';
+import React, { useEffect, useState } from 'react';
+import { BaseTreeProps } from '../typing';
+
+import { ProFormText } from '@ant-design/pro-components';
+import './baseTree.less';
+const { TreeNode } = Tree;
+
+const BaseTree: React.FC
= (props) => {
+ /**state */
+ // const { token } = theme.useToken();
+
+ const { treeData, ...defaultProps } = props;
+ console.log(treeData, 'treeData', defaultProps);
+ const [currTreeData, setCurrTreeData] = useState([
+ // { title: '节点1', key: '1' },
+ // { title: '节点2', key: '2', children: [{ title: '子节点1', key: '3' }] },
+ ]);
+
+ const [visible, setVisible] = useState(false);
+ const [editNodeKey, setEditNodeKey] = useState(null);
+ const [form] = Form.useForm();
+ const action_add_key = '';
+
+ /**工具方法集 */
+ // 柯里化-树的节点数值
+ function formatTreeValByNodeKey(
+ key: 'title' | 'key' | 'children',
+ node: Record,
+ ): any {
+ return formatTreeValByKey(key, node, props.fieldNames);
+ }
+
+ /**查询树节点 */
+ // 定义一个防抖处理函数,500ms 后执行 handleChange 函数
+ const debouncedHandleChange = _debounce((value) => {
+ // TODO 查询所有匹配的节点
+ console.log('debouncedHandleChange_value:', value);
+ }, 500);
+ // 搜索节点
+ function handleSearch(val) {
+ debouncedHandleChange(val);
+ }
+
+ const handleAddNode = () => {
+ // setVisible(true);
+ // form.resetFields();
+ };
+
+ // const getNodeByKey = (key) => {
+ // return currTreeData.find((node) => node.key === key);
+ // };
+
+ // const removeNodeByKey = (data, key) => {
+ // return data.filter((node) => {
+ // if (node.key === key) {
+ // return false;
+ // }
+ // if (node.children) {
+ // node.children = removeNodeByKey(node.children, key);
+ // }
+ // return true;
+ // });
+ // };
+
+ // const handleEditNode = (key) => {
+ // setEditNodeKey(key);
+ // setVisible(true);
+ // form.setFieldsValue({ nodeTitle: getNodeByKey(key).title });
+ // };
+
+ // const handleDeleteNode = (key) => {
+ // const newData = removeNodeByKey(currTreeData, key);
+ // setCurrTreeData(newData);
+ // };
+
+ // const handleAddChildNode = (key) => {
+ // setEditNodeKey(key);
+ // setVisible(true);
+ // form.resetFields();
+ // };
+
+ // 组装节点数据
+ const handleModalOk = () => {
+ form.validateFields().then((values) => {
+ const { nodeTitle } = values;
+ let newData;
+ if (editNodeKey) {
+ // 编辑节点标题
+ newData = currTreeData.map((node) => {
+ if (node.key === editNodeKey) {
+ return { ...node, title: nodeTitle };
+ }
+ return node;
+ });
+ } else if (editNodeKey === null) {
+ // 新增根节点
+ newData = [...currTreeData, { title: nodeTitle, key: Date.now().toString() }];
+ } else {
+ // 新增子节点
+ newData = currTreeData.map((node) => {
+ if (node.key === editNodeKey) {
+ return {
+ ...node,
+ children: [
+ ...(node.children || []),
+ { title: nodeTitle, key: Date.now().toString() },
+ ],
+ };
+ }
+ return node;
+ });
+ }
+ console.log('handleModalOk_newData', newData);
+ setCurrTreeData(newData);
+ setVisible(false);
+ setEditNodeKey('');
+ });
+ };
+
+ const handleModalCancel = () => {
+ setVisible(false);
+ setEditNodeKey('');
+ };
+
+ // render 新增节点操作
+ const renderAddAction = (node?: Record) => {
+ // console.log(node, 'renderAddAction_node');
+ return props?.addRender ? (
+ props?.addRender(node)
+ ) : (
+
+
+
+ );
+ };
+
+ // 定义每个节点内容 递归操作
+ const renderTreeNodes = (data) => {
+ if (Array.isArray(data) && data.length) {
+ return data.map((node) => {
+ return (
+
+ {formatTreeValByNodeKey('children', node) &&
+ renderTreeNodes(formatTreeValByNodeKey('children', node))}
+
+
+
+ );
+ });
+ }
+ return <>>;
+ };
+ // 渲染每个节点内容
+ const renderTreeItem = (node) => {
+ return (
+
+ {node.title}
+ {!props?.hideInDelete ? (
+ {
+ props.handleDelete(node);
+ }}
+ >
+
+
+ ) : (
+ <>>
+ )}
+
+ );
+ };
+
+ useEffect(() => {
+ setCurrTreeData(props.treeData);
+ console.log(props.treeData, 'props_treeData');
+ }, [props.treeData]);
+
+ return (
+
+ {!props?.hideInSearch ? (
+
handleSearch(e.target.value)}
+ key="name"
+ name="name"
+ label=""
+ fieldProps={{
+ style: {
+ margin: 0,
+ },
+ prefix: ,
+ }}
+ />
+ ) : (
+ <>>
+ )}
+ {
+ console.log('selected', selectedKeys);
+ props.selectTree(selectedKeys, info);
+ }}
+ titleRender={(node) => {
+ if (node.title) {
+ return renderTreeItem(node);
+ }
+ return renderAddAction(node);
+ }}
+ {...defaultProps}
+ >
+ {renderTreeNodes(currTreeData)}
+
+ {renderAddAction()}
+ {/* 添加一级节点
*/}
+
+ {/* TODO 使用ProForm */}
+
+
+
+
+
+
+
+ );
+};
+
+export default BaseTree;
diff --git a/src/components/Tree/src/deviceGroupTree.tsx b/src/components/Tree/src/deviceGroupTree.tsx
new file mode 100644
index 0000000..b0568ea
--- /dev/null
+++ b/src/components/Tree/src/deviceGroupTree.tsx
@@ -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 = (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 (
+
+
{
+ return (
+ {
+ handleAdd(node);
+ }}
+ style={{ color: token.colorPrimary }}
+ key={node?.key || 'add'}
+ >
+
+
{node?.key ? '添加子节点' : '添加节点'}
+
+ );
+ }}
+ handleDelete={(node) => {
+ // 提示删除
+ console.log('handleDelete_node', node);
+ }}
+ selectTree={(selectedKeys, info) => {
+ props.selectTree(selectedKeys, info);
+ }}
+ >
+ {/* 新增节点 修改节点 */}
+
+ );
+};
+
+export default DeviceGroupTree;
diff --git a/src/components/Tree/typing.ts b/src/components/Tree/typing.ts
new file mode 100644
index 0000000..96961cc
--- /dev/null
+++ b/src/components/Tree/typing.ts
@@ -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) => void;
+ selectTree: (arg1: any, arg2: any) => void;
+}
diff --git a/src/enums/deviceGroup.ts b/src/enums/deviceGroup.ts
new file mode 100644
index 0000000..9e8f4e6
--- /dev/null
+++ b/src/enums/deviceGroup.ts
@@ -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[] = [
+ {
+ label: '设备列表',
+ key: '1',
+ },
+ {
+ label: '业务模型部署',
+ key: '2',
+ },
+ {
+ label: '告警设置',
+ key: '3',
+ },
+];
diff --git a/src/global.css b/src/global.css
index fe98fc1..1137dec 100644
--- a/src/global.css
+++ b/src/global.css
@@ -88,6 +88,9 @@ ol {
.gn_form .ant-pro-form-group-container {
gap: 0px 12px !important;
}
+.gn_modal_form {
+ margin-top: 16px;
+}
.gn_table_query_filter {
padding: 20px 0;
}
@@ -114,14 +117,12 @@ ol {
margin-right: 0;
}
.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item .ant-steps-item-container {
+ position: relative;
display: flex;
align-items: center;
justify-content: center;
margin: 8px 0;
}
-.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item .ant-steps-item-tail {
- display: none;
-}
.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item .ant-steps-item-icon {
margin: 0 8px;
}
@@ -137,6 +138,21 @@ ol {
color: #666666;
font-size: 12px;
}
+.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item .ant-steps-item-tail {
+ position: absolute;
+ top: auto;
+ left: calc(100% - 30px);
+ width: 16px;
+ height: 16px;
+ margin: 0;
+ padding: 0;
+ background: url('../public/home/business_arrow_default.svg') no-repeat;
+ background-size: cover;
+ border: none;
+}
+.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item .ant-steps-item-tail:after {
+ background: transparent;
+}
.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item-finish {
background: #e5edff;
border: 1px solid #154ddd;
@@ -153,6 +169,10 @@ ol {
.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item-finish .ant-steps-item-description {
color: #154ddd;
}
+.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item-finish .ant-steps-item-tail {
+ background: url('../public/home/business_arrow.svg') no-repeat;
+ background-size: cover;
+}
.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item-active {
background: #e5edff;
border: 1px solid #154ddd;
@@ -163,10 +183,15 @@ ol {
.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item-active .ant-steps-item-description {
color: #154ddd;
}
+.gn_model_steps_form .ant-modal-content .ant-modal-body .ant-steps .ant-steps-item-active .ant-steps-item-tail {
+ background: url('../public/home/business_arrow.svg') no-repeat;
+ background-size: cover;
+}
/* Descriptions */
.gn_table_descriptions {
padding: 16px 16px 0;
background: #ffffff;
+ border: 1px solid rgba(21, 77, 221, 0.1);
border-radius: 8px;
}
/* ProTable ProList */
@@ -188,6 +213,21 @@ ol {
padding: 0;
}
/* 主题样式 */
+.ant-btn-primary,
+.ant-btn-primary:not(:disabled):not(.ant-btn-disabled):hover {
+ background-color: #154ddd;
+}
+.ant-btn-default:not(:disabled):not(.ant-btn-disabled):hover,
+.ant-btn-link {
+ color: #154ddd;
+}
+:where(.css-dev-only-do-not-override-42nv3w).ant-btn-default:not(:disabled):not(
+ .ant-btn-disabled
+ ):hover {
+ color: #154ddd;
+ background: #ffffff;
+ border-color: #154ddd;
+}
/* 单行文本溢出显示省略号 */
.single_line {
overflow: hidden;
diff --git a/src/global.less b/src/global.less
index 37f1a3f..f9b5053 100644
--- a/src/global.less
+++ b/src/global.less
@@ -114,6 +114,9 @@ ol {
gap: 0px 12px !important;
}
}
+.gn_modal_form {
+ margin-top: 16px;
+}
// 筛选表单
.gn_table_query_filter {
@@ -147,14 +150,13 @@ ol {
}
.ant-steps-item-container {
+ position: relative;
display: flex;
align-items: center;
justify-content: center;
margin: 8px 0;
}
- .ant-steps-item-tail {
- display: none;
- }
+
.ant-steps-item-icon {
margin: 0 8px;
}
@@ -170,6 +172,25 @@ ol {
color: #666666;
font-size: 12px;
}
+
+ .ant-steps-item-tail {
+ // display: none;
+ position: absolute;
+ top: auto;
+ left: calc(100% - 30px);
+ width: 16px;
+ height: 16px;
+ margin: 0;
+ padding: 0;
+ // background-color: red;
+ background: url('../public/home/business_arrow_default.svg') no-repeat;
+ background-size: cover;
+ border: none;
+ // right: -10px;
+ &:after {
+ background: transparent;
+ }
+ }
}
// 已完成
@@ -188,6 +209,10 @@ ol {
.ant-steps-item-description {
color: #154ddd;
}
+ .ant-steps-item-tail {
+ background: url('../public/home/business_arrow.svg') no-repeat;
+ background-size: cover;
+ }
}
// 当前选中
.ant-steps-item-active {
@@ -199,6 +224,10 @@ ol {
.ant-steps-item-description {
color: #154ddd;
}
+ .ant-steps-item-tail {
+ background: url('../public/home/business_arrow.svg') no-repeat;
+ background-size: cover;
+ }
}
}
}
@@ -208,6 +237,7 @@ ol {
.gn_table_descriptions {
padding: 16px 16px 0;
background: #ffffff;
+ border: 1px solid rgba(21, 77, 221, 0.1);
border-radius: 8px;
}
@@ -235,21 +265,21 @@ ol {
}
/* 主题样式 */
-// .ant-btn-primary,
-// .ant-btn-primary:not(:disabled):not(.ant-btn-disabled):hover {
-// background-color: @theme_color;
-// }
-// .ant-btn-default:not(:disabled):not(.ant-btn-disabled):hover,
-// .ant-btn-link {
-// color: @theme_color;
-// }
-// :where(.css-dev-only-do-not-override-42nv3w).ant-btn-default:not(:disabled):not(
-// .ant-btn-disabled
-// ):hover {
-// color: @theme_color;
-// background: #ffffff;
-// border-color: @theme_color;
-// }
+.ant-btn-primary,
+.ant-btn-primary:not(:disabled):not(.ant-btn-disabled):hover {
+ background-color: @theme_color;
+}
+.ant-btn-default:not(:disabled):not(.ant-btn-disabled):hover,
+.ant-btn-link {
+ color: @theme_color;
+}
+:where(.css-dev-only-do-not-override-42nv3w).ant-btn-default:not(:disabled):not(
+ .ant-btn-disabled
+ ):hover {
+ color: @theme_color;
+ background: #ffffff;
+ border-color: @theme_color;
+}
/* 单行文本溢出显示省略号 */
.single_line {
diff --git a/src/locales/zh-CN/device.ts b/src/locales/zh-CN/device.ts
index e0a575b..36647e9 100644
--- a/src/locales/zh-CN/device.ts
+++ b/src/locales/zh-CN/device.ts
@@ -1,28 +1,74 @@
/*
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-11-01 13:56:33
- * @LastEditors: zhoux zhouxia@supervision.ltd
- * @LastEditTime: 2023-11-21 14:23:38
+ * @LastEditors: donghao donghao@supervision.ltd
+ * @LastEditTime: 2024-04-29 17:37:55
* @FilePath: \general-ai-platform-web\src\locales\zh-CN\device.ts
- * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ * @Description: 设备相关
*/
-export const device: { [key: string]: string } = {
- 'device.device.table.list.id': 'ID',
- 'device.device.table.list.name': '设备名称',
- 'device.device.table.list.code': '设备代码',
- 'device.device.table.list.position': '位置',
- 'device.device.table.list.param': '设备参数',
- 'device.device.table.list.spec': '设备规格',
- 'device.device.table.list.categoryFkId': '设备类别',
- 'device.device.table.list.groupFkId': '设备分组',
- 'device.device.table.list.isEnable': '是否启用',
- 'device.device.table.list.remark': '备注',
- 'device.device.table.list.createTime': '创建时间',
- 'device.device.table.list.updateTime': '更新时间',
- 'device.device.table.rule.required.name': '设备名称为必填项',
- 'device.device.table.rule.required.code': '设备代码为必填项',
- 'device.device.table.list.add': '新建设备',
- 'device.device.table.list.update': '更新设备',
+// 节点设置
+export const device_group: { [key: string]: string } = {
+ 'device_group.tree_node.name': '节点名称',
+ 'device_group.tree_node.rule.required.name': '请填写节点名称',
+ 'device_group.tree_node.fatherName': '上级节点',
+ 'device_group.tree_node.lon': '经度',
+ 'device_group.tree_node.lat': '纬度',
+ 'device_group.tree_node.address': '地址',
+ 'device_group.tree_node.lonlat': '经纬度',
+ 'device_group.tree_node.managerName': '负责人',
+ 'device_group.tree_node.managerPhone': '联系方式',
+ 'device_group.tree_node.remark': '简介',
+ 'device_group.tree_node.createForm.add': '新建节点',
+ // 未启用
+
+ 'device_group.table.list.id': 'ID',
+ 'device_group.table.list.name': '分组名称',
+ 'device_group.table.list.code': '分组代码',
+ 'device_group.table.list.address': '地址',
+ 'device_group.table.list.telephone': '电话',
+ 'device_group.table.list.lon': '经度',
+ 'device_group.table.list.lat': '纬度',
+ 'device_group.table.list.managerName': '负责人姓名',
+ 'device_group.table.list.managerPhone': '负责人联系方式',
+ 'device_group.table.list.isEnable': '是否启用',
+ 'device_group.table.list.parentFkId': '父节点',
+ 'device_group.table.list.remark': '备注',
+ 'device_group.table.list.createTime': '创建时间',
+ 'device_group.table.list.updateTime': '更新时间',
+ 'device_group.table.rule.required.name': '分组名称为必填项',
+ 'device_group.table.rule.required.code': '分组代码为必填项',
+ 'device_group.table.rule.required.managerName': '负责人姓名为必填项',
+ 'device_group.table.rule.required.managerPhone': '负责人联系方式为必填项',
+ 'device_group.table.rule.required.parentFkId': '父节点为必填项',
+ 'device_group.table.list.add': '新建设备分组',
+ 'device_group.table.list.update': '更新设备分组',
+ 'device_group.table.list.treeAdd': '添加根节点',
+};
+
+export const device_group_list: { [key: string]: string } = {
+ 'device_group_list.table.list.name': '设备名称',
+ 'device_group_list.table.list.deviceType': '设备类型',
+ 'device_group_list.table.list.isEnable': '模型部署',
+ 'device_group_list.table.list.deployed.isEnable': '已部署',
+ 'device_group_list.table.list.undeployed.isEnable': '未部署',
+ 'device_group_list.table.list.action.setModel': '基础模型配置',
+ 'device_group_list.table.list.action.new': '新建设备',
+ 'device_group_list.table.list.action.modelType': '设备分类',
+
+ // 未启用
+ 'device_group_list.table.list.code': '设备代码',
+ 'device_group_list.table.list.position': '位置',
+ 'device_group_list.table.list.param': '设备参数',
+ 'device_group_list.table.list.spec': '设备规格',
+ 'device_group_list.table.list.categoryFkId': '设备类别',
+ 'device_group_list.table.list.groupFkId': '设备分组',
+ 'device_group_list.table.list.remark': '备注',
+ 'device_group_list.table.list.createTime': '创建时间',
+ 'device_group_list.table.list.updateTime': '更新时间',
+ 'device_group_list.table.rule.required.name': '设备名称为必填项',
+ 'device_group_list.table.rule.required.code': '设备代码为必填项',
+ 'device_group_list.table.list.add': '新建设备',
+ 'device_group_list.table.list.update': '更新设备',
};
export const device_category: { [key: string]: string } = {
'device.device_category.table.list.id': 'ID',
@@ -36,30 +82,7 @@ export const device_category: { [key: string]: string } = {
'device.device_category.table.list.add': '新建设备类别',
'device.device_category.table.list.update': '更新设备类别',
};
-export const device_group: { [key: string]: string } = {
- 'device.device_group.table.list.id': 'ID',
- 'device.device_group.table.list.name': '分组名称',
- 'device.device_group.table.list.code': '分组代码',
- 'device.device_group.table.list.address': '地址',
- 'device.device_group.table.list.telephone': '电话',
- 'device.device_group.table.list.lon': '经度',
- 'device.device_group.table.list.lat': '纬度',
- 'device.device_group.table.list.managerName': '负责人姓名',
- 'device.device_group.table.list.managerPhone': '负责人联系方式',
- 'device.device_group.table.list.isEnable': '是否启用',
- 'device.device_group.table.list.parentFkId': '父节点',
- 'device.device_group.table.list.remark': '备注',
- 'device.device_group.table.list.createTime': '创建时间',
- 'device.device_group.table.list.updateTime': '更新时间',
- 'device.device_group.table.rule.required.name': '分组名称为必填项',
- 'device.device_group.table.rule.required.code': '分组代码为必填项',
- 'device.device_group.table.rule.required.managerName': '负责人姓名为必填项',
- 'device.device_group.table.rule.required.managerPhone': '负责人联系方式为必填项',
- 'device.device_group.table.rule.required.parentFkId': '父节点为必填项',
- 'device.device_group.table.list.add': '新建设备分组',
- 'device.device_group.table.list.update': '更新设备分组',
- 'device.device_group.table.list.treeAdd': '添加根节点',
-};
+
export const device_relation: { [key: string]: string } = {
'device.device_relation.table.list.id': 'ID',
'device.device_relation.table.list.deviceParentFkId': '设备父节点',
diff --git a/src/locales/zh-CN/menu.ts b/src/locales/zh-CN/menu.ts
index 253d18f..4d81026 100644
--- a/src/locales/zh-CN/menu.ts
+++ b/src/locales/zh-CN/menu.ts
@@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-01 11:20:09
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-23 10:51:24
+ * @LastEditTime: 2024-04-26 09:36:38
* @FilePath: \uighur-recognition-web2\src\locales\zh-CN\menu.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@@ -64,7 +64,7 @@ export default {
'menu.model-runtime-lib': '模型运行库',
'menu.business-info-index': '企业信息',
- 'menu.business-node-setting': '节点设置',
+ 'menu.business-device-group': '节点设置',
'menu.business-model-index': '业务模型',
// 待废弃
'menu.realTime': '实时分析',
diff --git a/src/pages/Business/DeviceGroup/components/baseInfo.tsx b/src/pages/Business/DeviceGroup/components/baseInfo.tsx
new file mode 100644
index 0000000..e44801c
--- /dev/null
+++ b/src/pages/Business/DeviceGroup/components/baseInfo.tsx
@@ -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;
+};
+
+const BaseInfo: React.FC = ({ info }) => {
+ // 设备基本信息
+ const DeviceDetailColumns = [
+ {
+ title: ,
+ dataIndex: 'name',
+ },
+ {
+ title: ,
+ dataIndex: 'fatherName',
+ },
+ {
+ title: ,
+ dataIndex: 'address',
+ },
+ {
+ title: ,
+ dataIndex: 'lonlat',
+ render: (_, record) => {
+ return record?.lon + ',' + record?.lat;
+ },
+ },
+ {
+ title: ,
+ dataIndex: 'managerName',
+ },
+ {
+ title: (
+
+ ),
+ dataIndex: 'managerPhone',
+ },
+ {
+ title: ,
+ dataIndex: 'remark',
+ },
+ ];
+ return (
+
+ );
+};
+
+export default BaseInfo;
diff --git a/src/pages/Business/DeviceGroup/components/createDeviceForm.tsx b/src/pages/Business/DeviceGroup/components/createDeviceForm.tsx
new file mode 100644
index 0000000..4e8ecad
--- /dev/null
+++ b/src/pages/Business/DeviceGroup/components/createDeviceForm.tsx
@@ -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 = (props) => {
+ const intl = useIntl();
+ // const [isAuto, setIsAuto] = useState(true);
+ const [form] = Form.useForm();
+
+ return (
+
+ 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;
+ }}
+ >
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.name',
+ defaultMessage: '$$$',
+ })}`}
+ required={true}
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ ]}
+ />
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.fatherName',
+ defaultMessage: '$$$',
+ })}`}
+ disabled
+ />
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.address',
+ defaultMessage: '$$$',
+ })}`}
+ />
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.lon',
+ defaultMessage: '$$$',
+ })}`}
+ />
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.lat',
+ defaultMessage: '$$$',
+ })}`}
+ />
+
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.managerName',
+ defaultMessage: '$$$',
+ })}`}
+ />
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.managerPhone',
+ defaultMessage: '$$$',
+ })}`}
+ />
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.remark',
+ defaultMessage: '$$$',
+ })}`}
+ />
+
+
+ );
+};
+export default CreateDeviceForm;
diff --git a/src/pages/Business/DeviceGroup/components/createForm.tsx b/src/pages/Business/DeviceGroup/components/createForm.tsx
new file mode 100644
index 0000000..abaabd3
--- /dev/null
+++ b/src/pages/Business/DeviceGroup/components/createForm.tsx
@@ -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;
+ reload: any;
+};
+const CreateForm: React.FC = (props) => {
+ const intl = useIntl();
+ // const [isAuto, setIsAuto] = useState(true);
+ const [form] = Form.useForm();
+
+ return (
+
+ 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;
+ }}
+ >
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.name',
+ defaultMessage: '$$$',
+ })}`}
+ required={true}
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ ]}
+ />
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.fatherName',
+ defaultMessage: '$$$',
+ })}`}
+ disabled
+ />
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.address',
+ defaultMessage: '$$$',
+ })}`}
+ />
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.lon',
+ defaultMessage: '$$$',
+ })}`}
+ />
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.lat',
+ defaultMessage: '$$$',
+ })}`}
+ />
+
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.managerName',
+ defaultMessage: '$$$',
+ })}`}
+ />
+
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.managerPhone',
+ defaultMessage: '$$$',
+ })}`}
+ />
+ }
+ placeholder={`${intl.formatMessage({
+ id: 'common.please_input',
+ defaultMessage: '$$$',
+ })}${intl.formatMessage({
+ id: 'device_group.tree_node.remark',
+ defaultMessage: '$$$',
+ })}`}
+ />
+
+
+ );
+};
+export default CreateForm;
diff --git a/src/pages/Business/DeviceGroup/components/deviceList.tsx b/src/pages/Business/DeviceGroup/components/deviceList.tsx
new file mode 100644
index 0000000..6e412ba
--- /dev/null
+++ b/src/pages/Business/DeviceGroup/components/deviceList.tsx
@@ -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;
+};
+
+const DeviceList: React.FC = () => {
+ const access = useAccess();
+ // const intl = useIntl();
+ const actionRef = useRef();
+
+ const [createModalOpen, setCreateModalOpen] = useState(false);
+ // const [categoryFkIdIds, setCategoryFkIdIds] = useState([]);
+ // 动态设置每页数量
+ const [currentPageSize, setCurrentPageSize] = useState(10);
+
+ /**新增 编辑 删除 */
+ // 新增
+ const handleCreateModal = () => {
+ setCreateModalOpen(!createModalOpen);
+ };
+
+ function reloadList() {
+ actionRef.current?.reload();
+ }
+
+ const columns: ProColumns>[] = [
+ {
+ title: ,
+ dataIndex: 'name',
+ hideInSearch: true,
+ // width: 80,
+ // key: 'fixedName',
+ // fixed: 'left',
+ },
+ {
+ title: (
+
+ ),
+ dataIndex: 'deviceType',
+ hideInSearch: true,
+ // width: 120,
+ },
+ {
+ title: (
+
+ ),
+ dataIndex: 'isEnable',
+ hideInSearch: true,
+ // width: 80,
+ render: (dom, record) => {
+ return (
+
+
+
+ {record.isEnable ? (
+
+ ) : (
+
+ )}
+
+
+ );
+ },
+ },
+
+ {
+ title: ,
+ dataIndex: 'option',
+ valueType: 'option',
+ fixed: 'right',
+ key: 'option',
+ render: (_, record) => [
+ {
+ // setCurrentRow(record);
+ // history.push('/home/model-detail');
+ // doToDetail(record);
+ // setShowDetail(true);
+ }}
+ >
+
+
+ ),
+ },
+ {
+ key: 'updateDetail',
+ renderDom: (
+
+ ),
+ },
+ {
+ key: 'destroy',
+ renderDom: (
+ {
+ handleDestroy(record).then(() => {});
+ }}
+ >
+ ),
+ },
+ ]}
+ >,
+ ],
+ },
+ ];
+
+ return (
+
+
[
+
+
+
+
+
+ ,
+ ]}
+ 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) => {
+ return { ...v, key: v.id };
+ }),
+ success: resp.success,
+ total: resp.data.count,
+ current: current,
+ pageSize: currentPageSize,
+ };
+ }}
+ columns={columns}
+ />
+
+
+ );
+};
+
+export default DeviceList;
diff --git a/src/pages/Business/DeviceGroup/index.css b/src/pages/Business/DeviceGroup/index.css
new file mode 100644
index 0000000..77af702
--- /dev/null
+++ b/src/pages/Business/DeviceGroup/index.css
@@ -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;
+}
diff --git a/src/pages/Business/DeviceGroup/index.less b/src/pages/Business/DeviceGroup/index.less
new file mode 100644
index 0000000..b17d451
--- /dev/null
+++ b/src/pages/Business/DeviceGroup/index.less
@@ -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;
+ }
+ }
+ }
+}
diff --git a/src/pages/Business/DeviceGroup/index.tsx b/src/pages/Business/DeviceGroup/index.tsx
new file mode 100644
index 0000000..e59db12
--- /dev/null
+++ b/src/pages/Business/DeviceGroup/index.tsx
@@ -0,0 +1,136 @@
+/*
+ * @Author: donghao donghao@supervision.ltd
+ * @Date: 2024-04-22 15:23:36
+ * @LastEditors: donghao donghao@supervision.ltd
+ * @LastEditTime: 2024-04-29 16:50:22
+ * @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\index.tsx
+ * @Description: 设备节点设置 关键词 deviceGroup(dg)
+ * @交互说明
+ * 1、节点列表的查看、添加、删除
+ * 2、节点基本信息展示
+ * 3、设备列表分页查看、新建、编辑、删除、设备分类、基础模型配置
+ * 4、业务模型部署配置参数
+ * 5、企业告警设置
+ */
+import { DeviceGroupTree } from '@/components/Tree';
+import { deviceGroupEnums } from '@/enums/deviceGroup';
+import { getDeviceGroupList } from '@/services/testApi/deviceGroup';
+import { ProCard } from '@ant-design/pro-components';
+import { Button, Tabs } from 'antd';
+import { useEffect, useState } from 'react';
+import BaseInfo from './components/baseInfo';
+import CreateForm from './components/createForm';
+import DeviceList from './components/deviceList';
+
+import './index.less';
+
+const DeviceGroup: React.FC = () => {
+ /**state */
+ // 节点信息
+ const [deviceTreeList, setDeviceTreeList] = useState[]>([]);
+ const [nodeInfo, setNodeInfo] = useState>({}); // 当前节点信息
+ const [createModalOpen, setCreateModalOpen] = useState(false); // 创建新增窗口是否打开
+
+ // 切换模块
+ const [tabKey, setTabKey] = useState(deviceGroupEnums[0].key);
+ const [tabs] = useState([...deviceGroupEnums]);
+ const changeTabMode = (key: string) => {
+ setTabKey(key);
+ console.log(key);
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
+ // initList(key);
+ };
+ /**节点列表 */
+ // 设备节点树
+ async function loadDeviceTree() {
+ const resp = await getDeviceGroupList({ page: 1, pageSize: 100 });
+ console.log(resp.data, 'loadDeviceTree');
+ setDeviceTreeList(resp?.data.results);
+ setNodeInfo(resp?.data.results[0]);
+ }
+
+ // 新增
+ const handleCreateModal = () => {
+ setCreateModalOpen(!createModalOpen);
+ };
+
+ // 节点信息展示
+
+ // 切换
+
+ // 初始化加载
+ useEffect(() => {
+ loadDeviceTree();
+ }, []);
+
+ return (
+
+ {/* 节点列表 */}
+
+
节点列表}>
+
+ {
+ setNodeInfo(record);
+ }}
+ addTreeNode={(node) => {
+ //TODO 判断是根节点还是子节点 调用新增接口
+ console.log('addTreeNode_node', node);
+ handleCreateModal();
+ }}
+ selectTree={(selectedKeys, info) => {
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
+ info?.node && setNodeInfo(info?.node);
+ // handleSelectNode(selectedKeys, info)
+ console.log('selectTree_selected', selectedKeys, info);
+ }}
+ >
+
+
+
+
+ {/* 节点信息 */}
+
+
节点信息}
+ extra={
+
+ }
+ >
+
+
+ {
+ changeTabMode(key);
+ }}
+ >
+ {tabKey === '1' && }
+
+
+
+ {/* 弹窗 */}
+
{
+ // TODO 调用获取节点列表的接口
+ }}
+ />
+
+ );
+};
+
+export default DeviceGroup;
diff --git a/src/pages/Business/NodeSetting/index.tsx b/src/pages/Business/NodeSetting/index.tsx
deleted file mode 100644
index fc2478b..0000000
--- a/src/pages/Business/NodeSetting/index.tsx
+++ /dev/null
@@ -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 节点设置
;
-};
-
-export default NodeSetting;
diff --git a/src/pages/Model/ModelDetail/index.tsx b/src/pages/Model/ModelDetail/index.tsx
index 092863d..1fe0c13 100644
--- a/src/pages/Model/ModelDetail/index.tsx
+++ b/src/pages/Model/ModelDetail/index.tsx
@@ -45,11 +45,7 @@ const ModelDetail: React.FC = () => {
/**新增 编辑 删除 */
// 新增
const handleCreateModal = () => {
- if (createModalOpen) {
- setCreateModalOpen(false);
- } else {
- setCreateModalOpen(true);
- }
+ setCreateModalOpen(!createModalOpen);
};
function reloadList() {
diff --git a/src/pages/Project/BusinessInfo/components/baseInfo.tsx b/src/pages/Project/BusinessInfo/components/baseInfo.tsx
index 9f6a041..a0895e5 100644
--- a/src/pages/Project/BusinessInfo/components/baseInfo.tsx
+++ b/src/pages/Project/BusinessInfo/components/baseInfo.tsx
@@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-23 17:00:00
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-24 17:14:48
+ * @LastEditTime: 2024-04-28 09:33:34
* @FilePath: \general-ai-platform-web\src\pages\Project\BusinessInfo\components\baseInfo.tsx
* @Description: 基本信息展示
*
@@ -45,7 +45,7 @@ const BaseInfo: React.FC = ({ info }) => {
},
];
return (
-
+
);
diff --git a/src/services/testApi/device.ts b/src/services/testApi/device.ts
new file mode 100644
index 0000000..4140541
--- /dev/null
+++ b/src/services/testApi/device.ts
@@ -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
, //
+ options?: { [key: string]: any },
+) {
+ return request(
+ `/api/device/listByGroup`,
+ {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ params: {
+ ...body,
+ },
+ ...(options || {}),
+ },
+ );
+}
diff --git a/src/services/testApi/deviceGroup.ts b/src/services/testApi/deviceGroup.ts
index b8491b6..60ff8d2 100644
--- a/src/services/testApi/deviceGroup.ts
+++ b/src/services/testApi/deviceGroup.ts
@@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-25 15:39:42
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-25 15:49:38
+ * @LastEditTime: 2024-04-28 11:19:40
* @FilePath: \general-ai-platform-web\src\services\testApi\deviceGroup.ts
* @Description: 节点设置api
*/
@@ -11,26 +11,26 @@
import { request } from '@umijs/max';
/** 节点设置分页列表 */
-// export async function getDeviceGroupList(
-// body: Record, //
-// options?: { [key: string]: any },
-// ) {
-// return request(
-// `/api/device_group/list`,
-// {
-// method: 'GET',
-// headers: {
-// 'Content-Type': 'application/json',
-// },
-// params: {
-// ...body,
-// },
-// ...(options || {}),
-// },
-// );
-// }
+export async function getDeviceGroupList(
+ body: Record, //
+ options?: { [key: string]: any },
+) {
+ return request(
+ `/api/device_group/getDeviceGroupList`,
+ {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ params: {
+ ...body,
+ },
+ ...(options || {}),
+ },
+ );
+}
-/** 获取设备组树 POST /device_group/getDeviceGroupTree */
+/** 获取设备组树 GET /device_group/getDeviceGroupTree */
export async function getDeviceGroupTree(
body: Record, //
options?: { [key: string]: any },
@@ -49,3 +49,23 @@ export async function getDeviceGroupTree(
},
);
}
+
+/** 获取节点树 GET /device_group/getDeviceGroupTree */
+export async function getDeviceGroupSettingTree(
+ body: Record, //
+ options?: { [key: string]: any },
+) {
+ return request(
+ `/api/device_group/setting_data`,
+ {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ params: {
+ ...body,
+ },
+ ...(options || {}),
+ },
+ );
+}
diff --git a/src/services/testApi/dict.ts b/src/services/testApi/dict.ts
index c91511f..5dbaada 100644
--- a/src/services/testApi/dict.ts
+++ b/src/services/testApi/dict.ts
@@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-09 13:46:44
* @LastEditors: donghao donghao@supervision.ltd
- * @LastEditTime: 2024-04-17 14:09:35
+ * @LastEditTime: 2024-04-28 14:24:40
* @FilePath: \general-ai-manage\src\services\testApi\businessProject.ts
* @Description: 字典表mock数据映射
*/
@@ -10,12 +10,28 @@
/* eslint-disable */
import { request } from '@umijs/max';
-/** 企业项目分页列表 */
+/** 行业分类列表 */
export async function getDictIndustry(
body: Record, //
options?: { [key: string]: any },
) {
- return request(`/api/dict/industry/`, {
+ return request(`/api/dict/industry`, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ params: {
+ ...body,
+ },
+ ...(options || {}),
+ });
+}
+/** 设备类型列表 */
+export async function getDictDeviceType(
+ body: Record, //
+ options?: { [key: string]: any },
+) {
+ return request(`/api/dict/deviceType`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
diff --git a/src/utils/baseTree.ts b/src/utils/baseTree.ts
new file mode 100644
index 0000000..58c43ff
--- /dev/null
+++ b/src/utils/baseTree.ts
@@ -0,0 +1,13 @@
+export const formatTreeValByKey = (
+ key: string,
+ node: Record,
+ 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;
+};