Explorar el Código

feat: 单点登录

wzyyy hace 3 años
padre
commit
2ce45ce89a

+ 4 - 4
config/proxy.ts

@@ -12,11 +12,11 @@ export default {
       // target: 'http://192.168.32.44:8844/',
       // ws: 'ws://192.168.32.44:8844/',
       // 开发环境
-      // target: 'http://120.79.18.123:8844/',
-      // ws: 'ws://120.79.18.123:8844/',
+      target: 'http://120.79.18.123:8844/',
+      ws: 'ws://120.79.18.123:8844/',
       // 测试环境
-      target: 'http://120.77.179.54:8844/',
-      ws: 'ws://120.77.179.54:8844/',
+      // target: 'http://120.77.179.54:8844/',
+      // ws: 'ws://120.77.179.54:8844/',
       // target: 'http://192.168.66.5:8844/',
       // ws: 'ws://192.168.66.5:8844/',
       // ws: 'ws://demo.jetlinks.cn/jetlinks',

+ 10 - 4
src/app.tsx

@@ -18,6 +18,7 @@ import { AIcon } from '@/components';
 
 const isDev = process.env.NODE_ENV === 'development';
 const loginPath = '/user/login';
+const bindPath = '/account/center/bind';
 let extraRoutes: any[] = [];
 
 /** 获取用户信息比较慢的时候会展示一个 loading */
@@ -43,7 +44,7 @@ export async function getInitialState(): Promise<{
     return undefined;
   };
   // 如果是登录页面,不执行
-  if (history.location.pathname !== loginPath) {
+  if (history.location.pathname !== loginPath && history.location.pathname !== bindPath) {
     const currentUser = await fetchUserInfo();
     return {
       fetchUserInfo,
@@ -113,7 +114,7 @@ export async function getInitialState(): Promise<{
  * @param url
  * @param options
  */
-const filterUrl = ['/authorize/captcha/config', '/authorize/login'];
+const filterUrl = ['/authorize/captcha/config', '/authorize/login', '/sso/bind-code/'];
 const requestInterceptor = (url: string, options: RequestOptionsInit) => {
   // const {params} = options;
   let authHeader = {};
@@ -195,7 +196,12 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
     onPageChange: () => {
       const { location } = history;
       // 如果没有登录,重定向到 login
-      if (!initialState?.currentUser && location.pathname !== loginPath) {
+      console.log(location.pathname);
+      if (
+        !initialState?.currentUser &&
+        location.pathname !== loginPath &&
+        location.pathname !== bindPath
+      ) {
         history.push(loginPath);
       }
     },
@@ -253,7 +259,7 @@ export function patchRoutes(routes: any) {
 }
 
 export function render(oldRender: any) {
-  if (history.location.pathname !== loginPath) {
+  if (history.location.pathname !== loginPath && history.location.pathname !== bindPath) {
     SystemConfigService.getAMapKey().then((res) => {
       if (res && res.status === 200 && res.result) {
         localStorage.setItem(SystemConst.AMAP_KEY, res.result.apiKey);

+ 35 - 0
src/pages/account/Center/bind/index.less

@@ -1,6 +1,7 @@
 .cards {
   box-sizing: border-box;
   width: 850px;
+  min-height: 510px;
   background: #fff;
   border: 1px solid #e0e4e8;
   border-radius: 2px;
@@ -20,6 +21,7 @@
     display: flex;
     justify-content: center;
 
+    //登录
     .infotitle {
       width: 64px;
       height: 24px;
@@ -48,6 +50,39 @@
         mix-blend-mode: normal;
       }
     }
+
+    //未登录
+    .topimg {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+
+    .topfont {
+      margin-top: 30px;
+      margin-bottom: 30px;
+      font-size: 14px;
+      font-family: 'PingFang SC';
+      font-style: normal;
+      line-height: 14px;
+      opacity: 0.75;
+      mix-blend-mode: normal;
+    }
+    .form {
+      width: 250px;
+      :global {
+        // .ant-form-item{
+        //   margin-bottom: 24px;
+        // }
+        .ant-form-item-label > label {
+          font-weight: 600;
+        }
+        .ant-form-item-label
+          > label.ant-form-item-required:not(.ant-form-item-required-mark-optional)::before {
+          content: none;
+        }
+      }
+    }
   }
 
   .btn {

+ 146 - 57
src/pages/account/Center/bind/index.tsx

@@ -1,14 +1,20 @@
-import { Button, Card, message } from 'antd';
+import { Button, Card, message, Form, Input } from 'antd';
 import { useEffect, useState } from 'react';
 import Service from '@/pages/account/Center/service';
+import api from '@/pages/user/Login/service';
 import styles from './index.less';
+import Token from '@/utils/token';
+import { useModel } from '@@/plugin-model/useModel';
 
 export const service = new Service();
 
 const Bind = () => {
+  const [form] = Form.useForm();
   const [bindUser, setBindUser] = useState<any>();
   const [user, setUser] = useState<any>();
   const [code, setCode] = useState<string>('');
+  const [isLogin, setIslogin] = useState<any>('yes');
+  const { initialState, setInitialState } = useModel('@@initialState');
 
   const bindPage = require('/public/images/bind/bindPage.png');
   const Vector = require('/public/images/bind/Vector.png');
@@ -28,7 +34,62 @@ const Bind = () => {
   };
   const getDetail = () => {
     service.getUserDetail().subscribe((res) => {
-      setUser(res.result);
+      setUser(res?.result);
+    });
+  };
+
+  //未登录页
+  const loginDiv = () => (
+    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
+      <div className={styles.topimg}>
+        <img src={logo} style={{ width: '50px', height: '50px' }} />
+        <img src={Vector} style={{ height: '15px', margin: '0 15px' }} />
+        <img src={logo} style={{ width: '50px', height: '50px' }} />
+      </div>
+      <div className={styles.topfont}>
+        你已通过{bindUser?.type === 'dingtalk' ? '钉钉' : '微信'}授权,完善以下登录信息即可以完成绑定
+      </div>
+      <div className={styles.form}>
+        <Form layout="vertical" form={form}>
+          <Form.Item
+            label="账户"
+            name="username"
+            rules={[{ required: true, message: '请输入账户' }]}
+          >
+            <Input />
+          </Form.Item>
+          <Form.Item
+            label="密码"
+            name="password"
+            rules={[{ required: true, message: '请输入密码' }]}
+          >
+            <Input.Password />
+          </Form.Item>
+        </Form>
+      </div>
+    </div>
+  );
+
+  const fetchUserInfo = async () => {
+    const userInfo = (await initialState?.fetchUserInfo?.()) as UserInfo;
+    if (userInfo) {
+      await setInitialState({
+        ...initialState,
+        currentUser: userInfo,
+      });
+    }
+  };
+  const doLogin = async (data: any) => {
+    api.login(data).subscribe({
+      next: async (userInfo) => {
+        Token.set(userInfo.token);
+        await fetchUserInfo();
+        localStorage.setItem('onLogin', 'yes');
+        setTimeout(() => window.close(), 1000);
+      },
+      error: () => {
+        message.error('登录失败,请重试!');
+      },
     });
   };
 
@@ -37,8 +98,14 @@ const Bind = () => {
     // const params = 'b584032923c78d69e6148cf0e9312723'
     setCode(params);
     bindUserInfo(params);
-    getDetail();
+    if (localStorage.getItem('onLogin') === 'yes') {
+      getDetail();
+    }
+    if (localStorage.getItem('onLogin')) {
+      setIslogin(localStorage.getItem('onLogin'));
+    }
   }, []);
+
   return (
     <>
       <div
@@ -55,66 +122,88 @@ const Bind = () => {
         <div className={styles.cards}>
           <div className={styles.title}>第三方账户绑定</div>
           <div className={styles.info}>
-            <Card
-              title={
-                <div style={{ display: 'flex', alignItems: 'center' }}>
-                  <div>
-                    <img src={Rectangle} />
+            {isLogin === 'no' ? (
+              <>{loginDiv()}</>
+            ) : (
+              <>
+                <Card
+                  title={
+                    <div style={{ display: 'flex', alignItems: 'center' }}>
+                      <div>
+                        <img src={Rectangle} />
+                      </div>
+                      <div className={styles.infotitle}>个人信息</div>
+                    </div>
+                  }
+                >
+                  <div className={styles.item}>
+                    <div style={{ height: 100, marginTop: 10, marginBottom: 10 }}>
+                      <img src={logo} style={{ height: 70 }} />
+                    </div>
+                    <p className={styles.fonts}>账号:{user?.username}</p>
+                    <p className={styles.fonts}>用户名:{user?.name}</p>
                   </div>
-                  <div className={styles.infotitle}>个人信息</div>
-                </div>
-              }
-            >
-              <div className={styles.item}>
-                <div style={{ height: 100, marginTop: 10, marginBottom: 10 }}>
-                  <img src={logo} style={{ height: 70 }} />
+                </Card>
+                <div style={{ position: 'relative', top: '135px', margin: '0 20px' }}>
+                  <img src={Vector} style={{ height: '15px' }} />
                 </div>
-                <p className={styles.fonts}>账号:{user?.username}</p>
-                <p className={styles.fonts}>用户名:{user?.name}</p>
-              </div>
-            </Card>
-            <div style={{ position: 'relative', top: '135px', margin: '0 20px' }}>
-              <img src={Vector} style={{ height: '15px' }} />
-            </div>
-            <Card
-              title={
-                <div style={{ display: 'flex', alignItems: 'center' }}>
-                  <div>
-                    <img src={Rectangle} />
+                <Card
+                  title={
+                    <div style={{ display: 'flex', alignItems: 'center' }}>
+                      <div>
+                        <img src={Rectangle} />
+                      </div>
+                      <div className={styles.infotitle}>三方账户信息</div>
+                    </div>
+                  }
+                >
+                  <div className={styles.item}>
+                    <div style={{ height: 100, marginTop: 10, marginBottom: 10 }}>
+                      <img style={{ height: 70 }} src={iconMap.get(bindUser?.type)} />
+                    </div>
+                    <p className={styles.fonts}>账户:{bindUser?.providerName}</p>
+                    <p className={styles.fonts}>用户名:{bindUser?.result.others.name}</p>
                   </div>
-                  <div className={styles.infotitle}>三方账户信息</div>
-                </div>
-              }
-            >
-              <div className={styles.item}>
-                <div style={{ height: 100, marginTop: 10, marginBottom: 10 }}>
-                  <img style={{ height: 70 }} src={iconMap.get(bindUser?.type)} />
-                </div>
-                <p className={styles.fonts}>账户:{bindUser?.providerName}</p>
-                <p className={styles.fonts}>用户名:{bindUser?.result.others.name}</p>
-              </div>
-            </Card>
+                </Card>
+              </>
+            )}
           </div>
-          {}
           <div className={styles.btn}>
-            <Button
-              style={{ marginTop: 30, marginBottom: 30 }}
-              type="primary"
-              onClick={() => {
-                // window.close()
-                service.bind(code).then((res) => {
-                  if (res.status === 200) {
-                    message.success('绑定成功');
-                    localStorage.setItem('onBind', 'true');
-                    setTimeout(() => window.close(), 1000);
-                  } else {
-                    message.error('绑定失败');
+            {isLogin === 'no' ? (
+              <Button
+                style={{ marginTop: 10, marginBottom: 30, width: 250 }}
+                type="primary"
+                onClick={async () => {
+                  const data = await form.validateFields();
+                  if (data) {
+                    doLogin({
+                      ...data,
+                      bindCode: code,
+                    });
                   }
-                });
-              }}
-            >
-              立即绑定
-            </Button>
+                }}
+              >
+                登录并已绑定账户
+              </Button>
+            ) : (
+              <Button
+                style={{ marginTop: 30, marginBottom: 30 }}
+                type="primary"
+                onClick={() => {
+                  service.bind(code).then((res) => {
+                    if (res.status === 200) {
+                      message.success('绑定成功');
+                      localStorage.setItem('onBind', 'true');
+                      setTimeout(() => window.close(), 1000);
+                    } else {
+                      message.error('绑定失败');
+                    }
+                  });
+                }}
+              >
+                立即绑定
+              </Button>
+            )}
           </div>
         </div>
       </div>

+ 3 - 6
src/pages/account/Center/index.tsx

@@ -280,13 +280,10 @@ const Center = () => {
                       <Button
                         type="primary"
                         onClick={() => {
-                          window.open(
-                            `/${SystemConst.API_BASE}/sso/${item.provider}/login`,
-                            '',
-                            'width=700,height=500,left=500,top=300',
-                          );
-                          // window.open(`/#/account/center/bind`,'','width=700,height=500,left=500,top=300');
+                          window.open(`/${SystemConst.API_BASE}/sso/${item.provider}/login`);
+                          // window.open(`/#/account/center/bind`);
                           localStorage.setItem('onBind', 'false');
+                          localStorage.setItem('onLogin', 'yes');
                           window.onstorage = (e) => {
                             if (e.newValue) {
                               getBindInfo();

+ 2 - 2
src/pages/device/Instance/Detail/Modbus/index.tsx

@@ -54,7 +54,7 @@ const Modbus = () => {
     },
     {
       title: '值',
-      render: (record: any) => <>{propertyValue[record?.property] || '-'}</>,
+      render: (record: any) => <>{propertyValue[record?.metadataId] || '-'}</>,
     },
     {
       title: '状态',
@@ -201,7 +201,7 @@ const Modbus = () => {
         const { value } = payload;
         propertyValue[value.property] = value.formatValue;
         setPropertyValue({ ...propertyValue });
-        // console.log(propertyValue)
+        console.log(propertyValue);
       });
   }, [data]);
 

+ 1 - 1
src/pages/link/Channel/Modbus/Access/index.tsx

@@ -57,7 +57,7 @@ const Access = () => {
     },
     {
       title: '值',
-      render: (record: any) => <>{propertyValue[record?.property] || '-'}</>,
+      render: (record: any) => <>{propertyValue[record?.metadataId] || '-'}</>,
     },
     {
       title: '状态',

+ 11 - 1
src/pages/user/Login/index.tsx

@@ -19,7 +19,6 @@ const Login: React.FC = () => {
   const [captcha, setCaptcha] = useState<{ key?: string; base64?: string }>({});
 
   const { initialState, setInitialState } = useModel('@@initialState');
-
   const intl = useIntl();
 
   const fetchUserInfo = async () => {
@@ -188,6 +187,17 @@ const Login: React.FC = () => {
                       defaultMessage: '登录',
                     })}
                   </Submit>
+                  {/* <Button
+                      onClick={()=>{
+                        localStorage.setItem('onLogin', 'no');
+                        window.open(`/${SystemConst.API_BASE}/sso/dingd2rgqrqnbvgbvi9x/login`);
+                        window.onstorage = (e) => {
+                          if (e.newValue) {
+                            window.location.href = '/';
+                          }
+                        };
+                      }}
+                  >三方登录</Button> */}
                 </Form>
               </div>
             </div>