浏览代码

fix: 恢复User文件

fix: 111
outaozhen 3 年之前
父节点
当前提交
9d18b98c80
共有 3 个文件被更改,包括 330 次插入1 次删除
  1. 1 1
      config/routes.ts
  2. 124 0
      src/pages/User/Login/index.less
  3. 205 0
      src/pages/User/Login/index.tsx

+ 1 - 1
config/routes.ts

@@ -12,7 +12,7 @@ const routes: Route[] = [
           {
             name: 'login',
             path: '/user/login',
-            component: './user/Login'
+            component: './User/Login'
           }
         ]
       },

+ 124 - 0
src/pages/User/Login/index.less

@@ -0,0 +1,124 @@
+@import '~antd/es/style/themes/default.less';
+
+.container {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  overflow: auto;
+  background: @layout-body-background;
+}
+
+.lang {
+  width: 100%;
+  height: 30px;
+  line-height: 44px;
+  text-align: right;
+  :global(.ant-dropdown-trigger) {
+    margin-right: 24px;
+  }
+}
+
+.content {
+  // flex: 1;
+  margin: 0 auto;
+  // padding: 32px 0;
+}
+
+@media (min-width: @screen-md-min) {
+  .container {
+    background: url('https://d4.smartcost.com.cn/iamge_login_bg.png') no-repeat center 0;
+    // background-repeat: no-repeat;
+    // background-position: center 110px;
+    // background-position: center 0;
+    background-size: 100% 100%;
+  }
+  .smallBox {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    width: 400px;
+    margin-top: -200px;
+    margin-left: -200px;
+    // margin: 0 auto;
+    background: rgb(255 255 255 / 89%);
+  }
+
+  .content {
+    padding: 0 0 35px;
+  }
+}
+
+.top {
+  text-align: center;
+}
+
+.header {
+  height: 44px;
+  line-height: 44px;
+  a {
+    text-decoration: none;
+  }
+}
+
+.logo {
+  height: 44px;
+  margin-right: 16px;
+  vertical-align: top;
+}
+
+.title {
+  position: relative;
+  top: 2px;
+  color: @heading-color;
+  font-weight: 600;
+  font-size: 18px;
+  font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif;
+}
+
+.desc {
+  margin-top: 12px;
+  margin-bottom: 40px;
+  color: @text-color-secondary;
+  font-size: @font-size-base;
+}
+
+.main {
+  width: 328px;
+  margin: 0 auto;
+  @media screen and (max-width: @screen-sm) {
+    width: 95%;
+    max-width: 328px;
+  }
+
+  :global(.@{ant-prefix}-tabs-nav-list) {
+    margin: auto;
+    font-size: 16px;
+  }
+
+  .icon {
+    margin-left: 16px;
+    color: rgb(0 0 0/ 20%);
+    font-size: 24px;
+    vertical-align: middle;
+    cursor: pointer;
+    transition: color 0.3s;
+
+    &:hover {
+      color: @primary-color;
+    }
+  }
+
+  .other {
+    margin-top: 24px;
+    line-height: 22px;
+    text-align: left;
+    .register {
+      float: right;
+    }
+  }
+
+  .prefixIcon {
+    color: @primary-color;
+    font-size: @font-size-base;
+  }
+}

+ 205 - 0
src/pages/User/Login/index.tsx

@@ -0,0 +1,205 @@
+import { LockOutlined, UserOutlined } from '@ant-design/icons'
+import { Alert, message } from 'antd'
+import React, { useState, useTransition } from 'react'
+import ProForm, { ProFormCheckbox, ProFormText } from '@ant-design/pro-form'
+import {
+  useIntl,
+  history,
+  FormattedMessage,
+  SelectLang,
+  useModel,
+  useRequest,
+  createSearchParams
+} from '@umijs/max'
+import { login } from '@/services/api/login'
+import { queryCurrentUser } from '@/services/api/login'
+import consts from '@/utils/consts'
+import styles from './index.less'
+
+const LoginMessage: React.FC<{
+  content: string
+}> = ({ content }) => (
+  <Alert
+    style={{
+      marginBottom: 24
+    }}
+    message={content}
+    type="error"
+    showIcon
+  />
+)
+
+const Login: React.FC = () => {
+  const [userLoginState, setUserLoginState] = useState<API.LoginResult>({})
+  const [type] = useState<string>('account')
+  const [, startTransition] = useTransition()
+  const { initialState, setInitialState } = useModel('@@initialState')
+  const intl = useIntl()
+
+  /** 此方法会跳转到 redirect 参数所在的位置 */
+  const goto = userInfo => {
+    // console.log(userInfo)
+
+    if (!history || !userInfo) return
+    const searchParams = createSearchParams(window.location.search)
+    const redirect = searchParams.get('redirect')
+    history.replace(redirect || '/')
+  }
+
+  const { run: tryGetUserInfo, loading } = useRequest(queryCurrentUser, {
+    manual: true,
+    onSuccess: async result => {
+      setInitialState({
+        ...initialState,
+        currentUser: result.currentUser
+      })
+      startTransition(() => {
+        goto(result.currentUser)
+      })
+    }
+  })
+
+  const { run: tryLogin } = useRequest((values: API.LoginParams) => login(values), {
+    manual: true,
+    onSuccess: async result => {
+      window.localStorage.setItem('TOKEN_ID', result)
+      message.success('登录成功')
+      await tryGetUserInfo()
+    },
+    onError: () => {
+      setUserLoginState({ ...userLoginState, code: -1 })
+    }
+  })
+
+  const handleSubmit = async (values: API.LoginParams) => {
+    try {
+      await tryLogin(values)
+    } catch (error) {
+      message.error('登录失败,请重试')
+    }
+  }
+  const { code } = userLoginState
+
+  return (
+    <div className={styles.container}>
+      <div className={[styles.smallBox, 'border rounded-xl'].join(' ')}>
+        <div className={styles.lang} data-lang>
+          {SelectLang && <SelectLang />}
+        </div>
+        <div className={styles.content}>
+          <div className={styles.top}>
+            <div className={styles.header}>
+              <div className="flex justify-center">
+                <img alt="logo" className={styles.logo} src="/logo.png" />
+                <span className={styles.title}>珠海市政府投资项目经济技术指标库</span>
+              </div>
+            </div>
+            <div className={styles.desc}>{intl.formatMessage({ id: 'pages.layouts.userLayout.title' })}</div>
+          </div>
+          <div className={styles.main}>
+            <ProForm
+              initialValues={{
+                autoLogin: true
+              }}
+              isKeyPressSubmit
+              submitter={{
+                searchConfig: {
+                  submitText: intl.formatMessage({
+                    id: 'pages.login.submit',
+                    defaultMessage: '登录'
+                  })
+                },
+                render: (_, dom) => dom.pop(),
+                submitButtonProps: {
+                  loading,
+                  size: 'large',
+                  style: {
+                    width: '100%'
+                  }
+                }
+              }}
+              onFinish={values => handleSubmit(values as API.LoginParams)}>
+              {/* <Tabs activeKey={type} onChange={setType}>
+                <Tabs.TabPane
+                  key="account"
+                  tab={intl.formatMessage({
+                    id: 'pages.login.accountLogin.tab',
+                    defaultMessage: '账户密码登录'
+                  })}
+                />
+              </Tabs> */}
+
+              {code === consts.RET_CODE.ERROR && <LoginMessage content={'账户或密码错误'} />}
+              {type === 'account' && (
+                <>
+                  <ProFormText
+                    name="account"
+                    fieldProps={{
+                      size: 'large',
+                      prefix: <UserOutlined className={styles.prefixIcon} />
+                    }}
+                    placeholder={intl.formatMessage({
+                      id: 'pages.login.username.placeholder',
+                      defaultMessage: '请输入用户名'
+                    })}
+                    rules={[
+                      {
+                        required: true,
+                        message: (
+                          <FormattedMessage
+                            id="pages.login.username.required"
+                            defaultMessage="请输入用户名!"
+                          />
+                        )
+                      }
+                    ]}
+                  />
+                  <ProFormText.Password
+                    name="password"
+                    fieldProps={{
+                      size: 'large',
+                      prefix: <LockOutlined className={styles.prefixIcon} />
+                    }}
+                    placeholder={intl.formatMessage({
+                      id: 'pages.login.password.placeholder',
+                      defaultMessage: '请输入密码!'
+                    })}
+                    rules={[
+                      {
+                        required: true,
+                        message: (
+                          <FormattedMessage
+                            id="pages.login.password.required"
+                            defaultMessage="请输入密码!"
+                          />
+                        )
+                      }
+                    ]}
+                  />
+                </>
+              )}
+
+              {/* {status === 'error' && loginType === 'mobile' && <LoginMessage content="验证码错误" />} */}
+              <div
+                style={{
+                  marginBottom: 24
+                }}>
+                <ProFormCheckbox noStyle name="autoLogin">
+                  <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
+                </ProFormCheckbox>
+                <a
+                  style={{
+                    float: 'right'
+                  }}>
+                  <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
+                </a>
+              </div>
+            </ProForm>
+          </div>
+        </div>
+      </div>
+    </div>
+  )
+}
+
+export default Login