tianyunperfect 5 lat temu
rodzic
commit
2168e59a84

+ 3 - 2
package.json

@@ -57,15 +57,16 @@
     "antd": "^4.0.0",
     "classnames": "^2.2.6",
     "immer": "^6.0.3",
-    "lodash": "^4.17.15",
+    "lodash": "^4.17.19",
     "moment": "^2.24.0",
-    "nice-hooks": "^1.2.0",
+    "nice-hooks": "^1.2.1",
     "omit.js": "^1.0.2",
     "path-to-regexp": "2.4.0",
     "qs": "^6.9.0",
     "react": "^16.8.6",
     "react-dom": "^16.8.6",
     "react-helmet-async": "^1.0.4",
+    "react-quill": "^1.3.5",
     "umi": "^3.0.14",
     "umi-request": "^1.0.8",
     "use-merge-value": "^1.0.1"

+ 1 - 1
src/components/GlobalHeader/AvatarDropdown.tsx

@@ -65,7 +65,7 @@ class AvatarDropdown extends React.Component<GlobalHeaderRightProps> {
     return currentUser && currentUser.userName ? (
       <HeaderDropdown overlay={menuHeaderDropdown}>
         <span className={`${styles.action} ${styles.account}`}>
-          <Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
+          <Avatar size="small" className={styles.avatar} src="https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png" alt="avatar" />
           <span className={styles.name}>{currentUser.userName}</span>
         </span>
       </HeaderDropdown>

+ 3 - 6
src/components/GlobalHeader/RightContent.tsx

@@ -1,11 +1,8 @@
-import { Tooltip, Tag } from 'antd';
-import { QuestionCircleOutlined } from '@ant-design/icons';
+import {Tag} from 'antd';
 import React from 'react';
-import { connect, ConnectProps } from 'umi';
-import { ConnectState } from '@/models/connect';
+import {connect, ConnectProps} from 'umi';
+import {ConnectState} from '@/models/connect';
 import Avatar from './AvatarDropdown';
-import HeaderSearch from '../HeaderSearch';
-import SelectLang from '../SelectLang';
 import styles from './index.less';
 
 export type SiderTheme = 'light' | 'dark';

+ 6 - 7
src/layouts/SecurityLayout.tsx

@@ -1,10 +1,9 @@
 import React from 'react';
-import { PageLoading } from '@ant-design/pro-layout';
-import { Redirect, connect, ConnectProps } from 'umi';
-import { stringify } from 'querystring';
-import { ConnectState } from '@/models/connect';
-import { CurrentUser } from '@/models/user';
-import {isTokenExist} from "@/utils/tokenUtil";
+import {PageLoading} from '@ant-design/pro-layout';
+import {connect, ConnectProps, Redirect} from 'umi';
+import {stringify} from 'querystring';
+import {ConnectState} from '@/models/connect';
+import {CurrentUser} from '@/models/user';
 
 interface SecurityLayoutProps extends ConnectProps {
   loading?: boolean;
@@ -37,7 +36,7 @@ class SecurityLayout extends React.Component<SecurityLayoutProps, SecurityLayout
     const { children, loading, currentUser } = this.props;
     // You can replace it to your authentication rule (such as check token exists)
     // 你可以把它替换成你自己的登录认证规则(比如判断 token 是否存在)
-    const isLogin = isTokenExist();
+    const isLogin = currentUser != null && currentUser.id != null;
     const queryString = stringify({
       redirect: window.location.href,
     });

+ 16 - 12
src/models/login.ts

@@ -1,14 +1,14 @@
-import { stringify } from 'querystring';
-import { history, Reducer, Effect } from 'umi';
+import {stringify} from 'querystring';
+import {history, Reducer, Effect} from 'umi';
 
-import { fakeAccountLogin } from '@/services/login';
-import { setAuthority } from '@/utils/authority';
-import { getPageQuery } from '@/utils/utils';
+import {fakeAccountLogin} from '@/services/login';
+import {setAuthority} from '@/utils/authority';
+import {getPageQuery} from '@/utils/utils';
 
 export interface StateType {
   status?: 'SUCCESS' | 'error';
   type?: string;
-  currentAuthority?: 'user' | 'guest' | 'admin';
+  currentAuthority?: '2' | '1';  // 1是管理员 ,2 是普通成员
 }
 
 export interface LoginModelType {
@@ -31,17 +31,20 @@ const Model: LoginModelType = {
   },
 
   effects: {
-    *login({ payload }, { call, put }) {
+    * login({payload}, {call, put}) {
+      // 登录
       const response = yield call(fakeAccountLogin, payload);
+      // 保存登录信息,无论成功和失败
+      localStorage.setItem("success", response.message);
       yield put({
         type: 'changeLoginStatus',
         payload: response,
       });
-      // Login successfully
       if (response.success) {
+        // 是否需要跳转
         const urlParams = new URL(window.location.href);
         const params = getPageQuery();
-        let { redirect } = params as { redirect: string };
+        let {redirect} = params as { redirect: string };
         if (redirect) {
           const redirectUrlParams = new URL(redirect);
           if (redirectUrlParams.origin === urlParams.origin) {
@@ -60,7 +63,8 @@ const Model: LoginModelType = {
     },
 
     logout() {
-      const { redirect } = getPageQuery();
+      localStorage.removeItem("success");
+      const {redirect} = getPageQuery();
       // Note: There may be security issues, please note
       if (window.location.pathname !== '/user/login' && !redirect) {
         history.replace({
@@ -74,8 +78,8 @@ const Model: LoginModelType = {
   },
 
   reducers: {
-    changeLoginStatus(state, { payload }) {
-      setAuthority(payload.currentAuthority);
+    changeLoginStatus(state, {payload}) {
+      setAuthority(payload.data.roleId);
       return {
         ...state,
         status: payload.message,

+ 1 - 0
src/models/user.ts

@@ -3,6 +3,7 @@ import {Effect, Reducer} from 'umi';
 import {queryCurrent, query as queryUsers} from '@/services/user';
 
 export interface CurrentUser {
+  unreadCount?: number;
   avatar?: string;
   userName?: string;
   id?: number

+ 17 - 5
src/pages/Memory/data.d.ts

@@ -10,23 +10,26 @@ export interface TableListItem {
   onlyWord: string;
   modelType: number;
 
-  maxBatchSize:number,
-  maxSeqLength:number,
-  numAttentionHeads:number,
-  numHiddenLayers:number,
-  doLowerCase:number,
+  maxBatchSize: number,
+  maxSeqLength: number,
+  numAttentionHeads: number,
+  numHiddenLayers: number,
+  doLowerCase: number,
 }
+
 // 分页参数
 export interface TableListPagination {
   total: number;
   pageSize: number;
   current: number;
 }
+
 // 返回的分页数据
 export interface TableListData {
   list: TableListItem[];
   pagination: Partial<TableListPagination>;
 }
+
 // 查询参数
 export interface TableListParams {
   sorter?: string;
@@ -37,3 +40,12 @@ export interface TableListParams {
   pageSize?: number;
   currentPage?: number;
 }
+
+export interface Memory {
+  id?: number | null;
+  userId?: number | null;
+  front: string;
+  back: string;
+  tag: string;
+
+}

+ 4 - 0
src/pages/Memory/index.less

@@ -1,3 +1,7 @@
 .upload{
   display: inline;
 }
+
+.btn-right{
+  margin-right: 5px;
+}

+ 201 - 339
src/pages/Memory/index.tsx

@@ -1,364 +1,226 @@
-import {PlusOutlined} from '@ant-design/icons';
-import {Button, Divider, message, Modal, Radio} from 'antd';
-import React, {useRef, useState} from 'react';
+import {Button, message} from 'antd';
+import React, {useEffect} from 'react';
 import {PageHeaderWrapper} from '@ant-design/pro-layout';
-import ProTable, {ActionType, ProColumns} from '@ant-design/pro-table';
-import {SorterResult} from 'antd/es/table/interface';
-import QueryForm from '@/pages/Memory/components/QueryForm';
-import {TableListItem} from './data.d';
+import {useSingleState} from "nice-hooks";
+import ReactQuill from "react-quill";
+import 'react-quill/dist/quill.snow.css';
+import {Memory} from './data.d';
 import service from './service';
 
-/**
- * 添加节点
- * @param fields
- */
-const handleAdd = async (fields: TableListItem) => {
-  const hide = message.loading('正在添加');
-  try {
-    const res = await service.addModel({...fields});
-    hide();
-    if (res.success) {
-      message.success('添加成功');
-      return true;
+enum Step {
+  MAIN = 0,
+  MEMORY = 1,
+  ADD = 2,
+}
+
+interface State {
+  remindCount: number;
+  step: Step;
+  showBack?: boolean
+}
+
+const TableList: React.FC<{}> = () => {
+
+
+  const [state, setState] = useSingleState<State>({
+    remindCount: 0,
+    step: Step.MAIN, // 0 主页,1 复习,2 添加
+    showBack: false
+  })
+
+  const [memory, setMemory] = useSingleState<Memory>({
+    id: null,
+    userId: null,
+    front: "",
+    back: "",
+    tag: ''
+  })
+
+  /**
+   * 查询用户待提醒数量
+   * @param fields
+   */
+  const countRemind = async () => {
+    const hide = message.loading('正在查询');
+    try {
+      const res = await service.countRemind({});
+      hide();
+      if (res.success) {
+        setState({remindCount: parseInt(res.data, 10)}, () => {
+          if (state.remindCount === 0) {
+            message.info('复习完毕!');
+          }
+        })
+        return true;
+      }
+
+      return false;
+    } catch (error) {
+      hide();
+      message.error('查询异常!');
+      return false;
     }
-    message.error('添加失败请重试!');
-    return false;
+  };
+  useEffect(() => {
+    countRemind();
+  }, []);
 
-  } catch (error) {
-    hide();
-    message.error('添加失败请重试!');
-    return false;
+  useEffect(() => {
+    // console.log(state)
+    // console.log(memory)
+  })
+  /**
+   * 进入统计页面
+   */
+  const changStepMain = () => {
+    setState({step: Step.MAIN})
+    countRemind();
   }
-};
-
-/**
- * 更新节点
- * @param fields
- */
-const handleUpdate = async (fields: TableListItem) => {
-  const hide = message.loading('正在配置');
-  try {
-    const res = await service.updateModel(fields);
-    hide();
+  /**
+   * 进入复习页面
+   */
+  const changStepMemory = async () => {
+    if (state.remindCount <= 0) {
+      message.info('已经复习完了哟!');
+      return;
+    }
+    setState({step: Step.MEMORY});
+    const res = await service.findNext({});
     if (res.success) {
-      message.success('配置成功');
-      return true;
+      setMemory({...memory, ...res.data});
+    }
+  }
+  const memorySuccess = async (factorInt: number) => {
+    const res = await service.memorySuccess({id: memory.id, factor: factorInt});
+    if (res.success) {
+      setMemory({...memory, ...res.data});
+    } else {
+      message.info('恭喜!复习完毕!');
+      setState({step: Step.MAIN});
     }
-    message.error('配置失败请重试!');
-    return false;
-  } catch (error) {
-    hide();
-    message.error('配置失败请重试!');
-    return false;
   }
-};
 
-/**
- *  删除节点
- * @param fields
- */
-const handleRemove = async (fields: TableListItem) => {
-  const hide = message.loading('正在删除');
-  try {
-    const res = await service.removeModel(fields);
-    hide();
-    message.success('删除成功,即将刷新');
-    return res.success;
-  } catch (error) {
-    hide();
-    message.error('删除失败,请重试');
-    return false;
+  const changStepAdd = () => {
+    setState({step: Step.ADD})
   }
-};
 
-const TableList: React.FC<{}> = () => {
-  const [sorter, setSorter] = useState<string>('');
-  const [modelVisible, setModalVisible] = useState<boolean>(false);
-  const [formValues, setFormValues] = useState({});
-  const actionRef = useRef<ActionType>();
-  const [queryVisible, setQueryVisible] = useState<boolean>(false);
+  /**
+   * 清空memory
+   */
+  const clearMemory = () => {
+    setMemory({
+      id: null,
+      front: "",
+      back: ""
+    });
+  }
 
-  const columns: ProColumns<TableListItem>[] = [
-    {
-      title: '模型类型',
-      dataIndex: 'modelType',
-      hideInSearch: true,
-      width: 120,
-      rules: [
-        {
-          required: true,
-          message: '模型类型为必填项',
-        },
-      ],
-      renderFormItem: () => {
-        return (
-          <Radio.Group>
-            <Radio value={0}>albert</Radio>
-            <Radio value={1}>bilstm</Radio>
-          </Radio.Group>
-        );
-      },
-      valueEnum: {
-        0: {text: 'albert'},
-        1: {text: 'bilstm'},
-      },
-    },
-    {
-      title: '模型名称',
-      dataIndex: 'modelName',
-      width: 150,
-      copyable: true,
-      rules: [
-        {
-          required: true,
-          message: '模型名称为必填项',
-        },
-      ],
-    },
-    {
-      title: '模型文件',
-      dataIndex: 'modelFile',
-      hideInSearch: true,
-      width: 200,
-      copyable: true,
-      rules: [
-        {
-          required: true,
-          message: '模型文件为必填项',
-        },
-      ],
-    },
-    {
-      title: '向量文件',
-      dataIndex: 'vocabFile',
-      hideInSearch: true,
-      width: 200,
-      copyable: true,
-      rules: [
-        {
-          required: true,
-          message: '词向量文件为必填项',
-        },
-      ],
-    },
-    {
-      title: '标签文件',
-      dataIndex: 'labelFile',
-      hideInSearch: true,
-      width: 200,
-      copyable: true,
-      rules: [
-        {
-          required: true,
-          message: '标签文件为必填项',
-        },
-      ],
-    },
-    {
-      title: '必包含',
-      dataIndex: 'mustTag',
-      hideInSearch: true,
-      copyable: true,
-      formItemProps: {
-        placeholder: '逗号分隔'
-      },
-      hideInTable: true,
-    },
-    {
-      title: '必不包含',
-      dataIndex: 'mustNotTag',
-      hideInSearch: true,
-      copyable: true,
-      formItemProps: {
-        placeholder: '逗号分隔'
-      },
-      hideInTable: true,
-    },
+  return (
+    <PageHeaderWrapper title={false}>
+      {state.step === Step.MAIN ? (
+        <div>
+          <div>待复习: {state.remindCount}</div>
+          <p/>
+          <Button type="primary" size="large" onClick={changStepMemory}>复习</Button>
+          <p/>
+          <Button type="primary" size="large" onClick={changStepAdd}>添加</Button>
+        </div>
+      ) : null}
 
-    {
-      title: 'BatchSize',
-      dataIndex: 'maxBatchSize',
-      hideInSearch: true,
-      hideInTable: true,
-    },
-    {
-      title: 'SeqLength',
-      dataIndex: 'maxSeqLength',
-      hideInSearch: true,
-      hideInTable: true,
-    },
+      {state.step === Step.MEMORY ? (
+        <div>
+          问题
+          <hr/>
+          <div dangerouslySetInnerHTML={{__html: memory.front}}/>
+          <hr/>
+          {state.showBack ? (
+            <div>
+              <div dangerouslySetInnerHTML={{__html: memory.back}}/>
+              <hr/>
+              <Button type="primary" onClick={() => {
+                memorySuccess(0.5)
+              }}>生疏</Button>
+              <span> </span>
+              <Button type="primary" onClick={() => {
+                memorySuccess(2)
+              }}>一般</Button>
+              <span> </span>
+              <Button type="primary" onClick={() => {
+                memorySuccess(3)
+              }}>简单</Button>
+              <p/>
+              <div>
+                <Button type="primary" onClick={async () => {
+                  await service.restart(memory);
+                  changStepMemory();
+                }}>重新开始复习</Button>
+                <span> </span>
+                <Button type="primary" onClick={async () => {
+                  await service.noMemory(memory);
+                  changStepMemory();
+                }}>不在复习</Button>
+                <span> </span>
+                <Button type="primary" onClick={async () => {
+                  await service.delete(memory);
+                  changStepMemory();
+                }}>删除</Button>
+              </div>
+              <p/>
+              <div>
+                <Button type="primary" onClick={() => {
+                  changStepAdd();
+                }}>编辑</Button>
+              </div>
+            </div>
 
-    {
-      title: 'HiddenLayers',
-      dataIndex: 'numHiddenLayers',
-      hideInSearch: true,
-      hideInTable: true,
-    },
-    {
-      title: 'AttentionHeads',
-      dataIndex: 'numAttentionHeads',
-      hideInSearch: true,
-      hideInTable: true,
-    },
-    {
-      title: '纯文本',
-      dataIndex: 'onlyWord',
-      hideInSearch: true,
-      hideInTable: true,
-      renderFormItem: () => {
-        return (
-          <Radio.Group>
-            <Radio value="true">是</Radio>
-            <Radio value="false">否</Radio>
-          </Radio.Group>
-        );
-      },
-      valueEnum: {
-        true: {text: '是'},
-        false: {text: '否'},
-      },
-    },
-    {
-      title: '大小写',
-      dataIndex: 'doLowerCase',
-      hideInSearch: true,
-      hideInTable: true,
-      renderFormItem: () => {
-        return (
-          <Radio.Group>
-            <Radio value={0}>区分</Radio>
-            <Radio value={1}>不分区</Radio>
-          </Radio.Group>
-        );
-      },
-      valueEnum: {
-        0: {text: '区分'},
-        1: {text: '不分区'},
-      },
-    },
 
-    {
-      title: '操作',
-      width: 200,
-      dataIndex: 'option',
-      valueType: 'option',
-      render: (_, record,index,action) => (
-        <>
-          <a
-            onClick={() => {
-              setFormValues(record);
-              setModalVisible(true);
-              console.log(record);
-            }}
-          >
-            配置
-          </a>
-          <Divider type="vertical"/>
-          <a
-            onClick={async () => {
-              const success = await  handleRemove(record);
-              if (success) {
-                await action.reload();
-              }
-              console.log(record);
-            }}
-          >
-            删除
-          </a>
-          <Divider type="vertical"/>
-          <a
-            onClick={async () => {
-              setFormValues(record);
-              setQueryVisible(true);
-            }}
-          >
-            查询
-          </a>
-        </>
-      ),
-    },
-  ];
+          ) : (
+            <div>
+              <Button type="primary" onClick={() => {
+                setState({showBack: true})
+              }}>显示答案</Button>
+            </div>
+          )}
 
-  return (
-    <PageHeaderWrapper title={false}>
-      <ProTable<TableListItem>
-        headerTitle="查询表格"
-        actionRef={actionRef}
-        rowKey="id"
-        onChange={(_, _filter, _sorter) => {
-          const sorterResult = _sorter as SorterResult<TableListItem>;
-          if (sorterResult.field) {
-            setSorter(`${sorterResult.field}_${sorterResult.order}`);
-          }
-        }}
-        pagination={{
-          defaultPageSize: 10,
-        }}
-        params={{
-          sorter,
-        }}
-        /* eslint-disable */
-        toolBarRender={(action, {selectedRows}) => [
-          <Button
-            type="primary"
-            onClick={() => {
-              setModalVisible(true);
-              setFormValues({
-                maxBatchSize: 1,
-                maxSeqLength: 40,
-                numAttentionHeads: 12,
-                numHiddenLayers: 3,
-                doLowerCase: "1",
-                onlyWord: "true",
-              });
-            }}
-          >
-            <PlusOutlined/> 新建
-          </Button>,
-        ]}
-        request={(params) => service.queryModel(params)}
-        columns={columns}
-        rowSelection={{}}
-      />
-      <Modal
-        destroyOnClose
-        title={'id' in formValues ? '编辑' : '新建'}
-        visible={modelVisible}
-        onCancel={() => setModalVisible(false)}
-        footer={null}
-      >
-        <ProTable<TableListItem, TableListItem>
-          onSubmit={async (value) => {
-            let success = false;
-            if ('id' in formValues) {
-              value['id'] = formValues['id']
-              success = await handleUpdate(value);
+
+        </div>
+      ) : null}
+
+      {state.step === Step.ADD ? (
+        <div>
+          <h4>正面</h4>
+          <ReactQuill theme="snow" value={memory.front} onChange={(value) => {
+            setMemory({front: value})
+          }}/>
+          <p/>
+          <h4>反面</h4>
+          <ReactQuill theme="snow" value={memory.back} onChange={(value) => {
+            setMemory({back: value})
+          }}/>
+          <p/>
+          <Button type="primary" onClick={async () => {
+            let res;
+            if (memory != null && memory.id != null) {
+              res = await service.update(memory);
             } else {
-              success = await handleAdd(value);
+              res = await service.insert(memory);
             }
-            if (success) {
-              setModalVisible(false);
-              if (actionRef.current) {
-                actionRef.current.reload();
-              }
+            if (res.success) {
+              message.info('操作成功');
+              clearMemory();
+            } else {
+              message.info(`操作失败: ${res.message}`);
             }
-          }}
-          rowKey="id"
-          type="form"
-          columns={columns}
-          rowSelection={{}}
-          form={{initialValues: formValues}}
-        />
-      </Modal>
-
-      {queryVisible ? (
-        <QueryForm
-          onCancel={() => setQueryVisible(false)}
-          modalVisible={queryVisible}
-          values={formValues}
-        />
+          }}>确定</Button>
+          <span> </span>
+          <Button type="primary" onClick={() => {
+            clearMemory();
+            changStepMain();
+          }}>关闭</Button>
+        </div>
       ) : null}
 
+
     </PageHeaderWrapper>
   );
 };

+ 9 - 0
src/pages/Memory/service.ts

@@ -6,4 +6,13 @@ export default {
   addModel: api.post('/modelInfo/insert'),
   updateModel: api.post('/modelInfo/updateByName'),
   similarityQuery: api.post('/modelInfo/similarityQuery'),
+
+  countRemind: api.get("/api/memory/countRemind"),
+  insert: api.post("/api/memory/insert"),
+  findNext: api.get("/api/memory/findNext"),
+  memorySuccess: api.get("/api/memory/success"),
+  update: api.post("/api/memory/update"),
+  restart: api.post("/api/memory/restart"),
+  noMemory: api.post("/api/memory/noMemory"),
+  delete: api.post("/api/memory/delete"),
 };

+ 1 - 1
src/pages/Setting/index.tsx

@@ -123,7 +123,7 @@ const TableList: React.FC<{}> = () => {
   ];
 
   return (
-    <PageHeaderWrapper>
+    <PageHeaderWrapper title={false}>
       <ProTable<TableListItem>
         headerTitle="查询表格"
         actionRef={actionRef}

+ 25 - 20
src/pages/user/login/index.tsx

@@ -1,15 +1,16 @@
-import { AlipayCircleOutlined, TaobaoCircleOutlined, WeiboCircleOutlined } from '@ant-design/icons';
-import { Alert, Checkbox } from 'antd';
-import React, { useState } from 'react';
-import { Link, connect, Dispatch } from 'umi';
-import { StateType } from '@/models/login';
-import { LoginParamsType } from '@/services/login';
-import { ConnectState } from '@/models/connect';
+import {AlipayCircleOutlined, TaobaoCircleOutlined, WeiboCircleOutlined} from '@ant-design/icons';
+import {Alert, Checkbox} from 'antd';
+import React, {useState} from 'react';
+import {Link, connect, Dispatch} from 'umi';
+import {StateType} from '@/models/login';
+import {LoginParamsType} from '@/services/login';
+import {ConnectState} from '@/models/connect';
 import LoginFrom from './components/Login';
 
 import styles from './style.less';
 
-const { Tab, UserName, Password, Mobile, Captcha, Submit } = LoginFrom;
+const {Tab, UserName, Password, Mobile, Captcha, Submit} = LoginFrom;
+
 interface LoginProps {
   dispatch: Dispatch;
   userLogin: StateType;
@@ -18,7 +19,7 @@ interface LoginProps {
 
 const LoginMessage: React.FC<{
   content: string;
-}> = ({ content }) => (
+}> = ({content}) => (
   <Alert
     style={{
       marginBottom: 24,
@@ -30,24 +31,28 @@ const LoginMessage: React.FC<{
 );
 
 const Login: React.FC<LoginProps> = (props) => {
-  const { userLogin = {}, submitting } = props;
-  const { status, type: loginType } = userLogin;
+  const {userLogin = {}, submitting} = props;
+  const {status, type: loginType} = userLogin;
   const [autoLogin, setAutoLogin] = useState(true);
   const [identityType, setType] = useState<string>('account');
 
   const handleSubmit = (values: LoginParamsType) => {
-    const { dispatch } = props;
+    const {dispatch} = props;
     dispatch({
       type: 'login/login',
-      payload: { ...values, identityType },
+      payload: {...values, identityType},
     });
   };
+  const getSuccess = () => {
+    const item = localStorage.getItem("success");
+    return item == null ? "SUCCESS" : item;
+  }
   return (
     <div className={styles.main}>
       <LoginFrom activeKey={identityType} onTabChange={setType} onSubmit={handleSubmit}>
         <Tab key="account" tab="账户密码登录">
-          {status !== 'SUCCESS' && !submitting && (
-            <LoginMessage content="账户或密码错误" />
+          {getSuccess() !== 'SUCCESS' && !submitting && (
+            <LoginMessage content="账户或密码错误"/>
           )}
 
           <UserName
@@ -73,7 +78,7 @@ const Login: React.FC<LoginProps> = (props) => {
         </Tab>
         <Tab key="mobile" tab="手机号登录">
           {status === 'error' && loginType === 'mobile' && !submitting && (
-            <LoginMessage content="验证码错误" />
+            <LoginMessage content="验证码错误"/>
           )}
           <Mobile
             name="mobile"
@@ -118,9 +123,9 @@ const Login: React.FC<LoginProps> = (props) => {
         <Submit loading={submitting}>登录</Submit>
         <div className={styles.other}>
           其他登录方式
-          <AlipayCircleOutlined className={styles.icon} />
-          <TaobaoCircleOutlined className={styles.icon} />
-          <WeiboCircleOutlined className={styles.icon} />
+          <AlipayCircleOutlined className={styles.icon}/>
+          <TaobaoCircleOutlined className={styles.icon}/>
+          <WeiboCircleOutlined className={styles.icon}/>
           <Link className={styles.register} to="/user/register">
             注册账户
           </Link>
@@ -130,7 +135,7 @@ const Login: React.FC<LoginProps> = (props) => {
   );
 };
 
-export default connect(({ login, loading }: ConnectState) => ({
+export default connect(({login, loading}: ConnectState) => ({
   userLogin: login,
   submitting: loading.effects['login/login'],
 }))(Login);

+ 27 - 5
src/utils/request.ts

@@ -52,16 +52,38 @@ const errorHandler = (error: { response: Response }): Response => {
 const request = extend({
   errorHandler, // 默认错误处理
   credentials: 'include', // 默认请求是否带上cookie
-  // 默认请求头
-  headers: {
-    authorization: getToken(), // 携带token
-  },
 });
 
 
+// request拦截器, 改变url 或 options.
+request.interceptors.request.use((url, options) => {
+
+  const token = getToken();
+  if (token) {
+    const headers = {
+      'authorization': token
+    };
+    return (
+      {
+        url,
+        options: {...options, headers},
+      }
+    );
+  } else {
+    return (
+      {
+        url,
+        options: {...options},
+      }
+    );
+  }
+
+})
+
+
 // response拦截器, 处理response
 request.interceptors.response.use((response, options) => {
-  let token = response.headers.get("authorization");
+  const token = response.headers.get("authorization");
   if (token) {
     setToken(token);
   }