diff --git a/.gitignore b/.gitignore
index fb92985..44719a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@ tsconfig.tsbuildinfo
scripts/update.sh
output
+runtime
diff --git a/Dockerfile b/Dockerfile
index 95f5c87..6ad5a10 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,18 +1,13 @@
FROM node:18-alpine as builder
-COPY . /app/
+COPY . /app/
WORKDIR /app
-ARG EIP=mrdoc.fun
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
RUN npm config set registry https://registry.npmmirror.com
RUN npm i -g pm2 @nestjs/cli pnpm
-RUN apk --no-cache add bash
-RUN sed -i "s/localhost/$EIP/g" /app/docker/prod-sample.yaml
-RUN cp -f /app/docker/prod-sample.yaml /app/config/prod.yaml
+RUN apk --no-cache add bash
RUN bash build-output.sh
-
FROM node:18-alpine as prod
-LABEL maintainer="www.mrdoc.fun"
ENV TZ=Asia/Shanghai
COPY --from=builder /app/docker/* /app/docker/
COPY --from=builder /app/output/ /app/
@@ -20,9 +15,9 @@ COPY --from=builder /app/output/ /app/
WORKDIR /app
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
RUN npm config set registry https://registry.npmmirror.com
-RUN set -x \
+RUN set -x \
&& apk update \
- && apk add --no-cache tzdata redis \
+ && apk add --no-cache tzdata redis \
&& chmod +x /app/docker/start.sh \
&& npm i -g pm2 @nestjs/cli pnpm \
&& rm -rf /var/cache/apk/*
diff --git a/README.md b/README.md
index 765ccee..fa4bbdd 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Think 是一款开源知识管理工具。通过独立的知识库空间,结
- `nest.js`:服务端框架
- `tiptap`:编辑器及文档协作
-可访问[云策文档帮助中心](https://think.codingit.cn/share/wiki/eb520cdf-aa4b-4af2-ae4a-7140e21403ab),查看更多功能文档。
+可访问[云策文档帮助中心](https://think.codingit.cn/share/wiki/JtXHW2BjrQ6G),查看更多功能文档。
## 链接
@@ -19,156 +19,20 @@ Think 是一款开源知识管理工具。通过独立的知识库空间,结
欢迎进群交流。
-
-
+
## 预览
-![知识库](http://wipi.oss-cn-shanghai.aliyuncs.com/2022-02-20/YN67GM4VQMBTZFZ88TYP8X/image.png)
-![新建文档](http://wipi.oss-cn-shanghai.aliyuncs.com/2022-02-20/YN67GM4VQMBTZFZ88TYPQX/image.png)
-![编辑器](http://wipi.oss-cn-shanghai.aliyuncs.com/2022-02-20/YN67GM4VQMBTZFZ88TYPZX/image.png)
+
+ 查看预览图
+
+
+
+
-## 项目结构
+## 项目开发
-本项目依赖 pnpm 使用 monorepo 形式进行代码组织,分包如下:
-
-- `@think/config`: 客户端、服务端、OSS、MySQL、Redis 等配置管理
-- `@think/domains`:领域模型数据定义
-- `@think/constants`:常量配置
-- `@think/server`:服务端
-- `@think/client`:客户端
-
-## 项目依赖
-
-- nodejs ≥ 16.5
-- pnpm
-- pm2
-- mysql ≥ 5.7
-- redis (可选)
-
-依赖安装命令: `npm i -g pm2 @nestjs/cli pnpm`
-
-
-#### 数据库
-
-首先安装 `MySQL`,推荐使用 docker 进行安装。
-
-```bash
-docker image pull mysql:5.7
-# m1 的 mac 可以用:docker image pull --platform linux/x86_64 mysql:5.7
-docker run -d --restart=always --name think -p 3306:3306 -e MYSQL_DATABASE=think -e MYSQL_ROOT_PASSWORD=root mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
-```
-
-#### 可选:Redis
-
-如果需要文档版本服务,请在根目录 `yaml` 配置中进行 `db.redis` 的配置。
-
-```
-docker pull redis:latest
-docker run --name think-redis -p 6379:6379 -d redis --appendonly yes --requirepass "root"
-```
-
-## Docker-compose 一键构建安装
-
-- 实测腾讯轻量云 2C4G 机器构建需 8 分钟左右
-
-**请注意修改 `docker-compose.yml` 中的 `EIP` 参数,否则无法正常使用!!!**
-
-
-```
-# 首次安装
-git clone https://github.com/fantasticit/think.git
-cd think
-docker-compose up -d
-
-# 二次更新升级
-cd think
-git pull
-docker-compose build
-docker-compose up -d
-
-# FAQ
-如遇二次更新有问题,请更新代码重新构建,然后删除本地配置文件并重启容器.
-如果还不能解决,1.有能力可自行解决|2.等待更新|3.去mrdoc.fun站点留言
-```
-
-然后访问 `http://ip:5001` 即可.
-
-
-
-## 手动安装教程
-
-- 前台页面地址:`http://localhost:5001`
-- 服务接口地址:`http://localhost:5002`
-- 协作接口地址:`http://localhost:5003`
-
-如需修改配置,开发环境编辑 `config/dev.yaml`。生产环境编辑 `config/prod.yaml` (如没有,可复制开发环境的配置修改即可.)
-
-### 本地源代码运行(开发环境)
-
-
-```bash
-git clone https://github.com/fantasticit/think.git
-cd think
-pnpm install
-pnpm run dev
-```
-
-然后访问 `http://ip:5001` 即可.
-
-
-
-### 本地源代码运行(生产环境)
-
-生产环境部署的脚本如下:
-
-```bash
-git clone https://github.com/fantasticit/think.git
-cd think
-pnpm install
-pnpm run build
-pnpm run pm2
-
-pm2 startup
-pm2 save
-```
-
-### nginx 配置参考
-
-采用反向代理进行 `nginx` 配置,**同时设置 `proxy_set_header X-Real-IP $remote_addr;` 以便服务端获取到真实 ip 地址**。
-
-```bash
-upstream wipi_client {
- server 127.0.0.1:3000;
- keepalive 64;
-}
-
-# http -> https 重定向
-server {
- listen 80;
- server_name 域名;
- rewrite ^(.*)$ https://$host$1 permanent;
-}
-
-server {
- listen 443 ssl;
- server_name 域名;
- ssl_certificate 证书存放路径;
- ssl_certificate_key 证书存放路径;
-
- location / {
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header Host $host;
- proxy_set_header X-Nginx-Proxy true;
- proxy_cache_bypass $http_upgrade;
- proxy_pass http://wipi_client; #反向代理
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
-}
-```
+[项目开发说明](./let-us-start.md)。
## 自动化部署
@@ -176,24 +40,17 @@ server {
参考:[webhook](https://github.com/adnanh/webhook/blob/master/docs/Hook-Examples.md#incoming-github-webhook)
-## 商用
-
-如需商用,请联系作者,取得授权后可商用。
-
## 赞助
如果这个项目对您有帮助,并且您希望支持该项目的开发和维护,请随时扫描一下二维码进行捐赠。非常感谢您的捐款,谢谢!
-如果您希望留下您的信息,可以到[感谢信](https://think.codingit.cn/wiki/eb520cdf-aa4b-4af2-ae4a-7140e21403ab/document/230548f5-3220-4c5b-a209-02b1eb0299e7)评论区留言。
+## 贡献者
-## 资料
+感谢所有为本项目作出贡献的同学!
-- next.js 源码:https://github.com/vercel/next.js
-- next.js 文档:https://nextjs.org/
-- nest.js 源码:https://github.com/nestjs/nest
-- nest.js 文档:https://nestjs.com/
+
diff --git a/build-output.sh b/build-output.sh
index a2caa46..ed23432 100755
--- a/build-output.sh
+++ b/build-output.sh
@@ -1,7 +1,12 @@
#! /bin/bash
# 该脚本只保留生产环境运行所需文件到统一目录
+if [ ! -f './config/prod.yaml' ]; then
+ echo "缺少 config/prod.yaml 文件,可参考 docker-prod-sample.yaml 进行配置"
+ exit 1
+fi
# 构建
+pnpm fetch --prod
pnpm install
pnpm run build
@@ -71,7 +76,7 @@ cd ../../
# @see https://github.com/typicode/husky/issues/914#issuecomment-826768549
cd ${outputDir}
npm set-script prepare ""
-pnpm install -r --prod
+pnpm install -r --offline --prod
cd ../
echo "${outputDir} 打包完成"
diff --git a/config/dev.yaml b/config/dev.yaml
index b38705e..1b7e340 100644
--- a/config/dev.yaml
+++ b/config/dev.yaml
@@ -23,13 +23,22 @@ server:
enableRateLimit: true # 是否限流
rateLimitWindowMs: 60000 # 限流时间
rateLimitMax: 1000 # 单位限流时间内单个 ip 最大访问数量
+ email: # 邮箱服务,参考 http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html?servCode=6010376 获取 SMTP 配置
+ host: ''
+ port: 465
+ user: ''
+ password: ''
+ admin:
+ name: 'admin' # 注意修改
+ password: 'admin' # 注意修改
+ email: 'admin@think.com' # 注意修改为真实邮箱地址
# 数据库配置
db:
mysql:
host: '127.0.0.1'
- username: 'root'
- password: 'root'
+ username: 'think'
+ password: 'think'
database: 'think'
port: 3306
charset: 'utf8mb4'
diff --git a/docker/prod-sample.yaml b/config/docker-prod-sample.yaml
similarity index 76%
rename from docker/prod-sample.yaml
rename to config/docker-prod-sample.yaml
index 3b445e5..103f5c1 100644
--- a/docker/prod-sample.yaml
+++ b/config/docker-prod-sample.yaml
@@ -1,4 +1,4 @@
-# 生产环境docker示例配置
+# 开发环境配置
client:
port: 5001
assetPrefix: '/'
@@ -7,7 +7,7 @@ client:
# 以下为页面 meta 配置
seoAppName: '云策文档'
seoDescription: '云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。'
- seoKeywords: '云策文档,协作,文档,前端面试题,fantasticit,https://github.com/fantasticit/think'
+ seoKeywords: '云策文档,协作,文档,fantasticit,https://github.com/fantasticit/think'
# 预先连接的来源,空格分割(比如图片存储服务器)
dnsPrefetch: '//wipi.oss-cn-shanghai.aliyuncs.com'
# 站点地址(如:http://think.codingit.cn/),一定要设置,否则会出现 cookie、跨域等问题
@@ -23,22 +23,31 @@ server:
enableRateLimit: true # 是否限流
rateLimitWindowMs: 60000 # 限流时间
rateLimitMax: 1000 # 单位限流时间内单个 ip 最大访问数量
+ email: # 邮箱服务,参考 http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html?servCode=6010376 获取 SMTP 配置
+ host: ''
+ port: 465
+ user: ''
+ password: ''
+ admin:
+ name: 'admin' # 注意修改
+ password: 'admin' # 注意修改
+ email: 'admin@think.com' # 注意修改为真实邮箱地址
# 数据库配置
db:
mysql:
- host: 'mysql-with-think'
- username: 'jonnyan404'
- password: 'www.mrdoc.fun'
+ host: 'mysql-for-think'
+ username: 'think'
+ password: 'think'
database: 'think'
port: 3306
charset: 'utf8mb4'
timezone: '+08:00'
synchronize: true
redis:
- host: '127.0.0.1'
+ host: 'redis-for-think'
port: '6379'
- password: ''
+ password: 'root'
# oss 文件存储服务
oss:
diff --git a/docker-compose.yml b/docker-compose.yml
index c776d79..0e4ea89 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,44 +1,58 @@
-version: "3"
+version: '3'
services:
- thinkdoc:
+ think:
build:
context: .
- args:
- EIP: x.x.x.x # api接口IP,必须设置,可以是 IP 或者域名.
image: think
- container_name: thinkdoc
- #restart: always
+ container_name: think
volumes:
- - /path/to/you/dir/config:/app/config # 请注意修改 /path/to/you/dir 为云策文档配置文件目录.
- - /path/to/you/dir/static:/app/packages/server/static # 请注意修改 /path/to/you/dir 为云策文档附件存储目录.
+ - ./config:/app/config
+ - ./runtime/static:/app/packages/server/static
environment:
- TZ=Asia/Shanghai
ports:
- - "5001-5003:5001-5003"
+ - '5001-5003:5001-5003'
depends_on:
- mysql
+ - redis
+ networks:
+ - think
mysql:
image: mysql:5.7
- container_name: mysql-with-think
- #restart: always
+ restart: always
+ container_name: mysql-for-think
volumes:
- - /path/to/you/dir/mysql:/var/lib/mysql # 请注意修改 /path/to/you/dir 为您要存储mysql数据的目录绝对路径.
+ - ./runtime/mysql:/var/lib/mysql
environment:
- TZ=Asia/Shanghai
- - MYSQL_ROOT_PASSWORD=Jonnyan404!
+ - MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=think
- - MYSQL_USER=jonnyan404
- - MYSQL_PASSWORD=www.mrdoc.fun
+ - MYSQL_USER=think
+ - MYSQL_PASSWORD=think
expose:
- - "3306"
+ - '3306'
ports:
- - "63306:3306" # 如果不需要外部连接mysql,可注释此行+上一行.
+ - '3306:3306'
command:
- - "--character-set-server=utf8mb4"
- - "--collation-server=utf8mb4_unicode_ci"
-# Volumes for persisting data, see https://docs.docker.com/engine/admin/volumes/volumes/
-#volumes:
-# thinkdoc-data:
-# driver: local
-# mysql-data:
-# driver: local
+ - '--character-set-server=utf8mb4'
+ - '--collation-server=utf8mb4_unicode_ci'
+ networks:
+ - think
+ redis:
+ image: redis:latest
+ restart: always
+ container_name: redis-for-think
+ command: >
+ --requirepass root
+ expose:
+ - '6379'
+ ports:
+ - '6379:6379'
+ volumes:
+ - ./runtime/redis:/data
+ privileged: true
+ networks:
+ - think
+networks:
+ think:
+ driver: bridge
diff --git a/docker/start.sh b/docker/start.sh
index 60c3e2f..821e6cc 100644
--- a/docker/start.sh
+++ b/docker/start.sh
@@ -1,14 +1,8 @@
#!/bin/sh
### Author:jonnyan404
### date:2022年5月22日
-CONFIG_FILE='/app/config/prod.yaml'
-if [ ! -f $CONFIG_FILE ]; then
- echo "#####Generating configuration file#####"
- cp /app/docker/prod-sample.yaml $CONFIG_FILE
-else
- echo "#####Configuration file already exists#####"
-fi
-redis-server --daemonize yes
pnpm run pm2
+pm2 startup
+pm2 save
pm2 logs
diff --git a/let-us-start.md b/let-us-start.md
new file mode 100644
index 0000000..1fbfbea
--- /dev/null
+++ b/let-us-start.md
@@ -0,0 +1,110 @@
+# think
+
+## 项目结构
+
+本项目依赖 pnpm 使用 monorepo 形式进行代码组织,分包如下:
+
+- `@think/config`: 客户端、服务端、OSS、MySQL、Redis 等配置管理
+- `@think/domains`:领域模型数据定义
+- `@think/constants`:常量配置
+- `@think/server`:服务端
+- `@think/client`:客户端
+
+## 项目依赖
+
+为了将项目运行起来,至少需要以下依赖。
+
+- nodejs >=16.5.0:推荐使用 nvm 安装
+- pnpm:安装 nodejs 后,运行 `npm i -g pnpm` 即可安装
+- pm2:安装 nodejs 后,运行 `npm i -g pm2` 即可安装
+- MySQL 5.7
+- Redis
+
+## 配置文件
+
+项目所有的配置文件都在 `config` 目录下,其中 `dev.yaml` 中各字段均有解释,生产环境打包依赖 `prod.yaml`(需要自行修改为所需配置)。如果运行不起来,请对比 `dev.yaml` 检查配置。
+
+**如果部署遇到问题,首先请确认相应配置是否正确!**
+
+## 项目运行
+
+无论是开发环境,还是生产环境,项目运行成功后会在 3 个端口启动相应服务(默认 5001、5002、5003),具体端口号由 `config` 文件夹下的配置文件决定。
+
+- 前台页面地址:`http://localhost:5001`
+- 服务接口地址:`http://localhost:5002`
+- 协作接口地址:`http://localhost:5003`
+
+### 本地开发
+
+1. 安装数据库
+
+首先安装 `MySQL` 和 `Redis`,推荐使用 docker 进行安装。
+
+```bash
+docker image pull mysql:5.7
+# m1 的 mac 可以用:docker image pull --platform linux/x86_64 mysql:5.7
+docker run -d --restart=always --name mysql-for-think-dev -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_USER=think -e MYSQL_PASSWORD=think -e MYSQL_DATABASE=think mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
+
+docker pull redis:latest
+docker run --name redis-for-think-dev -p 6379:6379 -d redis --appendonly yes --requirepass "root"
+```
+
+2. 安装依赖并运行
+
+```bash
+git clone https://github.com/fantasticit/think.git
+cd think
+pnpm install
+pnpm run dev
+```
+
+### 生产部署
+
+首先确认在 `config` 文件夹下新建 `prod.yaml` 配置文件,然后运行以下命令。
+
+```bash
+git clone https://github.com/fantasticit/think.git
+cd think
+pnpm install # 安装依赖
+pnpm run build # 项目打包
+
+# 以下如果没有安装 pm2,直接 pnpm run start,推荐使用 pm2
+pnpm run pm2
+pm2 startup
+pm2 save
+```
+
+### docker-compose
+
+也可以使用 docker-compose 进行项目部署。首先,根据需要修改 `docker-compose.yml` 中的数据库、Redis 相关用户名、密码等配置,然后,从 `config/docker-prod-sample.yaml` 复制出 `config/prod.yaml` 并修改其中对应的配置。
+
+```bash
+# 首次安装
+git clone https://github.com/fantasticit/think.git
+cd think
+vim docker-compose.yml
+docker-compose up -d
+
+# 二次更新升级
+cd think
+git pull
+docker-compose build
+docker-compose up -d
+
+# 如果二次更新有问题
+docker-compose kill
+docker-compose rm
+docker image rm think # 删掉构建的镜像
+docker-compose up -d
+```
+
+### nginx 配置参考
+
+无论以何种方式进行项目部署,项目运行成功后会在 3 个端口启动服务(默认 5001、5002、5003,具体由配置文件决定)。`nginx` 配置参考 <[think/nginx.conf.sample](https://github.com/fantasticit/think/blob/main/nginx.conf.sample)>。
+
+特别强调,在 `config` 文件夹的配置中 `client.siteUrl` 一定要配置正确,否则客户端可能无法正常运行。
+
+```yaml
+# 站点地址(如:http://think.codingit.cn/),一定要设置,否则会出现 cookie、跨域等问题
+siteUrl: 'http://localhost:5001'
+```
diff --git a/nginx.conf.bak b/nginx.conf.sample
similarity index 81%
rename from nginx.conf.bak
rename to nginx.conf.sample
index f3e36d9..f2b36de 100644
--- a/nginx.conf.bak
+++ b/nginx.conf.sample
@@ -1,9 +1,9 @@
-upstream think_server {
+upstream think_client {
server 127.0.0.1:5001;
keepalive 64;
}
-upstream think_client {
+upstream think_server {
server 127.0.0.1:5002;
keepalive 64;
}
@@ -29,7 +29,7 @@ server {
client_max_body_size 100m;
- location /think {
+ location /api {
proxy_pass http://think_server;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
@@ -43,16 +43,23 @@ server {
}
location /think/wss {
- proxy_pass http://think_wss;
- proxy_read_timeout 300s;
- proxy_send_timeout 300s;
+ proxy_pass http://think_wss;
+ proxy_read_timeout 300s;
+ proxy_send_timeout 300s;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection 'upgrade';
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection 'upgrade';
+ }
+
+ location /static/ {
+ gzip_static on;
+ expires max;
+ add_header Cache-Control public;
+ alias /apps/think/packages/server/static/;
}
}
diff --git a/packages/client/src/components/admin/system-config/index.tsx b/packages/client/src/components/admin/system-config/index.tsx
new file mode 100644
index 0000000..c1b12c9
--- /dev/null
+++ b/packages/client/src/components/admin/system-config/index.tsx
@@ -0,0 +1,29 @@
+import { TabPane, Tabs } from '@douyinfe/semi-ui';
+import React from 'react';
+
+import { Mail } from './mail';
+import { System } from './system';
+
+interface IProps {
+ tab?: string;
+ onNavigate: (arg: string) => void;
+}
+
+const TitleMap = {
+ base: '系统管理',
+ mail: '邮箱服务',
+};
+
+export const SystemConfig: React.FC = ({ tab, onNavigate }) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/packages/client/src/components/admin/system-config/mail/index.tsx b/packages/client/src/components/admin/system-config/mail/index.tsx
new file mode 100644
index 0000000..fec4553
--- /dev/null
+++ b/packages/client/src/components/admin/system-config/mail/index.tsx
@@ -0,0 +1,88 @@
+import { Banner, Button, Form, Toast } from '@douyinfe/semi-ui';
+import { DataRender } from 'components/data-render';
+import { useSystemConfig } from 'data/user';
+import { useToggle } from 'hooks/use-toggle';
+import React, { useCallback } from 'react';
+
+export const Mail = () => {
+ const { data, loading, error, sendTestEmail, updateSystemConfig } = useSystemConfig();
+ const [changed, toggleChanged] = useToggle(false);
+
+ const onFormChange = useCallback(() => {
+ toggleChanged(true);
+ }, [toggleChanged]);
+
+ const onFinish = useCallback(
+ (values) => {
+ updateSystemConfig(values).then(() => {
+ Toast.success('操作成功');
+ });
+ },
+ [updateSystemConfig]
+ );
+
+ return (
+ (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+ />
+ );
+};
diff --git a/packages/client/src/components/admin/system-config/system/index.tsx b/packages/client/src/components/admin/system-config/system/index.tsx
new file mode 100644
index 0000000..d4c539b
--- /dev/null
+++ b/packages/client/src/components/admin/system-config/system/index.tsx
@@ -0,0 +1,49 @@
+import { Banner, Button, Form, Toast } from '@douyinfe/semi-ui';
+import { DataRender } from 'components/data-render';
+import { useSystemConfig } from 'data/user';
+import { useToggle } from 'hooks/use-toggle';
+import React, { useCallback } from 'react';
+
+export const System = () => {
+ const { data, loading, error, updateSystemConfig } = useSystemConfig();
+ const [changed, toggleChanged] = useToggle(false);
+
+ const onFormChange = useCallback(() => {
+ toggleChanged(true);
+ }, [toggleChanged]);
+
+ const onFinish = useCallback(
+ (values) => {
+ updateSystemConfig(values).then(() => {
+ Toast.success('操作成功');
+ });
+ },
+ [updateSystemConfig]
+ );
+
+ return (
+ (
+
+
+
+
+
+
+
+ )}
+ />
+ );
+};
diff --git a/packages/client/src/components/document/collaboration/index.tsx b/packages/client/src/components/document/collaboration/index.tsx
index 16dd5a5..39d9e0f 100644
--- a/packages/client/src/components/document/collaboration/index.tsx
+++ b/packages/client/src/components/document/collaboration/index.tsx
@@ -16,7 +16,6 @@ import {
Tooltip,
Typography,
} from '@douyinfe/semi-ui';
-import { IUser } from '@think/domains';
import { DataRender } from 'components/data-render';
import { DocumentLinkCopyer } from 'components/document/link';
import { useDoumentMembers } from 'data/document';
@@ -54,6 +53,7 @@ const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked,
export const DocumentCollaboration: React.FC = ({ wikiId, documentId, disabled = false }) => {
const { isMobile } = IsOnMobile.useHook();
const ref = useRef();
+ const toastedUsersRef = useRef([]);
const { user: currentUser } = useUser();
const [visible, toggleVisible] = useToggle(false);
const { users, loading, error, addUser, updateUser, deleteUser } = useDoumentMembers(documentId, {
@@ -169,7 +169,10 @@ export const DocumentCollaboration: React.FC = ({ wikiId, documentId, di
return joinUser.name !== currentUser.name;
})
.forEach((joinUser) => {
- Toast.info(`${joinUser.name}-${joinUser.clientId}加入文档`);
+ if (!toastedUsersRef.current.includes(joinUser.clientId)) {
+ Toast.info(`${joinUser.name}-${joinUser.clientId}加入文档`);
+ toastedUsersRef.current.push(joinUser.clientId);
+ }
});
setCollaborationUsers(joinUsers);
@@ -178,6 +181,7 @@ export const DocumentCollaboration: React.FC = ({ wikiId, documentId, di
event.on(JOIN_USER, handler);
return () => {
+ toastedUsersRef.current = [];
event.off(JOIN_USER, handler);
};
}, [currentUser]);
diff --git a/packages/client/src/components/user/index.tsx b/packages/client/src/components/user/index.tsx
index d6bb585..2d4111e 100644
--- a/packages/client/src/components/user/index.tsx
+++ b/packages/client/src/components/user/index.tsx
@@ -2,7 +2,8 @@ import { IconSpin } from '@douyinfe/semi-icons';
import { Avatar, Button, Dropdown, Typography } from '@douyinfe/semi-ui';
import { useUser } from 'data/user';
import { useToggle } from 'hooks/use-toggle';
-import React from 'react';
+import Router from 'next/router';
+import React, { useCallback } from 'react';
import { UserSetting } from './setting';
@@ -12,6 +13,10 @@ export const User: React.FC = () => {
const { user, loading, error, toLogin, logout } = useUser();
const [visible, toggleVisible] = useToggle(false);
+ const toAdmin = useCallback(() => {
+ Router.push('/admin');
+ }, []);
+
if (loading) return } theme="borderless" type="tertiary" />;
if (error || !user) {
@@ -32,6 +37,11 @@ export const User: React.FC = () => {
toggleVisible(true)}>
账户设置
+ {user.isSystemAdmin ? (
+
+ 管理后台
+
+ ) : null}
退出登录
diff --git a/packages/client/src/components/user/setting/index.tsx b/packages/client/src/components/user/setting/index.tsx
index c4d967b..9360655 100644
--- a/packages/client/src/components/user/setting/index.tsx
+++ b/packages/client/src/components/user/setting/index.tsx
@@ -65,7 +65,13 @@ export const UserSetting: React.FC = ({ visible, toggleVisible }) => {
disabled
placeholder="请输入账户名称"
>
-
+
);
diff --git a/packages/client/src/components/wiki/card/index.tsx b/packages/client/src/components/wiki/card/index.tsx
index b855579..61051f9 100644
--- a/packages/client/src/components/wiki/card/index.tsx
+++ b/packages/client/src/components/wiki/card/index.tsx
@@ -42,7 +42,9 @@ export const WikiCard: React.FC<{ wiki: IWikiWithIsMember; shareMode?: boolean }
-
{wiki.name}
+
+ {wiki.name}
+
{wiki.description}
diff --git a/packages/client/src/components/wiki/pin-card/index.tsx b/packages/client/src/components/wiki/pin-card/index.tsx
index b26f66f..bb65bd8 100644
--- a/packages/client/src/components/wiki/pin-card/index.tsx
+++ b/packages/client/src/components/wiki/pin-card/index.tsx
@@ -7,7 +7,7 @@ import Link from 'next/link';
import styles from './index.module.scss';
-const { Text } = Typography;
+const { Text, Paragraph } = Typography;
export const WikiPinCard: React.FC<{ wiki: IWiki }> = ({ wiki }) => {
return (
@@ -35,7 +35,9 @@ export const WikiPinCard: React.FC<{ wiki: IWiki }> = ({ wiki }) => {
- {wiki.name}
+
+ {wiki.name}
+