lanjianrong 4 vuotta sitten
vanhempi
commit
2269c69ffb
6 muutettua tiedostoa jossa 239 lisäystä ja 201 poistoa
  1. 10 10
      config/proxy.ts
  2. 0 1
      package.json
  3. 59 46
      src/app.tsx
  4. 44 43
      src/global.tsx
  5. 98 101
      src/pages/user/Login/index.tsx
  6. 28 0
      src/services/user.ts

+ 10 - 10
config/proxy.ts

@@ -7,24 +7,24 @@
  */
 export default {
   dev: {
-    '/api/': {
-      target: 'https://preview.pro.ant.design',
+    '/backstage/': {
+      target: 'http://cld2.com',
       changeOrigin: true,
-      pathRewrite: { '^': '' },
-    },
+      pathRewrite: { '^': '' }
+    }
   },
   test: {
     '/api/': {
       target: 'https://preview.pro.ant.design',
       changeOrigin: true,
-      pathRewrite: { '^': '' },
-    },
+      pathRewrite: { '^': '' }
+    }
   },
   pre: {
     '/api/': {
       target: 'your pre url',
       changeOrigin: true,
-      pathRewrite: { '^': '' },
-    },
-  },
-};
+      pathRewrite: { '^': '' }
+    }
+  }
+}

+ 0 - 1
package.json

@@ -86,7 +86,6 @@
     "@umijs/preset-ant-design-pro": "^1.2.0",
     "@umijs/preset-dumi": "^1.1.7",
     "@umijs/preset-react": "^1.7.4",
-    "@umijs/preset-ui": "^2.2.9",
     "@umijs/yorkie": "^2.0.3",
     "carlo": "^0.9.46",
     "cross-env": "^7.0.0",

+ 59 - 46
src/app.tsx

@@ -1,52 +1,52 @@
-import type { Settings as LayoutSettings } from '@ant-design/pro-layout';
-import { PageLoading } from '@ant-design/pro-layout';
-import { notification } from 'antd';
-import type { RequestConfig, RunTimeLayoutConfig } from 'umi';
-import { getIntl, getLocale, history, Link } from 'umi';
-import RightContent from '@/components/RightContent';
-import Footer from '@/components/Footer';
-import type { ResponseError } from 'umi-request';
-import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
-import { BookOutlined, LinkOutlined } from '@ant-design/icons';
+import type { Settings as LayoutSettings } from '@ant-design/pro-layout'
+import { PageLoading } from '@ant-design/pro-layout'
+import { notification } from 'antd'
+import type { RequestConfig, RunTimeLayoutConfig } from 'umi'
+import { getIntl, getLocale, history, Link } from 'umi'
+import RightContent from '@/components/RightContent'
+import Footer from '@/components/Footer'
+import type { ResponseError } from 'umi-request'
+import { currentUser as queryCurrentUser } from './services/ant-design-pro/api'
+import { BookOutlined, LinkOutlined } from '@ant-design/icons'
 
-const isDev = process.env.NODE_ENV === 'development';
-const loginPath = '/user/login';
+const isDev = process.env.NODE_ENV === 'development'
+const loginPath = '/user/login'
 
 /** 获取用户信息比较慢的时候会展示一个 loading */
 export const initialStateConfig = {
-  loading: <PageLoading />,
-};
+  loading: <PageLoading />
+}
 
 /**
  * @see  https://umijs.org/zh-CN/plugins/plugin-initial-state
  * */
 export async function getInitialState(): Promise<{
-  settings?: Partial<LayoutSettings>;
-  currentUser?: API.CurrentUser;
-  fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
+  settings?: Partial<LayoutSettings>
+  currentUser?: API.CurrentUser
+  fetchUserInfo?: () => Promise<API.CurrentUser | undefined>
 }> {
   const fetchUserInfo = async () => {
     try {
-      const currentUser = await queryCurrentUser();
-      return currentUser;
+      const currentUser = await queryCurrentUser()
+      return currentUser
     } catch (error) {
-      history.push(loginPath);
+      history.push(loginPath)
     }
-    return undefined;
-  };
+    return undefined
+  }
   // 如果是登录页面,不执行
   if (history.location.pathname !== loginPath) {
-    const currentUser = await fetchUserInfo();
+    const currentUser = await fetchUserInfo()
     return {
       fetchUserInfo,
       currentUser,
-      settings: {},
-    };
+      settings: {}
+    }
   }
   return {
     fetchUserInfo,
-    settings: {},
-  };
+    settings: {}
+  }
 }
 
 /**
@@ -73,29 +73,42 @@ export async function getInitialState(): Promise<{
  */
 export const request: RequestConfig = {
   errorHandler: (error: ResponseError) => {
-    const { messages } = getIntl(getLocale());
-    const { response } = error;
+    const { messages } = getIntl(getLocale())
+    const { response } = error
 
     if (response && response.status) {
-      const { status, statusText, url } = response;
-      const requestErrorMessage = messages['app.request.error'];
-      const errorMessage = `${requestErrorMessage} ${status}: ${url}`;
-      const errorDescription = messages[`app.request.${status}`] || statusText;
+      const { status, statusText, url } = response
+      const requestErrorMessage = messages['app.request.error']
+      const errorMessage = `${requestErrorMessage} ${status}: ${url}`
+      const errorDescription = messages[`app.request.${status}`] || statusText
       notification.error({
         message: errorMessage,
-        description: errorDescription,
-      });
+        description: errorDescription
+      })
     }
 
     if (!response) {
       notification.error({
         description: '您的网络发生异常,无法连接服务器',
-        message: '网络异常',
-      });
+        message: '网络异常'
+      })
     }
-    throw error;
+    throw error
   },
-};
+  prefix: '/backstage',
+  errorConfig: {
+    adaptor: resData => {
+      return {
+        ...resData,
+        success: resData.code === 0,
+        errorMessage: resData.msg
+      }
+    }
+  }
+  // requestInterceptors: [(url, options) => {
+  //   return { url, options: { ...options, prefix: '/api'}}
+  // }]
+}
 
 // ProLayout 支持的api https://procomponents.ant.design/components/layout
 export const layout: RunTimeLayoutConfig = ({ initialState }) => {
@@ -103,14 +116,14 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
     rightContentRender: () => <RightContent />,
     disableContentMargin: false,
     waterMarkProps: {
-      content: initialState?.currentUser?.name,
+      content: initialState?.currentUser?.name
     },
     footerRender: () => <Footer />,
     onPageChange: () => {
-      const { location } = history;
+      const { location } = history
       // 如果没有登录,重定向到 login
       if (!initialState?.currentUser && location.pathname !== loginPath) {
-        history.push(loginPath);
+        history.push(loginPath)
       }
     },
     links: isDev
@@ -122,12 +135,12 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
           <Link to="/~docs">
             <BookOutlined />
             <span>业务组件文档</span>
-          </Link>,
+          </Link>
         ]
       : [],
     menuHeaderRender: undefined,
     // 自定义 403 页面
     // unAccessible: <div>unAccessible</div>,
-    ...initialState?.settings,
-  };
-};
+    ...initialState?.settings
+  }
+}

+ 44 - 43
src/global.tsx

@@ -1,83 +1,84 @@
-import { Button, message, notification } from 'antd';
-import { useIntl } from 'umi';
-import defaultSettings from '../config/defaultSettings';
+import { Button, message, notification } from 'antd'
+import { useIntl } from 'umi'
+import defaultSettings from '../config/defaultSettings'
+
 import 'windi.css'
-const { pwa } = defaultSettings;
-const isHttps = document.location.protocol === 'https:';
+
+const { pwa } = defaultSettings
+const isHttps = document.location.protocol === 'https:'
 
 // if pwa is true
 if (pwa) {
   // Notify user if offline now
   window.addEventListener('sw.offline', () => {
-    message.warning(useIntl().formatMessage({ id: 'app.pwa.offline' }));
-  });
+    message.warning(useIntl().formatMessage({ id: 'app.pwa.offline' }))
+  })
 
   // Pop up a prompt on the page asking the user if they want to use the latest version
   window.addEventListener('sw.updated', (event: Event) => {
-    const e = event as CustomEvent;
+    const e = event as CustomEvent
     const reloadSW = async () => {
       // Check if there is sw whose state is waiting in ServiceWorkerRegistration
       // https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
-      const worker = e.detail && e.detail.waiting;
+      const worker = e.detail && e.detail.waiting
       if (!worker) {
-        return true;
+        return true
       }
       // Send skip-waiting event to waiting SW with MessageChannel
       await new Promise((resolve, reject) => {
-        const channel = new MessageChannel();
-        channel.port1.onmessage = (msgEvent) => {
+        const channel = new MessageChannel()
+        channel.port1.onmessage = msgEvent => {
           if (msgEvent.data.error) {
-            reject(msgEvent.data.error);
+            reject(msgEvent.data.error)
           } else {
-            resolve(msgEvent.data);
+            resolve(msgEvent.data)
           }
-        };
-        worker.postMessage({ type: 'skip-waiting' }, [channel.port2]);
-      });
+        }
+        worker.postMessage({ type: 'skip-waiting' }, [channel.port2])
+      })
       // Refresh current page to use the updated HTML and other assets after SW has skiped waiting
-      window.location.reload(true);
-      return true;
-    };
-    const key = `open${Date.now()}`;
+      window.location.reload(true)
+      return true
+    }
+    const key = `open${Date.now()}`
     const btn = (
       <Button
         type="primary"
         onClick={() => {
-          notification.close(key);
-          reloadSW();
-        }}
-      >
+          notification.close(key)
+          reloadSW()
+        }}>
         {useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.ok' })}
       </Button>
-    );
+    )
     notification.open({
       message: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated' }),
       description: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.hint' }),
       btn,
       key,
-      onClose: async () => null,
-    });
-  });
+      onClose: async () => null
+    })
+  })
 } else if ('serviceWorker' in navigator && isHttps) {
   // unregister service worker
-  const { serviceWorker } = navigator;
+  const { serviceWorker } = navigator
   if (serviceWorker.getRegistrations) {
-    serviceWorker.getRegistrations().then((sws) => {
-      sws.forEach((sw) => {
-        sw.unregister();
-      });
-    });
+    serviceWorker.getRegistrations().then(sws => {
+      sws.forEach(sw => {
+        sw.unregister()
+      })
+    })
   }
-  serviceWorker.getRegistration().then((sw) => {
-    if (sw) sw.unregister();
-  });
+  serviceWorker.getRegistration().then(sw => {
+    if (sw) sw.unregister()
+  })
 
   // remove all caches
   if (window.caches && window.caches.keys()) {
-    caches.keys().then((keys) => {
-      keys.forEach((key) => {
-        caches.delete(key);
-      });
-    });
+    caches.keys().then(keys => {
+      keys.forEach(key => {
+        caches.delete(key)
+      })
+    })
   }
 }

+ 98 - 101
src/pages/user/Login/index.tsx

@@ -1,90 +1,90 @@
 import {
-  AlipayCircleOutlined,
+  // AlipayCircleOutlined,
   LockOutlined,
-  MobileOutlined,
-  TaobaoCircleOutlined,
-  UserOutlined,
-  WeiboCircleOutlined,
-} from '@ant-design/icons';
-import { Alert, Space, message, Tabs } from 'antd';
-import React, { useState } from 'react';
-import ProForm, { ProFormCaptcha, ProFormCheckbox, ProFormText } from '@ant-design/pro-form';
-import { useIntl, Link, history, FormattedMessage, SelectLang, useModel } from 'umi';
-import Footer from '@/components/Footer';
-import { login } from '@/services/ant-design-pro/api';
-import { getFakeCaptcha } from '@/services/ant-design-pro/login';
+  // MobileOutlined,
+  // TaobaoCircleOutlined,
+  UserOutlined
+  // WeiboCircleOutlined
+} from '@ant-design/icons'
+import { Alert, message, Tabs } from 'antd'
+import React, { useState } from 'react'
+import ProForm, { ProFormCheckbox, ProFormText } from '@ant-design/pro-form'
+import { useIntl, Link, history, FormattedMessage, SelectLang, useModel } from 'umi'
+import Footer from '@/components/Footer'
+import { login } from '@/services/user'
+// import { getFakeCaptcha } from '@/services/ant-design-pro/login'
 
-import styles from './index.less';
+import styles from './index.less'
 
 const LoginMessage: React.FC<{
-  content: string;
+  content: string
 }> = ({ content }) => (
   <Alert
     style={{
-      marginBottom: 24,
+      marginBottom: 24
     }}
     message={content}
     type="error"
     showIcon
   />
-);
+)
 
 /** 此方法会跳转到 redirect 参数所在的位置 */
 const goto = () => {
-  if (!history) return;
+  if (!history) return
   setTimeout(() => {
-    const { query } = history.location;
-    const { redirect } = query as { redirect: string };
-    history.push(redirect || '/');
-  }, 10);
-};
+    const { query } = history.location
+    const { redirect } = query as { redirect: string }
+    history.push(redirect || '/')
+  }, 10)
+}
 
 const Login: React.FC = () => {
-  const [submitting, setSubmitting] = useState(false);
-  const [userLoginState, setUserLoginState] = useState<API.LoginResult>({});
-  const [type, setType] = useState<string>('account');
-  const { initialState, setInitialState } = useModel('@@initialState');
+  const [submitting, setSubmitting] = useState(false)
+  const [userLoginState, setUserLoginState] = useState<API.LoginResult>({})
+  const [type, setType] = useState<string>('account')
+  const { initialState, setInitialState } = useModel('@@initialState')
 
-  const intl = useIntl();
+  const intl = useIntl()
 
   const fetchUserInfo = async () => {
-    const userInfo = await initialState?.fetchUserInfo?.();
+    const userInfo = await initialState?.fetchUserInfo?.()
     if (userInfo) {
       setInitialState({
         ...initialState,
-        currentUser: userInfo,
-      });
+        currentUser: userInfo
+      })
     }
-  };
+  }
 
   const handleSubmit = async (values: API.LoginParams) => {
-    setSubmitting(true);
+    setSubmitting(true)
     try {
       // 登录
-      const msg = await login({ ...values, type });
+      const msg = await login({ ...values, type })
+
       if (msg.status === 'ok') {
         const defaultloginSuccessMessage = intl.formatMessage({
           id: 'pages.login.success',
-          defaultMessage: '登录成功',
-        });
-        message.success(defaultloginSuccessMessage);
-        await fetchUserInfo();
-        goto();
-        return;
+          defaultMessage: '登录成功'
+        })
+        message.success(defaultloginSuccessMessage)
+        await fetchUserInfo()
+        goto()
+        return
       }
       // 如果失败去设置用户错误信息
-      setUserLoginState(msg);
+      setUserLoginState(msg)
     } catch (error) {
-      const defaultloginFailureMessage = intl.formatMessage({
-        id: 'pages.login.failure',
-        defaultMessage: '登录失败,请重试!',
-      });
-
-      message.error(defaultloginFailureMessage);
+      // const defaultloginFailureMessage = intl.formatMessage({
+      //   id: 'pages.login.failure',
+      //   defaultMessage: '登录失败,请重试!'
+      // })
+      // message.error(defaultloginFailureMessage)
     }
-    setSubmitting(false);
-  };
-  const { status, type: loginType } = userLoginState;
+    setSubmitting(false)
+  }
+  const { status, type: loginType } = userLoginState
 
   return (
     <div className={styles.container}>
@@ -92,7 +92,7 @@ const Login: React.FC = () => {
       <div className={styles.content}>
         <div className={styles.top}>
           <div className={styles.header}>
-            <Link to="/">
+            <Link to="/" className="flex justify-center">
               <img alt="logo" className={styles.logo} src="/logo.svg" />
               <span className={styles.title}>CLD.V2</span>
             </Link>
@@ -105,34 +105,33 @@ const Login: React.FC = () => {
         <div className={styles.main}>
           <ProForm
             initialValues={{
-              autoLogin: true,
+              autoLogin: true
             }}
             submitter={{
               searchConfig: {
                 submitText: intl.formatMessage({
                   id: 'pages.login.submit',
-                  defaultMessage: '登录',
-                }),
+                  defaultMessage: '登录'
+                })
               },
               render: (_, dom) => dom.pop(),
               submitButtonProps: {
                 loading: submitting,
                 size: 'large',
                 style: {
-                  width: '100%',
-                },
-              },
-            }}
-            onFinish={async (values) => {
-              handleSubmit(values as API.LoginParams);
+                  width: '100%'
+                }
+              }
             }}
-          >
+            onFinish={async values => {
+              handleSubmit(values as API.LoginParams)
+            }}>
             <Tabs activeKey={type} onChange={setType}>
               <Tabs.TabPane
                 key="account"
                 tab={intl.formatMessage({
                   id: 'pages.login.accountLogin.tab',
-                  defaultMessage: '账户密码登录',
+                  defaultMessage: '账户密码登录'
                 })}
               />
               {/* <Tabs.TabPane
@@ -148,7 +147,7 @@ const Login: React.FC = () => {
               <LoginMessage
                 content={intl.formatMessage({
                   id: 'pages.login.accountLogin.errorMessage',
-                  defaultMessage: '账户或密码错误(admin/ant.design)',
+                  defaultMessage: '账户或密码错误(admin/ant.design)'
                 })}
               />
             )}
@@ -158,11 +157,11 @@ const Login: React.FC = () => {
                   name="username"
                   fieldProps={{
                     size: 'large',
-                    prefix: <UserOutlined className={styles.prefixIcon} />,
+                    prefix: <UserOutlined className={styles.prefixIcon} />
                   }}
                   placeholder={intl.formatMessage({
                     id: 'pages.login.username.placeholder',
-                    defaultMessage: '用户名: admin or user',
+                    defaultMessage: '用户名: admin or user'
                   })}
                   rules={[
                     {
@@ -172,19 +171,19 @@ const Login: React.FC = () => {
                           id="pages.login.username.required"
                           defaultMessage="请输入用户名!"
                         />
-                      ),
-                    },
+                      )
+                    }
                   ]}
                 />
                 <ProFormText.Password
                   name="password"
                   fieldProps={{
                     size: 'large',
-                    prefix: <LockOutlined className={styles.prefixIcon} />,
+                    prefix: <LockOutlined className={styles.prefixIcon} />
                   }}
                   placeholder={intl.formatMessage({
                     id: 'pages.login.password.placeholder',
-                    defaultMessage: '密码: ant.design',
+                    defaultMessage: '密码: ant.design'
                   })}
                   rules={[
                     {
@@ -194,25 +193,25 @@ const Login: React.FC = () => {
                           id="pages.login.password.required"
                           defaultMessage="请输入密码!"
                         />
-                      ),
-                    },
+                      )
+                    }
                   ]}
                 />
               </>
             )}
-
+            {/*
             {status === 'error' && loginType === 'mobile' && <LoginMessage content="验证码错误" />}
             {type === 'mobile' && (
               <>
                 <ProFormText
                   fieldProps={{
                     size: 'large',
-                    prefix: <MobileOutlined className={styles.prefixIcon} />,
+                    prefix: <MobileOutlined className={styles.prefixIcon} />
                   }}
                   name="mobile"
                   placeholder={intl.formatMessage({
                     id: 'pages.login.phoneNumber.placeholder',
-                    defaultMessage: '手机号',
+                    defaultMessage: '手机号'
                   })}
                   rules={[
                     {
@@ -222,7 +221,7 @@ const Login: React.FC = () => {
                           id="pages.login.phoneNumber.required"
                           defaultMessage="请输入手机号!"
                         />
-                      ),
+                      )
                     },
                     {
                       pattern: /^1\d{10}$/,
@@ -231,33 +230,33 @@ const Login: React.FC = () => {
                           id="pages.login.phoneNumber.invalid"
                           defaultMessage="手机号格式错误!"
                         />
-                      ),
-                    },
+                      )
+                    }
                   ]}
                 />
                 <ProFormCaptcha
                   fieldProps={{
                     size: 'large',
-                    prefix: <LockOutlined className={styles.prefixIcon} />,
+                    prefix: <LockOutlined className={styles.prefixIcon} />
                   }}
                   captchaProps={{
-                    size: 'large',
+                    size: 'large'
                   }}
                   placeholder={intl.formatMessage({
                     id: 'pages.login.captcha.placeholder',
-                    defaultMessage: '请输入验证码',
+                    defaultMessage: '请输入验证码'
                   })}
                   captchaTextRender={(timing, count) => {
                     if (timing) {
                       return `${count} ${intl.formatMessage({
                         id: 'pages.getCaptchaSecondText',
-                        defaultMessage: '获取验证码',
-                      })}`;
+                        defaultMessage: '获取验证码'
+                      })}`
                     }
                     return intl.formatMessage({
                       id: 'pages.login.phoneLogin.getVerificationCode',
-                      defaultMessage: '获取验证码',
-                    });
+                      defaultMessage: '获取验证码'
+                    })
                   }}
                   name="captcha"
                   rules={[
@@ -268,34 +267,32 @@ const Login: React.FC = () => {
                           id="pages.login.captcha.required"
                           defaultMessage="请输入验证码!"
                         />
-                      ),
-                    },
+                      )
+                    }
                   ]}
-                  onGetCaptcha={async (phone) => {
+                  onGetCaptcha={async phone => {
                     const result = await getFakeCaptcha({
-                      phone,
-                    });
+                      phone
+                    })
                     if (result === false) {
-                      return;
+                      return
                     }
-                    message.success('获取验证码成功!验证码为:1234');
+                    message.success('获取验证码成功!验证码为:1234')
                   }}
                 />
               </>
-            )}
+            )} */}
             <div
               style={{
-                marginBottom: 24,
-              }}
-            >
+                marginBottom: 24
+              }}>
               <ProFormCheckbox noStyle name="autoLogin">
                 <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
               </ProFormCheckbox>
               <a
                 style={{
-                  float: 'right',
-                }}
-              >
+                  float: 'right'
+                }}>
                 <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
               </a>
             </div>
@@ -310,7 +307,7 @@ const Login: React.FC = () => {
       </div>
       <Footer />
     </div>
-  );
-};
+  )
+}
 
-export default Login;
+export default Login

+ 28 - 0
src/services/user.ts

@@ -0,0 +1,28 @@
+// @ts-ignore
+/* eslint-disable */
+import { request } from 'umi'
+
+/** 获取当前的用户 GET /api/currentUser */
+export async function currentUser(options?: { [key: string]: any }) {
+  return request<API.CurrentUser>('/api/currentUser', {
+    method: 'GET',
+    ...(options || {})
+  })
+}
+
+/** 退出登录接口 POST /api/login/outLogin */
+export async function outLogin(options?: { [key: string]: any }) {
+  return request<Record<string, any>>('/outLogin', {
+    method: 'POST',
+    ...(options || {})
+  })
+}
+
+/** 登录接口 POST /api/login/account */
+export async function login(body: API.LoginParams, options?: { [key: string]: any }) {
+  return request<API.LoginResult>('/login', {
+    method: 'POST',
+    data: body,
+    ...(options || {})
+  })
+}