xjj 2 vuotta sitten
vanhempi
commit
2f6b204d8b
48 muutettua tiedostoa jossa 1931 lisäystä ja 337 poistoa
  1. 1 0
      package.json
  2. 10 5
      src/Frameworks/SysRouter/index.ts
  3. 3 2
      src/Project/Functions/FuncMain.ts
  4. 14 0
      src/Project/Functions/Handlers/DataMeterHandler.ts
  5. 3 0
      src/Project/Os.ts
  6. BIN
      src/Project/assets/chartBox/ai_bg1.png
  7. BIN
      src/Project/assets/chartBox/arrow.png
  8. BIN
      src/Project/assets/chartBox/bg.png
  9. BIN
      src/Project/assets/chartBox/jiao1.png
  10. BIN
      src/Project/assets/chartBox/jiao2.png
  11. BIN
      src/Project/assets/chartBox/jiao3.png
  12. BIN
      src/Project/assets/chartBox/jiao4.png
  13. BIN
      src/Project/assets/chartBox/title-bg-mini.png
  14. BIN
      src/Project/assets/chartBox/title-bg.png
  15. BIN
      src/Project/assets/chartBox/titleBar01.png
  16. BIN
      src/Project/assets/chartBox/titleBar02.png
  17. BIN
      src/Project/assets/chartBox/titleBar03.png
  18. BIN
      src/Project/assets/chartBox/titleBar04.png
  19. BIN
      src/Project/assets/chartBox/titleBar05.png
  20. BIN
      src/Project/assets/chartBox/titleBar06.png
  21. BIN
      src/Project/assets/chartBox/titleBar07.png
  22. BIN
      src/Project/assets/chartBox/titleBefor.png
  23. BIN
      src/Project/assets/chartBox/titleBorder.png
  24. BIN
      src/Project/assets/chartBox/titleIcon.png
  25. BIN
      src/Project/assets/newUI/icon1_in.png
  26. BIN
      src/Project/assets/newUI/icon1_out.png
  27. BIN
      src/Project/assets/newUI/icon_in.png
  28. BIN
      src/Project/assets/newUI/icon_out.png
  29. BIN
      src/Project/assets/newUI/selectCancel.png
  30. 1 0
      src/Project/constants/index.ts
  31. 995 0
      src/Project/pages/DataMeter/Model/AlarmCenter.tsx
  32. 5 5
      src/Project/pages/DataMeter/Model/ChartBox/index.less
  33. 16 16
      src/Project/pages/DataMeter/Model/ChartBox/index.tsx
  34. 24 4
      src/Project/pages/DataMeter/Model/Map.tsx
  35. 162 0
      src/Project/pages/DataMeter/Model/Monitor.tsx
  36. 1 1
      src/Project/pages/DataMeter/Model/ProjectInfo.tsx
  37. 7 7
      src/Project/pages/DataMeter/Model/ProjectList.less
  38. 6 2
      src/Project/pages/DataMeter/Model/ProjectList.tsx
  39. 28 0
      src/Project/pages/DataMeter/Model/index.less
  40. 118 8
      src/Project/pages/DataMeter/Model/index.tsx
  41. 64 43
      src/Project/pages/DataMeter/index.less
  42. 141 6
      src/Project/pages/DataMeter/index.tsx
  43. 2 2
      src/Project/pages/DataMeter/typings.d.ts
  44. 0 234
      src/Project/services/DataMeter.js
  45. 292 0
      src/Project/services/DataMeter.ts
  46. 18 0
      src/Project/services/typings.d.ts
  47. 2 2
      src/app.ts
  48. 18 0
      yarn.lock

+ 1 - 0
package.json

@@ -17,6 +17,7 @@
     "@umijs/max": "^4.0.41",
     "antd": "^5.0.0",
     "echarts": "^5.4.1",
+    "flv.js": "^1.6.2",
     "pinyin-match": "^1.2.2",
     "react-grid-layout": "^1.2.5",
     "react-id-swiper": "^2.4.0",

+ 10 - 5
src/Frameworks/SysRouter/index.ts

@@ -59,11 +59,16 @@ export const route: GT.IRouterOptions[] = [
     //@ts-ignore
     // models: () => import('@/Project/pages/Map/models/index'),
     options: {
-      name: '驾驶舱',
-      left: 0,
-      top: 0,
-      width: '100%',
-      height: '100%',
+      header: false,
+    },
+  },
+  {
+    key: PAGE_KEY.DataMeter,
+    //@ts-ignore
+    component: () => import('@/Project/pages/DataMeter'),
+    //@ts-ignore
+    // models: () => import('@/Project/pages/Map/models/index'),
+    options: {
       header: false,
     },
   },

+ 3 - 2
src/Project/Functions/FuncMain.ts

@@ -1,8 +1,7 @@
 import Func from '@/Engine/ECS/Function';
 import LoginHandle from './Handlers/LoginHandler';
-import { PAGE_KEY } from '../constants';
-import SysPage from '@/Frameworks/SysPage';
 import PlatformMenuHandle from './Handlers/PlatformMenuHandle';
+import DataMeterHandle from './Handlers/DataMeterHandler';
 
 export enum FuncMainState {
   Login, // 登录页
@@ -10,6 +9,7 @@ export enum FuncMainState {
   ProjectSelection, // 项目选择页
   PageMenu, // 菜单页
   Map,
+  DataMeter,
 }
 
 export default class FuncMain extends Func<FuncMainState> {
@@ -23,6 +23,7 @@ export default class FuncMain extends Func<FuncMainState> {
       //   () => window.GT_APP.funcProjectSelection.setActive(false),
       // );
       sm.addState(FuncMainState.Login, new LoginHandle());
+      sm.addState(FuncMainState.DataMeter, new DataMeterHandle());
       sm.addState(FuncMainState.PlatformMenu, new PlatformMenuHandle());
 
       sm.addState(

+ 14 - 0
src/Project/Functions/Handlers/DataMeterHandler.ts

@@ -0,0 +1,14 @@
+import StateHandler from '@/Engine/StateMahines/StateHandler';
+import { FuncMainState } from '../FuncMain';
+
+export default class DataMeterHandle implements StateHandler<FuncMainState> {
+  stateIn(): void {
+    window.GT_APP.funcDataMeter.setActive(true);
+  }
+  stateRunning(): FuncMainState {
+    return FuncMainState.Login;
+  }
+  stateExit(): void {
+    window.GT_APP.funcDataMeter.setActive(false);
+  }
+}

+ 3 - 0
src/Project/Os.ts

@@ -1,4 +1,5 @@
 import FuncMain from './Functions/FuncMain';
+import FuncDataMeter from './Functions/LevelAFunctions/FuncDataMeter';
 import FuncLogin from './Functions/LevelAFunctions/FuncLogin';
 import FuncMap from './Functions/LevelAFunctions/FuncMap';
 import FuncPlatformMenu from './Functions/LevelAFunctions/FuncPlatformMenu';
@@ -10,6 +11,7 @@ class Os {
   funcPlatformMenu: FuncPlatformMenu;
   funcMap: FuncMap;
   funcProjectSelection: FuncProjectSelection;
+  funcDataMeter: FuncDataMeter;
   constructor() {
     this.funcMain = new FuncMain('FuncMain');
     this.funcLogin = new FuncLogin('FuncLogin');
@@ -18,6 +20,7 @@ class Os {
     this.funcProjectSelection = new FuncProjectSelection(
       'FuncProjectSelection',
     );
+    this.funcDataMeter = new FuncDataMeter('FuncDataMeter');
   }
 }
 

BIN
src/Project/assets/chartBox/ai_bg1.png


BIN
src/Project/assets/chartBox/arrow.png


BIN
src/Project/assets/chartBox/bg.png


BIN
src/Project/assets/chartBox/jiao1.png


BIN
src/Project/assets/chartBox/jiao2.png


BIN
src/Project/assets/chartBox/jiao3.png


BIN
src/Project/assets/chartBox/jiao4.png


BIN
src/Project/assets/chartBox/title-bg-mini.png


BIN
src/Project/assets/chartBox/title-bg.png


BIN
src/Project/assets/chartBox/titleBar01.png


BIN
src/Project/assets/chartBox/titleBar02.png


BIN
src/Project/assets/chartBox/titleBar03.png


BIN
src/Project/assets/chartBox/titleBar04.png


BIN
src/Project/assets/chartBox/titleBar05.png


BIN
src/Project/assets/chartBox/titleBar06.png


BIN
src/Project/assets/chartBox/titleBar07.png


BIN
src/Project/assets/chartBox/titleBefor.png


BIN
src/Project/assets/chartBox/titleBorder.png


BIN
src/Project/assets/chartBox/titleIcon.png


BIN
src/Project/assets/newUI/icon1_in.png


BIN
src/Project/assets/newUI/icon1_out.png


BIN
src/Project/assets/newUI/icon_in.png


BIN
src/Project/assets/newUI/icon_out.png


BIN
src/Project/assets/newUI/selectCancel.png


+ 1 - 0
src/Project/constants/index.ts

@@ -4,6 +4,7 @@ export enum PAGE_KEY {
   Login,
   PlatformMenu,
   ProjectSelection,
+  Map,
   DataMeter
 }
 

+ 995 - 0
src/Project/pages/DataMeter/Model/AlarmCenter.tsx

@@ -0,0 +1,995 @@
+import React, { useState, useEffect } from 'react';
+import { Popover, Radio, Avatar, Tooltip, Empty, Select } from 'antd';
+import style from './index.less';
+import moment from 'moment';
+import { ChartBoxTitle } from './ChartBox';
+import { useRequest } from '@umijs/max';
+import {
+  getProjectAlarm,
+  getIssueList,
+  getFaultAnalysis,
+  getBreakdownRecord,
+  getPatrolRecord,
+  getProjectList,
+} from '@/Project/services/DataMeter';
+
+const { Option } = Select;
+
+function AlarmCenter(props: DataMeter.IModelsProps) {
+  const { child, setActive, layout, subModule, projectId } = props;
+  // const [active, setActive] = useState();
+  // const active = layout.active || child.find(item => item.show).key;
+  const [active, setSelfActive] = useState(
+    layout.active || child.find((item) => item.show)?.key,
+  );
+  const [showTabs, setShowTabs] = useState(false);
+  const [title, setTitle] = useState('');
+  const [faultActive, setFaultActive] = useState(1);
+  const id = projectId || -1;
+  const projectAlarmRequest = useRequest(getProjectAlarm, {
+    defaultParams: [
+      {
+        pageSize: 50,
+        currentPage: 1,
+        msgType: '4,5,6',
+        projectId: id,
+      },
+    ],
+  });
+  const IssueListRequest = useRequest(getIssueList, {
+    defaultParams: [
+      {
+        projectId: id,
+        pageSize: 50,
+        currentPage: 1,
+      },
+    ],
+  });
+  const faultAnalysisRequest = useRequest(getFaultAnalysis, {
+    defaultParams: [id],
+  });
+  const breakdownRecordRequest = useRequest(getBreakdownRecord, {
+    defaultParams: [
+      {
+        pageSize: 50,
+        currentPage: 1,
+        projectId: id,
+      },
+    ],
+  });
+  const patrolRecordRequest = useRequest(getPatrolRecord, {
+    defaultParams: [
+      {
+        pageSize: 50,
+        currentPage: 1,
+        projectId: id,
+        status: 1,
+      },
+    ],
+  });
+  const projectRequest = useRequest(getProjectList, {
+    cacheKey: 'projectList',
+    staleTime: -1,
+  });
+  const projectAlarmList = projectAlarmRequest.data?.list || [];
+  const issueList = IssueListRequest.data?.list || [];
+  const faultAnalysis = faultAnalysisRequest.data?.list || [];
+  const breakdownList = breakdownRecordRequest.data?.list || [];
+  const patrolList = patrolRecordRequest.data?.list || [];
+  const projectList = projectRequest.data?.list || [];
+
+  const getTitle = (title: string) => {
+    return (
+      <Popover
+        placement="topLeft"
+        content={<div style={{ maxWidth: '2rem' }}>{title}</div>}
+      >
+        {title}
+      </Popover>
+    );
+  };
+  const onChange = (value: string) => {
+    let id = projectId || -1;
+    projectAlarmRequest.run({
+      pageSize: 50,
+      currentPage: 1,
+      msgType: value,
+      projectId: id,
+    });
+  };
+  const onChangeFault = (value: number) => {
+    setFaultActive(value);
+  };
+
+  const getBreakdownStatus = (status: number) => {
+    switch (status) {
+      case 0:
+        return '已提交';
+      case 1:
+        return '已派遣';
+      case 2:
+        return '已处理';
+      default:
+        return '';
+    }
+  };
+
+  const renderContent = () => {
+    let content;
+    switch (active) {
+      case 1:
+        if (faultActive == 1) {
+          if (faultAnalysis.length > 0) {
+            let col = faultAnalysis.map((item: any, index: number) => (
+              <tr key={index}>
+                <td
+                  style={
+                    subModule == 0
+                      ? { width: '33%', paddingRight: '0.1rem' }
+                      : { width: '50%', paddingRight: '0.1rem' }
+                  }
+                  className={style.alarmTitle}
+                >
+                  {getTitle(`${item.DeviceName}(${item.DeviceCode})`)}
+                </td>
+                <td
+                  style={
+                    subModule == 0
+                      ? {
+                          width: '33%',
+                          paddingRight: '0.1rem',
+                          whiteSpace: 'nowrap',
+                        }
+                      : {
+                          width: '50%',
+                          paddingRight: '0.1rem',
+                          whiteSpace: 'nowrap',
+                        }
+                  }
+                  className={style.alarmTitle}
+                >
+                  {getTitle(`${item.FaultDescription}`)}
+                </td>
+              </tr>
+            ));
+            content = (
+              <div
+                style={{
+                  paddingTop: '0.12rem',
+                  paddingLeft: '0.14rem',
+                  flex: '1',
+                  height: 0,
+                }}
+              >
+                <table
+                  className={style.alarmTable}
+                  style={{
+                    width: 'calc(100% - 12px)',
+                    background:
+                      'linear-gradient(270deg, rgba(153, 231, 255, 0.8) 0%, #60A8FF 100%)',
+                  }}
+                >
+                  <thead>
+                    <tr>
+                      <th
+                        style={
+                          subModule == 0
+                            ? { width: '33%', paddingRight: '0.1rem' }
+                            : { width: '50%', paddingRight: '0.1rem' }
+                        }
+                      >
+                        设备
+                      </th>
+                      <th
+                        style={
+                          subModule == 0
+                            ? { width: '33%', paddingRight: '0.1rem' }
+                            : { width: '50%', paddingRight: '0.1rem' }
+                        }
+                      >
+                        故障类型
+                      </th>
+                    </tr>
+                  </thead>
+                </table>
+                <div
+                  style={{
+                    overflowY: 'scroll',
+                    height: 'calc(100% - 0.24rem)',
+                  }}
+                >
+                  <table className={style.alarmTable}>
+                    <tbody>{col}</tbody>
+                  </table>
+                </div>
+              </div>
+            );
+          } else {
+            content = <Empty />;
+          }
+        } else if (faultActive == 2) {
+          if (breakdownList.length > 0) {
+            let col = breakdownList.map((item: any, idx: number) => (
+              <tr
+                key={item.id}
+                style={
+                  idx % 2 == 0
+                    ? {
+                        background:
+                          'linear-gradient(to right, rgba(153, 231, 255, 0.1), rgba(96, 168, 255, 0.1))',
+                      }
+                    : {
+                        background:
+                          'linear-gradient(to right, rgba(153, 231, 255, 0.2), rgba(96, 168, 255, 0.2))',
+                      }
+                }
+              >
+                <td
+                  style={
+                    subModule == 0
+                      ? { width: '40%', paddingRight: '0.1rem' }
+                      : { width: '50%', paddingRight: '0.1rem' }
+                  }
+                  className={style.alarmTitle}
+                >
+                  {getTitle(`${item.DeviceName}(${item.DeviceCode})`)}
+                </td>
+                <td
+                  style={
+                    subModule == 0
+                      ? {
+                          width: '20%',
+                          paddingRight: '0.1rem',
+                          whiteSpace: 'nowrap',
+                        }
+                      : {
+                          width: '50%',
+                          paddingRight: '0.1rem',
+                          whiteSpace: 'nowrap',
+                        }
+                  }
+                >
+                  {moment(item.ReportTime).format('YYYY-MM-DD')}
+                </td>
+                {subModule == 0 && (
+                  <td
+                    style={{
+                      width: '40%',
+                      paddingRight: '0.1rem',
+                      whiteSpace: 'nowrap',
+                    }}
+                    className={style.alarmTitle}
+                  >
+                    {getTitle(
+                      projectList.find(
+                        (project: any) => project.ID == item.ProjectId,
+                      )?.Name || '无',
+                    )}
+                  </td>
+                )}
+              </tr>
+            ));
+            content = (
+              <div
+                style={{
+                  paddingTop: '0.12rem',
+                  paddingLeft: '0.14rem',
+                  flex: '1',
+                  height: 0,
+                }}
+              >
+                <table
+                  className={style.alarmTable}
+                  style={{
+                    width: 'calc(100% - 12px)',
+                    background:
+                      'linear-gradient(270deg, rgba(153, 231, 255, 0.8) 0%, #60A8FF 100%)',
+                  }}
+                >
+                  <thead>
+                    <tr>
+                      <th
+                        style={
+                          subModule == 0
+                            ? { width: '40%', paddingRight: '0.1rem' }
+                            : { width: '50%', paddingRight: '0.1rem' }
+                        }
+                      >
+                        设备
+                      </th>
+                      <th
+                        style={
+                          subModule == 0
+                            ? { width: '20%', paddingRight: '0.1rem' }
+                            : { width: '50%', paddingRight: '0.1rem' }
+                        }
+                      >
+                        日期
+                      </th>
+                      {subModule == 0 && (
+                        <th style={{ width: '40%', paddingRight: '0.1rem' }}>
+                          项目名称
+                        </th>
+                      )}
+                    </tr>
+                  </thead>
+                </table>
+                <div
+                  style={{
+                    overflowY: 'scroll',
+                    height: 'calc(100% - 0.24rem)',
+                  }}
+                >
+                  <table className={style.alarmTable}>
+                    <tbody>{col}</tbody>
+                  </table>
+                </div>
+              </div>
+            );
+          } else {
+            content = <Empty />;
+          }
+        } else {
+          if (patrolList.length > 0) {
+            let col = patrolList.map((item: any, idx: number) => (
+              <tr
+                key={item.id}
+                style={
+                  idx % 2 == 0
+                    ? {
+                        background:
+                          'linear-gradient(to right, rgba(153, 231, 255, 0.1), rgba(96, 168, 255, 0.1))',
+                      }
+                    : {
+                        background:
+                          'linear-gradient(to right, rgba(153, 231, 255, 0.2), rgba(96, 168, 255, 0.2))',
+                      }
+                }
+              >
+                <td
+                  style={
+                    subModule == 0
+                      ? { width: '40%', paddingRight: '0.1rem' }
+                      : { width: '50%', paddingRight: '0.1rem' }
+                  }
+                  className={style.alarmTitle}
+                >
+                  {getTitle(`${item?.RouteInfo?.Name}`)}
+                </td>
+                <td
+                  style={
+                    subModule == 0
+                      ? {
+                          width: '20%',
+                          paddingRight: '0.1rem',
+                          whiteSpace: 'nowrap',
+                        }
+                      : {
+                          width: '50%',
+                          paddingRight: '0.1rem',
+                          whiteSpace: 'nowrap',
+                        }
+                  }
+                >
+                  {' '}
+                  {moment(item.CreatedTime).format('YYYY-MM-DD')}
+                </td>
+                {subModule == 0 && (
+                  <td
+                    style={{ width: '40%', paddingRight: '0.1rem' }}
+                    className={style.alarmTitle}
+                  >
+                    {getTitle(
+                      projectList.find(
+                        (project: any) => project.ID == item.ProjectId,
+                      )?.Name || '无',
+                    )}
+                  </td>
+                )}
+              </tr>
+            ));
+            content = (
+              <div
+                style={{
+                  paddingTop: '0.12rem',
+                  paddingLeft: '0.14rem',
+                  flex: '1',
+                  height: 0,
+                }}
+              >
+                <table
+                  className={style.alarmTable}
+                  style={{
+                    width: 'calc(100% - 12px)',
+                    background:
+                      'linear-gradient(270deg, rgba(153, 231, 255, 0.8) 0%, #60A8FF 100%)',
+                  }}
+                >
+                  <thead>
+                    <tr>
+                      <th
+                        style={
+                          subModule == 0
+                            ? { width: '40%', paddingRight: '0.1rem' }
+                            : { width: '50%', paddingRight: '0.1rem' }
+                        }
+                      >
+                        路线名称
+                      </th>
+                      <th
+                        style={
+                          subModule == 0
+                            ? { width: '20%', paddingRight: '0.1rem' }
+                            : { width: '50%', paddingRight: '0.1rem' }
+                        }
+                      >
+                        日期
+                      </th>
+                      {subModule == 0 && (
+                        <th style={{ width: '40%', paddingRight: '0.1rem' }}>
+                          项目名称
+                        </th>
+                      )}
+                    </tr>
+                  </thead>
+                </table>
+                <div
+                  style={{
+                    overflowY: 'scroll',
+                    height: 'calc(100% - 0.24rem)',
+                  }}
+                >
+                  <table className={style.alarmTable}>
+                    <tbody>{col}</tbody>
+                  </table>
+                </div>
+              </div>
+            );
+          } else {
+            content = <Empty />;
+          }
+        }
+        break;
+      case 2:
+        if (projectAlarmList.length > 0) {
+          let col = projectAlarmList.map((item: any, idx: number) => (
+            <tr
+              key={item.id}
+              style={
+                idx % 2 == 0
+                  ? {
+                      background:
+                        'linear-gradient(to right, rgba(153, 231, 255, 0.1), rgba(96, 168, 255, 0.1))',
+                    }
+                  : {
+                      background:
+                        'linear-gradient(to right, rgba(153, 231, 255, 0.2), rgba(96, 168, 255, 0.2))',
+                    }
+              }
+            >
+              {/* <td>{item.MsgBody}</td> */}
+              <td
+                style={{ width: '40%', paddingRight: '0.1rem' }}
+                className={style.alarmTitle}
+              >
+                {getTitle(item.MsgBody)}
+              </td>
+              {/* <td>{item.ReadStatus == 1 ? '已读' : '未读'}</td> */}
+              <td
+                style={
+                  subModule == 0
+                    ? {
+                        width: '20%',
+                        paddingRight: '0.1rem',
+                        whiteSpace: 'nowrap',
+                      }
+                    : {
+                        width: '50%',
+                        paddingRight: '0.1rem',
+                        whiteSpace: 'nowrap',
+                      }
+                }
+              >
+                {moment(item.CreatedOn).format('YYYY-MM-DD')}
+              </td>
+              {subModule == 0 && (
+                <td
+                  style={{ width: '40%', paddingRight: '0.1rem' }}
+                  className={style.alarmTitle}
+                >
+                  {getTitle(
+                    projectList.find(
+                      (project: any) => project.ID == item?.Project?.ID,
+                    )?.Name || '无',
+                  )}
+                </td>
+              )}
+            </tr>
+          ));
+          content = (
+            <div
+              style={{
+                paddingTop: '0.12rem',
+                paddingLeft: '0.14rem',
+                flex: '1',
+                height: 0,
+              }}
+            >
+              <table
+                className={style.alarmTable}
+                style={{
+                  width: 'calc(100% - 12px)',
+                  background:
+                    'linear-gradient(270deg, rgba(153, 231, 255, 0.8) 0%, #60A8FF 100%)',
+                }}
+              >
+                <thead>
+                  <tr>
+                    <th
+                      style={
+                        subModule == 0
+                          ? { width: '40%', paddingRight: '0.1rem' }
+                          : { width: '50%', paddingRight: '0.1rem' }
+                      }
+                    >
+                      预警内容
+                    </th>
+                    {/* <th>状态</th> */}
+                    <th
+                      style={
+                        subModule == 0
+                          ? { width: '20%', paddingRight: '0.1rem' }
+                          : { width: '50%', paddingRight: '0.1rem' }
+                      }
+                    >
+                      日期
+                    </th>
+                    {subModule == 0 && (
+                      <th style={{ width: '40%', paddingRight: '0.1rem' }}>
+                        项目名称
+                      </th>
+                    )}
+                  </tr>
+                </thead>
+              </table>
+              <div
+                style={{
+                  overflowY: 'scroll',
+                  height: 'calc(100% - 0.24rem)',
+                }}
+              >
+                <table className={style.alarmTable}>
+                  <tbody>{col}</tbody>
+                </table>
+              </div>
+            </div>
+          );
+        } else {
+          content = <Empty />;
+        }
+        break;
+      case 3:
+        if (issueList.length > 0) {
+          let col = issueList.map((item: any, idx: number) => (
+            <tr
+              key={item.id}
+              style={
+                idx % 2 == 0
+                  ? {
+                      background:
+                        'linear-gradient(to right, rgba(153, 231, 255, 0.1), rgba(96, 168, 255, 0.1))',
+                    }
+                  : {
+                      background:
+                        'linear-gradient(to right, rgba(153, 231, 255, 0.2), rgba(96, 168, 255, 0.2))',
+                    }
+              }
+            >
+              {/* <td>{item.title}</td> */}
+              <td
+                style={
+                  subModule == 0
+                    ? { width: '25%', paddingRight: '0.1rem' }
+                    : { width: '33%', paddingRight: '0.1rem' }
+                }
+                className={style.alarmTitle}
+              >
+                {getTitle(item.title)}
+              </td>
+              {/* <td>{STATUS[item.status]}</td> */}
+              <td
+                style={
+                  subModule == 0
+                    ? { width: '25%', paddingRight: '0.1rem' }
+                    : { width: '33%', paddingRight: '0.1rem' }
+                }
+                className={style.alarmTitle}
+              >
+                {getTitle(STATUS[item.status as keyof typeof STATUS])}
+              </td>
+              <td
+                style={
+                  subModule == 0
+                    ? {
+                        width: '20%',
+                        paddingRight: '0.1rem',
+                        whiteSpace: 'nowrap',
+                      }
+                    : {
+                        width: '33%',
+                        paddingRight: '0.1rem',
+                        whiteSpace: 'nowrap',
+                      }
+                }
+              >
+                {moment(item.c_time).format('YYYY-MM-DD')}
+              </td>
+              {subModule == 0 && (
+                <td
+                  style={{ width: '30%', paddingRight: '0.1rem' }}
+                  className={style.alarmTitle}
+                >
+                  {getTitle(
+                    projectList.find(
+                      (project: any) => project.ID == item.project_id,
+                    )?.Name || '无',
+                  )}
+                </td>
+              )}
+            </tr>
+          ));
+          content = (
+            <div
+              style={{
+                paddingTop: '0.12rem',
+                paddingLeft: '0.14rem',
+                flex: '1',
+                height: 0,
+              }}
+            >
+              <table
+                className={style.alarmTable}
+                style={{
+                  width: 'calc(100% - 12px)',
+                  background:
+                    'linear-gradient(270deg, rgba(153, 231, 255, 0.8) 0%, #60A8FF 100%)',
+                }}
+              >
+                <thead>
+                  <tr>
+                    <th
+                      style={
+                        subModule == 0
+                          ? { width: '25%', paddingRight: '0.1rem' }
+                          : { width: '33%', paddingRight: '0.1rem' }
+                      }
+                    >
+                      标题
+                    </th>
+                    <th
+                      style={
+                        subModule == 0
+                          ? { width: '25%', paddingRight: '0.1rem' }
+                          : { width: '33%', paddingRight: '0.1rem' }
+                      }
+                    >
+                      状态
+                    </th>
+                    <th
+                      style={
+                        subModule == 0
+                          ? { width: '20%', paddingRight: '0.1rem' }
+                          : { width: '33%', paddingRight: '0.1rem' }
+                      }
+                    >
+                      日期
+                    </th>
+                    {subModule == 0 && (
+                      <th style={{ width: '30%', paddingRight: '0.1rem' }}>
+                        项目名称
+                      </th>
+                    )}
+                  </tr>
+                </thead>
+              </table>
+              <div
+                style={{
+                  overflowY: 'scroll',
+                  height: 'calc(100% - 0.24rem)',
+                }}
+              >
+                <table className={style.alarmTable}>
+                  <tbody>{col}</tbody>
+                </table>
+              </div>
+            </div>
+          );
+        } else {
+          content = <Empty />;
+        }
+        break;
+      case 4:
+        var total: any = [];
+        var id = 1;
+        issueList.forEach((item: any) => {
+          id++;
+          total.push({
+            id,
+            title: item.title,
+            status: STATUS[item.status as keyof typeof STATUS],
+            time: new Date(item.c_time),
+            project_id: item.project_id,
+          });
+        });
+        projectAlarmList.forEach((item: any) => {
+          id++;
+          total.push({
+            id,
+            title: item.MsgBody,
+            status: item.ReadStatus == 1 ? '已读' : '未读',
+            time: new Date(item.CreatedOn),
+            project_id: item.Project?.ID,
+          });
+        });
+        faultAnalysis.forEach((item: any) => {
+          id++;
+          total.push({
+            id,
+            title: item.FaultDescription,
+            status: '-',
+            time: new Date(item.AnalysisTime),
+            project_id: item.ProjectId,
+          });
+        });
+        patrolList.forEach((item: any) => {
+          id++;
+          total.push({
+            id,
+            title: item?.RouteInfo?.Name,
+            status: '异常',
+            time: new Date(item.CreatedTime),
+            project_id: item.ProjectId,
+          });
+        });
+        breakdownList.forEach((item: any) => {
+          id++;
+          total.push({
+            id,
+            title: `${item.DeviceName}(${item.DeviceCode})`,
+            status: getBreakdownStatus(item.AcceptanceStatus),
+            time: new Date(item.ReportTime),
+            project_id: item.ProjectId,
+          });
+        });
+        total.sort((a: any, b: any) => b.time - a.time);
+        if (total.length > 0) {
+          let col = total.map((item: any, idx: number) => (
+            <tr
+              key={item.id}
+              style={
+                idx % 2 == 0
+                  ? {
+                      background:
+                        'linear-gradient(to right, rgba(153, 231, 255, 0.1), rgba(96, 168, 255, 0.1))',
+                    }
+                  : {
+                      background:
+                        'linear-gradient(to right, rgba(153, 231, 255, 0.2), rgba(96, 168, 255, 0.2))',
+                    }
+              }
+            >
+              <td
+                style={
+                  subModule == 0
+                    ? { width: '25%', paddingRight: '0.1rem' }
+                    : { width: '33%', paddingRight: '0.1rem' }
+                }
+                className={style.alarmTitle}
+              >
+                {getTitle(item.title)}
+              </td>
+              <td
+                style={
+                  subModule == 0
+                    ? { width: '15%', paddingRight: '0.1rem' }
+                    : { width: '33%', paddingRight: '0.1rem' }
+                }
+                className={style.alarmTitle}
+              >
+                {getTitle(item.status)}
+              </td>
+              <td
+                style={
+                  subModule == 0
+                    ? {
+                        width: '20%',
+                        paddingRight: '0.1rem',
+                        whiteSpace: 'nowrap',
+                      }
+                    : {
+                        width: '33%',
+                        paddingRight: '0.1rem',
+                        whiteSpace: 'nowrap',
+                      }
+                }
+              >
+                {moment(item.time).format('YYYY-MM-DD')}
+              </td>
+              {subModule == 0 && (
+                <td
+                  style={{ width: '40%', paddingRight: '0.1rem' }}
+                  className={style.alarmTitle}
+                >
+                  {getTitle(
+                    projectList.find(
+                      (project: any) => project.ID == item.project_id,
+                    )?.Name || '无',
+                  )}
+                </td>
+              )}
+            </tr>
+          ));
+          content = (
+            <div
+              style={{
+                paddingTop: '0.12rem',
+                paddingLeft: '0.14rem',
+                flex: '1',
+                height: 0,
+              }}
+            >
+              <table
+                className={style.alarmTable}
+                style={{
+                  width: 'calc(100% - 12px)',
+                  background:
+                    'linear-gradient(270deg, rgba(153, 231, 255, 0.8) 0%, #60A8FF 100%)',
+                }}
+              >
+                <thead>
+                  <tr>
+                    <th
+                      style={
+                        subModule == 0
+                          ? { width: '25%', paddingRight: '0.1rem' }
+                          : { width: '33%', paddingRight: '0.1rem' }
+                      }
+                    >
+                      预警内容
+                    </th>
+                    <th
+                      style={
+                        subModule == 0
+                          ? { width: '15%', paddingRight: '0.1rem' }
+                          : { width: '33%', paddingRight: '0.1rem' }
+                      }
+                    >
+                      状态
+                    </th>
+                    <th
+                      style={
+                        subModule == 0
+                          ? { width: '20%', paddingRight: '0.1rem' }
+                          : { width: '33%', paddingRight: '0.1rem' }
+                      }
+                    >
+                      日期
+                    </th>
+                    {subModule == 0 && (
+                      <th style={{ width: '40%', paddingRight: '0.1rem' }}>
+                        项目名称
+                      </th>
+                    )}
+                  </tr>
+                </thead>
+              </table>
+              <div
+                style={{
+                  overflowY: 'scroll',
+                  height: 'calc(100% - 0.24rem)',
+                }}
+              >
+                <table className={style.alarmTable}>
+                  <tbody>{col}</tbody>
+                </table>
+              </div>
+            </div>
+          );
+        } else {
+          content = <Empty />;
+        }
+        break;
+    }
+    return content;
+  };
+
+  useEffect(() => {
+    let current = child.find((item) => item.key == active);
+    if (current) {
+      setTitle(current.title);
+    }
+  }, [active]);
+
+  // useEffect(() => {
+  //   if (child.active) {
+  //     setActive(child.active);
+  //   } else {
+  //     let firstKey = child.find(item => item.show).key;
+  //     setActive(firstKey);
+  //   }
+  // }, [child]);
+
+  const STATUS = {
+    0: '待处理',
+    1: '现场经理协同处理中',
+    2: '项目经理审核中',
+    3: '项目经理协同处理中',
+    4: '总监审核中',
+    5: '总监协同处理中',
+    6: 'coo协调处理中',
+    7: '已完成',
+  };
+
+  return (
+    <div className={style.modelBox}>
+      {/* <ModelTitle type={2} active={showTabs} setActive={setShowTabs}>
+        {title == '全部' ? '报警中心' : title}
+      </ModelTitle> */}
+      <ChartBoxTitle
+        title={title == '全部' ? '报警中心' : title}
+        showTabs={showTabs}
+        setShowTabs={setShowTabs}
+        width={layout.w}
+      />
+      {showTabs && (
+        <ul className={style.tabsList}>
+          {(child || [])
+            .filter((item) => item.show)
+            .map((item) => (
+              <li
+                key={item.key}
+                className={`${active == item.key ? style.active : ''}`}
+                onClick={() => {
+                  setActive(item.key);
+                  setSelfActive(item.key);
+                }}
+              >
+                {item.title}
+              </li>
+            ))}
+        </ul>
+      )}
+      {active == 2 && (
+        <Select
+          className={style.activeSelect}
+          onChange={onChange}
+          dropdownClassName="dataMeter"
+          // style={{ width: 200, marginLeft: '0.16rem', marginTop: 10 }}
+          defaultValue="4,5,6"
+          options={[
+            { value: '4,5,6', label: '全部' },
+            { value: '4', label: '非关键节点预警' },
+            { value: '5', label: '关键节点预警' },
+            { value: '6', label: '问题工单逾期预警' },
+          ]}
+        ></Select>
+      )}
+      {active == 1 && (
+        <Select
+          className={style.activeSelect}
+          onChange={onChangeFault}
+          dropdownClassName="dataMeter"
+          // style={{ width: 200, marginLeft: '0.16rem', marginTop: 10 }}
+          defaultValue={faultActive}
+        >
+          <Option value={1}>工艺诊断异常</Option>
+          <Option value={2}>设备故障</Option>
+          <Option value={3}>巡检故障</Option>
+        </Select>
+      )}
+      {renderContent()}
+    </div>
+  );
+}
+
+export default AlarmCenter;

+ 5 - 5
src/Project/pages/DataMeter/Model/ChartBox/index.less

@@ -52,11 +52,11 @@
   .titleBg {
     height: 47px;
     width: 100%;
-    background: url('@/assets/chartBox/title-bg.png');
+    background: url('@/Project/assets/chartBox/title-bg.png');
     background-size: 100% 100%;
   }
   .titleBgMini {
-    background-image: url('@/assets/chartBox/title-bg-mini.png');
+    background-image: url('@/Project/assets/chartBox/title-bg-mini.png');
   }
 
   // .titleImg {
@@ -71,7 +71,7 @@
   //   height: 100%;
   //   --shf: 4.9406564584124654e-322;
   //   width: calc(((100% - 214px) / 479) * 132);
-  //   background: url('@/assets/chartBox/titleBar02.png') no-repeat center;
+  //   background: url('@/Project/assets/chartBox/titleBar02.png') no-repeat center;
   //   background-size: 100% 100%;
   // }
 
@@ -80,7 +80,7 @@
   //   height: 100%;
   //   // flex: 215 1 auto;
   //   width: calc(((100% - 214px) / 479) * 215);
-  //   background: url('@/assets/chartBox/titleBar04.png') no-repeat center;
+  //   background: url('@/Project/assets/chartBox/titleBar04.png') no-repeat center;
   //   background-size: 100% 100%;
   // }
 
@@ -89,7 +89,7 @@
   //   height: 100%;
   //   // flex: 132 1 auto;
   //   width: calc(((100% - 214px) / 479) * 132);
-  //   background: url('@/assets/chartBox/titleBar06.png') no-repeat center;
+  //   background: url('@/Project/assets/chartBox/titleBar06.png') no-repeat center;
   //   background-size: 100% 100%;
   // }
 }

+ 16 - 16
src/Project/pages/DataMeter/Model/ChartBox/index.tsx

@@ -10,18 +10,18 @@ export const ChartBoxTitle1 = (props:DataMeter.ITitleProps) => {
   return (
     <div className={Styles.main}>
       <div className={`${Styles.titleBg} ${isMini ? Styles.titleBgMini : ''}`}>
-        {/* <img className={Styles.titleImg} src={require('@/assets/chartBox/titleBar01.png')}/>
+        {/* <img className={Styles.titleImg} src={require('@/Project/assets/chartBox/titleBar01.png')}/>
         <div className={Styles.titleBar02}/>
-        <img className={Styles.titleImg} src={require('@/assets/chartBox/titleBar03.png')}/>
+        <img className={Styles.titleImg} src={require('@/Project/assets/chartBox/titleBar03.png')}/>
         <div className={Styles.titleBar04}/>
-        <img className={Styles.titleImg} src={require('@/assets/chartBox/titleBar05.png')}/>
+        <img className={Styles.titleImg} src={require('@/Project/assets/chartBox/titleBar05.png')}/>
         <div className={Styles.titleBar06}/>
-        <img className={Styles.titleImg} src={require('@/assets/chartBox/titleBar07.png')}/> */}
+        <img className={Styles.titleImg} src={require('@/Project/assets/chartBox/titleBar07.png')}/> */}
       </div>
-      <img className={Styles.jiao1} src={require('@/assets/chartBox/jiao1.png')} />
-      <img className={Styles.jiao2} src={require('@/assets/chartBox/jiao2.png')} />
-      {/* <img className={Styles.jiao3} src={require('@/assets/chartBox/jiao4.png')}/>
-      <img className={Styles.jiao4} src={require('@/assets/chartBox/jiao3.png')}/> */}
+      <img className={Styles.jiao1} src={require('@/Project/assets/chartBox/jiao1.png')} />
+      <img className={Styles.jiao2} src={require('@/Project/assets/chartBox/jiao2.png')} />
+      {/* <img className={Styles.jiao3} src={require('@/Project/assets/chartBox/jiao4.png')}/>
+      <img className={Styles.jiao4} src={require('@/Project/assets/chartBox/jiao3.png')}/> */}
       <div className={Styles.title} style={{ top: isMini ? '7px' : '' }}>
         {title}
       </div>
@@ -29,7 +29,7 @@ export const ChartBoxTitle1 = (props:DataMeter.ITitleProps) => {
         <img
           style={{ transform: rotate }}
           className={Styles.arrow}
-          src={require('@/assets/chartBox/arrow.png')}
+          src={require('@/Project/assets/chartBox/arrow.png')}
           onClick={() => {
             setRotate(showTabs ? '' : 'rotate(180deg)');
             setShowTabs(!showTabs);
@@ -43,8 +43,8 @@ export const ChartBoxTitle1 = (props:DataMeter.ITitleProps) => {
 export const ChartBoxBottom = () => {
   return (
     <>
-      <img className={Styles.jiao3} src={require('@/assets/chartBox/jiao4.png')} />
-      <img className={Styles.jiao4} src={require('@/assets/chartBox/jiao3.png')} />
+      <img className={Styles.jiao3} src={require('@/Project/assets/chartBox/jiao4.png')} />
+      <img className={Styles.jiao4} src={require('@/Project/assets/chartBox/jiao3.png')} />
     </>
   );
 };
@@ -52,8 +52,8 @@ export const ChartBoxBottom = () => {
 export const ChartBoxThreeAngle = () => {
   return (
     <div className={Styles.main}>
-      <img className={Styles.jiao1} src={require('@/assets/chartBox/jiao1.png')} />
-      <img className={Styles.jiao2} src={require('@/assets/chartBox/jiao2.png')} />
+      <img className={Styles.jiao1} src={require('@/Project/assets/chartBox/jiao1.png')} />
+      <img className={Styles.jiao2} src={require('@/Project/assets/chartBox/jiao2.png')} />
     </div>
   );
 };
@@ -67,21 +67,21 @@ export const ChartBoxTitle = (props:DataMeter.ITitleProps) => {
   return (
     <div className={Styles.main}>
       <div className={Styles.titleLeft}>
-        <img className={Styles.titleImg} src={require('@/assets/chartBox/titleBefor.png')} />
+        <img className={Styles.titleImg} src={require('@/Project/assets/chartBox/titleBefor.png')} />
         <span className={Styles.title}>{title}</span>
       </div>
       {setShowTabs && (
         <img
           // style={{ transform: rotate }}
           className={Styles.icon}
-          src={require('@/assets/chartBox/titleIcon.png')}
+          src={require('@/Project/assets/chartBox/titleIcon.png')}
           onClick={() => {
             // setRotate(showTabs ? '' : 'rotate(180deg)');
             setShowTabs(!showTabs);
           }}
         />
       )}
-      <img className={Styles.titleBorder} src={require('@/assets/chartBox/titleBorder.png')} />
+      <img className={Styles.titleBorder} src={require('@/Project/assets/chartBox/titleBorder.png')} />
     </div>
   );
 };

+ 24 - 4
src/Project/pages/DataMeter/Model/Map.tsx

@@ -25,12 +25,13 @@ const { TabPane } = Tabs;
 
 function Map(props: DataMeter.IModelsProps) {
   const { subModule, isNew, edit, layout, hasModel } = props;
+  let content: React.ReactElement;
   if (isNew) {
-    return <ProjectList {...props} />;
+    content = <ProjectList {...props} />;
   } else if (subModule != 0 && hasModel) {
-    return <NoModelMap {...props} />;
+    content = <NoModelMap {...props} />;
   } else {
-    return (
+    content = (
       <ModelMap
         {...props}
         // type={type}
@@ -45,6 +46,23 @@ function Map(props: DataMeter.IModelsProps) {
       </ModelMap>
     );
   }
+  // mouseEvent = {
+  //   onMouseEnter: () => {
+  //     UnityAction.emit('mouseHandle', 1);
+  //   },
+  //   onMouseLeave: () => {
+  //     UnityAction.emit('mouseHandle', 0);
+  //   },
+  // };
+  return (
+    <div
+      // {...mouseEvent}
+      key={layout.i}
+      // className={`${edit || type != 1 ? style.modelContent : ''}`}
+    >
+      {content}
+    </div>
+  );
 }
 
 function NoModelMap(props: DataMeter.IModelsProps) {
@@ -144,7 +162,7 @@ function ModelMap(props: DataMeter.IModelsProps) {
       const isLt = file.size / 1024 / 1024 < 1;
       if (!isLt) {
         message.error('图片必须小于1 M');
-      } 
+      }
       // else {
       //   setImgList([...imgList, file]);
       // }
@@ -462,3 +480,5 @@ function ModelMap(props: DataMeter.IModelsProps) {
     </div>
   );
 }
+
+export default Map;

+ 162 - 0
src/Project/pages/DataMeter/Model/Monitor.tsx

@@ -0,0 +1,162 @@
+import React from 'react';
+import { Empty, Tooltip } from 'antd';
+import { FullscreenOutlined } from '@ant-design/icons';
+import flvjs from 'flv.js';
+import style from './index.less';
+import { ChartBoxTitle } from './ChartBox';
+import { getMonitorList } from '@/Project/services/DataMeter';
+import { useRequest } from '@umijs/max';
+
+function Monitor(props: DataMeter.IModelsProps) {
+  const {
+    child,
+    projectId,
+    edit,
+    removeModel,
+    layout,
+    // match: {
+    //   params: { projectId },
+    // },
+  } = props;
+  // TODO: 接口请求
+  const { data: monitorList } = useRequest(() => getMonitorList(projectId));
+
+  var content;
+  var videoList;
+  if (!child || child.length == 0) {
+    videoList = monitorList.map((item: any) => ({
+      title: item.name,
+      key: item.id,
+      value: item.HttpFlvPath,
+      show: true,
+    }));
+  } else {
+    videoList = child;
+  }
+
+  if (videoList.length > 0) {
+    content = (
+      <ul className={style.videoList}>
+        {videoList.map((item: any) => {
+          return (
+            <li key={item.key}>
+              <div className={style.bg}>
+                {item.value && <VideoBox url={item.value} />}
+              </div>
+            </li>
+          );
+        })}
+      </ul>
+    );
+  } else {
+    content = <Empty />;
+  }
+
+  return (
+    <div className={style.layout} key={layout.i}>
+      <div className={style.modelBox}>
+        <ChartBoxTitle title={'视频监控'}></ChartBoxTitle>
+        <div className={style.modelContent}>{content}</div>
+      </div>
+      {/* {renderBtnToUnity(layout)} */}
+      <div
+        className={style.controlBox}
+        onMouseDown={(e) => {
+          e.stopPropagation();
+        }}
+      >
+        {edit && (
+          <Tooltip title="删除该模块">
+            <div
+              className={style.close}
+              onClick={() => {
+                removeModel(layout.key, layout.active);
+              }}
+            ></div>
+          </Tooltip>
+        )}
+      </div>
+    </div>
+  );
+}
+
+class VideoBox extends React.Component<any> {
+  // state = { videoEle: null };
+  videoEle!: HTMLVideoElement;
+  player!: flvjs.Player;
+  componentDidMount() {
+    const { url } = this.props;
+    const videoEle = this.videoEle;
+
+    if (flvjs.isSupported()) {
+      if (!videoEle) return;
+      let player = this.player;
+      player = flvjs.createPlayer({
+        type: 'flv',
+        isLive: true,
+        url,
+      });
+      player.attachMediaElement(videoEle);
+
+      try {
+        player.load();
+        player.play();
+      } catch (error) {
+        // console.log(error);
+      }
+    }
+    document.addEventListener('fullscreenchange', this.handleOutFullscreen);
+  }
+  componentWillUnmount() {
+    let player = this.player;
+    if (!player) return;
+    player.pause();
+    player.unload();
+    player.detachMediaElement();
+    player.destroy();
+    document.removeEventListener('fullscreenchange', this.handleOutFullscreen);
+  }
+  handleOutFullscreen(e: any) {
+    // UnityAction.emit('fullscreen', e.currentTarget.webkitIsFullScreen);
+  }
+  checkFull() {}
+
+  launchFullscreen() {
+    var element = this.videoEle;
+    //此方法不可以在異步任務中執行,否則火狐無法全屏
+    if (element.requestFullscreen) {
+      element.requestFullscreen();
+    } else {
+      var docHtml = document.documentElement;
+      var docBody = document.body;
+      var videobox = document.getElementById('videobox')!;
+      var cssText = 'width:100%;height:100%;overflow:hidden;';
+      docHtml.style.cssText = cssText;
+      docBody.style.cssText = cssText;
+      videobox.style.cssText = cssText + ';' + 'margin:0px;padding:0px;';
+      // document.fullscreen = true;
+    }
+  }
+  render() {
+    return (
+      <>
+        <FullscreenOutlined
+          onClick={() => {
+            this.launchFullscreen();
+          }}
+          className={style.fullscreen}
+          type="fullscreen"
+        />
+        <video
+          ref={(ele) => {
+            this.videoEle != ele;
+          }}
+          muted={true}
+          autoPlay={true}
+        ></video>
+      </>
+    );
+  }
+}
+
+export default Monitor;

+ 1 - 1
src/Project/pages/DataMeter/Model/ProjectInfo.tsx

@@ -119,7 +119,7 @@ function ProjectInfo(props: DataMeter.IModelsProps) {
     return dom;
   }, [child, projectDetail]);
 
-  if (!projectDetail) return 'loading....';
+  if (!projectDetail) return <div>loading....</div>;
   return (
     <div className={styles.modelBox}>
       <ChartBoxTitle title={'项目概况'} width={layout.w} />

+ 7 - 7
src/Project/pages/DataMeter/Model/ProjectList.less

@@ -2,7 +2,7 @@
   display: flex;
   flex-direction: column;
   height: 100%;
-  // background: url('@/assets/chartBox/bg.png') no-repeat center;
+  // background: url('@/Project/assets/chartBox/bg.png') no-repeat center;
   // background-size: 100% 100%;
   background: linear-gradient(rgba(29, 56, 104, 0.72), rgba(4, 18, 51, 0.76) );
   border: 1px solid;
@@ -39,7 +39,7 @@
   position: relative;
   margin-bottom: 16px;
   input {
-    background-image: url('@/assets/dataMeter/ProjectList/search_bg.png');
+    background-image: url('@/Project/assets/dataMeter/ProjectList/search_bg.png');
     background-size: 100% 100%;
     width: 100%;
     height: 35px;
@@ -81,7 +81,7 @@
   // padding-top: 16px;//28px;
   padding-left: 0;
   margin-bottom: 0;
-  // background-image: url('@/assets/dataMeter/ProjectList/listBG.png');
+  // background-image: url('@/Project/assets/dataMeter/ProjectList/listBG.png');
   // background-size: 100% 100%;
   li {
     width: 100%;
@@ -94,7 +94,7 @@
     text-overflow: ellipsis;
     white-space: nowrap;
     &.active {
-      // background-image: url('@/assets/dataMeter/ProjectList/selected.png');
+      // background-image: url('@/Project/assets/dataMeter/ProjectList/selected.png');
       // background-size: 100% 100%;
       // font-family: Microsoft YaHei UI;
       font-weight: bold;
@@ -124,7 +124,7 @@
   // height: 40%;
   // font-size: 16px;
   // font-family:  'Microsoft YaHei UI';//Microsoft YaHei UI;
-  background: url('@/assets/chartBox/ai_bg1.png') no-repeat center;
+  background: url('@/Project/assets/chartBox/ai_bg1.png') no-repeat center;
   background-size: 100% 100%;
   // overflow-y: auto;
   // padding: 24px 33px 23px 31px;
@@ -163,7 +163,7 @@
   font-size: 17px;
   line-height: 26px;
   // font-family: 'Microsoft YaHei UI';//Microsoft YaHei UI;
-  // background-image: url('@/assets/dataMeter/ProjectList/enterBtnBG.png');
+  // background-image: url('@/Project/assets/dataMeter/ProjectList/enterBtnBG.png');
   // background-size: 100% 100%;
   position: absolute;
   left: 0px;
@@ -186,7 +186,7 @@
   font-size: 17px;
   line-height: 26px;
   // font-family: 'Microsoft YaHei UI';// Microsoft YaHei UI;
-  // background-image: url('@/assets/dataMeter/ProjectList/enterBtnBG.png');
+  // background-image: url('@/Project/assets/dataMeter/ProjectList/enterBtnBG.png');
   // background-size: 100% 100%;
   position: absolute;
   left: 100px;

+ 6 - 2
src/Project/pages/DataMeter/Model/ProjectList.tsx

@@ -11,6 +11,7 @@ import ReactZmage from 'react-zmage';
 import PinyinMatch from 'pinyin-match';
 import { ChartBoxTitle } from './ChartBox';
 import { useRequest } from '@umijs/max';
+import { getProjectList } from '@/Project/services/DataMeter';
 
 let LoopTime: NodeJS.Timer;
 let searchTimer: NodeJS.Timer;
@@ -26,8 +27,11 @@ function ProjectList(props: DataMeter.IProjectListProps) {
   const [isPlay, setIsPlay] = useState(false);
   const [value, setValue] = useState<string>('');
   const ulRef = useRef<HTMLUListElement>(null);
-  const { data: projectList } = useRequest(() => {});
-
+  const ProjectListRequest = useRequest(getProjectList, {
+    cacheKey: 'projectList',
+    staleTime: -1,
+  });
+  const projectList = ProjectListRequest.data?.list || [];
   const list = useMemo<Api.IProject[]>(() => {
     const arr = projectList.filter((item: Api.IProject) => {
       let flag = subModule == 0 || item?.Stage == subModule || item?.Stage == 3;

+ 28 - 0
src/Project/pages/DataMeter/Model/index.less

@@ -0,0 +1,28 @@
+.controlBox {
+  position: absolute;
+  top: 0.1rem;
+  right: 0.3rem;
+  display: flex;
+}
+
+.edit {
+  width: 0.16rem;
+  height: 0.16rem;
+  // font-size: 0.2rem;
+  background: url('@/Project/assets/dataMeter/icon-edit.png') no-repeat center;
+  background-size: 100% 100%;
+  cursor: pointer;
+  margin-right: 0.1rem;
+  cursor: pointer;
+}
+
+.close {
+  width: 0.16rem;
+  height: 0.16rem;
+  // font-size: 0.2rem;
+  background: url('@/Project/assets/dataMeter/icon-close.png') no-repeat center;
+  background-size: 100% 100%;
+  cursor: pointer;
+  margin-right: 0.1rem;
+  cursor: pointer;
+}

+ 118 - 8
src/Project/pages/DataMeter/Model/index.tsx

@@ -1,16 +1,125 @@
-import style from '../index.less';
 import { CHILD_MAP } from '../config';
 import { Tooltip } from 'antd';
+import ProjectInfo from './ProjectInfo';
+import Map from './Map';
+import Monitor from './Monitor';
+import style from "./index.less"
+
 
 function Model(props: DataMeter.IModelsProps) {
-  const { layout } = props;
-  let content;
+  const { layout, edit, removeModel } = props;
+  let content: React.ReactElement;
+  let path: number;
+  switch (layout.key) {
+    case 'ProjectInfo':
+      content = <ProjectInfo {...props} />;
+      path = 1;
+      break;
+    case 'Map':
+      return <Map {...props} />;
+    case 'Monitor':
+      return <Monitor {...props} />;
+    // case 'AlarmCenter': //报警中心
+    //   content = (
+    //     <AlarmCenter
+    //       key={layout.i}
+    //       projectId={projectId}
+    //       {...props}
+    //       child={layout.child}
+    //       layout={layout}
+    //       setActive={setActive}
+    //       subModule={subModule}
+    //     />
+    //   );
+    //   break;
+    // case 'FileManagement':
+    //   content = (
+    //     <FileManagement
+    //       key={layout.i}
+    //       projectId={projectId}
+    //       {...props}
+    //       child={layout.child}
+    //     />
+    //   );
+    //   break;
+    // case 'DataCenter':
+    //   let originList = [];
+    //   let configList = (chartConfigList || []).map((config) => {
+    //     var data = layout.child.find((child) => child.key === config.id);
+    //     return {
+    //       ...config,
+    //       title: config.name,
+    //       key: config.id,
+    //       type: 'chartConfig',
+    //       show: data ? data.show : true,
+    //     };
+    //   });
+    //   layout.child.forEach((layout) => {
+    //     if (!layout.children && layout.type != 'chartConfig') {
+    //       originList.push(layout);
+    //     } else {
+    //       // 有子级则只将子级加入tabs
+    //       originList = originList.concat(layout.children);
+    //     }
+    //   });
 
+    //   originList = originList.concat(configList);
+    //   content = (
+    //     <DataCenter
+    //       projectId={projectId}
+    //       key={layout.i + projectId}
+    //       {...props}
+    //       child={
+    //         subModule == 0 ? originList : chartConfigList ? originList : []
+    //       }
+    //       layout={layout}
+    //       setActive={setActive}
+    //     />
+    //   );
+    //   break;
+    // case 'MessageCenter': //新闻动态
+    //   content = (
+    //     <MessageCenter
+    //       key={layout.i}
+    //       projectId={projectId}
+    //       {...props}
+    //       child={layout.child}
+    //       layout={layout}
+    //       setActive={setActive}
+    //     />
+    //   );
+    //   break;
+    // case 'Other':
+    //   content = (
+    //     <Other
+    //       key={layout.i}
+    //       {...props}
+    //       projectId={projectId}
+    //       child={layout.child}
+    //       layout={layout}
+    //       setActive={setActive}
+    //       subModule={subModule}
+    //     />
+    //   );
+    //   break;
+    // case 'PlanManagement':
+    //   content = (
+    //     <PlanManagement
+    //       key={layout.i}
+    //       projectId={projectId}
+    //       {...props}
+    //       child={layout.child}
+    //       layout={layout}
+    //       setActive={setActive}
+    //     />
+    //   );
+    //   break;
+    default:
+      content = <div>loading...</div>;
+      break;
+  }
   return (
-    <div
-      className={style.item}
-      key={layout.i}
-    >
+    <div key={layout.i}>
       {content}
       <Control {...props} />
     </div>
@@ -49,5 +158,6 @@ function Control(props: DataMeter.IModelsProps) {
     </div>
   );
 }
-
 export default Model;
+
+// export default (props: DataMeter.IModelsProps) => <div>123123</div>;

+ 64 - 43
src/Project/pages/DataMeter/index.less

@@ -4,7 +4,7 @@
 // }
 
 .dataMeter {
-  width: 100vw; 
+  width: 100vw;
   margin: 0 auto;
   min-height: 100%;
   background: url('@/Project/assets/newBackground.jpg') no-repeat center;
@@ -18,6 +18,7 @@
 .gridBox {
   width: 100%;
   position: relative;
+  height: 100%;
 }
 
 .noScroll {
@@ -34,7 +35,7 @@
 }
 
 .item {
-  // background: url('@/assets/dataMeter/conLeft.png') no-repeat 100% 100%;
+  // background: url('@/Project/assets/dataMeter/conLeft.png') no-repeat 100% 100%;
   background-size: 100% 100%;
   position: relative;
 
@@ -49,7 +50,7 @@
     width: 0.16rem;
     height: 0.16rem;
     // font-size: 0.2rem;
-    background: url('@/assets/dataMeter/icon-edit.png') no-repeat center;
+    background: url('@/Project/assets/dataMeter/icon-edit.png') no-repeat center;
     background-size: 100% 100%;
     cursor: pointer;
     margin-right: 0.1rem;
@@ -60,7 +61,7 @@
     width: 0.16rem;
     height: 0.16rem;
     // font-size: 0.2rem;
-    background: url('@/assets/dataMeter/icon-close.png') no-repeat center;
+    background: url('@/Project/assets/dataMeter/icon-close.png') no-repeat center;
     background-size: 100% 100%;
     cursor: pointer;
     margin-right: 0.1rem;
@@ -153,7 +154,7 @@
   }
 
   .iconUpload {
-    background: url('@/assets/dataMeter/icon-upload.png') no-repeat center;
+    background: url('@/Project/assets/dataMeter/icon-upload.png') no-repeat center;
     background-size: 100% 100%;
     cursor: pointer;
     width: 0.16rem;
@@ -177,10 +178,10 @@
   height: 100%;
   line-height: 1;
   font-size: 0.14rem;
-  // background: url('@/assets/chartBox/bg.png') no-repeat center;
+  // background: url('@/Project/assets/chartBox/bg.png') no-repeat center;
   // background-size: 100% 100%;
   // border: #2866B2 solid 1px;
-  background: linear-gradient(rgba(29, 56, 104, 0.72), rgba(4, 18, 51, 0.76) );
+  background: linear-gradient(rgba(29, 56, 104, 0.72), rgba(4, 18, 51, 0.76));
   border: 1px solid;
   border-image: linear-gradient(45deg, rgba(74, 196, 253, 0.45), rgba(173, 219, 240, 0.34), rgba(146, 213, 249, 0.28)) 1;
   // box-shadow: 0px 8px 32px 0px rgba(0, 0, 0, 0.16);
@@ -429,7 +430,7 @@
     margin-top: 10px;
     width: 149px;
     height: 24px;
-    background: url('@/assets/dataMeter/ProjectList/search_bg.png') no-repeat center;
+    background: url('@/Project/assets/dataMeter/ProjectList/search_bg.png') no-repeat center;
     background-size: 100% 100%;
     cursor: pointer;
   }
@@ -523,7 +524,7 @@
 
 // 地图
 .mapBg {
-  // background: url('@/assets/dataMeter/map-bg.png') no-repeat center;
+  // background: url('@/Project/assets/dataMeter/map-bg.png') no-repeat center;
   background-size: 100% 100%;
   // background: #010522;
 }
@@ -549,25 +550,25 @@
     &.icon1 {
       top: 0;
       left: 0;
-      background-image: url('@/assets/dataMeter/map-icon1.png');
+      background-image: url('@/Project/assets/dataMeter/map-icon1.png');
     }
 
     &.icon2 {
       top: 0;
       right: 0;
-      background-image: url('@/assets/dataMeter/map-icon2.png');
+      background-image: url('@/Project/assets/dataMeter/map-icon2.png');
     }
 
     &.icon3 {
       bottom: 0;
       left: 0;
-      background-image: url('@/assets/dataMeter/map-icon4.png');
+      background-image: url('@/Project/assets/dataMeter/map-icon4.png');
     }
 
     &.icon4 {
       bottom: 0;
       right: 0;
-      background-image: url('@/assets/dataMeter/map-icon3.png');
+      background-image: url('@/Project/assets/dataMeter/map-icon3.png');
     }
   }
 }
@@ -654,7 +655,7 @@
 
 // 模块列表
 .drawer {
-  width: 502px;    
+  width: 502px;
   padding: 43px 86px;
   // box-shadow: -2px 0 8px rgb(0, 0, 0, 0.15);
   position: fixed;
@@ -679,7 +680,7 @@
     color: #183266;
     line-height: 24px;
     letter-spacing: 2px;
-    background: linear-gradient(to right,rgba(153, 231, 255, 0.80), rgba(96, 168, 255, 1));
+    background: linear-gradient(to right, rgba(153, 231, 255, 0.80), rgba(96, 168, 255, 1));
 
     .title {
       margin: 0;
@@ -689,8 +690,8 @@
       line-height: 1;
       font-family: 'dataMeter';
     }
-    
-    .closeIcon{
+
+    .closeIcon {
       width: 26px;
       height: 26px;
       background: url('@/Project/assets/newUI/modalClose.png');
@@ -699,13 +700,15 @@
       background-position: center;
     }
   }
-  .itemContent{
+
+  .itemContent {
     width: 100%;
     display: flex;
     align-items: center;
     justify-content: space-between;
   }
-  .titleTip{
+
+  .titleTip {
     width: 304px;
     height: 36px;
     display: flex;
@@ -713,48 +716,56 @@
     align-items: center;
     margin-bottom: 14px;
     padding-right: 14px;
-    background: linear-gradient(to right,rgba(153, 231, 255, 0.80), rgba(96, 168, 255, 1));
-    .titleTipIcon{
+    background: linear-gradient(to right, rgba(153, 231, 255, 0.80), rgba(96, 168, 255, 1));
+
+    .titleTipIcon {
       width: 26px;
       height: 18px;
       margin-right: 8px;
     }
-    .iconIn{
+
+    .iconIn {
       .titleTipIcon;
       background: url('@/Project/assets/newUI/icon_in.png');
       background-size: 100% 100%;
     }
-    .iconOut{
+
+    .iconOut {
       .titleTipIcon;
       background: url('@/Project/assets/newUI/icon_out.png');
       background-size: 100% 100%;
     }
-    .titleTipText{
+
+    .titleTipText {
       font-size: 14px;
       font-weight: 400;
       color: #183266;
       line-height: 36px;
     }
-    .titleTipLine{
+
+    .titleTipLine {
       margin: 0 16px;
       width: 1px;
       height: 18px;
       background: #183266;
     }
   }
-  .itemIconIn{
+
+  .itemIconIn {
     width: 26px;
     height: 18px;
     background: url('@/Project/assets/newUI/icon1_in.png');
     background-size: 100% 100%;
   }
-  .itemIconOut{
+
+  .itemIconOut {
     width: 26px;
     height: 18px;
     background: url('@/Project/assets/newUI/icon1_out.png');
     background-size: 100% 100%;
   }
-  .childIconIn{
+
+  .childIconIn {
     margin-top: 8px;
     width: 16px;
     height: 12px;
@@ -762,7 +773,8 @@
     background: url('@/Project/assets/newUI/icon1_in.png');
     background-size: 100% 100%;
   }
-  .childIconOut{
+
+  .childIconOut {
     margin-top: 8px;
     width: 16px;
     height: 12px;
@@ -771,7 +783,7 @@
     background-size: 100% 100%;
   }
 
-  .icon{
+  .icon {
     width: 7px;
     height: 10px;
     background: url('@/Project/assets/dataMeter/arrowIcon.png') no-repeat center;
@@ -779,7 +791,8 @@
     margin-right: 12px;
     transition: transform 0.2s;
   }
-  .itemDiv{
+
+  .itemDiv {
     color: #C0F0FF;
     font-size: 16px;
     line-height: 32px;
@@ -801,7 +814,8 @@
     overflow-y: auto;
     background: url('@/Project/assets/dataMeter/contentBg.png') no-repeat center;
     background-size: 100% 100%;
-    .title{
+
+    .title {
       font-size: 22px;
       font-weight: 400;
       color: #C0F0FF;
@@ -810,22 +824,24 @@
     }
 
     :global {
-      .ant-list-bordered{
+      .ant-list-bordered {
         border: none;
       }
-      .ant-list-bordered .ant-list-item{
+
+      .ant-list-bordered .ant-list-item {
         background: url('~@/Project/assets/dataMeter/itemBg.png') no-repeat center;
         background-size: 100% 100%;
         margin-bottom: 14px;
         border-bottom: 1px solid #6597BA;
       }
-      
-      .ant-collapse-borderless > .ant-collapse-item > .ant-collapse-content > .ant-collapse-content-box{
+
+      .ant-collapse-borderless>.ant-collapse-item>.ant-collapse-content>.ant-collapse-content-box {
         padding-left: 26px;
       }
+
       .ant-collapse {
         border: none;
-  
+
         >.ant-collapse-item>.ant-collapse-header {
           color: #183266;
           background: #C0F0FF;
@@ -834,7 +850,7 @@
           font-weight: 500;
           line-height: 22px;
         }
-        
+
       }
     }
   }
@@ -846,9 +862,10 @@
   position: fixed;
   top: 0;
   right: 50px;
-  background: linear-gradient(to right,rgba(9, 20, 64, 0.85), rgba(48, 85, 148, 0.77));
+  background: linear-gradient(to right, rgba(9, 20, 64, 0.85), rgba(48, 85, 148, 0.77));
   z-index: 999;
   height: 1000px;
+
   .header {
     position: relative;
     padding: 10px 20px 10px 18px;
@@ -870,7 +887,7 @@
       letter-spacing: 2px;
     }
 
-    .closeIcon{
+    .closeIcon {
       width: 26px;
       height: 26px;
       background: url('@/Project/assets/newUI/modalClose.png');
@@ -925,6 +942,7 @@
       align-items: center;
       border-top: 2px solid #99E7FF;
       margin-top: 40px;
+
       :global {
         .ant-btn {
           height: 46px;
@@ -1066,16 +1084,19 @@
       font-size: 14px;
       line-height: 20px;
     }
-    .ant-col-8{
+
+    .ant-col-8 {
       margin-bottom: 18px;
     }
-    .ant-checkbox + span{
+
+    .ant-checkbox+span {
       font-size: 18px;
       color: #D7E4E8;
     }
   }
- 
+
 }
+
 //遮罩
 .mask {
   width: 780px;

+ 141 - 6
src/Project/pages/DataMeter/index.tsx

@@ -10,15 +10,27 @@ import {
   DEFAULT_MAP_LAYOUT,
   U3D_PATH_STATE,
 } from './config';
-import React, { useMemo, useRef, useState } from 'react';
+import React, { useEffect, useMemo, useRef, useState } from 'react';
+import { Modal } from 'antd';
+import Model from './Model';
+import { useModel, useRequest } from '@umijs/max';
+import {
+  getLayoutOptions,
+  saveLayoutOptions,
+} from '@/Project/services/DataMeter';
 
 const gridWidth = document.documentElement.clientWidth;
 
 function DataMeter(props: DataMeter.IProps) {
+  const {
+    initialState: { projectId },
+  } = useModel('@@initialState');
+
+  const { hasModel, subModule, isNew } = props;
   // 编辑模块
   const [editVisible, setEditVisible] = useState(false);
   // 子模块列表
-  const [currentModel, setCurrentModel] = useState(null);
+  const [currentModel, setCurrentModel] = useState<DataMeter.ILayout>();
   // 抽屉栏显示状态
   const [visible, setVisible] = useState(false);
   // 布局信息
@@ -26,7 +38,7 @@ function DataMeter(props: DataMeter.IProps) {
   // 编辑状态
   const [edit, setEdit] = useState(false);
   // 子模块多选
-  const [modelCheck, setModelCheck] = useState([]);
+  const [modelCheck, setModelCheck] = useState<any>([]);
 
   const [dataCenterChild, setDataCenterChild] = useState([]);
   // map 类型
@@ -42,6 +54,19 @@ function DataMeter(props: DataMeter.IProps) {
   //创建模板弹窗状态
   const [createMouldVisible, setCreateMouldVisible] = useState(false);
 
+  const layoutRequest = useRequest(getLayoutOptions, {
+    defaultParams: [
+      {
+        projectId: projectId || 0,
+        module: 1,
+        sub_module: subModule,
+        is_default: 0,
+      },
+    ],
+    onSuccess(data, params) {
+      setLayout(data.config_json);
+    },
+  });
   // 布局发生改变回调函数
   const onLayoutChange = (newLayout: DataMeter.ILayout[]) => {
     // console.log(newLayout);
@@ -60,9 +85,93 @@ function DataMeter(props: DataMeter.IProps) {
     }
   };
 
+  // 删除模块
+  const removeModel = (key: string, active: string) => {
+    Modal.confirm({
+      title: '提醒',
+      content: `确认删除模块吗?`,
+      okText: '确认',
+      cancelText: '取消',
+      onOk: () => {
+        let index = layout.findIndex((cur) => {
+          if (active) return key == cur.key && active == cur.active;
+          return key == cur.key;
+        });
+        let newLayout = [...layout];
+        newLayout.splice(index, 1);
+        setLayout(newLayout);
+      },
+    });
+  };
+  // 显示子模块编辑框
+  const showEditModel = (item: DataMeter.ILayout) => {
+    // 模块列表显示时会导致无法滚动的bug,编辑时隐藏模块列表
+    setVisible(false);
+    setEditVisible(true);
+    setCurrentModel(item);
+
+    // 设置默认选中
+    let checked: any[] = [];
+    item.child?.forEach((item) => {
+      if (item.show) checked.push(item.key);
+    });
+    setModelCheck(checked);
+  };
+  // 保存配置
+  const saveLayout = async (newLayout: DataMeter.ILayout[], isDefault = 0) => {
+    let id,
+      payload = {
+        projectId,
+        module: 1,
+        sub_module: subModule,
+        is_default: isDefault,
+      };
+    if (isDefault == 1) {
+      // 查询默认配置的id
+      let res = await getLayoutOptions({ ...payload });
+      id = res.data.id || 0;
+      // 修改默认配置
+      await saveLayoutOptions({
+        ...payload,
+        config_json: JSON.stringify(newLayout),
+        id,
+        //默认配置的projectId为0
+      });
+    } else {
+      let item = layoutRequest.data;
+      id = item.is_default == 1 ? 0 : item.id;
+      await saveLayoutOptions({
+        ...payload,
+        config_json: JSON.stringify(newLayout),
+        id,
+      });
+    }
+  };
   const models = useMemo(() => {
+    return layout.map((item) => {
+      const setActive = (key: number | string) => {
+        item.active = key;
+        saveLayout(layout);
+      };
+      return (
+        <Model
+          key={item.i}
+          hasModel={hasModel}
+          child={item.child || []}
+          projectId={projectId}
+          removeModel={removeModel}
+          edit={edit}
+          layout={item}
+          setActive={setActive}
+          subModule={subModule}
+          isNew={isNew}
+          showEditModel={showEditModel}
+        />
+      );
+    });
+  }, [layout]);
 
-  },[layout])
+  console.log(layoutRequest);
 
   return (
     <div
@@ -115,7 +224,30 @@ function DataMeter(props: DataMeter.IProps) {
           className="layout"
           isDraggable={edit}
           isResizable={edit}
-          layout={layout}
+          // layout={layout}
+          layout={[
+            {
+              i: '1',
+              w: 1,
+              h: 2,
+              x: 0,
+              y: 0,
+            },
+            {
+              i: '2',
+              w: 1,
+              h: 2,
+              x: 0,
+              y: 0,
+            },
+            {
+              i: '3',
+              w: 1,
+              h: 2,
+              x: 0,
+              y: 0,
+            },
+          ]}
           onLayoutChange={onLayoutChange}
           cols={COL_COLS}
           rowHeight={rowHeight}
@@ -123,10 +255,13 @@ function DataMeter(props: DataMeter.IProps) {
           margin={[15, 10]}
         >
           {/* {models} */}
+          <div>1</div>
+          <div>2</div>
+          <div>3</div>
         </GridLayout>
       </div>
     </div>
   );
 }
 
-
+export default DataMeter;

+ 2 - 2
src/Project/pages/DataMeter/typings.d.ts

@@ -37,13 +37,13 @@ declare namespace DataMeter {
     isNew: boolean;
     showEditModel: Function;
     removeModel: Function;
-    children?: React.ReactElement
+    children?: React.ReactElement;
   }
   interface ITitleProps {
     title: string;
     showTabs?: boolean;
     setShowTabs?: Function;
-    width: number;
+    width?: number;
   }
   interface IProjectListProps {
     edit:boolean,

+ 0 - 234
src/Project/services/DataMeter.js

@@ -1,234 +0,0 @@
-import request from '@/utils/request';
-import { stringify } from 'qs';
-
-// 获得项目详情
-export async function getProject(params) {
-  return request(`/project/${params.projectId}`);
-}
-
-// 异常报警通知列表
-export async function getFaultAnalysis(params) {
-  return request(`/fault_analysis/result/${params.projectId}`);
-}
-
-// 项目预警
-export async function getProjectAlarm(params) {
-  return request(`/notification/list?${stringify(params)}`);
-}
-
-
-/**
- * 问题追踪列表
- * @param {object} params
- * @param {number} params.projectId
- * @param {number} params.currentPage
- * @param {number} params.pageSize
- * @returns
- */
-export async function getIssueList(params) {
-  // return request(`/issue/list/${params.projectId}?${stringify(params)}`);
-  return request(`/issue/ticket/list/${params.projectId}?${stringify(params)}`);
-}
-
-/**
- * 消息推送
- * @param {object} params
- * @param {number} params.currentPage
- * @param {number} params.pageSize
- * @returns
- */
-export async function getNotificationList(params) {
-  return request(`/notification/list?${stringify(params)}`);
-}
-
-/**
- * 上传多媒体资源
- * @param {object} params
- * @param {array}  params.files
- * @param {number} params.projectId
- * @param {number} params.type  0-图片,1- 视频
- * @returns
- */
-
-export async function uploadMedia(params) {
-  return request(`/project-cabin-file/${params.projectId}/${type}`, {
-    method: 'POST',
-    body: {
-      ...params,
-    },
-  });
-}
-
-/**
- * 多媒体资源查询
- * @param {object} params
- * @param {number} params.projectId
- * @returns
- */
-
-export async function getMediaList(params) {
-  return request(`/project-file/${params.projectId}/26/-1`);
-}
-
-/**
- * 视频监控查询
- * @param {object} params
- * @param {string} params.currentPage
- * @param {string} params.pageSize
- * @param {number} params.projectId
- * @returns
- */
-
-export async function getMonitorList(params) {
-  // return request(`/monitor/list/${params.projectId}?${stringify(params)}`);
-  return request(`/monitor_config/query/${params.projectId}`);
-}
-
-/**
- * 项目动态
- * @param {object} params
- * @param {string} params.currentPage
- * @param {string} params.pageSize
- * @param {number} params.projectId
- * @param {number} params.type 动态类型:-1-所有类型, 0-项目动态 1-新闻动态 2-大事记 3-所获奖项
- * @returns
- */
-
-export async function getProjectActive(params) {
-  return request(`/project-active/list/${params.projectId}/${params.type}?${stringify(params)}`);
-}
-
-/**
- * 设计|采购|施工详细进度
- * @param {object} params
- * @param {number} params.projectId
- * @returns
- */
-
-export async function getProjectProgress(params) {
-  return request(`/project-progress/${params.projectId}`);
-}
-
-/**
- * 设计|采购|施工总进度
- * @param {object} params
- * @param {number} params.projectId
- * @returns
- */
-
-export async function getProjectTotalProgress(params) {
-  return request(`/project-plan-progress/${params.projectId}`);
-}
-
-/**
- * 安全操作规范列表查询
- * @param {object} params
- * @param {number} params.projectId
- * @param {string} params.currentPage
- * @param {string} params.pageSize
- * @returns
- */
-
-export async function getUserGuide(params) {
-  return request(`/user_guide/list/${params.projectId}?${stringify(params)}`);
-}
-
-/**
- * 项目日志列表查询
- * @param {object} params
- * @param {number} params.projectId
- * @param {string} params.currentPage
- * @param {string} params.pageSize
- * @returns
- */
-
-export async function getDailyList(params) {
-  return request(`/daily/list/${params.projectId}?${stringify(params)}`);
-}
-
-/**
- * 删除资源
- * @param {object} params
- * @param {number} params.id
- * @returns
- */
-
-export async function deleteFile(params) {
-  return request(`/delete/project-cabin-file/${params.id}`, {
-    method: 'POST',
-  });
-}
-
-/**
- * 保存布局配置
- * @param {object} params
- * @param {number} params.projectId 项目id,地图页为0
- * @param {number} params.id 配置id,大于0,则更新
- * @param {number} params.module 所属模块:1-驾驶舱 2-模型分层 3-管道流向
- * @param {number} params.sub_module 子模块: (驾驶舱)0-地图驾驶舱 1-建设驾驶舱 2-运营驾驶舱
- * @param {string} params.config_json 配置json数据
- * @param {number} params.is_default 是否默认配置,大于1时会校验调用者权限
- * @returns
- */
-
-export async function saveLayoutOptions(params) {
-  return request(`/project_config/save/${params.projectId || 0}`, {
-    method: 'POST',
-    body: {
-      ...params,
-    },
-  });
-}
-
-/**
- * 读取配置
- * @param {object} params
- * @param {number} params.projectId 项目id,地图页为0
- * @param {number} params.module 所属模块:1-驾驶舱 2-模型分层 3-管道流向
- * @param {number} params.sub_module 子模块: (驾驶舱)0-地图驾驶舱 1-建设驾驶舱 2-运营驾驶舱
- * @param {number} params.is_default 是否默认配置,大于1时会校验调用者权限
- * @returns
- */
-
-export async function getLayoutOptions(params) {
-  return request(`/project_config/query/${params.projectId || 0}?${stringify(params)}`);
-}
-
-// 获取故障列表
-export async function getBreakdownRecord(params) {
-  return request(`/breakdown-record/unhandled/list/${params.projectId}`);
-}
-
-//获取项目列表
-export async function getProjectList(params) {
-  return request(`/api/v2/project?${stringify(params)}`)
-}
-
-//获取巡检结果
-export async function getAutoPatrol(params) {
-  return request(`/patrol/auto/data/${params.projectId}`)
-}
-
-export async function getBreakdownList(params) {
-  return request(`/breakdown-record/list/${params.projectId}?${stringify(params)}`);
-}
-export async function getPatrolRecord(params) {
-  return request(`/patrol/data/${params.projectId}?${stringify(params)}`);
-}
-
-export async function getMouldList(params) {
-  return request(`/project_config/template-list/${params.project_id || 0}?${stringify(params)}`);
-}
-
-export async function createMouldList(params) {
-  return request(`/project_config/save-template/${params.projectId || 0}`, {
-    method: 'POST',
-    headers: { ContentType: 'application/x-www-form-urlencoded' },
-    body: params.formData,
-  });
-}
-export async function getAutoPatrolByRouteId(params) {
-  return request(`/patrol/data/${params.projectId}/${params.routeId}`)
-}
-
-

+ 292 - 0
src/Project/services/DataMeter.ts

@@ -0,0 +1,292 @@
+import { request } from 'umi';
+import {
+  DEFAULT_LAYOUT,
+  DEFAULT_MAP_LAYOUT,
+} from '@/Project/pages/DataMeter/config';
+
+// 获得项目详情
+export async function getProject(projectId: string | number) {
+  return request(`/project/${projectId}`);
+}
+
+// 异常报警通知列表
+export async function getFaultAnalysis(projectId: string | number) {
+  return request(`/fault_analysis/result/${projectId}`);
+}
+
+// 项目预警
+interface IProjectAlarmParams {
+  pageSize: number;
+  currentPage: number;
+  msgType: string;
+  projectId: number | string;
+}
+export async function getProjectAlarm(params: IProjectAlarmParams) {
+  return request(`/notification/list`, {
+    params: params,
+  });
+}
+
+/**
+ * 问题追踪列表
+ */
+interface IIssueListParams {
+  currentPage: number;
+  pageSize: number;
+  projectId: number | string;
+}
+export async function getIssueList(params: IIssueListParams) {
+  // return request(`/issue/list/${params.projectId}`);
+  return request(`/issue/ticket/list/${params.projectId}`, {
+    params: params,
+  });
+}
+
+/**
+ * 消息推送
+ */
+interface INotificationListParams {
+  currentPage: number;
+  pageSize: number;
+}
+export async function getNotificationList(params: INotificationListParams) {
+  return request(`/notification/list?`, {
+    params: params,
+  });
+}
+
+/**
+ * 上传多媒体资源
+ */
+interface IuploadMediaParams {
+  type: number; //0-图片,1- 视频
+  projectId: number;
+  files: any[];
+}
+export async function uploadMedia(params: IuploadMediaParams) {
+  return request(`/project-cabin-file/${params.projectId}/${params.type}`, {
+    method: 'POST',
+    body: {
+      ...params,
+    },
+  });
+}
+
+/**
+ * 多媒体资源查询
+ * @param {object} params
+ * @param {number} params.projectId
+ * @returns
+ */
+export async function getMediaList(params: any) {
+  return request(`/project-file/${params.projectId}/26/-1`);
+}
+
+/**
+ * 视频监控查询
+ * @param {object} params
+ * @param {string} params.currentPage
+ * @param {string} params.pageSize
+ * @param {number} params.projectId
+ * @returns
+ */
+
+export async function getMonitorList(projectId: string | number): Promise<any> {
+  // return request(`/monitor/list/${params.projectId}`);
+  let data: Api.IMonitor = await request(`/monitor_config/query/${projectId}`);
+  let obj: any;
+  try {
+    obj = JSON.parse(data.config_json) || {};
+  } catch (error) {
+    obj = {};
+  }
+  return Object.keys(obj).map((key) => obj[key]) || [];
+}
+
+/**
+ * 项目动态
+ * @param {object} params
+ * @param {string} params.currentPage
+ * @param {string} params.pageSize
+ * @param {number} params.projectId
+ * @param {number} params.type 动态类型:-1-所有类型, 0-项目动态 1-新闻动态 2-大事记 3-所获奖项
+ * @returns
+ */
+
+export async function getProjectActive(params: any) {
+  return request(`/project-active/list/${params.projectId}/${params.type}}`, {
+    params: params,
+  });
+}
+
+/**
+ * 设计|采购|施工详细进度
+ * @param {object} params
+ * @param {number} params.projectId
+ * @returns
+ */
+
+export async function getProjectProgress(params: any) {
+  return request(`/project-progress/${params.projectId}`);
+}
+
+/**
+ * 设计|采购|施工总进度
+ * @param {object} params
+ * @param {number} params.projectId
+ * @returns
+ */
+
+export async function getProjectTotalProgress(params: any) {
+  return request(`/project-plan-progress/${params.projectId}`);
+}
+
+/**
+ * 安全操作规范列表查询
+ * @param {object} params
+ * @param {number} params.projectId
+ * @param {string} params.currentPage
+ * @param {string} params.pageSize
+ * @returns
+ */
+
+export async function getUserGuide(params: any) {
+  return request(`/user_guide/list/${params.projectId}`, {
+    params: params,
+  });
+}
+
+/**
+ * 项目日志列表查询
+ * @param {object} params
+ * @param {number} params.projectId
+ * @param {string} params.currentPage
+ * @param {string} params.pageSize
+ * @returns
+ */
+
+export async function getDailyList(params: any) {
+  return request(`/daily/list/${params.projectId}`, {
+    params: params,
+  });
+}
+
+/**
+ * 删除资源
+ * @param {object} params
+ * @param {number} params.id
+ * @returns
+ */
+
+export async function deleteFile(params: any) {
+  return request(`/delete/project-cabin-file/${params.id}`, {
+    method: 'POST',
+  });
+}
+
+/**
+ * 保存布局配置
+ * @param {object} params
+ * @param {number} params.projectId 项目id,地图页为0
+ * @param {number} params.id 配置id,大于0,则更新
+ * @param {number} params.module 所属模块:1-驾驶舱 2-模型分层 3-管道流向
+ * @param {number} params.sub_module 子模块: (驾驶舱)0-地图驾驶舱 1-建设驾驶舱 2-运营驾驶舱
+ * @param {string} params.config_json 配置json数据
+ * @param {number} params.is_default 是否默认配置,大于1时会校验调用者权限
+ * @returns
+ */
+
+export async function saveLayoutOptions(params: any) {
+  return request(`/api/v1/project_config/save/${params.projectId || 0}`, {
+    method: 'POST',
+    body: {
+      ...params,
+    },
+  });
+}
+
+/**
+ * 读取配置
+ * @param {object} params
+ * @param {number} params.projectId 项目id,地图页为0
+ * @param {number} params.module 所属模块:1-驾驶舱 2-模型分层 3-管道流向
+ * @param {number} params.sub_module 子模块: (驾驶舱)0-地图驾驶舱 1-建设驾驶舱 2-运营驾驶舱
+ * @param {number} params.is_default 是否默认配置,大于1时会校验调用者权限
+ * @returns
+ */
+
+export async function getLayoutOptions(params: any) {
+  const response = await request(
+    `/api/v1/project_config/query/${params.projectId || 0}`,
+    {
+      params: params,
+    },
+  );
+
+  var data = response.data;
+  try {
+    data.config_json = JSON.parse(data.config_json);
+  } catch (error) {
+    // 解析失败则使用默认布局
+    var defaultLayout =
+      params.sub_module === 0 ? DEFAULT_MAP_LAYOUT : DEFAULT_LAYOUT;
+    data.config_json = defaultLayout;
+  }
+  return response;
+}
+
+// 获取故障列表
+export async function getBreakdownRecord(params: any) {
+  return request(`/breakdown-record/unhandled/list/${params.projectId}`);
+}
+
+//获取项目列表
+export async function getProjectList(params: any) {
+  const response = await request(`/api/v2/project`, {
+    params: params,
+  });
+  let nowDate = new Date();
+  (response.data.list || []).map((item: Api.IProject) => {
+    let type;
+    if (!item.EndDate) {
+      type = 2;
+    } else {
+      type = nowDate >= new Date(item.EndDate) ? 2 : 1;
+    }
+    item.type = type;
+  });
+  return response;
+}
+
+//获取巡检结果
+export async function getAutoPatrol(params: any) {
+  return request(`/patrol/auto/data/${params.projectId}`);
+}
+
+export async function getBreakdownList(params: any) {
+  return request(`/breakdown-record/list/${params.projectId}`, {
+    params: params,
+  });
+}
+export async function getPatrolRecord(params: any) {
+  return request(`/patrol/data/${params.projectId}`, {
+    params: params,
+  });
+}
+
+export async function getMouldList(params: any) {
+  return request(`/project_config/template-list/${params.project_id || 0}`, {
+    params: params,
+  });
+}
+
+export async function createMouldList(params: any) {
+  return request(`/project_config/save-template/${params.projectId || 0}`, {
+    method: 'POST',
+    headers: { ContentType: 'application/x-www-form-urlencoded' },
+    body: params.formData,
+  });
+}
+export async function getAutoPatrolByRouteId(params: any) {
+  return request(`/patrol/data/${params.projectId}/${params.routeId}`);
+}

+ 18 - 0
src/Project/services/typings.d.ts

@@ -27,6 +27,8 @@ declare namespace Api {
   interface IProject {
     Name: string;
     ID: number;
+    EndDate: string;
+    StartDate: string;
     Code: string;
     Position: string;
     Province: string;
@@ -76,5 +78,21 @@ declare namespace Api {
     PreSaleManagerUser: IUser | null;
     OptManagerUser: IUser | null;
     MechanicalDesignerUser: IUser | null;
+    type?: number;
+  }
+  interface IMonitor {
+    id: number;
+    project_id: number;
+    user_id: number;
+    module: number;
+    sub_module: number;
+    config_json: string;
+    is_default: number;
+    name: string;
+    is_template: number;
+    cover: string;
+    c_time: string;
+    m_time: string;
+    status: number;
   }
 }

+ 2 - 2
src/app.ts

@@ -9,7 +9,7 @@ export async function getInitialState(): Promise<any> {
   let currentUser = {},
     access = {};
   // 非登录页获取用户信息
-  if (!window.GT_APP.funcLogin.IsActive) {
+  if (!window.GT_APP?.funcLogin?.IsActive) {
     try {
       currentUser = (await queryCurrent()).data;
     } catch (error) {}
@@ -17,7 +17,7 @@ export async function getInitialState(): Promise<any> {
       access = await queryAccess(46);
     } catch (error) {}
   }
-  return { currentUser, access, projectId: 0 };
+  return { currentUser, access, projectId: 46 };
 }
 
 // axios配置

+ 18 - 0
yarn.lock

@@ -4077,6 +4077,11 @@ es6-iterator@^2.0.3:
     es5-ext "^0.10.35"
     es6-symbol "^3.1.1"
 
+es6-promise@^4.2.8:
+  version "4.2.8"
+  resolved "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
+  integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
+
 es6-symbol@^3.1.1, es6-symbol@^3.1.3:
   version "3.1.3"
   resolved "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
@@ -4545,6 +4550,14 @@ flatten@^1.0.2:
   resolved "https://registry.npmmirror.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b"
   integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==
 
+flv.js@^1.6.2:
+  version "1.6.2"
+  resolved "https://registry.npmmirror.com/flv.js/-/flv.js-1.6.2.tgz#fa3340fe3f7ee01d3977f7876aee66b8436e5922"
+  integrity sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==
+  dependencies:
+    es6-promise "^4.2.8"
+    webworkify-webpack "^2.1.5"
+
 follow-redirects@^1.14.9:
   version "1.15.2"
   resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
@@ -8882,6 +8895,11 @@ webidl-conversions@^3.0.0:
   resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
   integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
 
+webworkify-webpack@^2.1.5:
+  version "2.1.5"
+  resolved "https://registry.npmmirror.com/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz#bf4336624c0626cbe85cf1ffde157f7aa90b1d1c"
+  integrity sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw==
+
 whatwg-url@^5.0.0:
   version "5.0.0"
   resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"