Browse Source

开发提交

zhaojijng 3 years ago
parent
commit
508b842524

+ 6 - 7
mock/environment.ts

@@ -3,12 +3,11 @@ import { Request, Response } from 'express';
 export default {
   // 支持值为 Object 和 Array
   'POST /api/environment/map': (req: Request, res: Response) => {
-    //debugger;
     res.send({
       data: [
         {
           left: 0,
-          top: 400,
+          top: 0,
           width: 500,
           height: 400,
           Tdb: 27,
@@ -28,7 +27,7 @@ export default {
         },
         {
           left: 500,
-          top: 400,
+          top: 0,
           width: 500,
           height: 400,
           Tdb: 27,
@@ -45,7 +44,7 @@ export default {
         },
         {
           left: 1000,
-          top: 400,
+          top: 0,
           width: 500,
           height: 400,
           Tdb: 27,
@@ -66,7 +65,7 @@ export default {
         },
         {
           left: 0,
-          top: 800,
+          top: 400,
           width: 500,
           height: 400,
           Tdb: 27,
@@ -87,7 +86,7 @@ export default {
         },
         {
           left: 500,
-          top: 800,
+          top: 400,
           width: 500,
           height: 400,
           Tdb: 27,
@@ -107,7 +106,7 @@ export default {
         },
         {
           left: 1000,
-          top: 800,
+          top: 400,
           width: 500,
           height: 400,
           Tdb: 27,

+ 27 - 1
src/assets/css/map.less

@@ -1,5 +1,32 @@
+.mapwrap {
+  position: relative;
+  height: calc(100% - 280px);
+  overflow: hidden;
+  .mapControl {
+    position: absolute;
+    right: 20px;
+    bottom: 20px;
+    z-index: 1;
+    .zoom {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 44px;
+      height: 44px;
+      margin-bottom: 7px;
+      background: #fff;
+      border-radius: 4px;
+      box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.05), 0px 4px 15px rgba(0, 0, 0, 0.05);
+      cursor: pointer;
+    }
+  }
+}
 .map {
   position: relative;
+  width: 3000px;
+  height: 1200px;
+  transform-origin: 0% 0%;
+  cursor: pointer;
   .house {
     position: absolute;
     border: 2px solid #fff;
@@ -54,7 +81,6 @@
 .equipmentMap {
   .house {
     cursor: pointer;
-
     .showModal {
       position: absolute;
       right: 6px;

+ 4 - 4
src/components/PageHeader/index.tsx

@@ -4,19 +4,19 @@ import styles from './index.less';
 import { useModel, history } from 'umi';
 
 type PageHeaderProps = {
-  title: string;
+  title: React.ReactNode;
   action: React.ReactNode;
 };
 const PageHeader: React.FC<PageHeaderProps> = ({ title, action }) => {
   //console.log('PageHeader');
 
   useEffect(() => {
-    //console.log('PageHeader-useEffect');
+    //debugger
     const unlisten = history.listen((location, action) => {
-      //console.log('location,action', location, action);
+      console.log('location,action', location, action);
     });
     return () => {
-      // console.log('un--PageHeader--useEffect');
+      //console.log('un--PageHeader--useEffect');
       unlisten();
     };
   }, []);

+ 79 - 4
src/components/map/index.tsx

@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
 import mapstyles from '@/assets/css/map.less';
 import { getMapList } from '@/services/ant-design-pro/environment';
 import cx from 'classnames';
+import Icon from '@/tenants-ui/Icon';
 
 type MapProps = {
   //mapList: API.MapInfo[];
@@ -11,17 +12,91 @@ type MapProps = {
 
 const Map: React.FC<MapProps> = ({ type, render }) => {
   const [mapList, setMapList] = useState<API.MapInfo[]>([]);
+
+  const [startPageX, setStartPageX] = useState<number>(0);
+  const [startPageY, setStartPageY] = useState<number>(0);
+
+  const [translateX, setTranslateX] = useState<number>(0);
+  const [translateY, setTranslateY] = useState<number>(0);
+  const [mscale, setMscale] = useState<number>(1);
+  const [canMove, setCanMove] = useState<boolean>(false);
+  let mapWidth = 3000,
+    mapHeight = 1200;
+
+  const mouseDownEvent = (event: React.MouseEvent) => {
+    // startPageX = event.pageX;
+    //startPageY = event.pageY;
+    setStartPageX(event.pageX);
+    setStartPageY(event.pageY);
+    console.log('mouseDownEvent', startPageX, event.pageY);
+    setCanMove(true);
+  };
+  const mouseUpEvent = (event: React.MouseEvent) => {
+    console.log('mouseUpEvent', event);
+    setCanMove(false);
+  };
+  const mouseMoveEvent = (event: React.MouseEvent) => {
+    if (canMove) {
+      let nowPageX = event.pageX;
+      let nowPageY = event.pageY;
+      setTranslateX(translateX + nowPageX - startPageX);
+      setTranslateY(translateY + nowPageY - startPageY);
+      console.log('mouseMoveEvent-xx', translateX, nowPageX, startPageX);
+      console.log('mouseMoveEvent-yy', translateY, nowPageY, startPageY);
+
+      setStartPageX(event.pageX);
+      setStartPageY(event.pageY);
+    }
+  };
+  const mapZoom = (event: React.MouseEvent) => {
+    event.stopPropagation();
+    setMscale(mscale + 0.1);
+  };
+  const mapReduce = (event: React.MouseEvent) => {
+    event.stopPropagation();
+    console.log('mapReduce', mscale);
+    setMscale(mscale - 0.1);
+  };
   useEffect(() => {
     getMapList({ floorId: 'sffsdfdsfdf', floorNumber: 22 }).then(function (res) {
       var data: API.MapInfo[] = res.data || [];
       setMapList(data);
     });
   }, []);
+  //   useEffect(() => {// todo 要不要用呢
+  //     document.querySelector('#root').addEventListener(
+  //       'mouseup',
+  //       function () {
+  //         console.log('mouseUpEvent');
+  //         setCanMove(false);
+  //       },
+  //       true,
+  //     );
+  //   }, []);
+
   return (
-    <div className={cx(mapstyles.map, { [mapstyles.equipmentMap]: type == 'equipment' })}>
-      {mapList.map(function (item, index) {
-        return render(item, index);
-      })}
+    <div
+      className={mapstyles.mapwrap}
+      onMouseDown={(event) => {
+        mouseDownEvent(event);
+      }}
+      onMouseUp={(event) => {
+        mouseUpEvent(event);
+      }}
+      onMouseMove={(event) => {
+        mouseMoveEvent(event);
+      }}
+    >
+      <div
+        className={cx(mapstyles.map, { [mapstyles.equipmentMap]: type == 'equipment' })}
+        style={{
+          transform: `translate(${translateX}px,${translateY}px) scale(${mscale},${mscale})`,
+        }}
+      >
+        {mapList.map(function (item, index) {
+          return render(item, index);
+        })}
+      </div>
     </div>
   );
 };

+ 55 - 4
src/layouts/index.jsx

@@ -1,25 +1,76 @@
 import React, { useState, useEffect } from 'react';
 import { useModel, useLocation, useIntl } from 'umi';
 import styles from './index.less';
-import { MenuFoldOutlined } from '@ant-design/icons';
+import { MenuFoldOutlined, SmileOutlined } from '@ant-design/icons';
 import Icon from '@/tenants-ui/Icon';
 
-import { Drawer } from 'antd';
+import { Drawer, notification } from 'antd';
 import NavMenu from '@/components/navMenu';
 
 export default (props) => {
   const { menuVisible, closeMenu, toggleMenu } = useModel('controller');
 
+  const [notifyList] = useState([
+    {
+      title: '管理员操作指南',
+      id: 'notify1',
+      content: '具体介绍管理员权限下的管理功能及相关操作说明。',
+    },
+    { title: 'sagacare介绍', id: 'notify2', content: '环境健康主动管理服务' },
+  ]);
   const showMenuClick = () => {
-    // toggleMenu();
+    //toggleMenu(); //todo
   };
+
+  const openNotification = () => {
+    //debugger;
+    notifyList.map((item, index) => {
+      notification.open({
+        key: item.id,
+        message: item.title,
+        description: item.content,
+        duration: 0,
+        onClick: () => {
+          console.log('Notification Clicked!');
+        },
+        icon: <SmileOutlined style={{ color: '#108ee9', fontSize: 32 }} />,
+        style: {
+          width: 400,
+          borderRadius: 30,
+        },
+        closeIcon: <></>,
+      });
+    });
+  };
+  const closeNotify = () => {
+    //console.log('close-notify');
+    notifyList.map((item, index) => {
+      notification.close(item.id);
+    });
+  };
+
+  useEffect(() => {
+    document.querySelector('#root').addEventListener('click', closeNotify, true);
+    return () => {
+      console.log('layout-useEffect-off');
+      document.querySelector('#root').removeEventListener('click', closeNotify, true);
+    };
+  }, []);
+
   return (
     <div className={styles.layout}>
       <div className={styles.header}>
         <div className={styles.title}>之江项目</div>
         <div className={styles.right}>
           <div className={styles.picture}></div>
-          <Icon className={styles.notify} type="notify" style={{ fontSize: 21 }}></Icon>
+          <div
+            onClick={(event) => {
+              event.stopPropagation();
+              // openNotification(); //todo
+            }}
+          >
+            <Icon className={styles.notify} type="notify" style={{ fontSize: 21 }}></Icon>
+          </div>
           <MenuFoldOutlined style={{ fontSize: 24 }} onClick={showMenuClick} />
         </div>
       </div>

+ 10 - 0
src/layouts/index.less

@@ -4,6 +4,7 @@
   height: 100%;
   margin: 0 auto;
   padding: 20px;
+  user-select: none;
 }
 
 :global {
@@ -42,6 +43,15 @@
     .notify {
       margin-right: 24px;
       cursor: pointer;
+      :global {
+        .ant-notification-notice-message {
+          color: #656872;
+          font-size: 14px;
+        }
+        .ant-notification-notice-description {
+          color: #c4c4c4;
+        }
+      }
     }
   }
 }

+ 0 - 4
src/pages/Environment/index.less

@@ -23,10 +23,6 @@
     }
   }
 }
-.mapwrap {
-  height: calc(100% - 280px);
-  overflow: hidden;
-}
 
 //   .specialRoom {
 //     position: absolute;

+ 28 - 29
src/pages/Environment/index.tsx

@@ -162,35 +162,35 @@ const Environment: React.FC = () => {
           })}
         </div>
       </div>
-      <div className={styles.mapwrap}>
-        <Map
-          type={'enviroment'}
-          render={(item: API.MapInfo, index: number) => {
-            return (
-              <div
-                key={index + 'house'}
-                className={mapstyles.house}
-                style={{
-                  left: item.left,
-                  top: item.top,
-                  width: item.width,
-                  height: item.height,
-                  backgroundColor:
-                    'rgba(' +
-                    selNav.colorStr +
-                    (selNav.opacity as number) * getColorOpacity(item[selNav.id]) +
-                    ')',
-                }}
-              >
-                <div className={mapstyles.content}>
-                  <Icon className="" type={item.roomFuncType} style={{ fontSize: 20 }}></Icon>
-                  <div className={mapstyles.name}>{item.localName}</div>
-                </div>
+
+      <Map
+        type={'enviroment'}
+        render={(item: API.MapInfo, index: number) => {
+          return (
+            <div
+              key={index + 'house'}
+              className={mapstyles.house}
+              style={{
+                left: item.left,
+                top: item.top,
+                width: item.width,
+                height: item.height,
+                backgroundColor:
+                  'rgba(' +
+                  selNav.colorStr +
+                  (selNav.opacity as number) * getColorOpacity(item[selNav.id]) +
+                  ')',
+              }}
+            >
+              <div className={mapstyles.content}>
+                <Icon className="" type={item.roomFuncType} style={{ fontSize: 20 }}></Icon>
+                <div className={mapstyles.name}>{item.localName}</div>
               </div>
-            );
-          }}
-        ></Map>
-        {/* {mapList.map(function (item, index) {
+            </div>
+          );
+        }}
+      ></Map>
+      {/* {mapList.map(function (item, index) {
               return (
                 <div
                   key={index + 'house'}
@@ -214,7 +214,6 @@ const Environment: React.FC = () => {
                 </div>
               );
             })} */}
-      </div>
 
       {showChart && (
         <ChartModal

+ 0 - 4
src/pages/Equipment/index.less

@@ -19,7 +19,3 @@
     }
   }
 }
-.mapwrap {
-  height: calc(100% - 280px);
-  overflow: hidden;
-}

+ 45 - 47
src/pages/Equipment/index.tsx

@@ -151,55 +151,53 @@ const Environment: React.FC = () => {
           </div>
         )}
       </div>
-      <div className={styles.mapwrap}>
-        <Map
-          type={'equipment'}
-          render={(item, index) => {
-            return (
-              <div
-                key={index + 'house'}
-                className={mapstyles.house}
-                style={{
-                  left: item.left,
-                  top: item.top,
-                  width: item.width,
-                  height: item.height,
-                  backgroundColor:
-                    selNav.id == 'all'
-                      ? 'rgba(196, 196, 196, 0.2)'
-                      : getColorOpacity(item[selNav.id]),
-                }}
-              >
-                {selNav.id == 'all' && (
-                  <div className={mapstyles.allDevice}>
-                    {/* 所有设备的图标列表 */}
-                    {item.device.map((ditem, dindex: number) => {
-                      return (
-                        <div
-                          key={dindex + 'device'}
-                          className={mapstyles.icon}
-                          style={{
-                            backgroundColor: getColorOpacity(ditem.status, ditem.type),
-                          }}
-                        >
-                          <Icon className="" type={ditem.type} style={{ color: '#ffffff' }}></Icon>
-                        </div>
-                      );
-                    })}
-                  </div>
-                )}
-                <div className={mapstyles.showModal} onClick={showModalClick}>
-                  <Icon className="" type="hover"></Icon>
-                </div>
-                <div className={mapstyles.content}>
-                  <Icon className="" type={item.roomFuncType} style={{ fontSize: 20 }}></Icon>
-                  <div className={mapstyles.name}>{item.localName}</div>
+      <Map
+        type={'equipment'}
+        render={(item, index) => {
+          return (
+            <div
+              key={index + 'house'}
+              className={mapstyles.house}
+              style={{
+                left: item.left,
+                top: item.top,
+                width: item.width,
+                height: item.height,
+                backgroundColor:
+                  selNav.id == 'all'
+                    ? 'rgba(196, 196, 196, 0.2)'
+                    : getColorOpacity(item[selNav.id]),
+              }}
+            >
+              {selNav.id == 'all' && (
+                <div className={mapstyles.allDevice}>
+                  {/* 所有设备的图标列表 */}
+                  {item.device.map((ditem, dindex: number) => {
+                    return (
+                      <div
+                        key={dindex + 'device'}
+                        className={mapstyles.icon}
+                        style={{
+                          backgroundColor: getColorOpacity(ditem.status, ditem.type),
+                        }}
+                      >
+                        <Icon className="" type={ditem.type} style={{ color: '#ffffff' }}></Icon>
+                      </div>
+                    );
+                  })}
                 </div>
+              )}
+              <div className={mapstyles.showModal} onClick={showModalClick}>
+                <Icon className="" type="hover"></Icon>
               </div>
-            );
-          }}
-        ></Map>
-      </div>
+              <div className={mapstyles.content}>
+                <Icon className="" type={item.roomFuncType} style={{ fontSize: 20 }}></Icon>
+                <div className={mapstyles.name}>{item.localName}</div>
+              </div>
+            </div>
+          );
+        }}
+      ></Map>
       {showModal && (
         <DeviceModal
           onClose={() => {

+ 0 - 5
src/pages/Runtime/index.less

@@ -17,8 +17,3 @@
     width: 210px;
   }
 }
-
-.mapwrap {
-  height: calc(100% - 280px);
-  overflow: hidden;
-}

+ 34 - 36
src/pages/Runtime/index.tsx

@@ -77,12 +77,11 @@ const Runtime: React.FC = () => {
       <div className={styles.maptop}>
         <div className={styles.right}></div>
       </div>
-      <div className={styles.mapwrap}>
-        {/* <div className={styles.map}>
+      {/* <div className={styles.map}>
             <div className={styles.specialRoom}></div>
             <img src={mapImg}></img>
           </div> */}
-        {/* <div
+      {/* <div
               className={mapstyles.house}
               style={{
                 width: 180,
@@ -95,40 +94,39 @@ const Runtime: React.FC = () => {
                 <div className={mapstyles.name}>Jozy Zone</div>
               </div>
             </div> */}
-        <Map
-          type={'runtime'}
-          render={(item, index) => {
-            return (
-              <div
-                key={index + 'house'}
-                className={mapstyles.house}
-                style={{
-                  left: item.left,
-                  top: item.top,
-                  width: item.width,
-                  height: item.height,
-                  backgroundColor:
-                    item.runTimeStatus == 'normalRun'
-                      ? 'rgba(196, 196, 196, 0.2)'
-                      : item.runTimeStatus == 'overtimeWork'
-                      ? 'rgba(94, 139, 207, 0.2)'
-                      : 'rgba(0, 220, 35, 0.2)',
-                }}
-              >
-                <div className={mapstyles.allTime}>
-                  {(item.timeList || []).map(function (titem: string, tindex: number) {
-                    return <span key={tindex + 'time'}>{titem},</span>;
-                  })}
-                </div>
-                <div className={mapstyles.content}>
-                  <Icon className="" type={item.roomFuncType} style={{ fontSize: 20 }}></Icon>
-                  <div className={mapstyles.name}>{item.localName}</div>
-                </div>
+      <Map
+        type={'runtime'}
+        render={(item, index) => {
+          return (
+            <div
+              key={index + 'house'}
+              className={mapstyles.house}
+              style={{
+                left: item.left,
+                top: item.top,
+                width: item.width,
+                height: item.height,
+                backgroundColor:
+                  item.runTimeStatus == 'normalRun'
+                    ? 'rgba(196, 196, 196, 0.2)'
+                    : item.runTimeStatus == 'overtimeWork'
+                    ? 'rgba(94, 139, 207, 0.2)'
+                    : 'rgba(0, 220, 35, 0.2)',
+              }}
+            >
+              <div className={mapstyles.allTime}>
+                {(item.timeList || []).map(function (titem: string, tindex: number) {
+                  return <span key={tindex + 'time'}>{titem},</span>;
+                })}
               </div>
-            );
-          }}
-        ></Map>
-      </div>
+              <div className={mapstyles.content}>
+                <Icon className="" type={item.roomFuncType} style={{ fontSize: 20 }}></Icon>
+                <div className={mapstyles.name}>{item.localName}</div>
+              </div>
+            </div>
+          );
+        }}
+      ></Map>
     </>
   );
 };

+ 1 - 1
src/tenants-ui/Icon/index.jsx

@@ -1,7 +1,7 @@
 import { createFromIconfontCN } from '@ant-design/icons';
 
 const Icon = createFromIconfontCN({
-  scriptUrl: '//at.alicdn.com/t/font_3184967_s7z4njiltfc.js',
+  scriptUrl: '//at.alicdn.com/t/font_3184967_yamfb93ms7g.js',
 });
 
 export default ({ type, className, style = {} }) => {