From 808f7877eb2fb499ee726c75493924e8860baf64 Mon Sep 17 00:00:00 2001 From: fantasticit Date: Thu, 30 Jun 2022 14:20:38 +0800 Subject: [PATCH] refactor: support org --- config/dev.yaml | 1 + .../admin/system-config/system/index.tsx | 1 + .../document/collaboration/index.tsx | 17 +- .../src/components/document/delete/index.tsx | 14 +- .../src/components/document/editor/editor.tsx | 69 +--- .../src/components/document/editor/users.tsx | 94 ----- .../client/src/components/members/add.tsx | 77 ++-- .../client/src/components/members/edit.tsx | 74 ++-- .../client/src/components/members/index.tsx | 68 ++-- .../components/organization/delete/index.tsx | 49 +++ .../organization/public-switcher/index.tsx | 155 +++++--- .../components/organization/setting/index.tsx | 24 +- .../organization/setting/members/add.tsx | 62 ---- .../organization/setting/members/edit.tsx | 58 --- .../setting/members/index.module.scss | 6 - .../organization/setting/members/index.tsx | 106 +----- .../organization/setting/more/index.tsx | 16 +- .../organization/switcher/index.tsx | 111 +++--- .../src/components/wiki/create/index.tsx | 1 + .../src/components/wiki/delete/index.tsx | 11 +- .../components/wiki/setting/more/index.tsx | 6 +- .../components/wiki/setting/users/index.tsx | 8 +- packages/client/src/data/document.ts | 19 +- packages/client/src/data/organization.ts | 36 +- packages/client/src/data/user.ts | 17 +- packages/client/src/data/wiki.ts | 18 +- .../src/layouts/router-header/index.tsx | 31 +- packages/client/src/pages/admin/index.tsx | 3 +- packages/client/src/pages/app/index.tsx | 93 ++++- packages/client/src/pages/index.module.scss | 11 +- packages/client/src/pages/index.tsx | 50 ++- packages/client/src/pages/register/index.tsx | 42 ++- packages/client/src/services/http-client.ts | 2 +- packages/domains/lib/api/index.d.ts | 1 + packages/domains/lib/api/index.js | 1 + packages/domains/lib/api/organization.d.ts | 8 + packages/domains/lib/api/organization.js | 8 + packages/domains/lib/api/system.d.ts | 7 + packages/domains/lib/api/system.js | 10 + packages/domains/lib/models/organization.js | 31 -- packages/domains/lib/models/system.d.ts | 1 + packages/domains/lib/models/user.d.ts | 9 - packages/domains/lib/models/user.js | 11 +- packages/domains/lib/models/wiki.d.ts | 23 -- packages/domains/lib/models/wiki.js | 19 +- packages/domains/lib/util.d.ts | 8 +- packages/domains/lib/util.js | 11 +- packages/domains/src/api/index.ts | 1 + packages/domains/src/api/organization.ts | 9 + packages/domains/src/api/system.ts | 7 + packages/domains/src/api/user.ts | 2 - packages/domains/src/models/organization.ts | 36 -- packages/domains/src/models/system.ts | 1 + packages/domains/src/models/user.ts | 10 - packages/domains/src/models/wiki.ts | 26 -- packages/domains/src/util.ts | 13 +- packages/server/src/app.module.ts | 10 - packages/server/src/constants/index.ts | 1 + .../src/controllers/document.controller.ts | 19 +- .../controllers/organization.controller.ts | 22 +- .../src/controllers/system.controller.ts | 10 +- .../server/src/controllers/wiki.controller.ts | 46 +-- packages/server/src/dtos/create-user.dto.ts | 6 +- packages/server/src/dtos/doc-auth.dto.ts | 15 - packages/server/src/dtos/login-user.dto.ts | 2 +- .../server/src/dtos/organization-auth.dto.ts | 12 - .../server/src/dtos/organization-user.dto.ts | 10 - packages/server/src/dtos/wiki-user.dto.ts | 10 - packages/server/src/entities/system.entity.ts | 7 +- packages/server/src/entities/user.entity.ts | 10 +- packages/server/src/entities/verify.entity.ts | 27 -- packages/server/src/entities/view.entity.ts | 34 -- packages/server/src/modules/comment.module.ts | 2 + .../server/src/modules/organization.module.ts | 2 + packages/server/src/modules/verify.module.ts | 4 +- packages/server/src/modules/view.module.ts | 3 - packages/server/src/services/auth.service.ts | 133 +++++-- .../src/services/collaboration.service.ts | 35 +- .../server/src/services/comment.service.ts | 127 ++++--- .../server/src/services/document.service.ts | 282 ++++++-------- .../server/src/services/message.service.ts | 6 +- .../src/services/organization.service.ts | 42 ++- packages/server/src/services/star.service.ts | 16 +- .../server/src/services/system.service.ts | 20 +- .../server/src/services/template.service.ts | 9 +- packages/server/src/services/user.service.ts | 42 +-- .../server/src/services/verify.service.ts | 51 ++- packages/server/src/services/view.service.ts | 8 +- packages/server/src/services/wiki.service.ts | 346 +++++------------- 89 files changed, 1249 insertions(+), 1723 deletions(-) delete mode 100644 packages/client/src/components/document/editor/users.tsx create mode 100644 packages/client/src/components/organization/delete/index.tsx delete mode 100644 packages/client/src/components/organization/setting/members/add.tsx delete mode 100644 packages/client/src/components/organization/setting/members/edit.tsx delete mode 100644 packages/client/src/components/organization/setting/members/index.module.scss create mode 100644 packages/domains/lib/api/system.d.ts create mode 100644 packages/domains/lib/api/system.js create mode 100644 packages/domains/src/api/system.ts delete mode 100644 packages/server/src/dtos/doc-auth.dto.ts delete mode 100644 packages/server/src/dtos/organization-auth.dto.ts delete mode 100644 packages/server/src/dtos/organization-user.dto.ts delete mode 100644 packages/server/src/dtos/wiki-user.dto.ts delete mode 100644 packages/server/src/entities/verify.entity.ts delete mode 100644 packages/server/src/entities/view.entity.ts diff --git a/config/dev.yaml b/config/dev.yaml index 1b7e340..0a8bd3a 100644 --- a/config/dev.yaml +++ b/config/dev.yaml @@ -23,6 +23,7 @@ server: enableRateLimit: true # 是否限流 rateLimitWindowMs: 60000 # 限流时间 rateLimitMax: 1000 # 单位限流时间内单个 ip 最大访问数量 + enableEmailVerify: false email: # 邮箱服务,参考 http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html?servCode=6010376 获取 SMTP 配置 host: '' port: 465 diff --git a/packages/client/src/components/admin/system-config/system/index.tsx b/packages/client/src/components/admin/system-config/system/index.tsx index d4c539b..2020231 100644 --- a/packages/client/src/components/admin/system-config/system/index.tsx +++ b/packages/client/src/components/admin/system-config/system/index.tsx @@ -30,6 +30,7 @@ export const System = () => {
+ - - + {children} + ); }; diff --git a/packages/client/src/components/members/edit.tsx b/packages/client/src/components/members/edit.tsx index cd72139..5d25d0d 100644 --- a/packages/client/src/components/members/edit.tsx +++ b/packages/client/src/components/members/edit.tsx @@ -1,58 +1,44 @@ -import { Banner, Button, Modal, Select } from '@douyinfe/semi-ui'; +import { Banner, Popconfirm, Select, Toast } from '@douyinfe/semi-ui'; import { AuthEnum, AuthEnumArray, IAuth, IUser } from '@think/domains'; -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useState } from 'react'; interface IProps { - visible: boolean; - toggleVisible: (arg) => void; - currentUser: { user: IUser; auth: IAuth }; - onOk: (arg) => any; + userWithAuth: { user: IUser; auth: IAuth }; + updateUser: (arg) => any; } -export const EditUser: React.FC = ({ visible, toggleVisible, currentUser, onOk }) => { +export const EditUser: React.FC = ({ userWithAuth, updateUser, children }) => { const [userAuth, setUserAuth] = useState(AuthEnum.noAccess); const handleOk = useCallback(() => { - onOk(userAuth).then(() => { - setUserAuth(AuthEnum.noAccess); - toggleVisible(false); + return updateUser({ userName: userWithAuth.user.name, userAuth }).then(() => { + Toast.success('操作成功'); }); - }, [onOk, userAuth, toggleVisible]); - - useEffect(() => { - if (!visible) { - setUserAuth(AuthEnum.noAccess); - } - }, [visible]); + }, [updateUser, userAuth, userWithAuth]); return ( - toggleVisible(false)} - maskClosable={false} - style={{ maxWidth: '96vw' }} - footer={null} + + {[AuthEnum.creator, AuthEnum.admin].includes(userAuth) ? ( + + ) : null} + {} + + + } + onConfirm={handleOk} > -
- {[AuthEnum.creator, AuthEnum.admin].includes(userAuth) ? ( - - ) : null} - {} - - -
-
+ {children} + ); }; diff --git a/packages/client/src/components/members/index.tsx b/packages/client/src/components/members/index.tsx index d39933b..b034d72 100644 --- a/packages/client/src/components/members/index.tsx +++ b/packages/client/src/components/members/index.tsx @@ -1,11 +1,9 @@ import { IconDelete, IconEdit } from '@douyinfe/semi-icons'; import { Banner, Button, Popconfirm, Table, Typography } from '@douyinfe/semi-ui'; -import { AuthEnumTextMap, IOrganization } from '@think/domains'; +import { AuthEnumTextMap } from '@think/domains'; import { DataRender } from 'components/data-render'; import { LocaleTime } from 'components/locale-time'; -import { useOrganizationMembers } from 'data/organization'; -import { useToggle } from 'hooks/use-toggle'; -import React, { useState } from 'react'; +import React from 'react'; import { AddUser } from './add'; import { EditUser } from './edit'; @@ -14,33 +12,17 @@ import styles from './index.module.scss'; interface IProps { id: string; hook: any; + descriptions?: Array; } const { Title, Paragraph } = Typography; const { Column } = Table; -export const Members: React.FC = ({ id, hook }) => { - const { data, loading, error, addUser, updateUser, deleteUser } = hook(id); - const [visible, toggleVisible] = useToggle(false); - const [editVisible, toggleEditVisible] = useToggle(false); - const [currentUser, setCurrentUser] = useState(null); - - const editUser = (user) => { - setCurrentUser(user); - toggleEditVisible(true); - }; - - const handleEdit = (userAuth) => { - return updateUser({ userName: currentUser.user.name, userAuth }).then(() => { - setCurrentUser(null); - }); - }; - - console.log(data); +export const Members: React.FC = ({ id, hook, descriptions }) => { + const { data, loading, error, page, pageSize, setPage, addUser, updateUser, deleteUser } = hook(id); return (
-
{/* */}
= ({ id, hook }) => { title={权限说明} description={
- 创建者:管理组织内所有知识库、文档,可删除组织 - 管理员:管理组织内所有知识库、文档,不可删除组织 - 成员:可访问组织内所有知识库、文档,不可删除组织 + {descriptions && descriptions.length ? ( + descriptions.map((desc) => { + return {desc}; + }) + ) : ( + <> + 创建者:管理组织内所有知识库、文档,可删除组织 + 管理员:管理组织内所有知识库、文档,不可删除组织 + 成员:可访问组织内所有知识库、文档,不可删除组织 + + )}
} /> -
- + + +
- +
= ({ id, hook }) => { align="center" render={(_, data) => ( <> - - - - ); -}; diff --git a/packages/client/src/components/organization/setting/members/edit.tsx b/packages/client/src/components/organization/setting/members/edit.tsx deleted file mode 100644 index cd72139..0000000 --- a/packages/client/src/components/organization/setting/members/edit.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Banner, Button, Modal, Select } from '@douyinfe/semi-ui'; -import { AuthEnum, AuthEnumArray, IAuth, IUser } from '@think/domains'; -import React, { useCallback, useEffect, useState } from 'react'; - -interface IProps { - visible: boolean; - toggleVisible: (arg) => void; - currentUser: { user: IUser; auth: IAuth }; - onOk: (arg) => any; -} - -export const EditUser: React.FC = ({ visible, toggleVisible, currentUser, onOk }) => { - const [userAuth, setUserAuth] = useState(AuthEnum.noAccess); - - const handleOk = useCallback(() => { - onOk(userAuth).then(() => { - setUserAuth(AuthEnum.noAccess); - toggleVisible(false); - }); - }, [onOk, userAuth, toggleVisible]); - - useEffect(() => { - if (!visible) { - setUserAuth(AuthEnum.noAccess); - } - }, [visible]); - - return ( - toggleVisible(false)} - maskClosable={false} - style={{ maxWidth: '96vw' }} - footer={null} - > -
- {[AuthEnum.creator, AuthEnum.admin].includes(userAuth) ? ( - - ) : null} - {} - - -
-
- ); -}; diff --git a/packages/client/src/components/organization/setting/members/index.module.scss b/packages/client/src/components/organization/setting/members/index.module.scss deleted file mode 100644 index 7eb36ff..0000000 --- a/packages/client/src/components/organization/setting/members/index.module.scss +++ /dev/null @@ -1,6 +0,0 @@ -.wrap { - > header { - display: flex; - justify-content: flex-end; - } -} diff --git a/packages/client/src/components/organization/setting/members/index.tsx b/packages/client/src/components/organization/setting/members/index.tsx index 22faab7..e838107 100644 --- a/packages/client/src/components/organization/setting/members/index.tsx +++ b/packages/client/src/components/organization/setting/members/index.tsx @@ -1,110 +1,12 @@ -import { IconDelete, IconEdit } from '@douyinfe/semi-icons'; -import { Banner, Button, Popconfirm, Table, Typography } from '@douyinfe/semi-ui'; -import { AuthEnumTextMap, IOrganization } from '@think/domains'; -import { DataRender } from 'components/data-render'; -import { LocaleTime } from 'components/locale-time'; +import { IOrganization } from '@think/domains'; +import { Members } from 'components/members'; import { useOrganizationMembers } from 'data/organization'; -import { useToggle } from 'hooks/use-toggle'; -import React, { useState } from 'react'; - -import { AddUser } from './add'; -import { EditUser } from './edit'; -import styles from './index.module.scss'; +import React from 'react'; interface IProps { organizationId: IOrganization['id']; } -const { Title, Paragraph } = Typography; -const { Column } = Table; - export const OrganizationMembers: React.FC = ({ organizationId }) => { - const { data, loading, error, refresh, addUser, updateUser, deleteUser } = useOrganizationMembers(organizationId); - const [visible, toggleVisible] = useToggle(false); - const [editVisible, toggleEditVisible] = useToggle(false); - const [currentUser, setCurrentUser] = useState(null); - - const editUser = (user) => { - setCurrentUser(user); - toggleEditVisible(true); - }; - - const handleEdit = (userAuth) => { - return updateUser({ userName: currentUser.user.name, userAuth }).then(() => { - setCurrentUser(null); - }); - }; - - return ( -
-
{/* */}
- ( -
- 权限说明} - description={ -
- 创建者:管理组织内所有知识库、文档,可删除组织 - 管理员:管理组织内所有知识库、文档,不可删除组织 - 成员:可访问组织内所有知识库、文档,不可删除组织 -
- } - /> - -
- -
-
- - AuthEnumTextMap[auth]} - /> - } - /> - ( - <> -
-
- )} - /> - - - - - ); + return ; }; diff --git a/packages/client/src/components/organization/setting/more/index.tsx b/packages/client/src/components/organization/setting/more/index.tsx index e699410..086c012 100644 --- a/packages/client/src/components/organization/setting/more/index.tsx +++ b/packages/client/src/components/organization/setting/more/index.tsx @@ -1,27 +1,23 @@ import { Banner, Button, Typography } from '@douyinfe/semi-ui'; -import { WorkspaceDeletor } from 'components/wiki/delete'; - -interface IProps { - wikiId: string; -} +import { OrganizationDeletor } from 'components/organization/delete'; const { Paragraph } = Typography; -export const More: React.FC = ({ wikiId }) => { +export const More = ({ organizationId }) => { return (
删除知识库及内部所有文档,不可恢复!} + description={删除组织及内部所有知识库以及文档,不可恢复!} style={{ marginBottom: 16 }} /> - + - +
); }; diff --git a/packages/client/src/components/organization/switcher/index.tsx b/packages/client/src/components/organization/switcher/index.tsx index 1ec59e3..ef8daff 100644 --- a/packages/client/src/components/organization/switcher/index.tsx +++ b/packages/client/src/components/organization/switcher/index.tsx @@ -1,12 +1,10 @@ -import { IconAppCenter, IconSmallTriangleDown } from '@douyinfe/semi-icons'; +import { IconAppCenter, IconApps, IconSmallTriangleDown } from '@douyinfe/semi-icons'; import { Button, Dropdown, Space, Typography } from '@douyinfe/semi-ui'; import { Avatar } from '@douyinfe/semi-ui'; import { DataRender } from 'components/data-render'; import { useOrganizationDetail, useUserOrganizations } from 'data/organization'; import { useRouterQuery } from 'hooks/use-router-query'; import Link from 'next/link'; -import Router from 'next/router'; -import { useCallback } from 'react'; import styles from './index.module.scss'; @@ -22,10 +20,6 @@ export const OrganizationSwitcher = () => { error: userOrganizationsError, } = useUserOrganizations(); - const gotoCreate = useCallback(() => { - Router.push(`/app/org/create`); - }, []); - return ( { normalContent={() => { return ( - {(userOrganizations || []).map((org) => { - return ( - - - - - + {userOrganizations.map((org) => { + return ( + + - {org.name} - - - - - ); - })} - - - - - - - - 新建组织 - - + + + + {org.name} + + + + + ); + })} + + + ) : null} + + + + + + + + + 前往广场 + + + + + + + + + + + + + + + 新建组织 + + + + ); diff --git a/packages/client/src/components/wiki/create/index.tsx b/packages/client/src/components/wiki/create/index.tsx index f865016..d66d8a6 100644 --- a/packages/client/src/components/wiki/create/index.tsx +++ b/packages/client/src/components/wiki/create/index.tsx @@ -27,6 +27,7 @@ export const WikiCreator: React.FC = ({ visible, toggleVisible }) => { }); }); }; + const handleCancel = () => { toggleVisible(false); }; diff --git a/packages/client/src/components/wiki/delete/index.tsx b/packages/client/src/components/wiki/delete/index.tsx index a24b001..a1c189f 100644 --- a/packages/client/src/components/wiki/delete/index.tsx +++ b/packages/client/src/components/wiki/delete/index.tsx @@ -1,6 +1,7 @@ import { IconDelete } from '@douyinfe/semi-icons'; import { Modal, Space, Typography } from '@douyinfe/semi-ui'; import { useOwnWikis } from 'data/wiki'; +import { useRouterQuery } from 'hooks/use-router-query'; import Router from 'next/router'; import React, { useCallback } from 'react'; @@ -11,8 +12,9 @@ interface IProps { const { Text } = Typography; -export const WorkspaceDeletor: React.FC = ({ wikiId, onDelete, children }) => { - const { deletWiki } = useOwnWikis(); +export const WikiDeletor: React.FC = ({ wikiId, onDelete, children }) => { + const { organizationId } = useRouterQuery<{ organizationId: string }>(); + const { deletWiki } = useOwnWikis(organizationId); const deleteAction = useCallback(() => { Modal.error({ @@ -23,7 +25,8 @@ export const WorkspaceDeletor: React.FC = ({ wikiId, onDelete, children onDelete ? onDelete() : Router.push({ - pathname: `/wiki`, + pathname: `/app/org/[organizationId]`, + query: { organizationId }, }); }); }, @@ -32,7 +35,7 @@ export const WorkspaceDeletor: React.FC = ({ wikiId, onDelete, children }, style: { maxWidth: '96vw' }, }); - }, [wikiId, deletWiki, onDelete]); + }, [organizationId, wikiId, deletWiki, onDelete]); return ( diff --git a/packages/client/src/components/wiki/setting/more/index.tsx b/packages/client/src/components/wiki/setting/more/index.tsx index e699410..43079f4 100644 --- a/packages/client/src/components/wiki/setting/more/index.tsx +++ b/packages/client/src/components/wiki/setting/more/index.tsx @@ -1,5 +1,5 @@ import { Banner, Button, Typography } from '@douyinfe/semi-ui'; -import { WorkspaceDeletor } from 'components/wiki/delete'; +import { WikiDeletor } from 'components/wiki/delete'; interface IProps { wikiId: string; @@ -17,11 +17,11 @@ export const More: React.FC = ({ wikiId }) => { description={删除知识库及内部所有文档,不可恢复!} style={{ marginBottom: 16 }} /> - + - + ); }; diff --git a/packages/client/src/components/wiki/setting/users/index.tsx b/packages/client/src/components/wiki/setting/users/index.tsx index 9007ca8..ded43f0 100644 --- a/packages/client/src/components/wiki/setting/users/index.tsx +++ b/packages/client/src/components/wiki/setting/users/index.tsx @@ -7,5 +7,11 @@ interface IProps { } export const Users: React.FC = ({ wikiId }) => { - return ; + return ( + + ); }; diff --git a/packages/client/src/data/document.ts b/packages/client/src/data/document.ts index 55bf714..a814737 100644 --- a/packages/client/src/data/document.ts +++ b/packages/client/src/data/document.ts @@ -65,11 +65,20 @@ export type DocAuth = { * @param cookie * @returns */ -export const getDocumentMembers = (documentId, cookie = null): Promise> => { +export const getDocumentMembers = ( + documentId, + page, + pageSize, + cookie = null +): Promise> => { return HttpClient.request({ method: DocumentApiDefinition.getMemberById.method, url: DocumentApiDefinition.getMemberById.client(documentId), cookie, + params: { + page, + pageSize, + }, }); }; @@ -79,9 +88,11 @@ export const getDocumentMembers = (documentId, cookie = null): Promise>) => { + const [pageSize] = useState(12); + const [page, setPage] = useState(1); const { data, error, isLoading, refetch } = useQuery( - DocumentApiDefinition.getMemberById.client(documentId), - () => getDocumentMembers(documentId), + [DocumentApiDefinition.getMemberById.client(documentId), page], + () => getDocumentMembers(documentId, page, pageSize), options ); @@ -124,7 +135,7 @@ export const useDoumentMembers = (documentId, options?: UseQueryOptions { [refetch, id] ); - return { data, error, loading: isLoading, refresh: refetch, update }; + const deleteOrganization = useCallback(async () => { + const res = await HttpClient.request({ + method: OrganizationApiDefinition.deleteOrganization.method, + url: OrganizationApiDefinition.deleteOrganization.client(id), + }); + refetch(); + return res; + }, [refetch, id]); + + return { data, error, loading: isLoading, refresh: refetch, update, deleteOrganization }; }; export const getOrganizationMembers = ( id, + page = 1, + pageSize, cookie = null ): Promise<{ data: Array<{ auth: IAuth; user: IUser }>; total: number }> => { return HttpClient.request({ method: OrganizationApiDefinition.getMembers.method, url: OrganizationApiDefinition.getMembers.client(id), cookie, + params: { + page, + pageSize, + }, }); }; @@ -127,8 +142,10 @@ export const getOrganizationMembers = ( * @returns */ export const useOrganizationMembers = (id) => { - const { data, error, isLoading, refetch } = useQuery(OrganizationApiDefinition.getMembers.client(id), () => - getOrganizationMembers(id) + const [pageSize] = useState(12); + const [page, setPage] = useState(1); + const { data, error, isLoading, refetch } = useQuery([OrganizationApiDefinition.getMembers.client(id), page], () => + getOrganizationMembers(id, page, pageSize) ); const addUser = useCallback( @@ -170,5 +187,16 @@ export const useOrganizationMembers = (id) => { [refetch, id] ); - return { data, error, loading: isLoading, refresh: refetch, addUser, updateUser, deleteUser }; + return { + data, + error, + loading: isLoading, + page, + pageSize, + setPage, + refresh: refetch, + addUser, + updateUser, + deleteUser, + }; }; diff --git a/packages/client/src/data/user.ts b/packages/client/src/data/user.ts index d52eb0d..0c0778f 100644 --- a/packages/client/src/data/user.ts +++ b/packages/client/src/data/user.ts @@ -1,5 +1,5 @@ import { Toast } from '@douyinfe/semi-ui'; -import { ILoginUser, ISystemConfig, IUser, UserApiDefinition } from '@think/domains'; +import { ILoginUser, ISystemConfig, IUser, SystemApiDefinition, UserApiDefinition } from '@think/domains'; import { getStorage, setStorage } from 'helpers/storage'; import { useAsyncLoading } from 'hooks/use-async-loading'; import Router, { useRouter } from 'next/router'; @@ -138,10 +138,17 @@ export const useUser = () => { }; }; -/** - * 获取验证码 - * @returns - */ +export const useSystemPublicConfig = () => { + const { data, error, isLoading, refetch } = useQuery(SystemApiDefinition.getPublicConfig.client(), () => + HttpClient.request({ + method: SystemApiDefinition.getPublicConfig.method, + url: SystemApiDefinition.getPublicConfig.client(), + }) + ); + + return { data, error, loading: isLoading, refresh: refetch }; +}; + export const useSystemConfig = () => { const { data, error, isLoading, refetch } = useQuery(UserApiDefinition.getSystemConfig.client(), () => HttpClient.request({ diff --git a/packages/client/src/data/wiki.ts b/packages/client/src/data/wiki.ts index 1c6665b..86ef1bf 100644 --- a/packages/client/src/data/wiki.ts +++ b/packages/client/src/data/wiki.ts @@ -1,4 +1,4 @@ -import { IAuth, IDocument, IUser, IWiki, IWikiUser, WikiApiDefinition } from '@think/domains'; +import { IAuth, IDocument, IUser, IWiki, WikiApiDefinition } from '@think/domains'; import { event, REFRESH_TOCS } from 'event'; import { useCallback, useEffect, useState } from 'react'; import { useQuery } from 'react-query'; @@ -97,7 +97,7 @@ export const useOwnWikis = (organizationId) => { ); /** - * 删除文档 + * 删除知识库 * @param id * @returns */ @@ -318,12 +318,18 @@ export const useWikiDocuments = (wikiId) => { */ export const getWikiMembers = ( wikiId, + page, + pageSize, cookie = null ): Promise<{ data: Array<{ auth: IAuth; user: IUser }>; total: number }> => { return HttpClient.request({ method: WikiApiDefinition.getMemberById.method, url: WikiApiDefinition.getMemberById.client(wikiId), cookie, + params: { + page, + pageSize, + }, }); }; @@ -333,8 +339,10 @@ export const getWikiMembers = ( * @returns */ export const useWikiMembers = (wikiId) => { - const { data, error, isLoading, refetch } = useQuery(WikiApiDefinition.getMemberById.client(wikiId), () => - getWikiMembers(wikiId) + const [pageSize] = useState(12); + const [page, setPage] = useState(1); + const { data, error, isLoading, refetch } = useQuery([WikiApiDefinition.getMemberById.client(wikiId), page], () => + getWikiMembers(wikiId, page, pageSize) ); const addUser = useCallback( @@ -376,7 +384,7 @@ export const useWikiMembers = (wikiId) => { [refetch, wikiId] ); - return { data, loading: isLoading, error, addUser, updateUser, deleteUser }; + return { data, loading: isLoading, error, page, pageSize, setPage, addUser, updateUser, deleteUser }; }; /** diff --git a/packages/client/src/layouts/router-header/index.tsx b/packages/client/src/layouts/router-header/index.tsx index d479f0d..f5efde8 100644 --- a/packages/client/src/layouts/router-header/index.tsx +++ b/packages/client/src/layouts/router-header/index.tsx @@ -1,11 +1,12 @@ -import { Layout as SemiLayout, Nav, Space } from '@douyinfe/semi-ui'; +import { Button, Layout as SemiLayout, Nav, Space } from '@douyinfe/semi-ui'; import { Message } from 'components/message'; import { OrganizationPublicSwitcher } from 'components/organization/public-switcher'; import { Theme } from 'components/theme'; import { User } from 'components/user'; +import { useUser } from 'data/user'; import { IsOnMobile } from 'hooks/use-on-mobile'; import Router, { useRouter } from 'next/router'; -import React from 'react'; +import React, { useCallback } from 'react'; const { Header: SemiHeader } = SemiLayout; @@ -28,12 +29,26 @@ const menus = [ }); }, }, + { + itemKey: '/template', + text: '模板', + onClick: () => { + Router.push({ + pathname: `/template`, + }); + }, + }, ]; export const RouterHeader: React.FC = () => { + const { user } = useUser(); const { pathname } = useRouter(); const { isMobile } = IsOnMobile.useHook(); + const gotoApp = useCallback(() => { + Router.push(`/app`); + }, []); + return ( {isMobile ? ( @@ -47,6 +62,11 @@ export const RouterHeader: React.FC = () => { } footer={ + {user && ( + + )} @@ -65,7 +85,12 @@ export const RouterHeader: React.FC = () => { items={menus} footer={ - + {user && ( + + )} + {user && } diff --git a/packages/client/src/pages/admin/index.tsx b/packages/client/src/pages/admin/index.tsx index 93d9851..15b4bac 100644 --- a/packages/client/src/pages/admin/index.tsx +++ b/packages/client/src/pages/admin/index.tsx @@ -1,4 +1,4 @@ -import { Typography } from '@douyinfe/semi-ui'; +import { Banner, Typography } from '@douyinfe/semi-ui'; import { SystemConfig } from 'components/admin/system-config'; import { Seo } from 'components/seo'; import { useUser } from 'data/user'; @@ -37,6 +37,7 @@ const Page: NextPage = () => { 管理后台 + ) : ( diff --git a/packages/client/src/pages/app/index.tsx b/packages/client/src/pages/app/index.tsx index a8e2e46..cd8f481 100644 --- a/packages/client/src/pages/app/index.tsx +++ b/packages/client/src/pages/app/index.tsx @@ -1,32 +1,103 @@ -import { Spin } from '@douyinfe/semi-ui'; -import { usePeronalOrganization } from 'data/organization'; +import { Avatar, Button, Table, Typography } from '@douyinfe/semi-ui'; +import { IOrganization } from '@think/domains'; +import { DataRender } from 'components/data-render'; +import { LocaleTime } from 'components/locale-time'; +import { usePeronalOrganization, useUserOrganizations } from 'data/organization'; import { SingleColumnLayout } from 'layouts/single-column'; +import Link from 'next/link'; import Router from 'next/router'; -import { useEffect } from 'react'; +import { useCallback, useEffect } from 'react'; + +const { Title, Paragraph } = Typography; +const { Column } = Table; const Page = () => { const { data: organization } = usePeronalOrganization(); + const { + data: userOrganizations, + loading: userOrganizationsLoading, + error: userOrganizationsError, + } = useUserOrganizations(); + + const gotoCreate = useCallback(() => { + Router.push({ + pathname: '/app/org/create', + }); + }, []); useEffect(() => { + if (userOrganizations && userOrganizations.length) return; if (!organization) return; Router.replace({ pathname: `/app/org/[organizationId]`, query: { organizationId: organization.id }, }); - }, [organization]); + }, [organization, userOrganizations]); return (
-
- +
+ + 组织列表 + +
+ ( + <> + + { + return ( + + + + + + {org.name} + + + + + ); + }} + /> + } + /> +
+ + )} + />
); diff --git a/packages/client/src/pages/index.module.scss b/packages/client/src/pages/index.module.scss index 4708e1b..cd7bf1d 100644 --- a/packages/client/src/pages/index.module.scss +++ b/packages/client/src/pages/index.module.scss @@ -1,12 +1,3 @@ -.wikiItemWrap { - padding: 12px 16px !important; - margin: 8px 2px; - cursor: pointer; - background-color: var(--semi-color-bg-2); - border: 1px solid var(--semi-color-border) !important; -} - -.titleWrap { +.wrap { display: flex; - justify-content: space-between; } diff --git a/packages/client/src/pages/index.tsx b/packages/client/src/pages/index.tsx index f8671e9..00fb336 100644 --- a/packages/client/src/pages/index.tsx +++ b/packages/client/src/pages/index.tsx @@ -1,35 +1,51 @@ import { Button, Typography } from '@douyinfe/semi-ui'; import { Seo } from 'components/seo'; +import { toLogin, useUser } from 'data/user'; import { SingleColumnLayout } from 'layouts/single-column'; import type { NextPage } from 'next'; import Router from 'next/router'; import React, { useCallback } from 'react'; -const { Title } = Typography; +import styles from './index.module.scss'; + +const { Title, Paragraph } = Typography; const Page: NextPage = () => { - const gotoApp = useCallback(() => { - Router.push(`/app`); + const { user } = useUser(); + + const start = useCallback(() => { + if (user) { + Router.push(`/app`); + } else { + toLogin(); + } + }, [user]); + + const toGithub = useCallback(() => { + window.open('https://github.com/fantasticit/think'); }, []); return (
-
- - 主页 - -
-
- +
+
+
+ 云策文档 + + 云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。 + +
+
+ + +
+
diff --git a/packages/client/src/pages/register/index.tsx b/packages/client/src/pages/register/index.tsx index e414e52..37ae2b9 100644 --- a/packages/client/src/pages/register/index.tsx +++ b/packages/client/src/pages/register/index.tsx @@ -2,7 +2,7 @@ import { Button, Col, Form, Layout, Modal, Row, Space, Toast, Typography } from import { Author } from 'components/author'; import { LogoImage, LogoText } from 'components/logo'; import { Seo } from 'components/seo'; -import { useRegister, useVerifyCode } from 'data/user'; +import { useRegister, useSystemPublicConfig, useVerifyCode } from 'data/user'; import { isEmail } from 'helpers/validator'; import { useInterval } from 'hooks/use-interval'; import { useRouterQuery } from 'hooks/use-router-query'; @@ -24,6 +24,7 @@ const Page = () => { const [hasSendVerifyCode, toggleHasSendVerifyCode] = useToggle(false); const [countDown, setCountDown] = useState(0); const { register, loading } = useRegister(); + const { data: systemConfig } = useSystemPublicConfig(); const { sendVerifyCode, loading: sendVerifyCodeLoading } = useVerifyCode(); const onFormChange = useCallback((formState) => { @@ -133,22 +134,29 @@ const Page = () => { ]} /> - - - - - - - - + {systemConfig && systemConfig.enableEmailVerify ? ( + + + + + + + + + ) : null}