index.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { useEffect, useState } from "react";
  2. import { getClientConfig } from "@/app/config/client";
  3. import { useAccessStore } from "@/app/store";
  4. import { api } from "@/app/client/api";
  5. import dayjs from "dayjs";
  6. import { showToast } from "@/app/components/ui-lib";
  7. export type ITokenData = {
  8. access_token: string;
  9. token_type: string;
  10. expires_in: number;
  11. scope?: string[];
  12. };
  13. /**
  14. * 使用oauth2登录站点
  15. */
  16. export const EnsureToken = (props: any) => {
  17. const accessStore = useAccessStore();
  18. const [loading, setLoading] = useState(true);
  19. const [user, setUser] = useState<any>();
  20. const config = getClientConfig();
  21. useEffect(() => {
  22. const parseToken = () => {
  23. const url = new URL(window.location.href);
  24. if (url.hash && url.hash.startsWith("#token=")) {
  25. try {
  26. setLoading(true);
  27. const token = JSON.parse(
  28. decodeURIComponent(url.hash.substring(7)),
  29. ) as ITokenData;
  30. accessStore.setAccessToken({
  31. accessToken: token.access_token,
  32. tokenType: token.token_type,
  33. expiresIn: dayjs().add(token.expires_in, "s").unix(),
  34. });
  35. setTimeout(() => {
  36. setLoading(false);
  37. url.hash = "";
  38. window.location.href = url.toString();
  39. }, 1000);
  40. return;
  41. } catch (e) {
  42. setLoading(false);
  43. console.log("parse token fail", e);
  44. showToast("登录异常,请联系管理员处理!");
  45. }
  46. return;
  47. }
  48. api.user
  49. .userinfo()
  50. .then(async (resp) => {
  51. if (!resp) {
  52. return;
  53. }
  54. if (resp.status == 401) {
  55. if (config?.authorizeUrl) {
  56. window.location.href = config?.authorizeUrl;
  57. } else {
  58. console.log("login expired");
  59. }
  60. return;
  61. }
  62. const data = await resp.json();
  63. if (data.code == 1) {
  64. accessStore.setLogin(true);
  65. setUser(data);
  66. } else {
  67. console.log("fail", data);
  68. }
  69. })
  70. .catch(() => {})
  71. .finally(() => {
  72. setLoading(false);
  73. });
  74. };
  75. parseToken();
  76. const handler = setInterval(parseToken, 10000);
  77. return () => {
  78. clearInterval(handler);
  79. };
  80. }, []);
  81. if (accessStore.isLogin() && user) {
  82. return <>{props.children}</>;
  83. }
  84. return (
  85. <div>
  86. <span>加载中,请稍后...</span>
  87. </div>
  88. );
  89. };