李富豪 преди 11 месеца
родител
ревизия
345671d518
променени са 42 файла, в които са добавени 332 реда и са изтрити 804 реда
  1. 11 21
      src/apis/api.ts
  2. 42 6
      src/apis/config.ts
  3. 7 0
      src/apis/index.ts
  4. 0 20
      src/components/iconFont/index.tsx
  5. 4 20
      src/pages/dataExport/index.tsx
  6. 3 3
      src/pages/dataExport/store.ts
  7. 3 80
      src/pages/dataExport/style.less
  8. 1 1
      src/pages/dataExport/types.ts
  9. 0 44
      src/pages/knowledgeBase/info/index.tsx
  10. 0 83
      src/pages/knowledgeBase/info/style.less
  11. 0 44
      src/pages/knowledgeBase/list/index.tsx
  12. 0 83
      src/pages/knowledgeBase/list/style.less
  13. 28 0
      src/pages/knowledgeLib/info/index.tsx
  14. 3 3
      src/pages/knowledgeLib/info/store.ts
  15. 6 0
      src/pages/knowledgeLib/info/style.less
  16. 1 1
      src/pages/knowledgeLib/info/types.ts
  17. 28 0
      src/pages/knowledgeLib/list/index.tsx
  18. 3 3
      src/pages/knowledgeLib/list/store.ts
  19. 6 0
      src/pages/knowledgeLib/list/style.less
  20. 1 1
      src/pages/knowledgeLib/list/types.ts
  21. 7 4
      src/pages/layout/components/Breadcrumb.tsx
  22. 7 4
      src/pages/layout/components/Header.tsx
  23. 27 15
      src/pages/layout/components/Nav.tsx
  24. 1 1
      src/pages/layout/index.tsx
  25. 0 19
      src/pages/layout/types.ts
  26. 41 47
      src/pages/login/index.tsx
  27. 9 21
      src/pages/login/store.tsx
  28. 4 2
      src/pages/login/style.less
  29. 0 3
      src/pages/login/types.ts
  30. 28 0
      src/pages/questionAnswer/info/index.tsx
  31. 3 3
      src/pages/questionAnswer/info/store.ts
  32. 6 0
      src/pages/questionAnswer/info/style.less
  33. 1 1
      src/pages/questionAnswer/info/types.ts
  34. 28 0
      src/pages/questionAnswer/list/index.tsx
  35. 3 3
      src/pages/questionAnswer/list/store.ts
  36. 6 0
      src/pages/questionAnswer/list/style.less
  37. 1 1
      src/pages/questionAnswer/list/types.ts
  38. 0 44
      src/pages/questionAnswerApp/info/index.tsx
  39. 0 83
      src/pages/questionAnswerApp/info/style.less
  40. 0 44
      src/pages/questionAnswerApp/list/index.tsx
  41. 0 83
      src/pages/questionAnswerApp/list/style.less
  42. 13 13
      src/router.tsx

+ 11 - 21
src/apis/api.ts

@@ -1,18 +1,9 @@
 import axios, { AxiosResponse } from 'axios';
 import { message } from 'antd';
-import config from './config';
+import config, { getHeaders } from './config';
 import LocalStorage from '@/LocalStorage';
 import router from '@/router';
 
-export const getHeaders = () => {
-    const headers: { 'token'?: string } = {};
-    const token = LocalStorage.getToken();
-    if (token) {
-        headers['token'] = token;
-    }
-    return headers;
-};
-
 // 创建axios实例
 const axiosInstance = axios.create({
     baseURL: config.baseURL,
@@ -33,16 +24,13 @@ axiosInstance.interceptors.request.use(
 // 响应拦截器
 axiosInstance.interceptors.response.use(
     (response: AxiosResponse) => {// 成功信息
-        const { data } = response;
-        if (data.code === 200) {// 成功
+        const { config, data } = response;
+        if (config.responseType === 'blob') {
             return Promise.resolve(data);
-        } else {// 失败
-            if (data.code === 401) {
-                LocalStorage.clear();
-                router.navigate({ pathname: '/login' }, { replace: true });
-                message.error('登录过期');
-                return Promise.reject();
-            } else {
+        } else {
+            if (data.code === 200) {// 成功
+                return Promise.resolve(data);
+            } else {// 失败
                 return Promise.reject(data);
             }
         }
@@ -53,8 +41,10 @@ axiosInstance.interceptors.response.use(
         if (String(error).includes('timeout')) {
             message.error('请求超时');
         } else {
-            if (statusCode < 500) {
-                message.error('请求失败');
+            if (statusCode === 401) {
+                LocalStorage.clear();
+                router.navigate({ pathname: '/login' }, { replace: true });
+                message.error('登录过期');
             } else {
                 message.error('服务异常');
             }

+ 42 - 6
src/apis/config.ts

@@ -1,14 +1,50 @@
-const apiURL = import.meta.env.VITE_API_URL;
+import { UploadProps, UploadFile, message } from 'antd';
+import LocalStorage from '@/LocalStorage';
 
-const webSocketURL = import.meta.env.VITE_WEBSOCKET_URL;
-
-const baseURL = '/api';
+const baseURL = '/api/client_api';
 
 const config = {
-    apiURL: apiURL,
-    webSocketURL: webSocketURL,
     baseURL: baseURL,
     v1URL: baseURL + '/v1',
 };
 
+export const getHeaders = () => {
+    const headers: { 'Authorization'?: string } = {};
+    const token = LocalStorage.getToken();
+    if (token) {
+        headers['Authorization'] = token;
+    }
+    return headers;
+};
+
+// 上传图片配置
+export const uploadImageConfig: UploadProps = {
+    action: config.v1URL + '/upload/image',
+    method: 'POST',
+    headers: getHeaders(),
+    accept: ['.png', '.jpg', '.jpeg'].join(','),
+};
+
+// 上传Excel配置
+export const uploadExcelConfig: UploadProps = {
+    action: config.v1URL + '/upload/excel',
+    method: 'POST',
+    headers: getHeaders(),
+    accept: ['.xls', '.xlsx'].join(','),
+};
+
+// 后置上传
+export const afterUpload = (file: UploadFile) => {
+    if (file.status === 'done') {// 上传成功
+        const { code, msg } = file.response;
+        if (code === 200) {
+            message.success('上传成功');
+        } else {
+            message.error(msg);
+        }
+    } else if (file.status === 'error') {// 上传失败
+        message.error('上传失败');
+    }
+}
+
 export default config;

+ 7 - 0
src/apis/index.ts

@@ -9,12 +9,19 @@ export type LoginApiParams = {
 
 // Api函数类型
 export type LoginApi = (data: LoginApiParams) => Promise<any>;
+export type LogoutApi = () => Promise<any>;
 
 // 登录
 const loginApi: LoginApi = async (data) => {
     return api.post('/auth/login', data, { baseURL: config.v1URL });
 };
 
+// 登出
+const logoutApi: LogoutApi = async () => {
+    return api.post('/auth/logout', {}, { baseURL: config.v1URL });
+};
+
 export const apis = {
     login: loginApi,
+    logout: logoutApi,
 };

+ 0 - 20
src/components/iconFont/index.tsx

@@ -1,20 +0,0 @@
-import * as React from 'react';
-import { createFromIconfontCN } from '@ant-design/icons';
-
-interface Props {
-	name: string,
-};
-
-const IconFont: React.FC<Props> = (props: Props) => {
-	const { name } = props;
-
-	const IconFont = createFromIconfontCN({
-		scriptUrl: '//at.alicdn.com/t/c/font_3589633_0nxlhu0gjmco.js',
-	});
-
-	return (
-		<IconFont type={name} />
-	);
-}
-
-export default IconFont;

+ 4 - 20
src/pages/dataExport/index.tsx

@@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
 import store from './store';
 import './style.less';
 
-const WorkbenchApp: React.FC = () => {
+const DataExport: React.FC = () => {
     const {
         state,
         init,
@@ -19,26 +19,10 @@ const WorkbenchApp: React.FC = () => {
     }, []);
 
     return (
-        <div className='workbench'>
-            <div className='workbench-top'>
-                <div className='workbench-top-style'>
-                    <div className='workbench-top-style-welcome'>
-                        <div className='workbench-top-style-welcome-text'>
-                        
-                        </div>
-                        <div className='workbench-top-style-welcome-picture'>
-
-                        </div>
-                    </div>
-                    <div className='workbench-top-style-fast'></div>
-                </div>
-                <div className='workbench-top-weather'>
-
-                </div>
-            </div>
-            <div className='workbench-bottom'></div>
+        <div className='dataExport'>
+            数据导出
         </div>
     );
 };
 
-export default observer(WorkbenchApp);
+export default observer(DataExport);

+ 3 - 3
src/pages/dataExport/store.ts

@@ -1,6 +1,6 @@
 import { makeAutoObservable } from 'mobx';
 import { apis } from '@/apis';
-import { State, ReadonlyState, StateAction, WorkbenchStore } from './types';
+import { State, ReadonlyState, StateAction, DataExportStore } from './types';
 
 // 定义状态
 const stateGenerator = (): ReadonlyState => ({
@@ -17,7 +17,7 @@ const stateActionsGenerator = (state: State): StateAction => {
 };
 
 // 使用仓库
-const useWorkbenchStore = (): WorkbenchStore => {
+const useDataExportStore = (): DataExportStore => {
     const state = makeAutoObservable(stateGenerator());
     const actions = stateActionsGenerator(state);
 
@@ -44,4 +44,4 @@ const useWorkbenchStore = (): WorkbenchStore => {
     };
 };
 
-export default useWorkbenchStore();
+export default useDataExportStore();

+ 3 - 80
src/pages/dataExport/style.less

@@ -1,83 +1,6 @@
-.workbench {
+.dataExport {
   width: 100%;
   height: 100%;
-  display: flex;
-  flex-direction: column;
-
-  &-top {
-    margin-bottom: 20px;
-    display: flex;
-
-    &-style {
-      width: 100%;
-      height: 290px;
-      margin-right: 20px;
-
-      &-welcome {
-        width: 100%;
-        height: 130px;
-        padding: 0 20px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-        margin-bottom: 20px;
-        display: flex;
-
-        &-text {
-          width: 30%;
-          display: flex;
-          flex-direction: column;
-          justify-content: center;
-          color: @primary-color;
-
-          &-first {
-            font-size: 20px;
-            font-weight: 500;
-          }
-
-          &-second {
-            font-size: 24px;
-            font-weight: 500;
-          }
-        }
-
-        &-picture {
-          width: 70%;
-
-          img {
-            width: 100%;
-            height: 100%;
-            object-fit: cover;
-            -webkit-user-drag: none;
-          }
-        }
-      }
-
-      &-fast {
-        width: 100%;
-        height: 140px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-      }
-    }
-
-    &-weather {
-      width: 300px;
-      height: 290px;
-      padding: 20px 20px 0;
-      background: #FFFFFF;
-      border-radius: @border-radius-base;
-    }
-  }
-
-  &-bottom {
-    width: 100%;
-    height: 0;
-    flex: 1;
-    padding: 20px;
-    background: #FFFFFF;
-    border-radius: @border-radius-base;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
+  background: #FFFFFF;
+  border-radius: @border-radius-base;
 }

+ 1 - 1
src/pages/dataExport/types.ts

@@ -12,7 +12,7 @@ export type StateAction = {
 };
 
 // 仓库类型
-export type WorkbenchStore = {
+export type DataExportStore = {
     state: ReadonlyState,
     init: () => void,
     reset: () => void,

+ 0 - 44
src/pages/knowledgeBase/info/index.tsx

@@ -1,44 +0,0 @@
-import * as React from 'react';
-import { observer } from 'mobx-react';
-import store from './store';
-import './style.less';
-
-const WorkbenchApp: React.FC = () => {
-    const {
-        state,
-        init,
-        reset
-    } = store;
-    const {
-        pageLoading
-    } = state;
-
-    React.useEffect(() => {
-        init();
-        return () => reset();
-    }, []);
-
-    return (
-        <div className='workbench'>
-            <div className='workbench-top'>
-                <div className='workbench-top-style'>
-                    <div className='workbench-top-style-welcome'>
-                        <div className='workbench-top-style-welcome-text'>
-                        
-                        </div>
-                        <div className='workbench-top-style-welcome-picture'>
-
-                        </div>
-                    </div>
-                    <div className='workbench-top-style-fast'></div>
-                </div>
-                <div className='workbench-top-weather'>
-
-                </div>
-            </div>
-            <div className='workbench-bottom'></div>
-        </div>
-    );
-};
-
-export default observer(WorkbenchApp);

+ 0 - 83
src/pages/knowledgeBase/info/style.less

@@ -1,83 +0,0 @@
-.workbench {
-  width: 100%;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-
-  &-top {
-    margin-bottom: 20px;
-    display: flex;
-
-    &-style {
-      width: 100%;
-      height: 290px;
-      margin-right: 20px;
-
-      &-welcome {
-        width: 100%;
-        height: 130px;
-        padding: 0 20px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-        margin-bottom: 20px;
-        display: flex;
-
-        &-text {
-          width: 30%;
-          display: flex;
-          flex-direction: column;
-          justify-content: center;
-          color: @primary-color;
-
-          &-first {
-            font-size: 20px;
-            font-weight: 500;
-          }
-
-          &-second {
-            font-size: 24px;
-            font-weight: 500;
-          }
-        }
-
-        &-picture {
-          width: 70%;
-
-          img {
-            width: 100%;
-            height: 100%;
-            object-fit: cover;
-            -webkit-user-drag: none;
-          }
-        }
-      }
-
-      &-fast {
-        width: 100%;
-        height: 140px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-      }
-    }
-
-    &-weather {
-      width: 300px;
-      height: 290px;
-      padding: 20px 20px 0;
-      background: #FFFFFF;
-      border-radius: @border-radius-base;
-    }
-  }
-
-  &-bottom {
-    width: 100%;
-    height: 0;
-    flex: 1;
-    padding: 20px;
-    background: #FFFFFF;
-    border-radius: @border-radius-base;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-}

+ 0 - 44
src/pages/knowledgeBase/list/index.tsx

@@ -1,44 +0,0 @@
-import * as React from 'react';
-import { observer } from 'mobx-react';
-import store from './store';
-import './style.less';
-
-const WorkbenchApp: React.FC = () => {
-    const {
-        state,
-        init,
-        reset
-    } = store;
-    const {
-        pageLoading
-    } = state;
-
-    React.useEffect(() => {
-        init();
-        return () => reset();
-    }, []);
-
-    return (
-        <div className='workbench'>
-            <div className='workbench-top'>
-                <div className='workbench-top-style'>
-                    <div className='workbench-top-style-welcome'>
-                        <div className='workbench-top-style-welcome-text'>
-                        
-                        </div>
-                        <div className='workbench-top-style-welcome-picture'>
-
-                        </div>
-                    </div>
-                    <div className='workbench-top-style-fast'></div>
-                </div>
-                <div className='workbench-top-weather'>
-
-                </div>
-            </div>
-            <div className='workbench-bottom'></div>
-        </div>
-    );
-};
-
-export default observer(WorkbenchApp);

+ 0 - 83
src/pages/knowledgeBase/list/style.less

@@ -1,83 +0,0 @@
-.workbench {
-  width: 100%;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-
-  &-top {
-    margin-bottom: 20px;
-    display: flex;
-
-    &-style {
-      width: 100%;
-      height: 290px;
-      margin-right: 20px;
-
-      &-welcome {
-        width: 100%;
-        height: 130px;
-        padding: 0 20px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-        margin-bottom: 20px;
-        display: flex;
-
-        &-text {
-          width: 30%;
-          display: flex;
-          flex-direction: column;
-          justify-content: center;
-          color: @primary-color;
-
-          &-first {
-            font-size: 20px;
-            font-weight: 500;
-          }
-
-          &-second {
-            font-size: 24px;
-            font-weight: 500;
-          }
-        }
-
-        &-picture {
-          width: 70%;
-
-          img {
-            width: 100%;
-            height: 100%;
-            object-fit: cover;
-            -webkit-user-drag: none;
-          }
-        }
-      }
-
-      &-fast {
-        width: 100%;
-        height: 140px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-      }
-    }
-
-    &-weather {
-      width: 300px;
-      height: 290px;
-      padding: 20px 20px 0;
-      background: #FFFFFF;
-      border-radius: @border-radius-base;
-    }
-  }
-
-  &-bottom {
-    width: 100%;
-    height: 0;
-    flex: 1;
-    padding: 20px;
-    background: #FFFFFF;
-    border-radius: @border-radius-base;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-}

+ 28 - 0
src/pages/knowledgeLib/info/index.tsx

@@ -0,0 +1,28 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import store from './store';
+import './style.less';
+
+const KnowledgeLibInfo: React.FC = () => {
+    const {
+        state,
+        init,
+        reset
+    } = store;
+    const {
+        pageLoading
+    } = state;
+
+    React.useEffect(() => {
+        init();
+        return () => reset();
+    }, []);
+
+    return (
+        <div className='knowledgeLibInfo'>
+            创建/修改-知识库
+        </div>
+    );
+};
+
+export default observer(KnowledgeLibInfo);

+ 3 - 3
src/pages/questionAnswerApp/info/store.ts → src/pages/knowledgeLib/info/store.ts

@@ -1,6 +1,6 @@
 import { makeAutoObservable } from 'mobx';
 import { apis } from '@/apis';
-import { State, ReadonlyState, StateAction, WorkbenchStore } from './types';
+import { State, ReadonlyState, StateAction, KnowledgeLibInfoStore } from './types';
 
 // 定义状态
 const stateGenerator = (): ReadonlyState => ({
@@ -17,7 +17,7 @@ const stateActionsGenerator = (state: State): StateAction => {
 };
 
 // 使用仓库
-const useWorkbenchStore = (): WorkbenchStore => {
+const useKnowledgeLibInfoStore = (): KnowledgeLibInfoStore => {
     const state = makeAutoObservable(stateGenerator());
     const actions = stateActionsGenerator(state);
 
@@ -44,4 +44,4 @@ const useWorkbenchStore = (): WorkbenchStore => {
     };
 };
 
-export default useWorkbenchStore();
+export default useKnowledgeLibInfoStore();

+ 6 - 0
src/pages/knowledgeLib/info/style.less

@@ -0,0 +1,6 @@
+.knowledgeLibInfo {
+  width: 100%;
+  height: 100%;
+  background: #FFFFFF;
+  border-radius: @border-radius-base;
+}

+ 1 - 1
src/pages/questionAnswerApp/list/types.ts → src/pages/knowledgeLib/info/types.ts

@@ -12,7 +12,7 @@ export type StateAction = {
 };
 
 // 仓库类型
-export type WorkbenchStore = {
+export type KnowledgeLibInfoStore = {
     state: ReadonlyState,
     init: () => void,
     reset: () => void,

+ 28 - 0
src/pages/knowledgeLib/list/index.tsx

@@ -0,0 +1,28 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import store from './store';
+import './style.less';
+
+const KnowledgeLibList: React.FC = () => {
+    const {
+        state,
+        init,
+        reset
+    } = store;
+    const {
+        pageLoading
+    } = state;
+
+    React.useEffect(() => {
+        init();
+        return () => reset();
+    }, []);
+
+    return (
+        <div className='knowledgeLibList'>
+            知识库列表
+        </div>
+    );
+};
+
+export default observer(KnowledgeLibList);

+ 3 - 3
src/pages/questionAnswerApp/list/store.ts → src/pages/knowledgeLib/list/store.ts

@@ -1,6 +1,6 @@
 import { makeAutoObservable } from 'mobx';
 import { apis } from '@/apis';
-import { State, ReadonlyState, StateAction, WorkbenchStore } from '../types';
+import { State, ReadonlyState, StateAction, KnowledgeLibListStore } from './types';
 
 // 定义状态
 const stateGenerator = (): ReadonlyState => ({
@@ -17,7 +17,7 @@ const stateActionsGenerator = (state: State): StateAction => {
 };
 
 // 使用仓库
-const useWorkbenchStore = (): WorkbenchStore => {
+const useKnowledgeLibListStore = (): KnowledgeLibListStore => {
     const state = makeAutoObservable(stateGenerator());
     const actions = stateActionsGenerator(state);
 
@@ -44,4 +44,4 @@ const useWorkbenchStore = (): WorkbenchStore => {
     };
 };
 
-export default useWorkbenchStore();
+export default useKnowledgeLibListStore();

+ 6 - 0
src/pages/knowledgeLib/list/style.less

@@ -0,0 +1,6 @@
+.knowledgeLibList {
+  width: 100%;
+  height: 100%;
+  background: #FFFFFF;
+  border-radius: @border-radius-base;
+}

+ 1 - 1
src/pages/knowledgeBase/info/types.ts → src/pages/knowledgeLib/list/types.ts

@@ -12,7 +12,7 @@ export type StateAction = {
 };
 
 // 仓库类型
-export type WorkbenchStore = {
+export type KnowledgeLibListStore = {
     state: ReadonlyState,
     init: () => void,
     reset: () => void,

+ 7 - 4
src/pages/layout/components/Breadcrumb.tsx

@@ -1,10 +1,13 @@
 import * as React from 'react';
 import { Link } from 'react-router-dom';
-import { observer } from 'mobx-react';
 import { Breadcrumb as AntdBreadcrumb } from 'antd';
-import { BreadcrumbProps } from '../types';
+import { State } from '../types';
 
-const Breadcrumb: React.FC<BreadcrumbProps> = (props: BreadcrumbProps) => {
+interface Props {
+    routerMatchList: State['routerMatchList'],
+};
+
+const Breadcrumb: React.FC<Props> = (props: Props) => {
     const { routerMatchList } = props;
 
     const items = routerMatchList.map((item, index) => {
@@ -24,4 +27,4 @@ const Breadcrumb: React.FC<BreadcrumbProps> = (props: BreadcrumbProps) => {
     );
 };
 
-export default observer(Breadcrumb);
+export default Breadcrumb;

+ 7 - 4
src/pages/layout/components/Header.tsx

@@ -1,14 +1,17 @@
 import * as React from 'react';
-import { observer } from 'mobx-react';
 import { Layout, MenuProps, Modal, Dropdown } from 'antd';
 import { CaretDownOutlined, PoweroffOutlined } from '@ant-design/icons';
 import logoSrc from '@/assets/public/logo.png';
 import router from '@/router';
-import { HeaderProps } from '../types';
 
 const { Header: AntdHeader } = Layout;
 
-const Header: React.FC<HeaderProps> = (props: HeaderProps) => {
+interface Props {
+    userName: string,
+    onClickLogout: () => Promise<any>,
+};
+
+const Header: React.FC<Props> = (props: Props) => {
     const {
         userName,
         onClickLogout
@@ -59,4 +62,4 @@ const Header: React.FC<HeaderProps> = (props: HeaderProps) => {
     );
 };
 
-export default observer(Header);
+export default Header;

+ 27 - 15
src/pages/layout/components/Nav.tsx

@@ -1,14 +1,26 @@
 import * as React from 'react';
-import { observer } from 'mobx-react';
-import { Layout, Menu, MenuProps, Button } from 'antd';
-import { TeamOutlined, MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
-import IconFont from '@/components/iconFont';
+import { Layout, Menu, Button } from 'antd';
+import {
+    RobotOutlined,
+    ReadOutlined,
+    FileSearchOutlined,
+    MenuFoldOutlined,
+    MenuUnfoldOutlined
+} from '@ant-design/icons';
 import router from '@/router';
-import { NavProps } from '../types';
 
 const Sider = Layout.Sider;
 
-const Nav: React.FC<NavProps> = (props: NavProps) => {
+interface Props {
+    selectedKey: string,
+    onChangeSelectedKey: (path: string, menuLevel: number) => void,
+    openKeys: string[],
+    onOpenChange: (openKeys: string[]) => void,
+    collapsed: boolean,
+    onClickCollapsed: () => void,
+};
+
+const Nav: React.FC<Props> = (props: Props) => {
     const {
         selectedKey,
         onChangeSelectedKey,
@@ -18,22 +30,22 @@ const Nav: React.FC<NavProps> = (props: NavProps) => {
         onClickCollapsed
     } = props;
 
-    const items: MenuProps['items'] = [
+    const items = [
         {
-            key: '/questionAnswerApp',
-            icon: <TeamOutlined />,
+            key: '/questionAnswer',
+            icon: <RobotOutlined />,
             label: '问答应用',
-            onClick: () => { router.navigate({ pathname: '/questionAnswerApp' }) }
+            onClick: () => { router.navigate({ pathname: '/questionAnswer' }) }
         },
         {
-            key: '/knowledgeBase',
-            icon: <IconFont name='icon-home' />,
+            key: '/knowledgeLib',
+            icon: <ReadOutlined />,
             label: '知识库',
-            onClick: () => { router.navigate({ pathname: '/knowledgeBase' }) }
+            onClick: () => { router.navigate({ pathname: '/knowledgeLib' }) }
         },
         {
             key: '/dataExport',
-            icon: <IconFont name='icon-home' />,
+            icon: <FileSearchOutlined />,
             label: '数据导出',
             onClick: () => { router.navigate({ pathname: '/dataExport' }) }
         }
@@ -70,4 +82,4 @@ const Nav: React.FC<NavProps> = (props: NavProps) => {
     );
 };
 
-export default observer(Nav);
+export default Nav;

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

@@ -1,5 +1,5 @@
 import * as React from 'react';
-import { useMatches, Outlet, useLocation } from 'react-router-dom';
+import { useMatches, useLocation, Outlet } from 'react-router-dom';
 import { observer } from 'mobx-react';
 import { Layout } from 'antd';
 import Header from './components/Header';

+ 0 - 19
src/pages/layout/types.ts

@@ -32,23 +32,4 @@ export type LayoutStore = {
     onClickCollapsed: () => void,
     init: (list: State['routerMatchList']) => void,
     reset: () => void,
-};
-
-/* 组件类型 */
-export type HeaderProps = {
-    userName: string,
-    onClickLogout: () => Promise<any>,
-};
-
-export type NavProps = {
-    selectedKey: string,
-    onChangeSelectedKey: (path: string, menuLevel: number) => void,
-    openKeys: string[],
-    onOpenChange: (openKeys: string[]) => void,
-    collapsed: boolean,
-    onClickCollapsed: () => void,
-};
-
-export type BreadcrumbProps = {
-    routerMatchList: State['routerMatchList'],
 };

+ 41 - 47
src/pages/login/index.tsx

@@ -12,13 +12,11 @@ const FormItem = Form.Item;
 const LoginApp: React.FC = () => {
     const {
         state,
-        onChangeRemember,
         onClickLogin,
         init,
         reset
     } = store;
     const {
-        rememberChecked,
         buttonLoading
     } = state;
 
@@ -29,8 +27,8 @@ const LoginApp: React.FC = () => {
         return () => reset();
     }, []);
 
-    // 检查密码
-    const checkPassword = (rule: any, value: string) => {
+    // 校验密码
+    const validatorPassword = (rule: any, value: string) => {
         if (value) {
             const passwordRegex = new RegExp(regex.password);
             if (passwordRegex.test(value)) {
@@ -56,51 +54,47 @@ const LoginApp: React.FC = () => {
                         </span>
                     </div>
                     <Form form={form}>
-                        <div style={{ height: 70 }}>
-                            <FormItem
-                                name='account'
-                                rules={[{ required: true, message: '账号不能为空', whitespace: true }]}
-                            >
-                                <Input size='large' placeholder='请输入账号' />
-                            </FormItem>
-                        </div>
-                        <div style={{ height: 70 }}>
-                            <FormItem
-                                name='password'
-                                rules={[{ validator: checkPassword, required: true }]}
-                            >
-                                <Input.Password size='large' placeholder='请输入密码' />
-                            </FormItem>
-                        </div>
-                        <Checkbox
-                            style={{ marginBottom: 30 }}
-                            checked={rememberChecked}
-                            onChange={(e) => {
-                                const checked = e.target.checked;
-                                onChangeRemember(checked);
-                            }}
+                        <FormItem
+                            name='account'
+                            rules={[{ required: true, message: '账号不能为空', whitespace: true }]}
                         >
-                            记住密码
-                        </Checkbox>
-                        <Button
-                            style={{ width: '100%' }}
-                            type='primary'
-                            size='large'
-                            loading={buttonLoading}
-                            onClick={() => {
-                                form.validateFields().then(async (values) => {
-                                    const data = {
-                                        phone_number: values.account,
-                                        password: values.password
-                                    }
-                                    await onClickLogin(data);
-                                }).catch((error) => {
-                                    console.error(error);
-                                });
-                            }}
+                            <Input size='large' placeholder='请输入账号' />
+                        </FormItem>
+                        <FormItem
+                            name='password'
+                            rules={[{ required: true, validator: validatorPassword }]}
                         >
-                            登录
-                        </Button>
+                            <Input.Password size='large' placeholder='请输入密码' />
+                        </FormItem>
+                        <FormItem
+                            name='remember'
+                            valuePropName='checked'
+                        >
+                            <Checkbox>
+                                记住密码
+                            </Checkbox>
+                        </FormItem>
+                        <FormItem>
+                            <Button
+                                type='primary'
+                                size='large'
+                                block={true}
+                                loading={buttonLoading}
+                                onClick={() => {
+                                    form.validateFields().then(async (values) => {
+                                        const data = {
+                                            account: values.account,
+                                            password: values.password
+                                        }
+                                        await onClickLogin(data);
+                                    }).catch((error) => {
+                                        console.error(error);
+                                    });
+                                }}
+                            >
+                                登录
+                            </Button>
+                        </FormItem>
                     </Form>
                 </div>
                 <Copyright />

+ 9 - 21
src/pages/login/store.tsx

@@ -7,16 +7,12 @@ import { State, ReadonlyState, StateAction, LoginStore } from './types';
 
 // 定义状态
 const stateGenerator = (): ReadonlyState => ({
-    rememberChecked: false,
     buttonLoading: false,
 });
 
 // 修改状态
 const stateActionsGenerator = (state: State): StateAction => {
     return {
-        setRememberChecked: (checked) => {
-            state.rememberChecked = checked;
-        },
         setButtonLoading: (loading) => {
             state.buttonLoading = loading;
         },
@@ -47,14 +43,14 @@ const useLoginStore = (): LoginStore => {
                     id: info.user_id,
                     name: info.user_name,
                 });
-                if (state.rememberChecked) {// 记住密码
-                    LocalStorage.setAccountPassword({
-                        account: data.phone_number,
-                        password: data.password,
-                    });
-                } else {// 不记住密码
-                    LocalStorage.setAccountPassword(undefined);
-                }
+                // if (state.rememberChecked) {// 记住密码
+                //     LocalStorage.setAccountPassword({
+                //         account: data.account,
+                //         password: data.password,
+                //     });
+                // } else {// 不记住密码
+                //     LocalStorage.setAccountPassword(undefined);
+                // }
                 router.navigate({ pathname: '/' }, { replace: true });
                 message.success('登录成功');
             } catch (error: any) {
@@ -66,11 +62,6 @@ const useLoginStore = (): LoginStore => {
         },
     }
 
-    // 更改记住密码
-    const onChangeRemember: LoginStore['onChangeRemember'] = (checked) => {
-        actions.setRememberChecked(checked);
-    }
-
     // 点击登录
     const onClickLogin: LoginStore['onClickLogin'] = async (data) => {
         // 登录
@@ -84,23 +75,20 @@ const useLoginStore = (): LoginStore => {
             form.setFieldsValue({
                 account: accountPassword.account,
                 password: accountPassword.password,
+                remember: true,
             });
-            actions.setRememberChecked(true);
         }
     }
 
     // 状态重置
     const reset: LoginStore['reset'] = () => {
-        const initialRememberChecked = stateGenerator().rememberChecked;
         const initialButtonLoading = stateGenerator().buttonLoading;
 
-        actions.setRememberChecked(initialRememberChecked);
         actions.setButtonLoading(initialButtonLoading);
     }
 
     return {
         state,
-        onChangeRemember,
         onClickLogin,
         init,
         reset

+ 4 - 2
src/pages/login/style.less

@@ -2,9 +2,11 @@
     width: 100%;
     height: 100%;
     display: flex;
+    overflow: hidden;
 
     &-left {
         width: 50%;
+        height: 100%;
 
         img {
             width: 100%;
@@ -25,13 +27,13 @@
             width: 50%;
 
             &-title {
-                margin-bottom: 50px;
+                margin-bottom: 30px;
 
                 &-text {
                     font-size: 24px;
                     color: @primary-color;
                     border-bottom: 2px solid @primary-color;
-                    background: linear-gradient(to bottom, #FFFFFF 50%, #b2cbf4 50%);
+                    background: linear-gradient(to bottom, #FFFFFF 50%, #D3DCF6 50%);
                 }
             }
         }

+ 0 - 3
src/pages/login/types.ts

@@ -3,7 +3,6 @@ import { LoginApiParams } from '@/apis';
 
 // 定义状态
 export type State = {
-    rememberChecked: boolean,
     buttonLoading: boolean,
 };
 
@@ -12,14 +11,12 @@ export type ReadonlyState = Readonly<State>;
 
 // 修改状态
 export type StateAction = {
-    setRememberChecked: (checked: State['rememberChecked']) => void,
     setButtonLoading: (loading: State['buttonLoading']) => void,
 };
 
 // 仓库类型
 export type LoginStore = {
     state: ReadonlyState,
-    onChangeRemember: (checked: boolean) => void,
     onClickLogin: (data: LoginApiParams) => Promise<any>,
     init: (form: FormInstance) => void,
     reset: () => void,

+ 28 - 0
src/pages/questionAnswer/info/index.tsx

@@ -0,0 +1,28 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import store from './store';
+import './style.less';
+
+const QuestionAnswerInfo: React.FC = () => {
+    const {
+        state,
+        init,
+        reset
+    } = store;
+    const {
+        pageLoading
+    } = state;
+
+    React.useEffect(() => {
+        init();
+        return () => reset();
+    }, []);
+
+    return (
+        <div className='questionAnswerInfo'>
+            创建/修改-问答应用
+        </div>
+    );
+};
+
+export default observer(QuestionAnswerInfo);

+ 3 - 3
src/pages/knowledgeBase/info/store.ts → src/pages/questionAnswer/info/store.ts

@@ -1,6 +1,6 @@
 import { makeAutoObservable } from 'mobx';
 import { apis } from '@/apis';
-import { State, ReadonlyState, StateAction, WorkbenchStore } from './types';
+import { State, ReadonlyState, StateAction, QuestionAnswerInfoStore } from './types';
 
 // 定义状态
 const stateGenerator = (): ReadonlyState => ({
@@ -17,7 +17,7 @@ const stateActionsGenerator = (state: State): StateAction => {
 };
 
 // 使用仓库
-const useWorkbenchStore = (): WorkbenchStore => {
+const useQuestionAnswerInfoStore = (): QuestionAnswerInfoStore => {
     const state = makeAutoObservable(stateGenerator());
     const actions = stateActionsGenerator(state);
 
@@ -44,4 +44,4 @@ const useWorkbenchStore = (): WorkbenchStore => {
     };
 };
 
-export default useWorkbenchStore();
+export default useQuestionAnswerInfoStore();

+ 6 - 0
src/pages/questionAnswer/info/style.less

@@ -0,0 +1,6 @@
+.questionAnswerInfo {
+  width: 100%;
+  height: 100%;
+  background: #FFFFFF;
+  border-radius: @border-radius-base;
+}

+ 1 - 1
src/pages/knowledgeBase/list/types.ts → src/pages/questionAnswer/info/types.ts

@@ -12,7 +12,7 @@ export type StateAction = {
 };
 
 // 仓库类型
-export type WorkbenchStore = {
+export type QuestionAnswerInfoStore = {
     state: ReadonlyState,
     init: () => void,
     reset: () => void,

+ 28 - 0
src/pages/questionAnswer/list/index.tsx

@@ -0,0 +1,28 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import store from './store';
+import './style.less';
+
+const QuestionAnswerList: React.FC = () => {
+    const {
+        state,
+        init,
+        reset
+    } = store;
+    const {
+        pageLoading
+    } = state;
+
+    React.useEffect(() => {
+        init();
+        return () => reset();
+    }, []);
+
+    return (
+        <div className='questionAnswerList'>
+            问答应用列表
+        </div>
+    );
+};
+
+export default observer(QuestionAnswerList);

+ 3 - 3
src/pages/knowledgeBase/list/store.ts → src/pages/questionAnswer/list/store.ts

@@ -1,6 +1,6 @@
 import { makeAutoObservable } from 'mobx';
 import { apis } from '@/apis';
-import { State, ReadonlyState, StateAction, WorkbenchStore } from './types';
+import { State, ReadonlyState, StateAction, QuestionAnswerListStore } from './types';
 
 // 定义状态
 const stateGenerator = (): ReadonlyState => ({
@@ -17,7 +17,7 @@ const stateActionsGenerator = (state: State): StateAction => {
 };
 
 // 使用仓库
-const useWorkbenchStore = (): WorkbenchStore => {
+const useQuestionAnswerListStore = (): QuestionAnswerListStore => {
     const state = makeAutoObservable(stateGenerator());
     const actions = stateActionsGenerator(state);
 
@@ -44,4 +44,4 @@ const useWorkbenchStore = (): WorkbenchStore => {
     };
 };
 
-export default useWorkbenchStore();
+export default useQuestionAnswerListStore();

+ 6 - 0
src/pages/questionAnswer/list/style.less

@@ -0,0 +1,6 @@
+.questionAnswerList {
+  width: 100%;
+  height: 100%;
+  background: #FFFFFF;
+  border-radius: @border-radius-base;
+}

+ 1 - 1
src/pages/questionAnswerApp/info/types.ts → src/pages/questionAnswer/list/types.ts

@@ -12,7 +12,7 @@ export type StateAction = {
 };
 
 // 仓库类型
-export type WorkbenchStore = {
+export type QuestionAnswerListStore = {
     state: ReadonlyState,
     init: () => void,
     reset: () => void,

+ 0 - 44
src/pages/questionAnswerApp/info/index.tsx

@@ -1,44 +0,0 @@
-import * as React from 'react';
-import { observer } from 'mobx-react';
-import store from './store';
-import './style.less';
-
-const WorkbenchApp: React.FC = () => {
-    const {
-        state,
-        init,
-        reset
-    } = store;
-    const {
-        pageLoading
-    } = state;
-
-    React.useEffect(() => {
-        init();
-        return () => reset();
-    }, []);
-
-    return (
-        <div className='workbench'>
-            <div className='workbench-top'>
-                <div className='workbench-top-style'>
-                    <div className='workbench-top-style-welcome'>
-                        <div className='workbench-top-style-welcome-text'>
-                        
-                        </div>
-                        <div className='workbench-top-style-welcome-picture'>
-
-                        </div>
-                    </div>
-                    <div className='workbench-top-style-fast'></div>
-                </div>
-                <div className='workbench-top-weather'>
-
-                </div>
-            </div>
-            <div className='workbench-bottom'></div>
-        </div>
-    );
-};
-
-export default observer(WorkbenchApp);

+ 0 - 83
src/pages/questionAnswerApp/info/style.less

@@ -1,83 +0,0 @@
-.workbench {
-  width: 100%;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-
-  &-top {
-    margin-bottom: 20px;
-    display: flex;
-
-    &-style {
-      width: 100%;
-      height: 290px;
-      margin-right: 20px;
-
-      &-welcome {
-        width: 100%;
-        height: 130px;
-        padding: 0 20px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-        margin-bottom: 20px;
-        display: flex;
-
-        &-text {
-          width: 30%;
-          display: flex;
-          flex-direction: column;
-          justify-content: center;
-          color: @primary-color;
-
-          &-first {
-            font-size: 20px;
-            font-weight: 500;
-          }
-
-          &-second {
-            font-size: 24px;
-            font-weight: 500;
-          }
-        }
-
-        &-picture {
-          width: 70%;
-
-          img {
-            width: 100%;
-            height: 100%;
-            object-fit: cover;
-            -webkit-user-drag: none;
-          }
-        }
-      }
-
-      &-fast {
-        width: 100%;
-        height: 140px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-      }
-    }
-
-    &-weather {
-      width: 300px;
-      height: 290px;
-      padding: 20px 20px 0;
-      background: #FFFFFF;
-      border-radius: @border-radius-base;
-    }
-  }
-
-  &-bottom {
-    width: 100%;
-    height: 0;
-    flex: 1;
-    padding: 20px;
-    background: #FFFFFF;
-    border-radius: @border-radius-base;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-}

+ 0 - 44
src/pages/questionAnswerApp/list/index.tsx

@@ -1,44 +0,0 @@
-import * as React from 'react';
-import { observer } from 'mobx-react';
-import store from './store';
-import './style.less';
-
-const WorkbenchApp: React.FC = () => {
-    const {
-        state,
-        init,
-        reset
-    } = store;
-    const {
-        pageLoading
-    } = state;
-
-    React.useEffect(() => {
-        init();
-        return () => reset();
-    }, []);
-
-    return (
-        <div className='workbench'>
-            <div className='workbench-top'>
-                <div className='workbench-top-style'>
-                    <div className='workbench-top-style-welcome'>
-                        <div className='workbench-top-style-welcome-text'>
-                        
-                        </div>
-                        <div className='workbench-top-style-welcome-picture'>
-
-                        </div>
-                    </div>
-                    <div className='workbench-top-style-fast'></div>
-                </div>
-                <div className='workbench-top-weather'>
-
-                </div>
-            </div>
-            <div className='workbench-bottom'></div>
-        </div>
-    );
-};
-
-export default observer(WorkbenchApp);

+ 0 - 83
src/pages/questionAnswerApp/list/style.less

@@ -1,83 +0,0 @@
-.workbench {
-  width: 100%;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-
-  &-top {
-    margin-bottom: 20px;
-    display: flex;
-
-    &-style {
-      width: 100%;
-      height: 290px;
-      margin-right: 20px;
-
-      &-welcome {
-        width: 100%;
-        height: 130px;
-        padding: 0 20px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-        margin-bottom: 20px;
-        display: flex;
-
-        &-text {
-          width: 30%;
-          display: flex;
-          flex-direction: column;
-          justify-content: center;
-          color: @primary-color;
-
-          &-first {
-            font-size: 20px;
-            font-weight: 500;
-          }
-
-          &-second {
-            font-size: 24px;
-            font-weight: 500;
-          }
-        }
-
-        &-picture {
-          width: 70%;
-
-          img {
-            width: 100%;
-            height: 100%;
-            object-fit: cover;
-            -webkit-user-drag: none;
-          }
-        }
-      }
-
-      &-fast {
-        width: 100%;
-        height: 140px;
-        background: #FFFFFF;
-        border-radius: @border-radius-base;
-      }
-    }
-
-    &-weather {
-      width: 300px;
-      height: 290px;
-      padding: 20px 20px 0;
-      background: #FFFFFF;
-      border-radius: @border-radius-base;
-    }
-  }
-
-  &-bottom {
-    width: 100%;
-    height: 0;
-    flex: 1;
-    padding: 20px;
-    background: #FFFFFF;
-    border-radius: @border-radius-base;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-}

+ 13 - 13
src/router.tsx

@@ -30,10 +30,10 @@ const routerList: RouteObject[] = [
         children: [
             {
                 index: true,
-                element: <Navigate to='/questionAnswerApp' />,
+                element: <Navigate to='/questionAnswer' />,
             },
             {   /* 问答应用 */
-                path: '/questionAnswerApp',
+                path: '/questionAnswer',
                 handle: {
                     menuLevel: 1,
                     breadcrumbName: '问答应用',
@@ -41,28 +41,28 @@ const routerList: RouteObject[] = [
                 children: [
                     {
                         index: true,
-                        element: lazyLoad(() => import('@/pages/questionAnswerApp/list/index')),
+                        element: lazyLoad(() => import('@/pages/questionAnswer/list/index')),
                     },
                     {   /* 问答应用-创建应用 */
-                        path: '/questionAnswerApp/create',
+                        path: '/questionAnswer/create',
                         handle: {
                             menuLevel: 1,
                             breadcrumbName: '创建应用',
                         },
-                        element: lazyLoad(() => import('@/pages/questionAnswerApp/info/index')),
+                        element: lazyLoad(() => import('@/pages/questionAnswer/info/index')),
                     },
                     {   /* 问答应用-修改应用 */
-                        path: '/questionAnswerApp/modify',
+                        path: '/questionAnswer/modify',
                         handle: {
                             menuLevel: 1,
                             breadcrumbName: '修改应用',
                         },
-                        element: lazyLoad(() => import('@/pages/questionAnswerApp/info/index')),
+                        element: lazyLoad(() => import('@/pages/questionAnswer/info/index')),
                     },
                 ]
             },
             {   /* 知识库 */
-                path: '/knowledgeBase',
+                path: '/knowledgeLib',
                 handle: {
                     menuLevel: 1,
                     breadcrumbName: '知识库',
@@ -70,23 +70,23 @@ const routerList: RouteObject[] = [
                 children: [
                     {
                         index: true,
-                        element: lazyLoad(() => import('@/pages/knowledgeBase/list/index')),
+                        element: lazyLoad(() => import('@/pages/knowledgeLib/list/index')),
                     },
                     {   /* 知识库-创建知识库 */
-                        path: '/knowledgeBase/create',
+                        path: '/knowledgeLib/create',
                         handle: {
                             menuLevel: 1,
                             breadcrumbName: '创建知识库',
                         },
-                        element: lazyLoad(() => import('@/pages/knowledgeBase/info/index')),
+                        element: lazyLoad(() => import('@/pages/knowledgeLib/info/index')),
                     },
                     {   /* 知识库-修改知识库 */
-                        path: '/knowledgeBase/modify',
+                        path: '/knowledgeLib/modify',
                         handle: {
                             menuLevel: 1,
                             breadcrumbName: '修改知识库',
                         },
-                        element: lazyLoad(() => import('@/pages/knowledgeBase/info/index')),
+                        element: lazyLoad(() => import('@/pages/knowledgeLib/info/index')),
                     },
                 ]
             },