소스 검색

feat: 单点登录

chenlei 4 달 전
부모
커밋
03e146d1b6
3개의 변경된 파일50개의 추가작업 그리고 4개의 파일을 삭제
  1. 1 1
      package.json
  2. 4 0
      src/api/index.ts
  3. 45 3
      src/pages/Login/index.tsx

+ 1 - 1
package.json

@@ -84,7 +84,7 @@
     "workbox-webpack-plugin": "^6.4.1"
   },
   "scripts": {
-    "start": "cross-env REACT_APP_API_URL=https://sit-shoubodyh.4dage.com REACT_APP_IMG_PUBLIC=/api node scripts/start.js",
+    "start": "cross-env REACT_APP_API_URL=http://192.168.20.61:8090 REACT_APP_IMG_PUBLIC=/api node scripts/start.js",
     "build": "cross-env PUBLIC_URL=./ REACT_APP_API_URL=https://sit-shoubodyh.4dage.com REACT_APP_IMG_PUBLIC= node scripts/build.js",
     "build:prod": "cross-env PUBLIC_URL=./ REACT_APP_API_URL=http://192.124.82.43:8091 REACT_APP_IMG_PUBLIC= node scripts/build.js"
   },

+ 4 - 0
src/api/index.ts

@@ -5,6 +5,10 @@ export const login = (data: LoginRequest) => {
   return requestByPost<LoginResponse>("/api/admin/login", data);
 };
 
+export const ssoLoginApi = (code: string) => {
+  return requestByGet("/api/admin/ssoLogin", { code });
+};
+
 export const logoutApi = () => {
   return requestByGet("/api/admin/logout");
 };

+ 45 - 3
src/pages/Login/index.tsx

@@ -1,10 +1,10 @@
-import { useState } from "react";
+import { useEffect, useState } from "react";
 import { Button, Form, Input } from "antd";
-import { useNavigate } from "react-router-dom";
+import { useNavigate, useParams, useSearchParams } from "react-router-dom";
 import { Base64 } from "@dage/utils";
 import { encodeStr, setTokenInfo } from "@dage/pc-components";
 import { getBaseURL } from "@dage/service";
-import { login } from "@/api";
+import { login, ssoLoginApi } from "@/api";
 import { LoginRequest } from "@/types";
 import { DEFAULT_ADMIN_MENU, DEFAULT_MENU } from "@/router";
 import IconAccount from "./images/icon_ac-min.png";
@@ -16,6 +16,7 @@ import "./index.scss";
 export default function Login() {
   const navigate = useNavigate();
   const baseUrl = getBaseURL();
+  const [params] = useSearchParams();
   const [loading, setLoading] = useState(false);
   const [timestamp, setTimestamp] = useState(new Date().getTime());
 
@@ -43,6 +44,34 @@ export default function Login() {
     }
   };
 
+  const handleSSOLogin = async (code: string) => {
+    try {
+      setLoading(true);
+      const data = await ssoLoginApi(code);
+      const list = data.user.isAdmin
+        ? [...DEFAULT_MENU, ...DEFAULT_ADMIN_MENU]
+        : [...DEFAULT_MENU];
+
+      // 用户信息存到本地
+      setTokenInfo(data);
+      navigate(list[0].redirect || list[0].path, {
+        replace: true,
+      });
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  useEffect(() => {
+    const code = params.get("code");
+    if (code) {
+      params.delete("code");
+      params.delete("sessionid");
+      navigate(`?${params.toString()}`, { replace: true });
+      handleSSOLogin(code);
+    }
+  }, []);
+
   return (
     <div className="login">
       <div className="login-img" />
@@ -108,6 +137,19 @@ export default function Login() {
             />
           </Form.Item>
 
+          <div style={{ textAlign: "right" }}>
+            <Button
+              type="link"
+              onClick={() => {
+                window.location.href = `https://m.canalmuseum.org.cn/oauth/authorize?client_id=b80b56f9852f45e5a4d52300194ed3f6&redirect_uri=${encodeURIComponent(
+                  location.href
+                )}&scope=userinfo`;
+              }}
+            >
+              单点登录
+            </Button>
+          </div>
+
           {/* 登录按钮 */}
           <div className="login-form__btn">
             <Button type="primary" htmlType="submit" loading={loading}>