Kaynağa Gözat

del qiankun

code4eat 3 yıl önce
ebeveyn
işleme
b95e7de04c

+ 22 - 2
.umirc.ts

@@ -1,14 +1,26 @@
+/*
+ * @Author: your name
+ * @Date: 2021-11-09 11:20:18
+ * @LastEditTime: 2021-12-20 10:23:40
+ * @LastEditors: Please set LastEditors
+ * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ * @FilePath: /KC-MiddlePlatform/.umirc.ts
+ */
 import { defineConfig } from 'umi';
 
 export default defineConfig({
   nodeModulesTransform: {
     type: 'none',
   },
+  theme: {},
   routes: [
-    { path: '/', component: '@/pages/index/index' },
+    {
+      path: '/',
+      component: '@/pages/index/index',
+    },
     { path: '/login', component: '@/pages/login/index' },
   ],
-  proxy:{
+  proxy: {
     // '/api': {
     //   'target': 'http://112.124.59.133:8083/',
     //   'changeOrigin': true,
@@ -16,4 +28,12 @@ export default defineConfig({
     // },
   },
   fastRefresh: {},
+  mfsu: {},
+  qiankun: {
+    master: {
+      sandbox: {
+        experimentalStyleIsolation: true, // 严格沙箱
+      },
+    },
+  },
 });

+ 72 - 83
mock/login.ts

@@ -1,105 +1,94 @@
 /*
  * @Author: your name
  * @Date: 2021-11-11 11:46:42
- * @LastEditTime: 2021-11-19 16:41:56
+ * @LastEditTime: 2021-12-16 11:21:20
  * @LastEditors: Please set LastEditors
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/mock/login.ts
  */
 
-
-
 import { Request, Response } from 'express';
 
+const getList = (req: Request, res: Response, u: string) => {
+  const dataSource = [
+    {
+      name: '医院一',
+      value: 1,
+    },
+    {
+      name: '医院二',
+      value: 2,
+    },
+    {
+      name: '医院三',
+      value: 3,
+    },
+  ];
+  const result = {
+    data: {
+      list: dataSource,
+      totalCount: dataSource.length,
+      current: 1,
+    },
+    success: true,
+    status: 200,
+  };
+
+  return res.json(result);
+};
 
-const  getList =  (req: Request, res: Response, u: string)=>{
-    const dataSource = [
-         {
-             name:'医院一',
-             value:1
-         },
-         {
-            name:'医院二',
-            value:2
-         },
-         {
-            name:'医院三',
-            value:3
-        }
-    ];
+const postData = (req: Request, res: Response, u: string) => {
+  const { account, password } = req.body;
+  if (account == 'admin' && password == '123') {
     const result = {
-      data:{
-          list:dataSource,
-          totalCount:dataSource.length,
-          current:1
+      data: {
+        userName: 'hasaki',
       },
       success: true,
-      status:200,
+      status: 200,
     };
-    
-    return res.json(result); 
-    
-}
 
-const postData =  (req: Request, res: Response, u: string)=>{
-    const {account,password} = req.body;
-    if(account == 'admin'&&password =='123'){
-        const result = {
-            data:{
-                userName:'hasaki'
-            },
-            success: true,
-            status:200,
-        };
-
-        setTimeout(()=>{
-            return res.json(result); 
-        },5000);
-
-    }else {
-        const result = {
-            data:{
-              a:1
-            },
-            success:false,
-            errorMessage:'用户名或密码错误!',
-            status:200,
-        };
-        return res.json(result); 
-    }
-    
-}
-
-const getHospSubSystemList = (req: Request, res: Response,)=>{
+    setTimeout(() => {
+      return res.json(result);
+    }, 2000);
+  } else {
     const result = {
-        data:[
-            {
-                icon:'https://i.postimg.cc/J4fsWx1V/2x.png',
-                id:0,
-                name:'平台管理',
-                url:''
-            },
-            {
-                icon:'https://i.postimg.cc/yNrSZ4pN/2x.png',
-                id:1,
-                name:'追踪方法学',
-                url:''
-            }
-        ],
-        success: true,
-        status:200,
-      };
-      
-      return res.json(result); 
-}
-
+      data: {
+        a: 1,
+      },
+      success: false,
+      errorMessage: '用户名或密码错误!',
+      status: 200,
+    };
+    return res.json(result);
+  }
+};
 
+const getHospSubSystemList = (req: Request, res: Response) => {
+  const result = {
+    data: [
+      {
+        icon: 'https://i.postimg.cc/J4fsWx1V/2x.png',
+        id: 0,
+        name: '平台管理',
+        url: 'http://localhost:2000',
+      },
+      {
+        icon: 'https://i.postimg.cc/yNrSZ4pN/2x.png',
+        id: 1,
+        name: '智慧查检系统',
+        url: 'http://localhost:8804',
+      },
+    ],
+    success: true,
+    status: 200,
+  };
 
+  return res.json(result);
+};
 
 export default {
-    'GET /api/getSubHosp': getList,
-    'POST /api/login': postData,
-    'GET /api/getHospSubSystemList':getHospSubSystemList,
+  'GET /api/getSubHosp': getList,
+  'POST /api/login': postData,
+  'GET /api/getHospSubSystemList': getHospSubSystemList,
 };
-
-

+ 5 - 4
package.json

@@ -27,14 +27,15 @@
     "@ant-design/pro-form": "^1.18.3",
     "@ant-design/pro-layout": "^6.15.3",
     "@ant-design/pro-table": "^2.30.8",
-    "react": "17.x",
-    "react-dom": "17.x",
+    "react": "16.x",
+    "react-dom": "16.x",
     "umi": "^3.5.20"
   },
   "devDependencies": {
     "@types/express": "^4.17.13",
-    "@types/react": "^17.0.0",
-    "@types/react-dom": "^17.0.0",
+    "@types/react": "^16.0.0",
+    "@types/react-dom": "^16.0.0",
+    "@umijs/plugin-qiankun": "^2.35.4",
     "@umijs/preset-react": "1.x",
     "@umijs/test": "^3.5.20",
     "express": "^4.17.1",

+ 139 - 143
src/app.tsx

@@ -1,16 +1,25 @@
 /*
  * @Author: your name
  * @Date: 2021-11-09 13:57:41
- * @LastEditTime: 2021-11-29 09:53:18
+ * @LastEditTime: 2021-12-20 10:23:27
  * @LastEditors: Please set LastEditors
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/app.ts
  */
-import { PageLoading } from '@ant-design/pro-layout';
-import { notification, } from 'antd';
-import { RequestConfig,history } from 'umi';
-import type { RequestOptionsInit} from 'umi-request';
 
+import React from 'react';
+import {
+  PageLoading,
+  BasicLayoutProps,
+  Settings as LayoutSettings,
+} from '@ant-design/pro-layout';
+import { notification, ConfigProvider } from 'antd';
+import { RequestConfig, history } from 'umi';
+import type { RequestOptionsInit } from 'umi-request';
+
+import { getHospSubSystemList } from '@/service/login';
+
+import TopBar from '@/components/topBar/index';
 
 const loginPath = '/login';
 
@@ -18,158 +27,145 @@ let hospSign: string = ''; //医院标识
 
 /** 获取用户信息比较慢的时候会展示一个 loading */
 export const initialStateConfig = {
-        loading: <PageLoading />,
+  loading: <PageLoading />,
 };
 
-export async function getInitialState(): Promise<{
-        userData?: any,
-        systemLists?:SystemListItem[],  //当前医院可选子系统列表
-        openedSysLists?:SystemListItem[], //当前已打开的系统列表
-}> {
-        const fetchUserInfo = async () => {
-                try {
-                        const userData = localStorage.getItem('KC-MiddlePlatformUserData');
-                        // console.log({ userData });
-                        if (userData) {
-                                return JSON.parse(userData);
-                        }
-                        throw Error;
-                } catch (error) {
-
-                        history.push(`${loginPath}?hospSign=${hospSign}`);
-                }
-                return undefined;
-        };
-
-        const userData = await fetchUserInfo();
-
-        return {
-                userData,
-                openedSysLists:[],
-                systemLists:[
-                     {
-                         id:1,
-                         icon:'https://i.postimg.cc/J4fsWx1V/2x.png',
-                         url:'http://118.31.245.65:8804/user/login/?redirect=%2FDataManagement%2FpublicData&hospSign=tYAoFaa20yCAgaiy',
-                         name:'追踪方法学'
-                     },
-                     {
-                        id:2,
-                        icon:'https://i.postimg.cc/J4fsWx1V/2x.png',
-                        url:'http://118.31.245.65:8804/user/login/?redirect=%2FDataManagement%2FpublicData&hospSign=tYAoFaa20yCAgaiy',
-                        name:'全成本核算'
-                     }
-                ]
-        }
-}
-
-
-
+type InitialStateType = {
+  userData?: any;
+  systemLists?: SystemListItem[]; //当前医院可选子系统列表
+  openedSysLists?: SystemListItem[]; //当前已打开的系统列表
+  currentSelectedSys?: SystemListItem; //当前选中的tab
+  logout?: () => Promise<boolean>;
+};
 
-const requestInterceptorsHandle = (url: string, options: RequestOptionsInit) => {
-        return {
-                url: `${url}`,
-                options: { ...options, interceptors: true },
-        };
+export async function getInitialState(): Promise<InitialStateType> {
+  const fetchUserInfo = async () => {
+    try {
+      const userData = localStorage.getItem('KC-MiddlePlatformUserData');
+      // console.log({ userData });
+      if (userData) {
+        return JSON.parse(userData);
+      }
+      throw Error;
+    } catch (error) {
+      history.push(`${loginPath}?hospSign=${hospSign}`);
+    }
+    return undefined;
+  };
+
+  const logout = () => {
+    localStorage.removeItem('KC-MiddlePlatformUserData');
+    history.replace(`${loginPath}?hospSign=${hospSign}`);
+    return Promise.resolve(true);
+  };
+
+  //获取当前账号所有子应用列表
+  const systemLists = await getHospSubSystemList();
+
+  const userData = await fetchUserInfo();
+
+  return {
+    userData,
+    openedSysLists: [],
+    currentSelectedSys: undefined,
+    logout,
+    systemLists,
+  };
 }
 
-const responseInterceptorsHandle = async (response: Response, options: RequestOptionsInit) => {
-        const _response: { data: any,status:number,success:boolean } = await response.clone().json();
-        // // console.log({_response});
-        if(_response.success){
-                return _response.data;
-        }else{
-                return _response
-        }
-}
+const requestInterceptorsHandle = (
+  url: string,
+  options: RequestOptionsInit,
+) => {
+  return {
+    url: `${url}`,
+    options: { ...options, interceptors: true },
+  };
+};
 
+const responseInterceptorsHandle = async (
+  response: Response,
+  options: RequestOptionsInit,
+) => {
+  const _response: { data: any; status: number; success: boolean } =
+    await response.clone().json();
+  // // console.log({_response});
+  if (_response.success) {
+    return _response.data;
+  } else {
+    return _response;
+  }
+};
 
 interface ErrorInfoStructure {
-        success: boolean; // if request is success
-        data?: any; // response data
-        status?:number,
-        errorCode: string; // code for errorType
-        errorMessage: string; // message display to user 
-        showType?: number; // error display type: 0 silent; 1 message.warn; 2 message.error; 4 notification; 9 page
-        traceId?: string; // Convenient for back-end Troubleshooting: unique request ID
-        host?: string; // Convenient for backend Troubleshooting: host of current access server
+  success: boolean; // if request is success
+  data?: any; // response data
+  status?: number;
+  errorCode: string; // code for errorType
+  errorMessage: string; // message display to user
+  showType?: number; // error display type: 0 silent; 1 message.warn; 2 message.error; 4 notification; 9 page
+  traceId?: string; // Convenient for back-end Troubleshooting: unique request ID
+  host?: string; // Convenient for backend Troubleshooting: host of current access server
 }
 
-
 interface ResponseErr extends Error {
-        data?: any; // 这里是后端返回的原始数据
-        info: ErrorInfoStructure;
+  data?: any; // 这里是后端返回的原始数据
+  info: ErrorInfoStructure;
 }
 
-
-
-
-const errorHandlerFunc = (error:ResponseErr) => {
-        console.log({error});
-        
-        try {
-                
-                const { info } = error;
-                const errortext = '';
-                const { status, errorMessage } = info
-                notification.error({
-                        message: ` ${status}: ${errorMessage}`,
-                        description: errortext,
-                });
-
-        } catch (err) {
-                console.log({'errorHandlerFunc':err});
-                notification.error({
-                        message:'登录遇到未知错误,查看控制台!',
-                });
-        }
+const errorHandlerFunc = (error: ResponseErr) => {
+  console.log({ error });
+
+  try {
+    const { info } = error;
+    const errortext = '';
+    const { status, errorMessage } = info;
+    notification.error({
+      message: ` ${status}: ${errorMessage}`,
+      description: errortext,
+    });
+  } catch (err) {
+    console.log({ errorHandlerFunc: err });
+    notification.error({
+      message: '登录遇到未知错误,查看控制台!',
+    });
+  }
 };
 
-
 export const request: RequestConfig = {
-        timeout: 10000,
-        errorConfig: {
-                adaptor: (resData) => {
-                        console.log({ resData });
-                        if (resData) {
-                                return {
-                                        ...resData,
-                                        success: resData.success,
-                                        errorMessage: resData.errorMessage,
-                                };
-                        } else {
-                                return {
-                                        success: false,
-                                        errorCode: 0,
-                                        status:0,
-                                        errorMessage: '出现未知错误!',
-                                };
-                        }
-                },
-        },
-        errorHandler:(err:any)=>errorHandlerFunc(err),
-        middlewares: [
-                async function middlewareA(ctx, next) {
-                        // console.log('A before');
-                        await next();
-                        // console.log('A after');
-                },
-                async function middlewareB(ctx, next) {
-                        // console.log('B before');
-                        await next();
-                        // console.log('B after');
-                }
-        ],
-        requestInterceptors: [requestInterceptorsHandle],
-        responseInterceptors: [responseInterceptorsHandle],
+  timeout: 10000,
+  errorConfig: {
+    adaptor: (resData) => {
+      console.log({ resData });
+      if (resData) {
+        return {
+          ...resData,
+          success: resData.success,
+          errorMessage: resData.errorMessage,
+        };
+      } else {
+        return {
+          success: false,
+          errorCode: 0,
+          status: 0,
+          errorMessage: '出现未知错误!',
+        };
+      }
+    },
+  },
+  errorHandler: (err: any) => errorHandlerFunc(err),
+  middlewares: [
+    async function middlewareA(ctx, next) {
+      // console.log('A before');
+      await next();
+      // console.log('A after');
+    },
+    async function middlewareB(ctx, next) {
+      // console.log('B before');
+      await next();
+      // console.log('B after');
+    },
+  ],
+  requestInterceptors: [requestInterceptorsHandle],
+  responseInterceptors: [responseInterceptorsHandle],
 };
-
-
-
-
-
-
-
-
-
-

+ 150 - 0
src/components/topBar/index.tsx

@@ -0,0 +1,150 @@
+/*
+ * @Author: your name
+ * @Date: 2021-11-16 09:12:37
+ * @LastEditTime: 2021-12-17 10:59:01
+ * @LastEditors: Please set LastEditors
+ * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ * @FilePath: /KC-MiddlePlatform/src/pages/index/components/topBar/index.tsx
+ */
+
+import React, { useEffect, useState } from 'react';
+import './style.less';
+
+import { Tooltip } from 'antd';
+import { LogoutOutlined, SettingOutlined } from '@ant-design/icons';
+
+import logo from '../../../public/images/kc-logo.png';
+import platFormMenuIcon from '../../../public/images/platformMenu.png';
+import tabCloseIcon from '../../../public/images/tabCloseIcon.png';
+
+interface TopBarType {
+  onTabChange?: (data: SystemListItem) => void; //当tab切换时回调
+  sysList?: SystemListItem[]; //可选系统列表
+  openedTabs: SystemListItem[]; //已打开的列表
+  currentTab?: SystemListItem; //当前tab
+  userPannelTabClick?: (tag: 'SETTING' | 'LOGOUT') => void;
+}
+
+const TopBar: React.FC<TopBarType> = (props) => {
+  const {
+    onTabChange,
+    sysList = [],
+    openedTabs = [],
+    currentTab,
+    userPannelTabClick,
+  } = props;
+  const [systemTabs, setSystemTabs] = useState<SystemListItem[]>([]); //已打开的tab
+  const [currentSelectedTab, setCurrentSelectedTab] =
+    useState<SystemListItem>();
+  const [ifOpenPannel, setIfOpenPannel] = useState(false);
+  const [arrowRotate, setArrowRotate] = useState(false);
+
+  const _systemTabClickHandle = (item: SystemListItem) => {
+    //导航栏tab点击
+    setCurrentSelectedTab(item);
+    onTabChange && onTabChange(item);
+  };
+
+  const _systemListClickHandle = (data: SystemListItem) => {
+    //导航栏系统菜单列表点击回调
+    onTabChange && onTabChange(data);
+  };
+
+  const _userPannelTabClick = (tag: 'SETTING' | 'LOGOUT') => {
+    //用户菜单tab点击回调
+    userPannelTabClick && userPannelTabClick(tag);
+  };
+
+  const UserPannel = () => {
+    return (
+      <div className="userPannel">
+        <div
+          className="userPannelTab"
+          onClick={() => _userPannelTabClick('SETTING')}
+        >
+          <SettingOutlined />
+          设置
+        </div>
+        <div
+          className="userPannelTab"
+          onClick={() => _userPannelTabClick('LOGOUT')}
+        >
+          <LogoutOutlined />
+          退出
+        </div>
+      </div>
+    );
+  };
+
+  useEffect(() => {
+    setSystemTabs(openedTabs);
+    currentTab && setCurrentSelectedTab(currentTab);
+  }, [props]);
+
+  return (
+    <div className="topBar">
+      <div className="logoWrap">
+        <img className="logo" src={logo} />
+      </div>
+      <div
+        className={ifOpenPannel ? 'platformMenu on' : 'platformMenu'}
+        onClick={() => setIfOpenPannel(!ifOpenPannel)}
+      >
+        <img src={platFormMenuIcon} />
+        <div className="systemPannel">
+          {sysList.map((item) => (
+            <div
+              key={item.id}
+              className="systemList"
+              onClick={() => _systemListClickHandle(item)}
+            >
+              <img src={item.icon} alt="" />
+              <span className="name">{item.name}</span>
+            </div>
+          ))}
+        </div>
+      </div>
+      {/**
+       * 已打开的tab
+       */}
+      <div className="tabWrap">
+        {systemTabs.map((item) => (
+          <div
+            key={item.id}
+            className={currentSelectedTab?.id == item.id ? 'tab on' : 'tab'}
+            onClick={() => _systemTabClickHandle(item)}
+          >
+            {item.name} <img src={tabCloseIcon} alt="close" />
+          </div>
+        ))}
+      </div>
+      <div className="userRelaInfoWrap">
+        <div className="notification">
+          <img
+            className="notificationIcon"
+            src={require('../../../public/images/notificationIcon.png')}
+          />
+        </div>
+        <Tooltip
+          title={<UserPannel />}
+          color="#fff"
+          onVisibleChange={(visible) => setArrowRotate(visible)}
+        >
+          <div className="user">
+            <img
+              className="avator"
+              src={require('../../../public/images/Mask.png')}
+            />
+            <span className="name">Mr Lawrence</span>
+            <img
+              className={arrowRotate ? 'arrow on' : 'arrow'}
+              src={require('../../../public/images/arrow_white.png')}
+            />
+          </div>
+        </Tooltip>
+      </div>
+    </div>
+  );
+};
+
+export default TopBar;

+ 222 - 0
src/components/topBar/style.less

@@ -0,0 +1,222 @@
+.userPannel {
+  width: 100px;
+  background-color: white;
+  .userPannelTab {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-evenly;
+    align-items: center;
+    height: 30px;
+    font-size: 14px;
+    font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+    font-weight: 400;
+    color: rgb(131, 127, 127);
+    cursor: pointer;
+    border-bottom: 1px solid #eee;
+
+    &:hover {
+      background-color: #eee;
+    }
+
+    &:last-child {
+      border-bottom: none;
+    }
+  }
+}
+
+.topBar {
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-start;
+  align-items: center;
+  width: 100%;
+  height: 48px;
+  padding-left: 16px;
+  background: #3071f2;
+
+  .logoWrap {
+    width: 200px;
+
+    .logo {
+      width: 108px;
+      height: 18px;
+    }
+  }
+
+  .platformMenu {
+    position: relative;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 32px;
+    height: 32px;
+    border-radius: 4px;
+    cursor: pointer;
+    margin-right: 16px;
+
+    img {
+      width: 16px;
+      height: 16px;
+    }
+
+    .systemPannel {
+      display: none;
+      position: absolute;
+      left: 0;
+      top: 50px;
+      z-index: 99;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+      background: #ffffff;
+      padding: 16px 20px;
+      box-shadow: 0px 6px 10px 0px rgba(26, 34, 51, 0.2);
+      border-radius: 8px;
+      border: 1px solid #e6eaf2;
+
+      .systemList {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        width: 80px;
+        height: 98px;
+        margin-right: 10px;
+        border-radius: 8px;
+
+        .name {
+          font-size: 12px;
+          font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+          font-weight: 400;
+          color: #666e80;
+        }
+
+        & > img {
+          width: 40px;
+          height: 40px;
+          background: #ffb44d;
+          border-radius: 10px;
+          margin-bottom: 16px;
+        }
+
+        &:last-child {
+          margin-right: 0;
+        }
+
+        &:hover {
+          background: #f7f8fa;
+
+          .name {
+            font-size: 12px;
+            font-family: SourceHanSansCN-Bold, SourceHanSansCN;
+            font-weight: bold;
+            color: #334466;
+          }
+        }
+      }
+    }
+
+    &.on {
+      background: #0b54e6;
+
+      .systemPannel {
+        display: flex;
+      }
+    }
+  }
+
+  .tabWrap {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    align-items: center;
+
+    .tab {
+      padding: 8px 9px;
+      border-radius: 4px;
+      font-size: 14px;
+      font-family: SourceHanSansCN-Medium, SourceHanSansCN;
+      font-weight: 500;
+      color: #ffffff;
+      opacity: 0.8;
+      margin-right: 16px;
+      cursor: pointer;
+      box-sizing: border-box;
+
+      & > img {
+        width: 8px;
+        height: 8px;
+        margin-left: 16px;
+      }
+
+      &:hover {
+        background: #5387ee;
+      }
+
+      &.on {
+        opacity: 1;
+        background: #0b54e6;
+      }
+
+      &:last-child {
+        margin-right: 0;
+      }
+    }
+  }
+
+  .userRelaInfoWrap {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+    position: fixed;
+    right: 0;
+    padding-right: 16px;
+
+    .notification {
+      display: flex;
+      flex-direction: row;
+      justify-content: center;
+      align-items: center;
+      width: 18px;
+      height: 18px;
+      margin-right: 16px;
+      cursor: pointer;
+
+      .notificationIcon {
+        width: 100%;
+      }
+    }
+
+    .user {
+      cursor: pointer;
+      display: flex;
+      flex-direction: row;
+      justify-content: center;
+      align-items: center;
+      .avator {
+        width: 26px;
+        height: 26px;
+        margin-right: 8px;
+      }
+
+      .name {
+        font-size: 14px;
+        font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+        font-weight: 400;
+        color: #ffffff;
+        margin-right: 10px;
+      }
+
+      .arrow {
+        width: 11px;
+        height: 7px;
+        transition: all 0.3s ease-in;
+
+        &.on {
+          transform: rotate(180deg);
+        }
+      }
+    }
+  }
+}

+ 8 - 3
src/global.less

@@ -1,6 +1,11 @@
+input {
+  outline: none !important;
+}
 
+//overwrite antd-pro css
 
+.ant-pro-global-header {
+  padding: 0 !important;
+}
 
-input {
-    outline: none !important;
-}
+//--------------------

+ 2 - 1
src/pages/404.tsx

@@ -6,6 +6,7 @@
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/404.tsx
  */
+
 import { Result } from 'antd';
 import React from 'react';
 
@@ -17,4 +18,4 @@ const NoFoundPage: React.FC = () => (
   />
 );
 
-export default NoFoundPage;
+export default NoFoundPage;

+ 46 - 22
src/pages/index/components/iframePage/index.tsx

@@ -1,35 +1,48 @@
 /*
  * @Author: your name
  * @Date: 2021-11-19 15:20:40
- * @LastEditTime: 2021-11-19 16:13:00
+ * @LastEditTime: 2021-12-16 16:22:58
  * @LastEditors: Please set LastEditors
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/index/components/iframePage/index.tsx
  */
 
-import React,{useState,useRef} from "react"
+import React, { useState, useRef } from 'react';
 import { Spin } from 'antd';
 
 import { LoadingOutlined } from '@ant-design/icons';
 
-import './style.less'
+import './style.less';
 
 export interface IframePage {
-       url:string
+  activedItem?: SystemListItem;
+  list: SystemListItem[];
 }
 //http://118.31.245.65:8804/user/login/?redirect=%2FDataManagement%2FpublicData&hospSign=tYAoFaa20yCAgaiy
-const IframePage:React.FC<IframePage> = (props)=>{
-    
-    const [loading, setLoading] = useState(true);
-    const {url} = props;
-
-    const onLoadHandle = ()=>{
-        setLoading(false);
-    }
-
-     return (
-        <div className='iframeContainer'>
-        {
+
+const Iframe = ({ id, url }: SystemListItem) => {
+  const [loading, setLoading] = useState(true);
+
+  const onLoadHandle = () => {
+    setLoading(false);
+  };
+
+  return (
+    <iframe
+      key={id}
+      onLoad={onLoadHandle}
+      className="iframe"
+      src={url}
+    ></iframe>
+  );
+};
+
+const IframePage: React.FC<IframePage> = (props) => {
+  const { list, activedItem } = props;
+
+  return (
+    <div className="iframeContainer">
+      {/* {
             loading && (
                   <div className='content'>
                         <div className='spin'>
@@ -38,11 +51,22 @@ const IframePage:React.FC<IframePage> = (props)=>{
                         </div>
                   </div>
             )
-        }
-        <iframe  onLoad={onLoadHandle} className='iframe' src={url}></iframe>
+        } */}
+      {list.map((item) => (
+        <div
+          key={item.id}
+          style={{
+            position: 'absolute',
+            height: '100%',
+            width: '100%',
+            zIndex: activedItem && activedItem.id == item.id ? 9 : 1,
+          }}
+        >
+          <Iframe {...item} />
         </div>
-     )
-}
-
+      ))}
+    </div>
+  );
+};
 
-export default IframePage;
+export default IframePage;

+ 122 - 82
src/pages/index/components/topBar/index.tsx

@@ -1,110 +1,150 @@
 /*
  * @Author: your name
  * @Date: 2021-11-16 09:12:37
- * @LastEditTime: 2021-11-29 14:08:45
+ * @LastEditTime: 2021-12-16 16:18:44
  * @LastEditors: Please set LastEditors
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/index/components/topBar/index.tsx
  */
 
-
-import React,{useEffect,useState} from "react";
+import React, { useEffect, useState } from 'react';
 import './style.less';
 
 import { Tooltip } from 'antd';
-import {
-    LogoutOutlined,
-    SettingOutlined
-  } from '@ant-design/icons';
+import { LogoutOutlined, SettingOutlined } from '@ant-design/icons';
 
 import logo from '../../../../../public/images/kc-logo.png';
 import platFormMenuIcon from '../../../../../public/images/platformMenu.png';
 import tabCloseIcon from '../../../../../public/images/tabCloseIcon.png';
 
 interface TopBarType {
-    onTabChange?:(data:SystemListItem) => void, //当tab切换时回调
-    onCurrentSystemChanged?:(data:SystemListItem) => void, //当菜单切换系统时回调
-    sysList?:SystemListItem[],
-    openedTabs:SystemListItem[],
-    currentTab?:SystemListItem,
+  onTabChange?: (data: SystemListItem) => void; //当tab切换时回调
+  sysList?: SystemListItem[]; //可选系统列表
+  openedTabs: SystemListItem[]; //已打开的列表
+  currentTab?: SystemListItem; //当前tab
+  userPannelTabClick?: (tag: 'SETTING' | 'LOGOUT') => void;
 }
 
+const TopBar: React.FC<TopBarType> = (props) => {
+  const {
+    onTabChange,
+    sysList = [],
+    openedTabs = [],
+    currentTab,
+    userPannelTabClick,
+  } = props;
+  const [systemTabs, setSystemTabs] = useState<SystemListItem[]>([]); //已打开的tab
+  const [currentSelectedTab, setCurrentSelectedTab] =
+    useState<SystemListItem>();
+  const [ifOpenPannel, setIfOpenPannel] = useState(false);
+  const [arrowRotate, setArrowRotate] = useState(false);
 
-const TopBar:React.FC<TopBarType> = (props)=>{
-    
-    const {onTabChange,onCurrentSystemChanged,sysList=[],openedTabs = [],currentTab} = props;
-    const [systemTabs,setSystemTabs] = useState<SystemListItem[]>([]);  //已打开的tab
-    const [currentSelectedTab,setCurrentSelectedTab] = useState<SystemListItem>();
-    const [ifOpenPannel,setIfOpenPannel] = useState(false);
-    
-    const systemTabClickHandle =(item:SystemListItem)=>{   //导航栏tab点击
-        setCurrentSelectedTab(item);
-        onTabChange&&onTabChange(item);
-    }
+  const _systemTabClickHandle = (item: SystemListItem) => {
+    //导航栏tab点击
+    setCurrentSelectedTab(item);
+    onTabChange && onTabChange(item);
+  };
 
-    const systemListClickHandle = (data:SystemListItem)=>{   //导航栏系统菜单列表点击回调
-        onCurrentSystemChanged&&onCurrentSystemChanged(data);
-    }
+  const _systemListClickHandle = (data: SystemListItem) => {
+    //导航栏系统菜单列表点击回调
+    onTabChange && onTabChange(data);
+  };
 
-    const userPannelTabClick = (tag:string)=>{
+  const _userPannelTabClick = (tag: 'SETTING' | 'LOGOUT') => {
+    //用户菜单tab点击回调
+    userPannelTabClick && userPannelTabClick(tag);
+  };
 
-    }
-    
+  const UserPannel = () => {
+    return (
+      <div className="userPannel">
+        <div
+          className="userPannelTab"
+          onClick={() => _userPannelTabClick('SETTING')}
+        >
+          <SettingOutlined />
+          设置
+        </div>
+        <div
+          className="userPannelTab"
+          onClick={() => _userPannelTabClick('LOGOUT')}
+        >
+          <LogoutOutlined />
+          退出
+        </div>
+      </div>
+    );
+  };
 
-    const UserPannel = ()=>{
-    
-        return (
-            <div className='userPannel'>
-                <div className='userPannelTab' onClick={()=>userPannelTabClick('SETTING')}><SettingOutlined />设置</div>
-                <div className='userPannelTab' onClick={()=>userPannelTabClick('LOGOUT')}><LogoutOutlined />退出</div>
-            </div>
-        )
-    }
+  useEffect(() => {
+    setSystemTabs(openedTabs);
+    currentTab && setCurrentSelectedTab(currentTab);
+  }, [props]);
 
-    useEffect(()=>{
-        setSystemTabs(openedTabs);
-        currentTab&&setCurrentSelectedTab(currentTab);
-    },[props]);
-    
-    return (
-        <div className='topBar'>
-            <div className='logoWrap'>
-                <img className='logo' src={logo} />
+  return (
+    <div className="topBar">
+      <div className="logoWrap">
+        <img className="logo" src={logo} />
+      </div>
+      <div
+        className={ifOpenPannel ? 'platformMenu on' : 'platformMenu'}
+        onClick={() => setIfOpenPannel(!ifOpenPannel)}
+      >
+        <img src={platFormMenuIcon} />
+        <div className="systemPannel">
+          {sysList.map((item) => (
+            <div
+              key={item.id}
+              className="systemList"
+              onClick={() => _systemListClickHandle(item)}
+            >
+              <img src={item.icon} alt="" />
+              <span className="name">{item.name}</span>
             </div>
-            <div className={ifOpenPannel?'platformMenu on':'platformMenu'} onClick={()=>setIfOpenPannel(!ifOpenPannel)}>
-                <img src={platFormMenuIcon} />
-                <div className='systemPannel'>
-                       {
-                           sysList.map(item=>(
-                              <div key={item.id} className='systemList' onClick={()=>systemListClickHandle(item)}>
-                                  <img src={item.icon} alt="" />
-                                  <span className='name'>{item.name}</span>
-                              </div>
-                           ))
-                       }
-                </div>
-            </div>
-            <div className='tabWrap'>
-                   {
-                       systemTabs.map(item=>(
-                         <div key={item.id} className={currentSelectedTab?.id == item.id?'tab on':'tab'} onClick={()=>systemTabClickHandle(item)}>{item.name} <img src={tabCloseIcon} alt="close" /></div>
-                       ))
-                   }
-            </div>
-            <div className='userRelaInfoWrap'>
-                   <div className='notification'><img className='notificationIcon' src={require('../../../../../public/images/notificationIcon.png')} /></div>
-                   <Tooltip title={<UserPannel />}  color='#fff' >
-                        <div className='user'>
-                                <img className='avator' src={require('../../../../../public/images/Mask.png')} />
-                                <span className='name'>Mr Lawrence</span>
-                                <img className='arrow' src={require('../../../../../public/images/arrow_white.png')} />
-                        </div>
-                   </Tooltip>
-            </div>
-            
+          ))}
         </div>
-     )
-}
-
+      </div>
+      {/**
+       * 已打开的tab
+       */}
+      <div className="tabWrap">
+        {systemTabs.map((item) => (
+          <div
+            key={item.id}
+            className={currentSelectedTab?.id == item.id ? 'tab on' : 'tab'}
+            onClick={() => _systemTabClickHandle(item)}
+          >
+            {item.name} <img src={tabCloseIcon} alt="close" />
+          </div>
+        ))}
+      </div>
+      <div className="userRelaInfoWrap">
+        <div className="notification">
+          <img
+            className="notificationIcon"
+            src={require('../../../../../public/images/notificationIcon.png')}
+          />
+        </div>
+        <Tooltip
+          title={<UserPannel />}
+          color="#fff"
+          onVisibleChange={(visible) => setArrowRotate(visible)}
+        >
+          <div className="user">
+            <img
+              className="avator"
+              src={require('../../../../../public/images/Mask.png')}
+            />
+            <span className="name">Mr Lawrence</span>
+            <img
+              className={arrowRotate ? 'arrow on' : 'arrow'}
+              src={require('../../../../../public/images/arrow_white.png')}
+            />
+          </div>
+        </Tooltip>
+      </div>
+    </div>
+  );
+};
 
-export default TopBar
+export default TopBar;

+ 40 - 33
src/pages/index/components/topBar/style.less

@@ -2,29 +2,28 @@
   width: 100px;
   background-color: white;
   .userPannelTab {
-      display: flex;
-      flex-direction: row;
-      justify-content:space-evenly;
-      align-items: center;
-      height:30px;
-      font-size: 14px;
-      font-family: SourceHanSansCN-Normal, SourceHanSansCN;
-      font-weight: 400;
-      color:rgb(131, 127, 127);
-      cursor: pointer;
-      border-bottom: 1px solid #eee;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-evenly;
+    align-items: center;
+    height: 30px;
+    font-size: 14px;
+    font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+    font-weight: 400;
+    color: rgb(131, 127, 127);
+    cursor: pointer;
+    border-bottom: 1px solid #eee;
 
-      &:hover {
-         background-color:#eee;
-      }
+    &:hover {
+      background-color: #eee;
+    }
 
-      &:last-child {
-        border-bottom: none;
-      }
+    &:last-child {
+      border-bottom: none;
+    }
   }
 }
 
-
 .topBar {
   display: flex;
   flex-direction: row;
@@ -33,7 +32,7 @@
   width: 100%;
   height: 48px;
   padding-left: 16px;
-  background: #3071F2;
+  background: #3071f2;
 
   .logoWrap {
     width: 200px;
@@ -65,15 +64,15 @@
       position: absolute;
       left: 0;
       top: 50px;
-      z-index: 9;
+      z-index: 99;
       flex-direction: row;
       justify-content: flex-start;
       align-items: center;
-      background: #FFFFFF;
+      background: #ffffff;
       padding: 16px 20px;
       box-shadow: 0px 6px 10px 0px rgba(26, 34, 51, 0.2);
       border-radius: 8px;
-      border: 1px solid #E6EAF2;
+      border: 1px solid #e6eaf2;
 
       .systemList {
         display: flex;
@@ -84,18 +83,18 @@
         height: 98px;
         margin-right: 10px;
         border-radius: 8px;
-
+        line-height: normal;
         .name {
           font-size: 12px;
           font-family: SourceHanSansCN-Normal, SourceHanSansCN;
           font-weight: 400;
-          color: #666E80;
+          color: #666e80;
         }
 
-        &>img {
+        & > img {
           width: 40px;
           height: 40px;
-          background: #FFB44D;
+          background: #ffb44d;
           border-radius: 10px;
           margin-bottom: 16px;
         }
@@ -105,7 +104,7 @@
         }
 
         &:hover {
-          background: #F7F8FA;
+          background: #f7f8fa;
 
           .name {
             font-size: 12px;
@@ -118,7 +117,7 @@
     }
 
     &.on {
-      background: #0B54E6;
+      background: #0b54e6;
 
       .systemPannel {
         display: flex;
@@ -138,13 +137,13 @@
       font-size: 14px;
       font-family: SourceHanSansCN-Medium, SourceHanSansCN;
       font-weight: 500;
-      color: #FFFFFF;
+      color: #ffffff;
       opacity: 0.8;
       margin-right: 16px;
       cursor: pointer;
       box-sizing: border-box;
 
-      &>img {
+      & > img {
         width: 8px;
         height: 8px;
         margin-left: 16px;
@@ -156,7 +155,7 @@
 
       &.on {
         opacity: 1;
-        background: #0B54E6;
+        background: #0b54e6;
       }
 
       &:last-child {
@@ -191,7 +190,10 @@
 
     .user {
       cursor: pointer;
-
+      display: flex;
+      flex-direction: row;
+      justify-content: center;
+      align-items: center;
       .avator {
         width: 26px;
         height: 26px;
@@ -202,13 +204,18 @@
         font-size: 14px;
         font-family: SourceHanSansCN-Normal, SourceHanSansCN;
         font-weight: 400;
-        color: #FFFFFF;
+        color: #ffffff;
         margin-right: 10px;
       }
 
       .arrow {
         width: 11px;
         height: 7px;
+        transition: all 0.3s ease-in;
+
+        &.on {
+          transform: rotate(180deg);
+        }
       }
     }
   }

+ 3 - 5
src/pages/index/index.less

@@ -1,6 +1,4 @@
-
-
-
 .indexPage {
-    min-width:1100px;
-}
+  font-size: 0;
+  min-width: 1100px;
+}

+ 91 - 70
src/pages/index/index.tsx

@@ -1,94 +1,115 @@
 /*
  * @Author: your name
  * @Date: 2021-11-10 09:33:30
- * @LastEditTime: 2021-11-29 10:13:27
+ * @LastEditTime: 2021-12-20 10:24:05
  * @LastEditors: Please set LastEditors
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/index.tsx
  */
 
-
-import React, { useState,useEffect } from 'react';
+import { useState, useEffect } from 'react';
 import TopBar from './components/topBar';
-import IframePage from './components/iframePage'
-import { useModel } from 'umi';
+import IframePage from './components/iframePage';
+import { useModel, MicroApp } from 'umi';
 import './index.less';
 
 const IndexPage = () => {
+  const {
+    systemLists, //当前医院可选子系统列表
+    setInitialState,
+    openedSysLists, //当前已打开的系统列表
+    loading,
+    currentSelectedSys, //当前选中的系统
+    logout,
+  } = useModel('@@initialState', (model) => {
+    console.log({ model });
+    return {
+      systemLists: model.initialState?.systemLists,
+      setInitialState: model.setInitialState,
+      openedSysLists: model.initialState?.openedSysLists,
+      loading: model.loading,
+      currentSelectedSys: model.initialState?.currentSelectedSys,
+      logout: model.initialState?.logout,
+    };
+  });
 
-      const { 
-            systemLists,  //当前医院可选子系统列表
-            setInitialState,
-            openedSysLists, //当前已打开的系统列表
-            loading,
-            currentSelectedSys, //当前选中的系统
-      } = useModel('@@initialState',model=>{
-          return {
-                systemLists:model.initialState?.systemLists,
-                setInitialState:model.setInitialState,
-                openedSysLists:model.initialState?.openedSysLists,
-                loading:model.loading,
-                currentSelectedSys:model.initialState?.currentSelectedSys,
-            }
-      });
-      const [selectableSysList,setSelectableSysList] = useState<SystemListItem[]>([]);
-      const [openedTabs,setOpenTabs] = useState<SystemListItem[]>();
-      const [currentOpenedTab,setCurrentOpenedTab] = useState<SystemListItem>();
+  const [selectableSysList, setSelectableSysList] = useState<SystemListItem[]>(
+    [],
+  ); //可选的子应用
+  const [openedTabs, setOpenTabs] = useState<SystemListItem[]>(); //当前已开启的子应用集合
+  const [currentOpenedTab, setCurrentOpenedTab] = useState<SystemListItem>(); //当前激活的应用
 
+  const onCurrentSystemChanged = async (data: SystemListItem) => {
+    console.log({ 当前选中tab: data });
+    setCurrentOpenedTab(data);
+    const index = openedSysLists?.findIndex((t) => t.id == data.id);
+    if (index != -1) {
+      //现在打开的tab里已经存在
+      await setInitialState((s) => {
+        return {
+          ...s,
+          currentSelectedSys: data,
+        };
+      });
+    } else {
+      //新打开的tab
+      await setInitialState((s) => {
+        return {
+          ...s,
+          currentSelectedSys: data,
+          openedSysLists: openedSysLists?.concat(data),
+        };
+      });
+    }
+  };
 
-      const onTabChangeHandle = ()=>{
-            
+  const userPannelTabClick = async (tag: string) => {
+    if (tag == 'LOGOUT') {
+      if (logout) {
+        await logout();
       }
+    }
+  };
 
-      const onCurrentSystemChanged = async (data:SystemListItem)=>{
-            console.log({'当前选中tab':data});
-            setCurrentOpenedTab(data);
-            const index = openedSysLists?.findIndex(t=>t.id == data.id);
-            if(index != -1){
-                  //现在打开的tab里已经存在
-                  await setInitialState((s)=>{
-                        return {
-                              ...s,
-                              currentSelectedSystem:data
-                        }
-                  });
-            }else {
-                  //新打开的tab
-                  await setInitialState((s)=>{
-                        return {
-                              ...s,
-                              currentSelectedSystem:data,
-                              openedSysLists:openedSysLists?.concat(data)
-                        }
-                  });
-            }
-      }
+  useEffect(() => {
+    if (systemLists) setSelectableSysList(systemLists);
+  }, [systemLists]);
+
+  useEffect(() => {
+    if (openedSysLists) setOpenTabs(openedSysLists);
+    // console.log({openedSysLists});
+  }, [openedSysLists]);
 
-      useEffect(() => {
-            if(systemLists)setSelectableSysList(systemLists);
-      }, [systemLists]);
+  useEffect(() => {
+    setCurrentOpenedTab(currentSelectedSys); //当前激活的tab
+  }, [currentSelectedSys]);
 
+  useEffect(() => {
+    if (systemLists) setSelectableSysList(systemLists);
+    if (openedSysLists) setOpenTabs(openedSysLists);
+  }, []);
 
-      useEffect(() => {
-            if(openedSysLists)setOpenTabs(openedSysLists);
-      }, [openedSysLists]);
+  if (loading) return <h1>Loading...</h1>;
 
+  return (
+    <div className="indexPage">
+      <TopBar
+        openedTabs={openedTabs ? openedTabs : []}
+        onTabChange={(data) => {
+          onCurrentSystemChanged(data);
+        }}
+        sysList={selectableSysList}
+        currentTab={currentOpenedTab}
+        userPannelTabClick={(tag) => userPannelTabClick(tag)}
+      />
 
-      if(loading)return <h1>Loading...</h1>
-      
-      return (
-            <div className='indexPage'>
-                  <TopBar 
-                        openedTabs={openedTabs?openedTabs:[]}
-                        onTabChange={()=>onTabChangeHandle()} 
-                        onCurrentSystemChanged={data=>onCurrentSystemChanged(data)} 
-                        sysList={selectableSysList} 
-                        currentTab={currentOpenedTab}
-                  />
-                  <IframePage url={`http://118.31.245.65:8804/user/login/?redirect=%2FDataManagement%2FpublicData&hospSign=tYAoFaa20yCAgaiy`} />
-            </div>
-      )
-}
+      {/* <MicroApp name='MedicalWisdomCheckSys' /> */}
 
+      {openedTabs && (
+        <IframePage activedItem={currentOpenedTab} list={openedTabs} />
+      )}
+    </div>
+  );
+};
 
-export default IndexPage;
+export default IndexPage;

+ 202 - 164
src/pages/login/index.tsx

@@ -1,191 +1,229 @@
 /*
  * @Author: your name
  * @Date: 2021-11-09 14:58:08
- * @LastEditTime: 2021-11-19 16:42:22
+ * @LastEditTime: 2021-12-16 15:17:06
  * @LastEditors: Please set LastEditors
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/login/index.tsx
  */
 
-
-import React, { useRef, useEffect, useState } from 'react'
+import React, { useRef, useEffect, useState } from 'react';
 import { Select, message } from 'antd';
-import './style.less'
+import './style.less';
 
 import { useModel, history } from 'umi';
 
 import { Form, Input, Button, Checkbox } from 'antd';
 
-import logo from '../../../public/images/kc-logo.png'
+import logo from '../../../public/images/kc-logo.png';
 
 import KCSelect from '@/components/kc-select';
 
-import { getSubHosp, login,getHospSubSystemList } from '@/service/login';
+import { getSubHosp, login, getHospSubSystemList } from '@/service/login';
 
 const { Option } = Select;
 
 const LoginPage: React.FC<any> = () => {
-    const [transitionObj, setTransitionObj] = useState<string>();
-    const [transformObj, setTransformObj] = useState<string>();
-    const loginPageRef = useRef<HTMLDivElement>(null);
-    const [subHospList, setSubHospList] = useState<{ name: string, value: string | number }[]>([]);  //分院列表
-    const [ifSelectSystem,setIfSelectSystem] = useState(false); //是否跳转到选择系统界面
-    const [ifLoading,setIfLoading] = useState(false);
-    const [systemList,setSystemList] = useState<SystemListItem[]>([]);  //可选平台列表
-    const { initialState, setInitialState } = useModel('@@initialState');
-
-
-    const onMouseMoveHandle = (mouseEvent: any) => {
-        //    console.log({mouseEvent});
-        const loginPage = loginPageRef.current;
-        if (loginPage) {
-            let centerX = loginPage.offsetLeft + loginPage.offsetWidth / 2,  //div中心点到页面左边距离
-                centerY = loginPage.offsetTop + loginPage.offsetHeight / 2;
-
-            let deltaX = mouseEvent.pageX - centerX,
-                deltaY = mouseEvent.pageY - centerY;
-
-            let percentageX = deltaX / centerX,  //向左或向右的 偏差率
-                percentageY = deltaY / centerY;
-            let deg = 20;  //控制 偏差的 程度
-            // console.log(percentageX*20,percentageY*20);
-            setTransformObj(`translate(${percentageX * deg}px,${percentageY * deg}px)`);
-            // setTransformObj('rotateX(' + percentageY * deg + 'deg)');
-        }
-
-    }
-
-    const onMouseLeaveHandle = () => {
-        setTransformObj(`translate(0px,0px)`);
-        setTransitionObj('all 0.2s linear');
+  const [transitionObj, setTransitionObj] = useState<string>();
+  const [transformObj, setTransformObj] = useState<string>();
+  const loginPageRef = useRef<HTMLDivElement>(null);
+  const [subHospList, setSubHospList] = useState<
+    { name: string; value: string | number }[]
+  >([]); //分院列表
+  const [ifSelectSystem, setIfSelectSystem] = useState(false); //是否跳转到选择系统界面
+  const [ifLoading, setIfLoading] = useState(false);
+  const [systemList, setSystemList] = useState<SystemListItem[]>([]); //可选平台列表
+  const { setInitialState } = useModel('@@initialState');
+
+  const onMouseMoveHandle = (mouseEvent: any) => {
+    //    console.log({mouseEvent});
+    const loginPage = loginPageRef.current;
+    if (loginPage) {
+      let centerX = loginPage.offsetLeft + loginPage.offsetWidth / 2, //div中心点到页面左边距离
+        centerY = loginPage.offsetTop + loginPage.offsetHeight / 2;
+
+      let deltaX = mouseEvent.pageX - centerX,
+        deltaY = mouseEvent.pageY - centerY;
+
+      let percentageX = deltaX / centerX, //向左或向右的 偏差率
+        percentageY = deltaY / centerY;
+      let deg = 20; //控制 偏差的 程度
+      // console.log(percentageX*20,percentageY*20);
+      setTransformObj(
+        `translate(${percentageX * deg}px,${percentageY * deg}px)`,
+      );
+      // setTransformObj('rotateX(' + percentageY * deg + 'deg)');
     }
-
-    const getSubHospFunc = async () => {
-        const { list } = await getSubHosp();
-        setSubHospList(list);
-    }
-
-    const getHospSubSystemListFunc = async ()=>{
-         const data = await getHospSubSystemList();
-         if(data)setSystemList(data);
-    }
-
-    const onFinish = async (values:LoginPageTypes.LoginInfo) => {
-        setIfLoading(true);
-        const resp = await login(values);
-        setIfLoading(false);
-        if (resp) {
-            message.success('登录成功!');
-            await getHospSubSystemListFunc();
-            await setInitialState((s) => ({ ...s, userData: resp,systemLists:systemList }));
-            localStorage.setItem('KC-MiddlePlatformUserData', JSON.stringify(resp));
-            
-            if(systemList.length>1){
-                //当前医院拥有多个子平台时,进入选择
-                setIfSelectSystem(true);
-            }else {
-                //否则直接进入首页
-                const { query } = history.location;
-                const { redirect } = query as { redirect: string };
-                history.push(redirect || '/');
-                return;
-            }
-            setIfLoading(false);
-            
-        }
-    }
-
-    const selectSysHandle = (systemInfo:LoginPageTypes.SystemListItem)=>{
+  };
+
+  const onMouseLeaveHandle = () => {
+    setTransformObj(`translate(0px,0px)`);
+    setTransitionObj('all 0.2s linear');
+  };
+
+  //获取当前账号分院列表
+  const getSubHospFunc = async () => {
+    const { list } = await getSubHosp();
+    setSubHospList(list);
+  };
+
+  //获取当前账号所有子应用列表
+  const getHospSubSystemListFunc = async (): Promise<SystemListItem[]> => {
+    const data = await getHospSubSystemList();
+    if (data) setSystemList(data);
+    return data;
+  };
+
+  const onFinish = async (values: LoginPageTypes.LoginInfo) => {
+    setIfLoading(true);
+    const resp = await login(values);
+    setIfLoading(false);
+    if (resp) {
+      // message.success('登录成功!');
+      const data = await getHospSubSystemListFunc();
+      await setInitialState((s) => ({
+        ...s,
+        userData: resp,
+        systemLists: data,
+      }));
+      localStorage.setItem('KC-MiddlePlatformUserData', JSON.stringify(resp));
+
+      if (data.length > 1) {
+        //当前医院拥有多个子平台时,进入选择
+        setIfSelectSystem(true);
+      } else {
+        //否则直接进入首页
         const { query } = history.location;
         const { redirect } = query as { redirect: string };
-        history.push(redirect || '/');
+        history.replace(redirect || '/');
+        return;
+      }
+      setIfLoading(false);
     }
-
-    useEffect(() => {
-        //根据hospSign获取分院信息
-        getSubHospFunc();
-    }, []);
-
-
-
-
-    return (
-        <div className='loginPage' onMouseMove={onMouseMoveHandle} onMouseLeave={onMouseLeaveHandle} ref={loginPageRef}>
-            <div className='circleBigOne' style={{ transform: transformObj, transition: transitionObj }}></div>
-            <div className='circleBigerOne' ></div>
-            <div className='circleLittleOne' style={{ transform: transformObj, transition: transitionObj }}></div>
-            <div className='loginBlock'>
-                {
-                    ifSelectSystem ? (
-                        <div className='systemSelector'>
-                            {
-                                systemList.map((t)=>(
-                                      <div className='sysItem' key={t.id} onClick={()=>selectSysHandle(t)}>
-                                          <img className='icon' src={t.icon} alt="" />
-                                          <span className='sysName'>{t.name}</span>
-                                      </div>
-                                ))
-                            }
-                        </div>
-                    ) : (
-                        <>
-                            <div className='left'>
-                                <img className='bannerImg' src={require('../../../public/images/loginBannner.png')} />
-                            </div>
-                            <div className='rightLoginArea'>
-                                <div className='subHospSelector'>
-                                    {
-                                        subHospList.length > 0 && (
-                                            <KCSelect allowClear={false} style={{ width: 200 }} defaultValue={subHospList[0].value} suffixIcon={<img style={{ width: '10px', height: '6px' }} src={require('../../../public/images/arrow.png')} />}>
-                                                {
-                                                    subHospList.map(item => {
-                                                        return (
-                                                            <Option value={item.value} key={item.value}>{item.name}</Option>
-                                                        )
-                                                    })
-                                                }
-                                            </KCSelect>
-                                        )
-                                    }
-                                </div>
-                                <div className='systemName'>欢迎进入医务管理系统</div>
-                                <Form
-                                    onFinish={onFinish}
-                                >
-                                    <Form.Item
-                                        name="account"
-                                        rules={[{ required: true, message: 'Please input your username!' }]}
-                                    >
-                                        <Input className='input' />
-                                    </Form.Item>
-
-                                    <Form.Item
-                                        name="password"
-                                        rules={[{ required: true, message: 'Please input your password!' }]}
-                                    >
-                                        <Input.Password className='input' />
-                                    </Form.Item>
-
-                                    <Form.Item >
-                                        <Button className='loginBtn' type="primary" htmlType="submit" loading={ifLoading} >
-                                            登录
-                                        </Button>
-                                    </Form.Item>
-                                    <Form.Item name="remember" valuePropName="checked">
-                                        <Checkbox className='checkBtn'>记住密码</Checkbox>
-                                    </Form.Item>
-                                </Form>
-                            </div>
-                        </>
-                    )
-                }
+  };
+
+  const selectSysHandle = async (systemInfo: SystemListItem) => {
+    await setInitialState((s) => ({
+      ...s,
+      currentSelectedSys: systemInfo,
+      openedSysLists: [systemInfo],
+    }));
+    const { query } = history.location;
+    const { redirect } = query as { redirect: string };
+    history.push(redirect || '/');
+  };
+
+  useEffect(() => {
+    //根据hospSign获取分院信息
+    getSubHospFunc();
+  }, []);
+
+  return (
+    <div
+      className="loginPage"
+      onMouseMove={onMouseMoveHandle}
+      onMouseLeave={onMouseLeaveHandle}
+      ref={loginPageRef}
+    >
+      <div
+        className="circleBigOne"
+        style={{ transform: transformObj, transition: transitionObj }}
+      ></div>
+      <div className="circleBigerOne"></div>
+      <div
+        className="circleLittleOne"
+        style={{ transform: transformObj, transition: transitionObj }}
+      ></div>
+      <div className="loginBlock">
+        {ifSelectSystem ? (
+          <div className="systemSelector">
+            {systemList.map((t) => (
+              <div
+                className="sysItem"
+                key={t.id}
+                onClick={() => selectSysHandle(t)}
+              >
+                <img className="icon" src={t.icon} alt="" />
+                <span className="sysName">{t.name}</span>
+              </div>
+            ))}
+          </div>
+        ) : (
+          <>
+            <div className="left">
+              <img
+                className="bannerImg"
+                src={require('../../../public/images/loginBannner.png')}
+              />
             </div>
-            <div className='bottomLogo'>
-                <img className='logo' src={logo} />
-                <div className='copyright'>© 2021 康程智医(成都)技术部出品</div>
+            <div className="rightLoginArea">
+              <div className="subHospSelector">
+                {subHospList.length > 0 && (
+                  <KCSelect
+                    allowClear={false}
+                    style={{ width: 200 }}
+                    defaultValue={subHospList[0].value}
+                    suffixIcon={
+                      <img
+                        style={{ width: '10px', height: '6px' }}
+                        src={require('../../../public/images/arrow.png')}
+                      />
+                    }
+                  >
+                    {subHospList.map((item) => {
+                      return (
+                        <Option value={item.value} key={item.value}>
+                          {item.name}
+                        </Option>
+                      );
+                    })}
+                  </KCSelect>
+                )}
+              </div>
+              <div className="systemName">欢迎进入医务管理系统</div>
+              <Form onFinish={onFinish}>
+                <Form.Item
+                  name="account"
+                  rules={[
+                    { required: true, message: 'Please input your username!' },
+                  ]}
+                >
+                  <Input className="input" />
+                </Form.Item>
+
+                <Form.Item
+                  name="password"
+                  rules={[
+                    { required: true, message: 'Please input your password!' },
+                  ]}
+                >
+                  <Input.Password className="input" />
+                </Form.Item>
+
+                <Form.Item>
+                  <Button
+                    className="loginBtn"
+                    type="primary"
+                    htmlType="submit"
+                    loading={ifLoading}
+                  >
+                    登录
+                  </Button>
+                </Form.Item>
+                <Form.Item name="remember" valuePropName="checked">
+                  <Checkbox className="checkBtn">记住密码</Checkbox>
+                </Form.Item>
+              </Form>
             </div>
-        </div>
-    )
-}
-
-export default LoginPage;
+          </>
+        )}
+      </div>
+      <div className="bottomLogo">
+        <img className="logo" src={logo} />
+        <div className="copyright">© 2021 康程智医(成都)技术部出品</div>
+      </div>
+    </div>
+  );
+};
+
+export default LoginPage;

+ 14 - 18
src/pages/login/login.d.ts

@@ -1,28 +1,24 @@
 /*
  * @Author: your name
  * @Date: 2021-11-10 10:05:13
- * @LastEditTime: 2021-11-19 16:30:08
+ * @LastEditTime: 2021-11-15 17:10:14
  * @LastEditors: Please set LastEditors
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/login/login.d.ts
  */
 
+declare namespace LoginPageTypes {
+  //登录后可选平台项
+  type SystemListItem = {
+    icon: string;
+    id: number;
+    name: string;
+  };
 
-
-
-export interface LoginPageTypes {
-
-    //登录后可选平台项
-    type SystemListItem = {
-          icon:string,
-          id:number,
-          name:string
-    }
-
-    //登录发送信息
-    type LoginInfo = {
-        account:string,
-        remember:boolean,
-        password:string
-  }
+  //登录发送信息
+  type LoginInfo = {
+    account: string;
+    remember: boolean;
+    password: string;
+  };
 }

+ 8 - 9
src/typings.d.ts

@@ -1,17 +1,16 @@
 /*
  * @Author: your name
  * @Date: 2021-11-19 16:31:19
- * @LastEditTime: 2021-11-19 16:34:39
+ * @LastEditTime: 2021-12-15 14:09:45
  * @LastEditors: Please set LastEditors
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/typings.d.ts
  */
 
-
-
-type SystemListItem = {   //平台列表项
-    icon:string,
-    id:number,
-    name:string,
-    url:string,
-}
+type SystemListItem = {
+  //平台列表项
+  icon: string;
+  id: string;
+  name: string;
+  url: string;
+};