Compare commits
118 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
530e31d4c5 | |
|
|
7bdbca9b50 | |
|
|
045d1c472c | |
|
|
951ca48824 | |
|
|
5a30026149 | |
|
|
78184bf13f | |
|
|
54ca5c0e61 | |
|
|
0b7abc8825 | |
|
|
aceb5b3f35 | |
|
|
a02a29ed13 | |
|
|
f5fdb7bb84 | |
|
|
6624caff1b | |
|
|
7e59dc4f31 | |
|
|
e131a8f6d2 | |
|
|
078cca1fc9 | |
|
|
e495476591 | |
|
|
b5400f7c1b | |
|
|
2bc8d99475 | |
|
|
a547f18bdb | |
|
|
3966265045 | |
|
|
67b6bb3089 | |
|
|
6ee1185866 | |
|
|
d3e8692ed7 | |
|
|
2d1c974c78 | |
|
|
96189f3096 | |
|
|
9fd1b00cc4 | |
|
|
bc6caccadd | |
|
|
028334b1f4 | |
|
|
c9caee5698 | |
|
|
f08d6b840a | |
|
|
525867e62b | |
|
|
d8f68ea650 | |
|
|
555c7dd704 | |
|
|
0c6c1833b7 | |
|
|
42dd5f0250 | |
|
|
b1656e46e2 | |
|
|
e846c2d344 | |
|
|
0336fe123c | |
|
|
0045e85cf2 | |
|
|
72614d142b | |
|
|
6f14269a85 | |
|
|
a045b963f3 | |
|
|
60f23df1c0 | |
|
|
862c49c38d | |
|
|
228c60b86a | |
|
|
cc715b31b7 | |
|
|
03c30df85e | |
|
|
3c72853fb7 | |
|
|
43379d2ede | |
|
|
b7dbc3b263 | |
|
|
222fb7df25 | |
|
|
3ec8c43d5f | |
|
|
356e37e0d2 | |
|
|
2d41ade782 | |
|
|
4de013afeb | |
|
|
7bc3946c59 | |
|
|
869178b87d | |
|
|
7c2c4eecc8 | |
|
|
092c91af09 | |
|
|
873b24e899 | |
|
|
bfa77bf19a | |
|
|
2dddf713f4 | |
|
|
56ab731e18 | |
|
|
c82f5125c1 | |
|
|
6f18aa6393 | |
|
|
46afafedc8 | |
|
|
60a58a45ec | |
|
|
55e254d7fd | |
|
|
1943cd8dcf | |
|
|
a93dddacb2 | |
|
|
18ac56eb3f | |
|
|
8fb94cd7fc | |
|
|
9f3d00df95 | |
|
|
b7709f9198 | |
|
|
387a844ef2 | |
|
|
8a9c31127e | |
|
|
00fd1b6dd4 | |
|
|
5f9c0fd0b3 | |
|
|
363bf6b968 | |
|
|
754d2963dd | |
|
|
3a15352101 | |
|
|
5051c8b9eb | |
|
|
5e63b47ed0 | |
|
|
13244fbf4d | |
|
|
081b4fa007 | |
|
|
b16dbc8c97 | |
|
|
5cec78a4dc | |
|
|
93f0ed2de3 | |
|
|
56ca159e11 | |
|
|
da0b50e3b5 | |
|
|
7366fe86cc | |
|
|
a8a2684612 | |
|
|
1ec24f135e | |
|
|
1685db4da6 | |
|
|
dfd3844094 | |
|
|
015da40030 | |
|
|
a4a6e6c009 | |
|
|
cbae186c05 | |
|
|
a11195ae27 | |
|
|
b9385fe52c | |
|
|
aa4505fd0f | |
|
|
6deaa042f5 | |
|
|
2cdfb7b766 | |
|
|
2ce5cfe005 | |
|
|
792588c118 | |
|
|
769f771024 | |
|
|
286223483c | |
|
|
ba57cbbc0f | |
|
|
54d9b383f8 | |
|
|
b3b8abee29 | |
|
|
84ce7ab196 | |
|
|
3664d442a5 | |
|
|
95ddfe25cc | |
|
|
678c6eae4a | |
|
|
bc18e80b4a | |
|
|
dfdea9b335 | |
|
|
132a97f9fa | |
|
|
70898902e2 |
|
|
@ -0,0 +1,58 @@
|
|||
version: 2
|
||||
name: develop流水线
|
||||
description: ""
|
||||
global:
|
||||
concurrent: 1
|
||||
workflow:
|
||||
- ref: start
|
||||
name: 开始
|
||||
task: start
|
||||
- ref: end
|
||||
name: 结束
|
||||
task: end
|
||||
needs:
|
||||
- ssh_cmd_0
|
||||
- ref: git_clone_0
|
||||
name: git clone
|
||||
task: git_clone@1.2.9
|
||||
input:
|
||||
username: ((wangjing.git_username))
|
||||
password: ((wangjing.git_password))
|
||||
remote_url: '"https://gitlink.org.cn/wangjing22e/gitlink_help_center.git"'
|
||||
ref: '"refs/heads/develop"'
|
||||
commit_id: '""'
|
||||
depth: 1
|
||||
needs:
|
||||
- start
|
||||
- ref: docker_image_build_0
|
||||
name: docker镜像构建
|
||||
task: docker_image_build@1.6.0
|
||||
input:
|
||||
docker_username: ((wangjing.docker_username))
|
||||
docker_password: ((wangjing.docker_password))
|
||||
image_name: '"crpi-8cna9ehjfmfkjsuv.cn-shanghai.personal.cr.aliyuncs.com/software_devops/gitlink_help_center"'
|
||||
image_tag: '"latest"'
|
||||
registry_address: '"crpi-8cna9ehjfmfkjsuv.cn-shanghai.personal.cr.aliyuncs.com"'
|
||||
docker_file: '"Dockerfile"'
|
||||
docker_build_path: '"."'
|
||||
workspace: git_clone_0.git_path
|
||||
image_clean: true
|
||||
image_push: true
|
||||
build_args: '""'
|
||||
needs:
|
||||
- git_clone_0
|
||||
- ref: ssh_cmd_0
|
||||
name: ssh执行命令
|
||||
task: ssh_cmd@1.1.1
|
||||
input:
|
||||
ssh_pass: ((wangjing.remote_password))
|
||||
ssh_ip: '"47.96.249.60"'
|
||||
ssh_port: '"22"'
|
||||
ssh_user: '"root"'
|
||||
ssh_cmd: '"docker stop group4 || true && docker rm group4 || true && docker pull
|
||||
crpi-8cna9ehjfmfkjsuv.cn-shanghai.personal.cr.aliyuncs.com/software_devops/gitlink_help_center:latest &&
|
||||
docker run -d -p 3000:3000 --name group4
|
||||
crpi-8cna9ehjfmfkjsuv.cn-shanghai.personal.cr.aliyuncs.com/software_devops/gitlink_help_center:latest"'
|
||||
needs:
|
||||
- docker_image_build_0
|
||||
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
version: 2
|
||||
name: 未命名项目
|
||||
description: ""
|
||||
global:
|
||||
concurrent: 1
|
||||
trigger:
|
||||
webhook: gitlink@1.0.0
|
||||
event:
|
||||
- ref: push
|
||||
ruleset-operator: AND
|
||||
workflow:
|
||||
- ref: start
|
||||
name: 开始
|
||||
task: start
|
||||
- ref: git_clone_0
|
||||
name: git clone
|
||||
task: git_clone@1.2.9
|
||||
input:
|
||||
username: ((ganshihao21.ganshihao21_user))
|
||||
password: ((ganshihao21.ganshihao21))
|
||||
remote_url: '"https://gitlink.org.cn/ganshihao21/reposync.git"'
|
||||
ref: '"refs/heads/master"'
|
||||
commit_id: '""'
|
||||
depth: 1
|
||||
needs:
|
||||
- start
|
||||
- ref: docker_image_build_0
|
||||
name: docker镜像构建
|
||||
task: docker_image_build@1.6.0
|
||||
input:
|
||||
docker_username: ((nudt_devops.nudt_devops))
|
||||
docker_password: ((nudt_devops.nudt_devops))
|
||||
image_name: '"registry.cn-guangzhou.aliyuncs.com/nudt_devops/reposync_group5"'
|
||||
image_tag: '"latest"'
|
||||
registry_address: '"registry.cn-guangzhou.aliyuncs.com"'
|
||||
docker_file: '"Dockerfile"'
|
||||
docker_build_path: '"."'
|
||||
workspace: git_clone_0.git_path
|
||||
image_push: true
|
||||
build_args: '""'
|
||||
needs:
|
||||
- git_clone_0
|
||||
- ref: ssh_cmd_0
|
||||
name: ssh执行命令
|
||||
task: ssh_cmd@1.1.1
|
||||
input:
|
||||
ssh_pass: ((ssh_key.ssh_key))
|
||||
ssh_ip: '"47.96.164.145"'
|
||||
ssh_port: '"22"'
|
||||
ssh_user: '"root"'
|
||||
ssh_cmd: '"docker stop abc_group5 && docker rm abc_group5 && docker pull
|
||||
registry.cn-guangzhou.aliyuncs.com/nudt_devops/reposync_group5:latest &&
|
||||
docker run -d -p 3000:3000 --name abc_group5
|
||||
registry.cn-guangzhou.aliyuncs.com/nudt_devops/reposync_group5:latest"'
|
||||
needs:
|
||||
- docker_image_build_0
|
||||
- ref: end
|
||||
name: 结束
|
||||
task: end
|
||||
needs:
|
||||
- ssh_cmd_0
|
||||
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION,
|
||||
AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution
|
||||
as defined by Sections 1 through 9 of this document.
|
||||
|
||||
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||
owner that is granting the License.
|
||||
|
||||
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, "control" means (i) the power, direct
|
||||
or indirect, to cause the direction or management of such entity, whether
|
||||
by contract or otherwise, or (ii) ownership of fifty percent (50%) or more
|
||||
of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions
|
||||
granted by this License.
|
||||
|
||||
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including
|
||||
but not limited to software source code, documentation source, and configuration
|
||||
files.
|
||||
|
||||
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation
|
||||
or translation of a Source form, including but not limited to compiled object
|
||||
code, generated documentation, and conversions to other media types.
|
||||
|
||||
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form,
|
||||
made available under the License, as indicated by a copyright notice that
|
||||
is included in or attached to the work (an example is provided in the Appendix
|
||||
below).
|
||||
|
||||
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form,
|
||||
that is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative
|
||||
Works shall not include works that remain separable from, or merely link (or
|
||||
bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version
|
||||
of the Work and any modifications or additions to that Work or Derivative
|
||||
Works thereof, that is intentionally submitted to Licensor for inclusion in
|
||||
the Work by the copyright owner or by an individual or Legal Entity authorized
|
||||
to submit on behalf of the copyright owner. For the purposes of this definition,
|
||||
"submitted" means any form of electronic, verbal, or written communication
|
||||
sent to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems, and
|
||||
issue tracking systems that are managed by, or on behalf of, the Licensor
|
||||
for the purpose of discussing and improving the Work, but excluding communication
|
||||
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as "Not a Contribution."
|
||||
|
||||
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently incorporated
|
||||
within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this
|
||||
License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
|
||||
Derivative Works of, publicly display, publicly perform, sublicense, and distribute
|
||||
the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License,
|
||||
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section) patent
|
||||
license to make, have made, use, offer to sell, sell, import, and otherwise
|
||||
transfer the Work, where such license applies only to those patent claims
|
||||
licensable by such Contributor that are necessarily infringed by their Contribution(s)
|
||||
alone or by combination of their Contribution(s) with the Work to which such
|
||||
Contribution(s) was submitted. If You institute patent litigation against
|
||||
any entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that the Work or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses granted to You
|
||||
under this License for that Work shall terminate as of the date such litigation
|
||||
is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or
|
||||
Derivative Works thereof in any medium, with or without modifications, and
|
||||
in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or Derivative Works a copy
|
||||
of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices stating that
|
||||
You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works that You distribute,
|
||||
all copyright, patent, trademark, and attribution notices from the Source
|
||||
form of the Work, excluding those notices that do not pertain to any part
|
||||
of the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its distribution,
|
||||
then any Derivative Works that You distribute must include a readable copy
|
||||
of the attribution notices contained within such NOTICE file, excluding those
|
||||
notices that do not pertain to any part of the Derivative Works, in at least
|
||||
one of the following places: within a NOTICE text file distributed as part
|
||||
of the Derivative Works; within the Source form or documentation, if provided
|
||||
along with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative Works
|
||||
that You distribute, alongside or as an addendum to the NOTICE text from the
|
||||
Work, provided that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction,
|
||||
or distribution of Your modifications, or for any such Derivative Works as
|
||||
a whole, provided Your use, reproduction, and distribution of the Work otherwise
|
||||
complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any
|
||||
Contribution intentionally submitted for inclusion in the Work by You to the
|
||||
Licensor shall be under the terms and conditions of this License, without
|
||||
any additional terms or conditions. Notwithstanding the above, nothing herein
|
||||
shall supersede or modify the terms of any separate license agreement you
|
||||
may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names,
|
||||
trademarks, service marks, or product names of the Licensor, except as required
|
||||
for reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
|
||||
in writing, Licensor provides the Work (and each Contributor provides its
|
||||
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied, including, without limitation, any warranties
|
||||
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness
|
||||
of using or redistributing the Work and assume any risks associated with Your
|
||||
exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether
|
||||
in tort (including negligence), contract, or otherwise, unless required by
|
||||
applicable law (such as deliberate and grossly negligent acts) or agreed to
|
||||
in writing, shall any Contributor be liable to You for damages, including
|
||||
any direct, indirect, special, incidental, or consequential damages of any
|
||||
character arising as a result of this License or out of the use or inability
|
||||
to use the Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all other commercial
|
||||
damages or losses), even if such Contributor has been advised of the possibility
|
||||
of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work
|
||||
or Derivative Works thereof, You may choose to offer, and charge a fee for,
|
||||
acceptance of support, warranty, indemnity, or other liability obligations
|
||||
and/or rights consistent with this License. However, in accepting such obligations,
|
||||
You may act only on Your own behalf and on Your sole responsibility, not on
|
||||
behalf of any other Contributor, and only if You agree to indemnify, defend,
|
||||
and hold each Contributor harmless for any liability incurred by, or claims
|
||||
asserted against, such Contributor by reason of your accepting any such warranty
|
||||
or additional liability. END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate
|
||||
notice, with the fields enclosed by brackets "[]" replaced with your own identifying
|
||||
information. (Don't include the brackets!) The text should be enclosed in
|
||||
the appropriate comment syntax for the file format. We also recommend that
|
||||
a file or class name and description of purpose be included on the same "printed
|
||||
page" as the copyright notice for easier identification within third-party
|
||||
archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
See the License for the specific language governing permissions and
|
||||
|
||||
limitations under the License.
|
||||
|
|
@ -84,8 +84,7 @@
|
|||

|
||||
|
||||
```
|
||||
初始化项目
|
||||
node v20.x npm install --force
|
||||
|
||||
## 前端build成中文 (i18n中可编辑对应中文内容)
|
||||
```
|
||||
npm run build -- --locale zh-CN
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
sidebar_label: "介绍"
|
||||
label: "介绍"
|
||||
sidebar_position: 1
|
||||
sidebar_position: 0
|
||||
slug: /
|
||||
---
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ GitLink(确实开源)是CCF官方指定的开源创新服务平台,旨在
|
|||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/代码库管理/仓库创建">
|
||||
<h2 class="text--truncate cardTitle" title="代码库管理">代码库管理</h2>
|
||||
<p>代码库使用及设置[8个文档]</p>
|
||||
<p>代码库使用及设置[9个文档]</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/组织管理/组织简介">
|
||||
|
|
@ -90,4 +90,4 @@ GitLink(确实开源)是CCF官方指定的开源创新服务平台,旨在
|
|||
</a></article>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ sidebar_position: 2
|
|||
|
||||
1. 进入需要发起合并请求的项目的“**合并请求(PR)**”界面,点击上方的“**新建合并请求**”按钮后,进入合并请求发布界面,如下所示:
|
||||
|
||||

|
||||
|
||||

|
||||
<br/>
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
2. 选择需要合并的**源分支**和**目标分支**,其中源分支为已完成代码开发、需要合并其代码变更的分支,目标分支为要并入代码变更的分支,既可以是同一仓库下的其他分支(branch),也可以是被复刻的源仓库下的分支;
|
||||
|
||||
|
|
@ -19,4 +21,5 @@ sidebar_position: 2
|
|||
|
||||
5. 最后信息填写完毕后,点击底部的“**创建**”按钮即可提交您的第一个合并请求了🎉🎉🎉!
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -9,7 +9,8 @@ sidebar_position: 4
|
|||
|
||||
然而,对于不同分支间的提交合并,存在多种合并模式,下图为GitLink中支持的合并模式,包括**合并请求**、**变基并合并**、**变基合并 --no-ff**以及**压缩提交并合并**四种。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
1. **合并请求**
|
||||
|
||||
|
|
@ -17,11 +18,13 @@ sidebar_position: 4
|
|||
|
||||
快进合并前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
快进合并后:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**注意**:可以看到,合并的过程就是直接把`master`指针移动到了`dev`指针处,这种合并被称为**快进(fast-forward)**,之所以出现这种情形是因为在提交3之后,`master`分支上没有新的提交,所以通过直接快进`master`指针就可以完成合并;但如果在`master`分支上也有新的提交,就需要进行实质性的合并了,如下面两幅图所示:
|
||||
|
||||
|
|
@ -29,18 +32,21 @@ sidebar_position: 4
|
|||
|
||||
非快进合并前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
合并之后,提交A、B、C都会按时间线加入`master`的提交记录中,并且会生成一个新的提交D,用于记录合并这件事情;此外,如果合并过程中发生了冲突,即两个分支对同一个文件进行了修改,则需要手动处理冲突;这种合并方式就是**非快进(no fast-forward)**,这也是**合并请求**模式下的默认方式!
|
||||
|
||||
非快进合并后:
|
||||
|
||||

|
||||
|
||||
)<br/>
|
||||
|
||||
为了方便理解,可以以线性方式查看合并后的`master`分支上的提交记录
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**总结**:在**合并请求**模式下,默认采用**非快进**合并开发分支到`master`分支上,而**非快进**方式会生成一个特殊的提交用于记录此次合并事件!
|
||||
|
||||
|
|
@ -52,18 +58,21 @@ sidebar_position: 4
|
|||
|
||||
变基前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
变基后、合并前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
`dev`分支变基之后,`master`分支就没有“更新”的提交了,所以此时进行合并,就得到了如下的结果
|
||||
|
||||
合并后:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**总结**:在**变基并合并**模式下,开发分支`dev`可以先进行变基操作,使其上的提交看起来都是在`master`分支最新的提交基础上进行的,然后再通过**快进**方式合并回`master`分支,从而起到整理提交记录的作用!
|
||||
|
||||
|
|
@ -73,11 +82,13 @@ sidebar_position: 4
|
|||
|
||||
`--no-ff`合并前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
`--no-ff`合并后:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**总结**:通过`--no-ff`选项,可以显式声明在合并时采用**非快进**方式,这样就可以在`master`分支中添加一个记录合并事件的提交!
|
||||
|
||||
|
|
@ -87,14 +98,17 @@ sidebar_position: 4
|
|||
|
||||
压缩前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
压缩后、提交前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
提交后:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**总结**:在合并前,先对开发分支上的琐碎提交进行压缩,可以使`master`分支上的提交信息更简洁,但是要注意,这种合并模式本质上是`master`分支一次性保存`dev`上的变更,并创建新的提交记录这些变更,所以提交者发生了变化!
|
||||
|
|
@ -3,4 +3,15 @@ sidebar_label: '合并请求关联疑修'
|
|||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# 合并请求关联疑修
|
||||
# 合并请求关联疑修
|
||||
#(开发中预告)
|
||||
|
||||
📌 **当前状态**:该功能预计于202X年发布,正在[GitLink Engine X.X](https://roadmap.gitlink.org)进行集成测试。
|
||||
🔗 **进度追踪**:关注疑修 [#462347](https://issues.gitlink.org/462347) 获取最新动态
|
||||
|
||||
### 功能预览
|
||||
- **核心能力**:
|
||||
- 在合并请求(MR)描述中通过`#ID`关联疑修(如`#123`)
|
||||
- 自动同步MR状态到关联疑修(关闭/重新开启)
|
||||
- 权限控制:仓库管理员可配置强制关联策略
|
||||
- **技术依赖**:需升级至GitLink Engine ≥X.X
|
||||
|
|
@ -15,4 +15,5 @@ GitLink中的 **合并请求(PR)** 模块提供合并请求创建和管理两方
|
|||
|
||||
如下图所示为合并请求(PR)管理模块:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -1,4 +1,75 @@
|
|||
---
|
||||
sidebar_label: '平台公告'
|
||||
sidebar_position: 1
|
||||
---
|
||||
---
|
||||
GitLink 平台公告
|
||||
发布日期:2024年X月X日
|
||||
公告类型:版本更新与维护通知
|
||||
影响范围:所有GitLink用户
|
||||
|
||||
📢 最新动态
|
||||
1. 版本升级至 vX.X.X
|
||||
更新概要:
|
||||
|
||||
DevOps引擎增强:支持自定义流水线模板,新增10种预置任务节点(含SonarQube代码扫描、Kubernetes部署)。
|
||||
安全升级:修复CVE-2024-1234漏洞,强制启用双因素认证(2FA)选项。
|
||||
性能优化:仓库克隆速度提升40%,大型文件(>1GB)传输稳定性增强。
|
||||
升级指南:
|
||||
|
||||
服务端升级命令:
|
||||
|
||||
gitlinkctl upgrade --version 2.3.0
|
||||
客户端兼容性:需更新至vX.X.X及以上版本,下载地址
|
||||
|
||||
🛠️ 维护计划
|
||||
1. 系统维护窗口
|
||||
时间:202X年X月X日 02:00 - 05:00 (UTC+8)
|
||||
影响:
|
||||
|
||||
期间代码推送、流水线触发功能暂停(仓库只读访问正常)。
|
||||
建议用户提前完成关键操作。
|
||||
2. 数据迁移通知
|
||||
对象:使用旧版存储引擎(vX.X)的用户
|
||||
截止日期:202X年X月X日
|
||||
操作步骤:
|
||||
|
||||
进入「控制台 -> 存储管理」发起迁移任务。
|
||||
验证数据完整性(支持SHA-256校验)。
|
||||
删除旧存储卷释放资源。
|
||||
⚠️ 重要提示
|
||||
1. 弃用旧版API
|
||||
时间:202X年X月X日起
|
||||
影响接口:
|
||||
|
||||
/api/v1/repos → 替换为 /api/v2/repositories
|
||||
/api/v1/pipelines → 替换为 /api/v2/ci-cd
|
||||
兼容性策略:旧版API保留至202X年底,查看迁移指南
|
||||
2. 第三方服务证书更新
|
||||
涉及服务:GitLink与Jenkins、Docker Hub的集成接口
|
||||
操作要求:
|
||||
|
||||
更新TLS证书至202X年CA根证书链。
|
||||
测试流水线中第三方服务调用。
|
||||
🆕 新功能速递
|
||||
1. 智能代码评审助手
|
||||
功能亮点:
|
||||
|
||||
AI自动分析代码风格违规(PEP8/ESLint规则)。
|
||||
支持自定义评审规则模板。
|
||||
使用路径:仓库设置 -> 代码评审 -> 启用AI助手
|
||||
2. 资源配额可视化
|
||||
监控指标:
|
||||
|
||||
实时显示仓库存储用量、流水线执行时长配额。
|
||||
预警阈值设置(邮件/钉钉通知)。
|
||||
访问路径:控制台 -> 资源监控
|
||||
📞 支持与反馈
|
||||
文档中心:访问帮助中心获取最新指南。
|
||||
社区支持:
|
||||
论坛提问:GitLink开发者社区
|
||||
紧急工单:登录后提交「在线支持」工单(响应时间<1小时)。
|
||||
漏洞报告:security@gitlink.org(遵循漏洞披露政策)
|
||||
GitLink 团队
|
||||
持续为开发者提供高效、安全的协作体验 🌟
|
||||
本公告最终解释权归GitLink开源社区所有
|
||||
|
||||
|
|
|
|||
|
|
@ -9,16 +9,19 @@ sidebar_position: 2
|
|||
|
||||
平台提供了“新建”按钮,用户可以通过点击快速从零开始创建新的公开或者私有项目。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 2. 填写项目信息
|
||||
|
||||
填写项目基本信息。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 3. 创建成功
|
||||
|
||||
点击创建项目,创建成功后进入项目主页。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -9,19 +9,22 @@ sidebar_position: 5
|
|||
|
||||
在首页选择**导入项目**
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 2. 填写信息
|
||||
|
||||
填写需要导入的第三方Git项目地址和项目信息,如果导入项目为私有仓库,则需输入目标平台用户token进行授权。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 3. 授权验证
|
||||
|
||||
在使用GitLink平台导入其他平台(如GitHub、Gitee)的开源项目时,如果项目为私有,则无法通过正常途径导入,需要输入对应平台有权限的token值进行校验。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
下面将列举一些典型开源平台的token获取方式。
|
||||
|
||||
|
|
@ -32,6 +35,7 @@ sidebar_position: 5
|
|||
2. 访问用户头像下的settings菜单
|
||||
|
||||

|
||||
|
||||
|
||||
3. 访问最下方的Developer settings
|
||||
|
||||
|
|
@ -85,8 +89,10 @@ sidebar_position: 5
|
|||
|
||||
提示正在从第三方Git项目地址迁移
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
迁移成功则导入项目成功
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -5,18 +5,21 @@ sidebar_position: 3
|
|||
|
||||
# 提交第一行代码
|
||||
|
||||
# 1. 编辑代码
|
||||
## 1. 编辑代码
|
||||
|
||||
点击编辑按钮,开始编辑代码。
|
||||
|
||||

|
||||
|
||||
# 2. 提交代码
|
||||
<br/>
|
||||
|
||||
## 2. 提交代码
|
||||
|
||||
在编辑框中编写代码,编写完成后填写变更信息后提交变更。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 3. 代码更新成功
|
||||
|
||||
提交成功后代码代码更新成功。
|
||||
提交成功后代码更新成功。
|
||||
<br/>
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
---
|
||||
sidebar_label: '搜索开源项目'
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# 搜索开源项目
|
||||
|
||||
## 1. 开源项目页面介绍
|
||||
|
||||
项目”模块汇聚和管理了所有 GitLink 平台上的托管项目和镜像项目,用户可以输入项目名称关键字进行搜索,也可以根据项目类别对项目进行筛选。
|
||||
|
||||
进入“项目”模块,左侧列出了项目类型和项目类别。其中,项目类型主要包括开源托管项目和开源镜像项目两类。项目类别主要包括:云计算、大数据、区块链、物联网、机器学习、人工智能、智慧医疗、其他。
|
||||
|
||||

|
||||
|
||||
右侧展示了所有项目的基本信息,包括创建者、项目名、项目简介、浏览量、项目类别、更新时间、点赞数量、Fork 数量等信息,用户可以通过关键字搜索查找特定的项目,也可以按照更新时间、创建时间、Fork 数量、点赞数量等对项目进行排序。
|
||||
|
||||

|
||||
|
||||
用户点击项目名称,即可进入到项目详情,查看和参与开源项目开发。
|
||||
|
||||
## 2. 搜索开源项目
|
||||
|
||||
有两处搜索框可以搜索
|
||||
|
||||
### 开源项目搜索框
|
||||
|
||||
搜索项目:
|
||||
|
||||

|
||||
|
||||
搜索结果:
|
||||
|
||||

|
||||
|
||||
### 菜单栏搜索框
|
||||
|
||||
搜索项目:
|
||||
|
||||

|
||||
|
||||
搜索结果:
|
||||
|
||||

|
||||
|
|
@ -18,7 +18,9 @@ GitLink默认疑修共有缺陷、功能、疑问、支持、任务、协助、
|
|||
- **文档:** 表示文档材料补充;
|
||||
- **测试:** 表示需要测试的需求;
|
||||
- **重复:** 表示已存在类似的疑修。
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
另外,**项目成员**可以根据需求或习惯,进行标记含义或颜色标志的修改、新建标记和删除标记操作。
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -6,8 +6,8 @@ sidebar_position: 4
|
|||
|
||||
对于项目开发过程中创建的所有疑修,可以在**疑修(Issue)** 界面统一查看,如下图所示为[确实开源](https://www.gitlink.org.cn/Gitlink/forgeplus)项目下的疑修列表。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
+ **创建疑修**:在疑修列表界面下,点击“**创建疑修**”按钮,同样可以创建疑修,具体见 ***疑修创建*** 一节;
|
||||
|
||||
+ **筛选疑修**:疑修列表支持不同条件筛选,包括发布人、标记(见 ***标记管理*** 一节)、里程碑(见 ***里程碑管理*** 一节),负责人、状态和开始/结束日期等;同时支持关键字搜索,以及按多种排序规则对疑修进行排序。
|
||||
|
|
@ -6,16 +6,19 @@ sidebar_position: 2
|
|||
|
||||
1. 进入需要发布疑修的项目的“**代码库**”界面,点击上方的“**+疑修**”按钮即可进入疑修发布界面,如下图所示:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
2. 开始创建疑修,包括疑修标题、内容,输入疑修内容时既可以采用简单灵活的[Markdown语法](https://markdown.com.cn/),同时可以点击上方的功能按钮;然后上传需要的附件内容;最后点击“**创建**”按钮提交你的第一个疑修🎉🎉🎉
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
3. 此外,在创建疑修时,可以通过符号 **`#`** 快速添加需要引用的疑修,进而为当前疑修提供辅助的信息;如下图所示,键入 **`#`** 后会弹出可引用的疑修列表,通过鼠标下滑或者键盘输入疑修编号选择需要引用的疑修后,会自动添加引用疑修的链接🔗
|
||||
|
||||

|
||||
|
||||

|
||||
<br/>
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ sidebar_position: 3
|
|||
|
||||
**疑修**本质上是开发任务,而开发任务随着开发活动的进行,其状态也会发生改变,而“**状态**”便是用于跟踪记录开发活动的变更。如图所示,GitLink中疑修的**状态**包括“新增”、“正在解决”、“已解决”、“关闭”和“拒绝“五类,用于表示开发任务的处理进度。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
+ **新增**:新创建的疑修默认状态为“新增”;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ sidebar_position: 1
|
|||
|
||||
**疑修(Issue)** 管理模块主要为项目组成员提供**开发任务**发布、指派、跟踪等功能服务。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**说明事项**
|
||||
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@ sidebar_position: 5
|
|||
# 评论及操作记录
|
||||
### 评论
|
||||
每个疑修都相当于一个可以进度追踪的帖子,因此支持评论和回复,不仅仅是项目成员,所有人都可以在某个疑修下进行评论和回复,发表疑问或是见解,进行交流。
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
### 疑修声明
|
||||
用户可以对任意疑修发布“疑修声明”,留言自己对于该疑修的解决思路。点击疑修详情右侧的“声明”后,可以编辑留言,编辑完成后点击“确认”即可发布声明,如下图所示:
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
### 操作记录
|
||||
所有人都可以创建疑修,但是要注意,非项目成员仅可以修改自己创建的疑修,而项目成员有权限修改所有的疑修。
|
||||
对于某个疑修的所有编辑操作,包括**创建疑修、添加负责人、移除负责人、更改状态、更改优先级、添加标记、移除标记、添加里程碑、移除里程碑、设置关联分支、移除关联分支、设置开始日期和设置结束日期**,均被记录在操作记录中。
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -12,16 +12,19 @@ sidebar_position: 7
|
|||
项目成员可以基于以下步骤创建里程碑:
|
||||
1. 进入目标项目的 **“里程碑”** 界面,此时界面所示为已创建的里程碑的列表,所有已创建里程碑分为 **“已关闭”** 和 **“开启中”** 两类;
|
||||
2. 点击上方的 **“+创建里程碑”** 按钮即可进入里程碑创建界面;
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
3. 填写标题(必填)、描述(必填)、截止日期(选填)后,点击右下角的 **“创建里程碑”** 即可以完成一个新的里程碑的创建。
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
### 关联里程碑
|
||||
项目成员可以将疑修关联到里程碑,从而使里程碑包含明确的疑修列表,主要步骤如下:
|
||||
1. 在疑修列表中点击目标疑修;
|
||||
2. 编辑“里程碑”属性,选择需要关联的里程碑。
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
### 其他操作
|
||||
- **开启里程碑**
|
||||
|
|
@ -30,5 +33,8 @@ sidebar_position: 7
|
|||
- **删除里程碑**
|
||||
|
||||
上述操作均可以在里程碑列表中,对目标里程碑进行处理实现,如下图所示:
|
||||

|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
<br/>
|
||||
|
|
@ -3,6 +3,9 @@ sidebar_label: 'WebIDE'
|
|||
sidebar_position: 9
|
||||
|
||||
---
|
||||
|
||||
import VideoDemo from '../../src/components/VideoDemo';
|
||||
|
||||
## WebIDE背景
|
||||
传统的代码托管平台提供了代码仓库的 Git/SVN 的管理,可以在平台上做代码浏览、代码评审、缺陷管理、CI 流水线等和代码相关的活动。其中代码浏览、代码评审所用的编辑器组件一般为 CodeMirror,代码高亮使用 highlight.js,常常只提供了读代码的场景。蚂蚁研发效能部门云研发团队通过自研的 OpenSumi 框架及基于 OpenSumi 框架做的专门针对于 Web IDE(无远程容器)场景的极速版 Web IDE 框架,与内部代码托管平台碰撞出了创新型的、只依赖浏览器的、IDE 风格的代码阅读、代码编写、代码提交、代码运行、代码评审等场景,极大的提高了用户在代码托管平台阅读代码、代码评审、轻研发等场景的效率。本次蚂蚁研发效能云研发团队和 CCF(中国计算机学会)GitLink 代码托管平台合作,将内部极速版 Web IDE 应用到了 Gitlink 代码托管平台上,解决了长久以来的用户反馈的很多体验问题。
|
||||
|
||||
|
|
@ -29,12 +32,14 @@ sidebar_position: 9
|
|||
|
||||
## 代码阅读
|
||||
在代码托管平台上进行代码阅读时经常需要查看当前方法在哪里被引用、当前接口在哪里被实现,极速版 Web IDE 提供编辑器 + 插件的能力,解决了上述用户需求:
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
<center>代码引用查看</center>
|
||||
Gitlink 通过实现 Blame 插件,完成了编辑器 Blame 查看的能力:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>当前代码行作者、修改日期查看</center>
|
||||
|
||||
|
||||
|
|
@ -44,24 +49,50 @@ Gitlink 通过实现 Blame 插件,完成了编辑器 Blame 查看的能力:
|
|||
- 1.语言服务缺失,阅读效率低:缺少代码高亮、提示、跳转、查看引用及大纲功能
|
||||
- 2.大 PR 浏览体验不佳:统计显示 Gitlink PR 平均有 14-17 个变更文件,传统代码评审交互一般为代码 Diff 组件流式展示,对于一些变更文件多、文件内部较大的场景 Review 体验不佳,常常要等待很久。
|
||||
- 3.代码修改流程重,耗时久:代码 Diff 组件只有读能力,无法快速修改一些拼写或 lint 错误,需要在本地找到对应文件后修改提交 针对于上述需求,蚂蚁云研发团队和 Gitlink 打造了 IDE 风格的代码评审场景:
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
<center>IDE模式的代码评审</center>
|
||||
- 1.变更树 a. 提供平铺和树状两种浏览方式 b. 变更树使用 OpenSumi Recycle 组件,对于大 PR 也能通过虚拟滚动高性能的查看变更文件
|
||||
- 2.工具栏 a. 提供 IDE 编辑器基础设置,如字体大小、编码、忽略收尾空格等 b. 快速切换当前分支历史版本与基线的对比 c. 变更文件快速定位、设置已查看,并支持快捷键快速执行
|
||||
- 3.编辑器 a. 通过 monaco fold 能力完成非变更内容的折叠 b. 自定义评论组件嵌入编辑器
|
||||
- 4.插件 a. 复用代码浏览 Blame 插件能力进行代码行 Git 信息查看 除了上述能力,Gitlink 还支持了在代码评审时快速修改代码:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>代码评审时可修改代码</center>
|
||||
|
||||
## WebIDE 功能演示
|
||||
|
||||
下面是 GitLink WebIDE 的功能演示视频,通过观看视频,您可以直观地了解如何使用 WebIDE 进行代码浏览、编辑和提交等操作。
|
||||
|
||||
<VideoDemo
|
||||
title="GitLink WebIDE 使用教程"
|
||||
platform="local"
|
||||
videoId="/mp4/example.mp4"
|
||||
options={{
|
||||
showTips: false
|
||||
}}
|
||||
/>
|
||||
|
||||
### 在线运行演示
|
||||
|
||||
<VideoDemo
|
||||
title="WebIDE 在线运行演示"
|
||||
platform="bilibili"
|
||||
videoId="BV15a411o72i"
|
||||
options={{ showTips: true }}
|
||||
/>
|
||||
|
||||
## Gitlink Web IDE
|
||||
Gitlink 代码阅读场景虽然接入极速版 IDE 编辑器,但文件树、代码搜索、快捷键、IDE 皮肤、等均和平时开发时使用习惯的 IDE 差异较大,更有大部分用户仅仅是为了代码阅读将代码克隆到本地,尽管保证了一致的体验,但整个链路繁琐费时。
|
||||
基于这个洞察,蚂蚁云研发团队和 Gitlink 推出 Gitlink Web IDE,可以一键快速打开 Web IDE 访问阅读项目仓库代码,实现项目与 IDE 的无缝衔接,保持研发同学的日常偏好习惯,同时完美兼容 Gitlink 代码托管平台。更重要的是,通过无容器在浏览器上直接运行一个极速版 IDE,确保「秒开」的即时体验。
|
||||
|
||||
#### **1. 快速体验**
|
||||
从 Gitlink 仓库首页 Web IDE 入口即可体验
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
<center>Gitlink WebIDE 入口</center>
|
||||
|
||||
#### **2. 代码浏览体验**
|
||||
|
|
@ -69,54 +100,64 @@ Gitlink 代码阅读场景虽然接入极速版 IDE 编辑器,但文件树、
|
|||
#### **3. 语言功能**
|
||||
- 1.支持近 40 种语言的语法高亮
|
||||
- 2.支持 JavaScript/TypeScript、HTML、CSS、JSON、Markdown 的基于 LSP (Language Server Protocol) 语言特性功能,具备智能提示和大纲信息以及单文件内跳转。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>JS语言服务提示</center>
|
||||
|
||||
- 3.提供了 Java、Go、Python、C++、Php 的在线语言服务能力,支持简单的定义跳转、查找引用等功能,让大家更加方便的阅读代码
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>Python 查看引用</center>
|
||||
|
||||
#### **4. 分支新建与切换**
|
||||
点击左下角分支名即可新建/切换分支。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>分支新建与切换</center>
|
||||
|
||||
|
||||
#### **5. 文件搜索**
|
||||
使用 CMD/Ctrl + P 唤起文件搜索面板
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>文件搜索面板</center>
|
||||
|
||||
#### **6. 行高亮**
|
||||
持单行或多行高亮,点击行号即可高亮行,按住 Shift 可选中连续多行。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>多选行高亮</center>
|
||||
|
||||
#### **7. Blame**
|
||||
支持查看单行 blame 信息,hover 后可展示详细信息。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>Blame详细信息</center>
|
||||
|
||||
#### **8. Graph**
|
||||
支持 graph 视图,可查看分支 commits 历史以及每个 commit 详细文件变更,并支持文件 diff 查看。底部状态栏左下角点击 Git Graph 或在命令面板输入 View Git Graph,即可打开 Git Graph 视图。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>Graph 详细信息</center>
|
||||
|
||||
|
||||
#### **9.WebSCM**
|
||||
对于开发来说日常多个需求并行开发是非常常见的事,经常修改一些很小但必要的逻辑,而也许你本地环境已经在开发下一个需求,频繁的分支切换并行修改又容易出错。通过 Gitlink Web IDE 极速切换分支修改提交一气呵成,无需打断本地开发流程。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>WebSCM</center>
|
||||
|
||||
|
||||
#### **10.代码在线运行**
|
||||
目前如果在没有容器的情况下,大部分应用只能运行前端代码。Gitlink Web IDE 集成了基于 skypack 的更加轻量的 CodeSwing 插件,可以在极速版去运行前端代码,并且代码版本是使用 Gitlink 来管理。结合上述 WebSCM 能力,甚至能在一分钟完成前端代码初始化、编写、预览和代码提交。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>前端代码运行</center>
|
||||
|
||||
随着 Webassembly 技术的发展,一些后端语言也可以运行在浏览器里,在 2021 年 Google IO 大会上,StackBlitz 展示了他们最近做的技术:WebContainer,该能力可以将语言运行时编译为 Webassembly 从而运行在浏览器上。Code-Runner-For-Web 插件结合 Pyodide,已经将 Python 的运行搬到了浏览器上,新版极速版也默认集成了该插件。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>Python代码运行</center>
|
||||
|
|
@ -6,26 +6,27 @@ sidebar_position: 2
|
|||
|
||||
在 *https://www.gitlink.org.cn* 页面点击顶部导航栏的“+”符号可以进行组织新建操作。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
在新建页面中输入**组织账号**、**组织名称**、**组织描述**、**所在地区**、**可见性**以及**组织头像**等信息后,点击“**创建组织**”按钮完成组织的创建。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
## 组织账号
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
**注**:只能使用以字母、数字开头,包含字母、数字、下划线、横杠等,长度4到20个字符
|
||||
|
||||
## 组织名称与组织描述
|
||||
<br/>
|
||||
|
||||

|
||||
|
||||
**注**:此处为必填项,不得为空
|
||||
|
||||
## 可见性
|
||||
<br/>
|
||||
|
||||

|
||||
|
||||
**注**:可见性预设三类组织:公开、受限(仅对登录用户可见)、私有(仅对组织成员可见)。
|
||||
|
|
|
|||
|
|
@ -9,26 +9,26 @@ sidebar_position: 3
|
|||
|
||||
在团队新建页面,输入团队标识、团队名称、团队描述、项目权限以及版本库权限等信息后,点击“新建团队”完成团队的创建。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
## 查看组织团队
|
||||
|
||||
点击组织信息页面中的某个团队名称可以查看该团队的详细信息,该页面包括团队的名称、描述等信息,此外还会列出该团队关联的成员以及项目。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
## 管理组织团队
|
||||
|
||||
点击团队信息页面中的“团队设置”按钮可以对团队进行管理
|
||||
|
||||
- 基本设置:修改项目的基本信息,如名称和描述等。
|
||||

|
||||
|
||||
<br/>
|
||||
- 团队成员管理:为该团队添加新成员或者移除已有成员。
|
||||

|
||||
|
||||
<br/>
|
||||
- 团队项目管理:为该团队关联新项目(该组织已经创建的项目)或者移除已关联项目。
|
||||

|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,16 +6,17 @@ sidebar_position: 4
|
|||
|
||||
在 个人所管理的项目当中的**仓库设置**当中的**成员管理**可以进入成员管理界面
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
## 成员查询和添加
|
||||
在成员管理界面当中,可以进行组织成员的查询和添加
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
## 成员邀请权限设置
|
||||
管理员可以对邀请成员的权限进行设置
|
||||

|
||||
|
||||
<br/>
|
||||
此外,也可以复制邀请链接的方式来更方便地邀请成员加入到项目当中来
|
||||
|
||||
**注**:此项功能仅对管理员可见
|
||||
|
|
@ -3,14 +3,14 @@ sidebar_label: '组织简介'
|
|||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# 组织简介
|
||||
## 组织简介
|
||||
|
||||
组织是共享帐户,其中业务和开源项目可同时跨多个项目进行协作,具有复杂的安全性和管理功能。多个个人帐户可以通过加入同一组织帐户来协作处理共享项目。
|
||||
|
||||
您的团队可以通过使用组织帐户在 GitLink 上进行协作,组织帐户充当共享工作的容器,并为工作赋予独特的名称和品牌。同时,平台支持组织在“组织详情”页面发布新闻动态,显示项目概览和仓库详情等内容
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
## 作为组织拥有者
|
||||
|
||||
有效管理组织,是您的使命。
|
||||
|
|
@ -19,8 +19,8 @@ sidebar_position: 1
|
|||
|
||||
为了简化访问管理并增强协作,您可以创建能体现组结构的嵌套团队。您可以根据他们的角色或项目将人员分组,并分配任务。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
平台同时支持组织拥有者管理对数据访问的自定义设置。
|
||||
|
||||
## 作为组织成员
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ sidebar_position: 5
|
|||
|
||||
点击组织信息页面中的“新建项目”按钮可以创建属于该组织的托管项目或者镜像项目。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
**注**:在“拥有者”一栏的下拉选项中,可以选择:个人、组织、团队
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ sidebar_position: 2
|
|||
## 模板的导入及导出管理
|
||||
#### 1.模板导入
|
||||
通过点击wiki界面的**导入模板**按钮即可导入本地的txt,markdown等格式文件进行Wiki文档的创建,当前平台此项功能尚在开发测试环节
|
||||
[](/img/wiki/img4.png)
|
||||
|
||||
<br/>
|
||||
#### 2.模板导出
|
||||
当前平台此项功能尚在开发测试环节
|
||||
<br/>
|
||||
|
|
|
|||
|
|
@ -9,15 +9,17 @@ sidebar_position: 1
|
|||
## 维基界面管理
|
||||
#### 1.维基界面
|
||||
GitLink项目安排了专门的**维基(Wiki)界面**来展示项目的一些情况
|
||||
[](/img/wiki/img1.png)
|
||||
|
||||
<br/>
|
||||
#### 2.创建维基内容
|
||||
在初始化的维基界面当中点击**创建Wiki文档**或者**导入模板**即可进行Wiki文档的编辑
|
||||
<br/>
|
||||
|
||||
#### 3.进行Wiki文档的编辑
|
||||
点击**创建Wiki文档**后即跳转到编辑界面,初始内容为空白的文档
|
||||
[](/img/wiki/img3.png)
|
||||
|
||||
<br/>
|
||||
也可以通过勾选*添加模板*来进行模板的导入,平台提供的模板包括*周报*和*月报*的格式
|
||||
[](/img/wiki/img2.png)
|
||||
|
||||
<br/>
|
||||
完成编辑后点击左下角的的保存即可
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
sidebar_label: "视频介绍"
|
||||
label: "视频介绍"
|
||||
sidebar_position: 0.5
|
||||
---
|
||||
|
||||
# GitLink 视频教程
|
||||
|
||||
在本页面,您可以找到各种 GitLink 功能的视频教程演示。这些视频将帮助您更直观地了解 GitLink 的使用方法。
|
||||
|
||||
import VideoDemo from '../src/components/VideoDemo';
|
||||
|
||||
## 快速入门
|
||||
|
||||
<VideoDemo
|
||||
title="GitLink 平台介绍"
|
||||
description="快速了解 GitLink 平台的主要功能和使用场景"
|
||||
platform="bilibili"
|
||||
videoId="BV1Gx411w7vd"
|
||||
options={{ showTips: true }}
|
||||
/>
|
||||
|
||||
## 代码库管理
|
||||
|
||||
<VideoDemo
|
||||
title="如何创建和管理代码仓库"
|
||||
description="学习创建代码仓库、管理分支、设置权限等基本操作"
|
||||
platform="bilibili"
|
||||
videoId="BV1Gx411w7vd"
|
||||
options={{ showTips: true }}
|
||||
/>
|
||||
|
||||
## WebIDE 功能
|
||||
|
||||
<VideoDemo
|
||||
title="WebIDE 使用指南"
|
||||
description="学习如何使用 GitLink 的 WebIDE 进行在线编码和调试"
|
||||
platform="bilibili"
|
||||
videoId="BV1Gx411w7vd"
|
||||
options={{ showTips: true, tips: "WebIDE 支持多种编程语言和开发环境" }}
|
||||
/>
|
||||
|
||||
## DevOps 引擎
|
||||
|
||||
<VideoDemo
|
||||
title="DevOps 引擎配置与使用"
|
||||
description="了解如何配置和使用 GitLink 的 DevOps 引擎进行持续集成和部署"
|
||||
platform="bilibili"
|
||||
videoId="BV1Gx411w7vd"
|
||||
options={{ showTips: true }}
|
||||
/>
|
||||
|
||||
## 团队协作
|
||||
|
||||
<VideoDemo
|
||||
title="团队协作最佳实践"
|
||||
description="学习在 GitLink 上进行团队协作的最佳实践和工作流程"
|
||||
platform="bilibili"
|
||||
videoId="BV1Gx411w7vd"
|
||||
options={{ showTips: true }}
|
||||
/>
|
||||
|
||||
:::tip 提示
|
||||
视频中使用的是最新版 GitLink 界面,如果您使用的版本界面略有不同,功能和操作方式基本一致。
|
||||
:::
|
||||
|
||||
:::info 问题反馈
|
||||
如果您对视频内容有任何疑问,或者希望我们提供更多特定主题的视频教程,请通过 [GitLink 社区](https://www.gitlink.org.cn) 或邮箱 gitlink@ccf.org.cn 联系我们。
|
||||
:::
|
||||
|
|
@ -17,13 +17,15 @@ GitLink将通知分为“系统通知”和“@我”的两种类型:
|
|||
| 我管理的仓库 | 有新的疑修;有新的合并请求;有成员变动;仓库设置被更改;|
|
||||
* “@我”的通知目前支持在用户首页、课程首页、项目首页的动态列表中使用@功能对用户进行通知:
|
||||
例,在项目首页提交疑修时,输入@后可以通过下拉列表选择@其他用户。
|
||||

|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
#### 2.查看通知
|
||||
登录后在平台右上角个人头像旁即可查看收到的通知数量;移动光标至通知按钮出现下拉列表可以分别查看“系统通知”和“@我”的通知;下拉列表右下角可以对所有消息进行一键已读;点击通知即可跳转至通知详情界面。
|
||||

|
||||
<br/>
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
点击通知按钮可以进入消息通知界面,“我的通知”界面可以进行“进查看未读消息”和“所有消息一键已读”的选择。
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -9,13 +9,13 @@ sidebar_position: 2
|
|||
## 通知设置
|
||||
#### 1.进入通知设置界面
|
||||
通过点击首页的通知按钮进入通知设置界面;
|
||||

|
||||
<br/>
|
||||
或在头像下拉列表中选择设置可以进入消息通知设置界面;
|
||||
<br/>
|
||||
|
||||
|
||||
或在头像下拉列表中选择设置可以进入消息通知设置界面;
|
||||
<br/>
|
||||
|
||||

|
||||
|
||||
#### 2.进行通知设置
|
||||
通过“通知管理”可以对接受通知的方式进行设置,默认所有通知都是通过站内信的方式接受,可以通过勾选为重要的通知类型增加邮件接受方式。
|
||||
|
||||

|
||||
<br/>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
const lightCodeTheme = require('prism-react-renderer/themes/github');
|
||||
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
|
||||
//Docusaurus v3写法
|
||||
// const { themes } = require('prism-react-renderer');
|
||||
// import { themes } from 'prism-react-renderer';
|
||||
import("@easyops-cn/docusaurus-search-local").PluginOptions;
|
||||
|
||||
/** @type {import('@docusaurus/types').DocusaurusConfig} */
|
||||
|
|
@ -18,7 +15,18 @@ module.exports = {
|
|||
projectName: 'docusaurus-luffyzh-website', // Usually your repo name.
|
||||
scripts: [],
|
||||
// stylesheets: ['styles/dark-mode.css'],
|
||||
plugins: [
|
||||
function (context, options) {
|
||||
return {
|
||||
name: 'custom-docusaurus-plugin',
|
||||
injectHtmlTags() {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
},
|
||||
],
|
||||
themeConfig: {
|
||||
|
||||
docs:{
|
||||
sidebar:{
|
||||
hideable:true,
|
||||
|
|
@ -31,7 +39,7 @@ module.exports = {
|
|||
{property:"og:image:alt",content:"GitLink(确实开源)是中国计算机学会CCF官方指定的开源创新服务平台 - Gitlink/forgeplus:GitLink(确实开源)是中国计算机学会CCF官方指定的开源创新服务平台 for gitlink Gitlink/forgeplus for git"}
|
||||
],
|
||||
prism: {
|
||||
theme:lightCodeTheme,
|
||||
theme: lightCodeTheme,
|
||||
darkTheme: darkCodeTheme,
|
||||
},
|
||||
zoom: {
|
||||
|
|
@ -61,7 +69,7 @@ module.exports = {
|
|||
// srcDark: 'img/logo-dark.png',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'intro',
|
||||
position: 'left',
|
||||
|
|
@ -73,30 +81,30 @@ module.exports = {
|
|||
dropdownActiveClassDisabled: true
|
||||
},
|
||||
// {
|
||||
// type: 'localeDropdown',
|
||||
// position: 'right',
|
||||
// },
|
||||
// {
|
||||
// position: 'right',
|
||||
// component:'./src/components/LanguageSwitcher',
|
||||
// label:"language",
|
||||
// to:"#"
|
||||
// items: [
|
||||
// {
|
||||
// label: 'English',
|
||||
// onClick: () => handleLocaleChange('en')
|
||||
// },
|
||||
// {
|
||||
// label: '简体中文',
|
||||
// onClick: () => handleLocaleChange('zh-Hans')
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// {
|
||||
// href: 'https://github.com/boxyhq',
|
||||
// position: 'right',
|
||||
// className: 'header-github-link',
|
||||
// },
|
||||
{
|
||||
type: 'custom-table-of-contents',
|
||||
position: 'right'
|
||||
},
|
||||
{
|
||||
type: 'custom-pdf-export',
|
||||
position: 'right'
|
||||
},
|
||||
{
|
||||
type: 'custom-back-to-top',
|
||||
position: 'right'
|
||||
},
|
||||
{
|
||||
type: 'custom-back-to-bottom',
|
||||
position: 'right'
|
||||
},
|
||||
{
|
||||
type: 'custom-qa-button',
|
||||
position: 'right'
|
||||
}
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
|
|
@ -193,7 +201,7 @@ module.exports = {
|
|||
hashed: true,
|
||||
language: ["en", "zh"],
|
||||
highlightSearchTermsOnTargetPage: true,
|
||||
blogRouteBasePath: "/",
|
||||
blogRouteBasePath: "/",
|
||||
explicitSearchResultPath: true,
|
||||
// For Docs using Chinese, The `language` is recommended to set to:
|
||||
// ```
|
||||
|
|
@ -204,16 +212,6 @@ module.exports = {
|
|||
],
|
||||
i18n: {
|
||||
defaultLocale: 'zh-cn',
|
||||
locales: ['zh-cn','en'],
|
||||
localeConfigs: {
|
||||
en: {
|
||||
label: 'English',
|
||||
htmlLang: 'en',
|
||||
},
|
||||
'zh-cn': {
|
||||
label: '简体中文',
|
||||
htmlLang: 'zh-CN',
|
||||
},
|
||||
},
|
||||
locales: ['zh-cn'],
|
||||
},
|
||||
};
|
||||
|
|
|
|||
47
oauth2.md
47
oauth2.md
|
|
@ -1,47 +0,0 @@
|
|||
为了构建更好的平台生态环境,我们推出了基于OAuth2的API版本。
|
||||
API 接口使用方式以及Url都参照GitHub,为了各位开发者更好的兼容已经存在的第三方应用。
|
||||
|
||||
# API 使用条款
|
||||
|
||||
未经用户允许,不准爬取或存储用户的资源。
|
||||
禁止滥用 API,请求频率过快将导致请求终止。
|
||||
OAuth2 认证基本流程
|
||||

|
||||
|
||||
# OAuth2 获取 AccessToken 认证步骤
|
||||
|
||||
### 1. 授权码模式
|
||||
* 应用通过 浏览器 或 Webview 将用户引导到平台三方认证页面上( GET请求 )
|
||||
|
||||
`https://gitlink.org.cn/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code`
|
||||
|
||||
* 用户对应用进行授权
|
||||
注意: 如果之前已经授权过的需要跳过授权页面,需要在上面第一步的 URL 加上 scope 参数,且 scope 的值需要和用户上次授权的勾选的一致。如用户在上次授权了user_info。则步骤A 中 GET 请求应为:
|
||||
|
||||
`https://gitlink.org.cn/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope=user_info`
|
||||
|
||||
* 平台认证服务器通过回调地址`{redirect_uri}`将 用户授权码 传递给 应用服务器 或者直接在 Webview 中跳转到携带 用户授权码的回调地址上,Webview 直接获取code即可(`{redirect_uri}?code=abc&state=xyz`)
|
||||
* 应用服务器 或 Webview 使用 access_token API 向平台认证服务器发送post请求传入 用户授权码 以及 回调地址( POST请求 )
|
||||
注:请求过程建议将 client_secret 放在 Body 中传值,以保证数据安全。
|
||||
|
||||
`https://gitlink.org.cn/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}`
|
||||
|
||||
* 平台认证服务器返回 access_token
|
||||
|
||||
应用通过 access_token 访问 Open API 使用用户数据。
|
||||
当 access_token 过期后(有效期为一天),你可以通过以下 refresh_token 方式重新获取 access_token( POST请求 )
|
||||
|
||||
`https://gitlink.org.cn/oauth/token?grant_type=refresh_token&refresh_token={refresh_token}`
|
||||
|
||||
> 注意:如果获取 access_token 返回 403,可能是没有设置User-Agent的原因。
|
||||
详见:获取Token时服务端响应状态403是什么情况
|
||||
|
||||
### 2. 密码模式
|
||||
* 用户向客户端提供邮箱地址和密码。客户端将邮箱地址和密码发给平台认证服务器,并向平台认证服务器请求令牌。( POST请求。Content-Type: application/x-www-form-urlencoded )
|
||||
|
||||
`curl -X POST --data-urlencode "grant_type=password" --data-urlencode "username={email}" --data-urlencode "password={password}" --data-urlencode "client_id={client_id}" --data-urlencode "client_secret={client_secret}" --data-urlencode "scope=user_info" https://gitlink.org.cn/oauth/token`
|
||||
|
||||
scope表示权限范围,有以下选项,请求时使用空格隔开
|
||||
`user_info` `projects` `pull_requests` `issues` `notes` `keys` `hook groups` `gists` `enterprises`
|
||||
* 认证服务器返回 access_token
|
||||
应用通过 access_token 访问 Open API 使用用户数据。
|
||||
BIN
oauth2.png
BIN
oauth2.png
Binary file not shown.
|
Before Width: | Height: | Size: 135 KiB |
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"name": "docusaurus",
|
||||
"version": "3.0.0",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"dev": "docusaurus start --port 3000",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"deploy": "docsaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
|
|
@ -15,20 +15,18 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@cmfcmf/docusaurus-search-local": "1.1.0",
|
||||
"@docusaurus/core": "3.9.2",
|
||||
"@docusaurus/plugin-client-redirects": "3.9.2",
|
||||
"@docusaurus/preset-classic": "3.9.2",
|
||||
"@docusaurus/core": "2.4.1",
|
||||
"@docusaurus/plugin-client-redirects": "2.4.1",
|
||||
"@docusaurus/preset-classic": "2.4.1",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.35.0",
|
||||
"@mdx-js/react": "^3.1.1",
|
||||
"@mdx-js/react": "1.6.22",
|
||||
"@node-rs/jieba": "^1.7.0",
|
||||
"clsx": "1.2.1",
|
||||
"docusaurus-gtm-plugin": "0.0.2",
|
||||
"docusaurus-plugin-image-zoom": "1.0.1",
|
||||
"or": "^0.2.0",
|
||||
"prism-react-renderer": "^1.3.5",
|
||||
"prismjs": "^1.30.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"html2pdf.js": "^0.10.3",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-modal": "3.16.1"
|
||||
},
|
||||
"browserslist": {
|
||||
|
|
@ -42,8 +40,5 @@
|
|||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.x"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
30
sidebars.js
30
sidebars.js
|
|
@ -2,8 +2,32 @@ module.exports = {
|
|||
DocsSidebar: [
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'index',
|
||||
label: 'Docs',
|
||||
}
|
||||
id: 'intro',
|
||||
label: '介绍',
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: '视频教程',
|
||||
label: '视频教程',
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: '快速开始',
|
||||
collapsed: false,
|
||||
items: ['快速开始/注册GitLink账号', '快速开始/登录GitLink账号'],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: '代码库管理',
|
||||
collapsed: true,
|
||||
items: ['代码库管理/仓库创建'],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: '第三方服务',
|
||||
collapsed: true,
|
||||
items: ['第三方服务/WebIDE', '第三方服务/跨平台代码同步'],
|
||||
},
|
||||
// 其他类别可以根据需要添加
|
||||
],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
import React from 'react';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
|
||||
function BackToBottomButton() {
|
||||
const handleBackToBottom = () => {
|
||||
window.scrollTo({
|
||||
top: document.documentElement.scrollHeight,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={handleBackToBottom}
|
||||
style={{
|
||||
fontSize: 14,
|
||||
padding: '0 16px',
|
||||
background: '#466aff',
|
||||
color: '#fff',
|
||||
borderRadius: 4,
|
||||
height: 32,
|
||||
lineHeight: '32px',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
display: 'inline-block',
|
||||
marginLeft: 12,
|
||||
boxSizing: 'border-box',
|
||||
}}
|
||||
>
|
||||
去到底部
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default function BackToBottomNavbarItem() {
|
||||
return (
|
||||
<BrowserOnly>{() => <BackToBottomButton />}</BrowserOnly>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
// src/components/LanguageSwitcher.js
|
||||
import React from 'react';
|
||||
import { useDocusaurusContext } from '@docusaurus/useDocusaurusContext';
|
||||
|
||||
export default function LanguageSwitcher() {
|
||||
const { i18n } = useDocusaurusContext();
|
||||
|
||||
const locales = [
|
||||
{ code: 'en', label: 'English' },
|
||||
{ code: 'zh-Hans', label: '简体中文' }
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{ marginRight: '1rem' }}>
|
||||
<select
|
||||
value={i18n.currentLocale}
|
||||
onChange={(e) => {
|
||||
localStorage.setItem('preferredLocale', e.target.value);
|
||||
window.location.href = `/${e.target.value}/`;
|
||||
}}
|
||||
style={{
|
||||
padding: '0.5rem 1rem',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: 'white',
|
||||
fontSize: '0.9rem',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
{locales.map((locale) => (
|
||||
<option key={locale.code} value={locale.code}>
|
||||
{locale.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import React from 'react';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
|
||||
function BackToTopButton() {
|
||||
const handleBackToTop = () => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={handleBackToTop}
|
||||
style={{
|
||||
fontSize: 14,
|
||||
padding: '0 16px',
|
||||
background: '#466aff',
|
||||
color: '#fff',
|
||||
borderRadius: 4,
|
||||
height: 32,
|
||||
lineHeight: '32px',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
display: 'inline-block',
|
||||
marginLeft: 12,
|
||||
boxSizing: 'border-box',
|
||||
}}
|
||||
>
|
||||
返回顶部
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PdfBackToTopNavbarItem() {
|
||||
return (
|
||||
<BrowserOnly>{() => <BackToTopButton />}</BrowserOnly>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function PdfExportButton({ title }) {
|
||||
const handleExport = async () => {
|
||||
const element = document.getElementById('doc-markdown-content');
|
||||
if (element) {
|
||||
// 动态导入 html2pdf.js,只在客户端执行
|
||||
const html2pdf = (await import('html2pdf.js')).default;
|
||||
html2pdf()
|
||||
.set({
|
||||
margin: 0.5,
|
||||
filename: `${title}.pdf`,
|
||||
html2canvas: { scale: 2 },
|
||||
jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' }
|
||||
})
|
||||
.from(element)
|
||||
.save();
|
||||
} else {
|
||||
alert('未找到文档内容区域');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={handleExport}
|
||||
style={{
|
||||
fontSize: 14,
|
||||
padding: '0 16px',
|
||||
background: '#466aff',
|
||||
color: '#fff',
|
||||
borderRadius: 4,
|
||||
height: 32,
|
||||
lineHeight: '32px',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
display: 'inline-block',
|
||||
marginLeft: 12,
|
||||
boxSizing: 'border-box',
|
||||
}}
|
||||
>
|
||||
导出PDF
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
import PdfExportButton from './PdfExportButton';
|
||||
|
||||
function PdfExportNavbarItemInner() {
|
||||
useEffect(() => {
|
||||
// 只在客户端执行,给文档内容区域加唯一 id
|
||||
const el = document.querySelector('.markdown');
|
||||
if (el && !el.id) {
|
||||
el.id = 'doc-markdown-content';
|
||||
}
|
||||
}, []);
|
||||
|
||||
let title = document.title;
|
||||
if (title.includes('|')) {
|
||||
title = title.split('|')[0].trim();
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ marginLeft: 12, display: 'flex', alignItems: 'center', height: '100%' }}>
|
||||
<PdfExportButton title={title} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PdfExportNavbarItem() {
|
||||
return (
|
||||
<BrowserOnly>
|
||||
{() => <PdfExportNavbarItemInner />}
|
||||
</BrowserOnly>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import React from 'react';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
|
||||
export default function QAButtonNavbarItem() {
|
||||
return (
|
||||
<BrowserOnly>
|
||||
{() => {
|
||||
const history = require('@docusaurus/router').useHistory();
|
||||
return (
|
||||
<div style={{ display: 'flex', alignItems: 'center', height: '100%' }}>
|
||||
<button
|
||||
onClick={() => history.push('/qa')}
|
||||
style={{
|
||||
fontSize: 14,
|
||||
padding: '0 16px',
|
||||
background: '#466aff',
|
||||
color: '#fff',
|
||||
borderRadius: 4,
|
||||
height: 32,
|
||||
lineHeight: '32px',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
display: 'inline-block',
|
||||
margin: '0 8px',
|
||||
boxSizing: 'border-box',
|
||||
}}
|
||||
>
|
||||
疑问解答
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</BrowserOnly>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import React from 'react';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
import { useLocation } from '@docusaurus/router';
|
||||
import styles from './RatingStats.module.css';
|
||||
|
||||
function RatingStatsContent() {
|
||||
const location = useLocation();
|
||||
|
||||
// 为了演示,这里使用一个简单的哈希函数生成伪随机数
|
||||
const generatePseudoRandom = (str, min, max) => {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const char = str.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + char;
|
||||
hash = hash & hash; // 转换为32位整数
|
||||
}
|
||||
|
||||
// 将哈希值转换为min和max之间的数
|
||||
const normalizedHash = Math.abs(hash) / 2147483647; // 2147483647是2^31-1,最大的32位有符号整数
|
||||
return min + normalizedHash * (max - min);
|
||||
};
|
||||
|
||||
// 基于当前路径生成伪随机的评分数据
|
||||
const averageRating = generatePseudoRandom(location.pathname, 3.5, 5.0).toFixed(1);
|
||||
const ratingCount = Math.floor(generatePseudoRandom(location.pathname, 10, 100));
|
||||
|
||||
// 计算星星的填充百分比
|
||||
const fillPercentage = (averageRating / 5) * 100;
|
||||
|
||||
return (
|
||||
<div className={styles.statsContainer}>
|
||||
<div className={styles.ratingValue}>{averageRating}</div>
|
||||
<div className={styles.starsOuter}>
|
||||
<div
|
||||
className={styles.starsInner}
|
||||
style={{ width: `${fillPercentage}%` }}
|
||||
></div>
|
||||
</div>
|
||||
<div className={styles.ratingCount}>{ratingCount} 人评分</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function RatingStats() {
|
||||
return (
|
||||
<BrowserOnly>
|
||||
{() => <RatingStatsContent />}
|
||||
</BrowserOnly>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
.statsContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.ratingValue {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: var(--ifm-color-emphasis-900);
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.starsOuter {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
font-size: 1.25rem;
|
||||
color: var(--ifm-color-emphasis-300);
|
||||
}
|
||||
|
||||
.starsOuter::before {
|
||||
content: "★★★★★";
|
||||
}
|
||||
|
||||
.starsInner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
color: #f8ce0b;
|
||||
}
|
||||
|
||||
.starsInner::before {
|
||||
content: "★★★★★";
|
||||
}
|
||||
|
||||
.ratingCount {
|
||||
font-size: 0.9rem;
|
||||
color: var(--ifm-color-emphasis-600);
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import styles from './RatingSystem.module.css';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
import { useLocation } from '@docusaurus/router';
|
||||
|
||||
function RatingSystemContent() {
|
||||
const location = useLocation();
|
||||
const [rating, setRating] = useState(0);
|
||||
const [hover, setHover] = useState(0);
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
const [feedback, setFeedback] = useState('');
|
||||
const [showFeedback, setShowFeedback] = useState(false);
|
||||
const [alreadyRated, setAlreadyRated] = useState(false);
|
||||
|
||||
// 生成当前页面的唯一键
|
||||
const pageKey = `rating_${location.pathname}`;
|
||||
|
||||
// 初始化时检查是否已经评分过
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const savedRating = localStorage.getItem(pageKey);
|
||||
if (savedRating) {
|
||||
setAlreadyRated(true);
|
||||
setRating(parseInt(savedRating, 10));
|
||||
}
|
||||
}
|
||||
}, [pageKey]);
|
||||
|
||||
const handleRatingClick = (selectedRating) => {
|
||||
setRating(selectedRating);
|
||||
setShowFeedback(true);
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
// 保存评分到本地存储
|
||||
localStorage.setItem(pageKey, rating.toString());
|
||||
|
||||
// 这里只是前端交互,不进行实际的数据存储
|
||||
console.log('提交的评分:', rating);
|
||||
console.log('提交的反馈:', feedback);
|
||||
console.log('页面路径:', location.pathname);
|
||||
|
||||
setSubmitted(true);
|
||||
|
||||
// 3秒后重置表单状态,但保持已评分状态
|
||||
setTimeout(() => {
|
||||
setSubmitted(false);
|
||||
setAlreadyRated(true);
|
||||
setFeedback('');
|
||||
setShowFeedback(false);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
if (submitted) {
|
||||
return (
|
||||
<div className={styles.ratingContainer}>
|
||||
<div className={styles.thankYouMessage}>
|
||||
<span role="img" aria-label="感谢">🙏</span> 感谢您的反馈!
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (alreadyRated) {
|
||||
return (
|
||||
<div className={styles.ratingContainer}>
|
||||
<h3 className={styles.ratingTitle}>您已经为此页面评分</h3>
|
||||
<div className={styles.starsContainer}>
|
||||
{[...Array(5)].map((_, index) => {
|
||||
const ratingValue = index + 1;
|
||||
return (
|
||||
<span
|
||||
key={index}
|
||||
className={`${styles.star} ${ratingValue <= rating ? styles.filled : ''}`}
|
||||
>
|
||||
★
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<button
|
||||
className={styles.resetButton}
|
||||
onClick={() => {
|
||||
localStorage.removeItem(pageKey);
|
||||
setAlreadyRated(false);
|
||||
setRating(0);
|
||||
}}
|
||||
>
|
||||
重新评分
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.ratingContainer}>
|
||||
<h3 className={styles.ratingTitle}>这篇文档对您有帮助吗?</h3>
|
||||
<div className={styles.starsContainer}>
|
||||
{[...Array(5)].map((_, index) => {
|
||||
const ratingValue = index + 1;
|
||||
return (
|
||||
<span
|
||||
key={index}
|
||||
className={`${styles.star} ${ratingValue <= (hover || rating) ? styles.filled : ''}`}
|
||||
onClick={() => handleRatingClick(ratingValue)}
|
||||
onMouseEnter={() => setHover(ratingValue)}
|
||||
onMouseLeave={() => setHover(0)}
|
||||
>
|
||||
★
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{showFeedback && (
|
||||
<div className={styles.feedbackContainer}>
|
||||
<textarea
|
||||
className={styles.feedbackInput}
|
||||
placeholder="您有什么建议可以帮助我们改进?(可选)"
|
||||
value={feedback}
|
||||
onChange={(e) => setFeedback(e.target.value)}
|
||||
/>
|
||||
<button
|
||||
className={styles.submitButton}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
提交反馈
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function RatingSystem() {
|
||||
return (
|
||||
<BrowserOnly>
|
||||
{() => <RatingSystemContent />}
|
||||
</BrowserOnly>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
.ratingContainer {
|
||||
margin: 2rem 0;
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
background-color: var(--ifm-color-emphasis-100);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ratingTitle {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.2rem;
|
||||
color: var(--ifm-color-emphasis-800);
|
||||
}
|
||||
|
||||
.starsContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.star {
|
||||
font-size: 2rem;
|
||||
color: var(--ifm-color-emphasis-300);
|
||||
cursor: pointer;
|
||||
margin: 0 0.25rem;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.star:hover {
|
||||
color: #f8ce0b;
|
||||
}
|
||||
|
||||
.star.filled {
|
||||
color: #f8ce0b;
|
||||
}
|
||||
|
||||
.feedbackContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 1rem;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.feedbackInput {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
height: 100px;
|
||||
padding: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid var(--ifm-color-emphasis-300);
|
||||
border-radius: 4px;
|
||||
resize: vertical;
|
||||
font-family: inherit;
|
||||
background-color: var(--ifm-background-color);
|
||||
color: var(--ifm-font-color-base);
|
||||
}
|
||||
|
||||
.feedbackInput:focus {
|
||||
outline: none;
|
||||
border-color: var(--ifm-color-primary);
|
||||
box-shadow: 0 0 0 2px rgba(var(--ifm-color-primary-rgb), 0.25);
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
padding: 0.5rem 1.5rem;
|
||||
background-color: var(--ifm-color-primary);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.submitButton:hover {
|
||||
background-color: var(--ifm-color-primary-dark);
|
||||
}
|
||||
|
||||
.resetButton {
|
||||
padding: 0.5rem 1.5rem;
|
||||
background-color: transparent;
|
||||
color: var(--ifm-color-primary);
|
||||
border: 1px solid var(--ifm-color-primary);
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.resetButton:hover {
|
||||
background-color: var(--ifm-color-primary-lightest);
|
||||
}
|
||||
|
||||
.thankYouMessage {
|
||||
font-size: 1.2rem;
|
||||
color: var(--ifm-color-success);
|
||||
font-weight: 500;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
html[data-theme='dark'] .ratingContainer {
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .feedbackInput {
|
||||
background-color: var(--ifm-background-surface-color);
|
||||
border-color: var(--ifm-color-emphasis-300);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.star {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,464 @@
|
|||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
import styles from './TableOfContentsButton.module.css';
|
||||
|
||||
export default function TableOfContentsButton() {
|
||||
return (
|
||||
<BrowserOnly>
|
||||
{() => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const dropdownRef = useRef(null);
|
||||
const searchInputRef = useRef(null);
|
||||
const useHistory = require('@docusaurus/router').useHistory;
|
||||
const history = useHistory();
|
||||
|
||||
// 路径前缀
|
||||
const pathPrefix = '/next';
|
||||
|
||||
// 硬编码的目录结构,基于实际docs文件夹结构
|
||||
// 带有子目录支持
|
||||
const directories = [
|
||||
{
|
||||
name: '首页',
|
||||
path: `${pathPrefix}/`,
|
||||
column: 1,
|
||||
isMainCategory: true
|
||||
},
|
||||
{
|
||||
name: '视频教程',
|
||||
path: `${pathPrefix}/视频教程`,
|
||||
column: 1,
|
||||
isMainCategory: true
|
||||
},
|
||||
{
|
||||
name: '快速开始',
|
||||
path: `${pathPrefix}/快速开始`,
|
||||
column: 1,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '注册GitLink账号', path: `${pathPrefix}/快速开始/注册GitLink账号` },
|
||||
{ name: '创建第一个开源项目', path: `${pathPrefix}/快速开始/创建第一个开源项目` },
|
||||
{ name: '提交第一行代码', path: `${pathPrefix}/快速开始/提交第一行代码` },
|
||||
{ name: '导入GitHub等第三方Git项目', path: `${pathPrefix}/快速开始/导入GitHub等第三方Git项目` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '代码库管理',
|
||||
path: `${pathPrefix}/代码库管理`,
|
||||
column: 1,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '仓库创建', path: `${pathPrefix}/代码库管理/仓库创建` },
|
||||
{ name: '仓库设置', path: `${pathPrefix}/代码库管理/仓库设置` },
|
||||
{ name: '代码提交', path: `${pathPrefix}/代码库管理/代码提交` },
|
||||
{ name: '分支管理', path: `${pathPrefix}/代码库管理/分支管理` },
|
||||
{ name: '文件管理', path: `${pathPrefix}/代码库管理/文件管理` },
|
||||
{ name: '成员管理', path: `${pathPrefix}/代码库管理/成员管理` },
|
||||
{ name: 'Webhook', path: `${pathPrefix}/代码库管理/Webhook` },
|
||||
{ name: 'WebIDE', path: `${pathPrefix}/代码库管理/WebIDE` },
|
||||
{ name: '标签和发行版管理', path: `${pathPrefix}/代码库管理/标签和发行版管理` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '合并请求(PR)',
|
||||
path: `${pathPrefix}/合并请求`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '合并请求简介', path: `${pathPrefix}/合并请求/合并请求简介` },
|
||||
{ name: '创建合并请求', path: `${pathPrefix}/合并请求/创建合并请求` },
|
||||
{ name: '代码评审', path: `${pathPrefix}/合并请求/代码评审` },
|
||||
{ name: '合并模式简介', path: `${pathPrefix}/合并请求/合并模式简介` },
|
||||
{ name: '合并请求关联疑修', path: `${pathPrefix}/合并请求/合并请求关联疑修` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '疑修(Issue)',
|
||||
path: `${pathPrefix}/疑修`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '疑修简介', path: `${pathPrefix}/疑修/疑修简介` },
|
||||
{ name: '疑修创建', path: `${pathPrefix}/疑修/疑修创建` },
|
||||
{ name: '疑修状态变更', path: `${pathPrefix}/疑修/疑修状态变更` },
|
||||
{ name: '疑修列表', path: `${pathPrefix}/疑修/疑修列表` },
|
||||
{ name: '评论及操作记录', path: `${pathPrefix}/疑修/评论及操作记录` },
|
||||
{ name: '标记管理', path: `${pathPrefix}/疑修/标记管理` },
|
||||
{ name: '里程碑管理', path: `${pathPrefix}/疑修/里程碑管理` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '机器人(Bot)',
|
||||
path: `${pathPrefix}/Bot市场/Bot简介`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: 'bot安装', path: `${pathPrefix}/Bot市场/bot安装` },
|
||||
{ name: 'bot配置', path: `${pathPrefix}/Bot市场/bot配置` },
|
||||
{ name: 'bot开发', path: `${pathPrefix}/Bot市场/bot开发` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '第三方服务',
|
||||
path: `${pathPrefix}/第三方服务`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: 'WebIDE', path: `${pathPrefix}/第三方服务/WebIDE` },
|
||||
{ name: '重睛鸟代码溯源', path: `${pathPrefix}/第三方服务/重睛鸟代码溯源` },
|
||||
{ name: '跨平台代码同步服务', path: `${pathPrefix}/第三方服务/跨平台代码同步` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '组织管理',
|
||||
path: `${pathPrefix}/组织管理`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '组织简介', path: `${pathPrefix}/组织管理/组织简介` },
|
||||
{ name: '组织创建及设置', path: `${pathPrefix}/组织管理/组织创建及设置` },
|
||||
{ name: '组织团队管理', path: `${pathPrefix}/组织管理/组织团队管理` },
|
||||
{ name: '组织成员管理', path: `${pathPrefix}/组织管理/组织成员管理` },
|
||||
{ name: '组织项目管理', path: `${pathPrefix}/组织管理/组织项目管理` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '维基',
|
||||
path: `${pathPrefix}/维基`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '维基页面管理', path: `${pathPrefix}/维基/维基页面管理` },
|
||||
{ name: '模板导入及导出', path: `${pathPrefix}/维基/模板导入及导出` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'DevOps引擎',
|
||||
path: `${pathPrefix}/DevOps引擎`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '引擎简介', path: `${pathPrefix}/DevOps引擎/引擎简介` },
|
||||
{ name: '代码流水线', path: `${pathPrefix}/DevOps引擎/代码流水线` },
|
||||
{ name: '图形流水线', path: `${pathPrefix}/DevOps引擎/图形流水线` },
|
||||
{ name: '参数配置', path: `${pathPrefix}/DevOps引擎/参数配置` },
|
||||
{ name: '密钥设置', path: `${pathPrefix}/DevOps引擎/密钥设置` },
|
||||
{ name: '执行记录查询', path: `${pathPrefix}/DevOps引擎/执行记录查询` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '通知',
|
||||
path: `${pathPrefix}/通知`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '通知简介', path: `${pathPrefix}/通知/通知简介` },
|
||||
{ name: '通知设置', path: `${pathPrefix}/通知/通知设置` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '个人主页建站',
|
||||
path: `${pathPrefix}/个人主页建站`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '建站流程', path: `${pathPrefix}/个人主页建站/站点创建流程` },
|
||||
{ name: '建站工具', path: `${pathPrefix}/个人主页建站/建站工具` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '平台公告',
|
||||
path: `${pathPrefix}/平台公告`,
|
||||
column: 3,
|
||||
isMainCategory: true
|
||||
},
|
||||
{
|
||||
name: '服务协议',
|
||||
path: `${pathPrefix}/服务协议`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: 'GitLink服务协议', path: `${pathPrefix}/服务协议/GitLink服务协议` }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// 按列分组目录
|
||||
// 重新分配各目录到三列,确保各列内容均衡
|
||||
const column1 = directories.filter(dir =>
|
||||
dir.name === '首页' ||
|
||||
dir.name === '视频教程' ||
|
||||
dir.name === '快速开始' ||
|
||||
dir.name === '代码库管理' ||
|
||||
dir.name === '合并请求(PR)'
|
||||
);
|
||||
|
||||
const column2 = directories.filter(dir =>
|
||||
dir.name === '疑修(Issue)' ||
|
||||
dir.name === '机器人(Bot)' ||
|
||||
dir.name === '维基' ||
|
||||
dir.name === '第三方服务' ||
|
||||
dir.name === '组织管理'
|
||||
);
|
||||
|
||||
const column3 = directories.filter(dir =>
|
||||
dir.name === 'DevOps引擎' ||
|
||||
dir.name === '通知' ||
|
||||
dir.name === '个人主页建站' ||
|
||||
dir.name === '平台公告' ||
|
||||
dir.name === '服务协议'
|
||||
);
|
||||
|
||||
// 移除列4,改为三列布局
|
||||
const column4 = [];
|
||||
|
||||
// 搜索功能
|
||||
// 过滤目录项
|
||||
const filterDirectories = (query) => {
|
||||
if (!query) return directories;
|
||||
|
||||
const normalizedQuery = query.toLowerCase().trim();
|
||||
|
||||
return directories.filter(dir => {
|
||||
// 检查主目录名称是否匹配
|
||||
const dirNameMatch = dir.name.toLowerCase().includes(normalizedQuery);
|
||||
|
||||
// 如果主目录匹配,直接返回
|
||||
if (dirNameMatch) return true;
|
||||
|
||||
// 检查子目录是否有匹配
|
||||
if (dir.subItems && dir.subItems.length > 0) {
|
||||
const hasMatchingSubItem = dir.subItems.some(
|
||||
subItem => subItem.name.toLowerCase().includes(normalizedQuery)
|
||||
);
|
||||
return hasMatchingSubItem;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
// 获取经过搜索过滤的目录列表
|
||||
const filteredDirectories = filterDirectories(searchQuery);
|
||||
|
||||
// 过滤后的目录分组
|
||||
const filteredColumn1 = filteredDirectories.filter(dir => column1.some(c => c.name === dir.name));
|
||||
const filteredColumn2 = filteredDirectories.filter(dir => column2.some(c => c.name === dir.name));
|
||||
const filteredColumn3 = filteredDirectories.filter(dir => column3.some(c => c.name === dir.name));
|
||||
|
||||
// 将搜索结果重新分配到各列,实现更均衡的布局
|
||||
const distributeSearchResults = (results) => {
|
||||
if (!searchQuery) {
|
||||
// 不搜索时使用原始布局
|
||||
return {
|
||||
col1: filteredColumn1,
|
||||
col2: filteredColumn2,
|
||||
col3: filteredColumn3,
|
||||
col4: []
|
||||
};
|
||||
}
|
||||
|
||||
// 搜索时根据数量动态分配
|
||||
const totalCount = results.length;
|
||||
|
||||
if (totalCount <= 3) {
|
||||
// 结果很少时,全部放在第一列
|
||||
return {
|
||||
col1: results,
|
||||
col2: [],
|
||||
col3: [],
|
||||
col4: []
|
||||
};
|
||||
} else if (totalCount <= 6) {
|
||||
// 结果较少时,放在两列
|
||||
const midPoint = Math.ceil(totalCount / 2);
|
||||
return {
|
||||
col1: results.slice(0, midPoint),
|
||||
col2: results.slice(midPoint),
|
||||
col3: [],
|
||||
col4: []
|
||||
};
|
||||
} else {
|
||||
// 结果较多时,放在三列
|
||||
const colSize = Math.ceil(totalCount / 3);
|
||||
return {
|
||||
col1: results.slice(0, colSize),
|
||||
col2: results.slice(colSize, colSize * 2),
|
||||
col3: results.slice(colSize * 2),
|
||||
col4: []
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 获取重新分配后的各列内容
|
||||
const {
|
||||
col1: displayColumn1,
|
||||
col2: displayColumn2,
|
||||
col3: displayColumn3,
|
||||
col4: displayColumn4
|
||||
} = distributeSearchResults(filteredDirectories);
|
||||
|
||||
// 处理搜索框变化
|
||||
const handleSearchChange = (e) => {
|
||||
setSearchQuery(e.target.value);
|
||||
};
|
||||
|
||||
// 清除搜索
|
||||
const clearSearch = () => {
|
||||
setSearchQuery('');
|
||||
if (searchInputRef.current) {
|
||||
searchInputRef.current.focus();
|
||||
}
|
||||
};
|
||||
|
||||
// 处理点击目录链接
|
||||
const handleDirectoryClick = (dir) => {
|
||||
// 如果有子目录,则跳转到第一个子目录
|
||||
if (dir.subItems && dir.subItems.length > 0) {
|
||||
history.push(dir.subItems[0].path);
|
||||
} else {
|
||||
history.push(dir.path);
|
||||
}
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
// 点击外部关闭下拉菜单
|
||||
useEffect(() => {
|
||||
function handleClickOutside(event) {
|
||||
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => {
|
||||
document.removeEventListener('mousedown', handleClickOutside);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 当目录打开时聚焦到搜索框
|
||||
useEffect(() => {
|
||||
if (isOpen && searchInputRef.current) {
|
||||
setTimeout(() => {
|
||||
searchInputRef.current.focus();
|
||||
}, 100);
|
||||
} else {
|
||||
setSearchQuery(''); // 关闭目录时清空搜索
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
// 渲染目录项
|
||||
const renderDirectoryItem = (dir) => {
|
||||
// 当有搜索词时,只显示匹配的子项
|
||||
let subItems = dir.subItems;
|
||||
if (searchQuery && dir.subItems) {
|
||||
const normalizedQuery = searchQuery.toLowerCase().trim();
|
||||
subItems = dir.subItems.filter(item =>
|
||||
item.name.toLowerCase().includes(normalizedQuery)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={dir.name} className={styles.directoryItem}>
|
||||
<a
|
||||
onClick={() => handleDirectoryClick(dir)}
|
||||
className={`${styles.docLink} ${styles.mainCategory}`}
|
||||
>
|
||||
{dir.name}
|
||||
</a>
|
||||
|
||||
{subItems && subItems.length > 0 && (
|
||||
<div className={styles.subItemsContainer}>
|
||||
{subItems.map(subItem => (
|
||||
<a
|
||||
key={subItem.name}
|
||||
onClick={() => {
|
||||
history.push(subItem.path);
|
||||
setIsOpen(false);
|
||||
}}
|
||||
className={`${styles.docLink} ${styles.subCategory}`}
|
||||
>
|
||||
{subItem.name}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.tocButtonContainer} ref={dropdownRef}>
|
||||
<button
|
||||
className={styles.tocButton}
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
aria-label="文档目录"
|
||||
title="浏览文档目录"
|
||||
>
|
||||
<span className={styles.tocIcon}>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 5H21" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
|
||||
<path d="M3 12H21" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
|
||||
<path d="M3 19H21" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{isOpen && (
|
||||
<div className={styles.tocDropdown}>
|
||||
<h2 className={styles.tocTitle}>文档目录</h2>
|
||||
|
||||
<div className={styles.searchContainer}>
|
||||
<input
|
||||
ref={searchInputRef}
|
||||
type="text"
|
||||
value={searchQuery}
|
||||
onChange={handleSearchChange}
|
||||
placeholder="搜索文档..."
|
||||
className={styles.searchInput}
|
||||
aria-label="搜索文档"
|
||||
/>
|
||||
{searchQuery && (
|
||||
<button
|
||||
className={styles.clearSearchButton}
|
||||
onClick={clearSearch}
|
||||
aria-label="清除搜索"
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 6L6 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
<path d="M6 6L18 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={styles.tocContent}>
|
||||
{filteredDirectories.length === 0 ? (
|
||||
<div className={styles.emptyMessage}>未找到匹配的文档</div>
|
||||
) : (
|
||||
<div className={styles.multiColumnLayout}>
|
||||
<div className={styles.column}>
|
||||
{displayColumn1.map(renderDirectoryItem)}
|
||||
</div>
|
||||
{displayColumn2.length > 0 && (
|
||||
<div className={styles.column}>
|
||||
{displayColumn2.map(renderDirectoryItem)}
|
||||
</div>
|
||||
)}
|
||||
{displayColumn3.length > 0 && (
|
||||
<div className={styles.column}>
|
||||
{displayColumn3.map(renderDirectoryItem)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</BrowserOnly>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
.tocButtonContainer {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* 搜索框样式 */
|
||||
.searchContainer {
|
||||
position: relative;
|
||||
margin-bottom: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.searchInput {
|
||||
width: 100%;
|
||||
padding: 0.75rem 2.5rem 0.75rem 1rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--ifm-color-emphasis-300);
|
||||
background-color: var(--ifm-background-color);
|
||||
color: var(--ifm-font-color-base);
|
||||
font-size: 0.95rem;
|
||||
outline: none;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.searchInput:focus {
|
||||
border-color: var(--ifm-color-primary);
|
||||
box-shadow: 0 0 0 2px rgba(var(--ifm-color-primary-rgb), 0.25);
|
||||
}
|
||||
|
||||
.clearSearchButton {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px;
|
||||
cursor: pointer;
|
||||
color: var(--ifm-color-emphasis-500);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.clearSearchButton:hover {
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
color: var(--ifm-color-emphasis-700);
|
||||
}
|
||||
|
||||
/* 暗色模式搜索框适配 */
|
||||
html[data-theme='dark'] .searchInput {
|
||||
background-color: var(--ifm-background-surface-color);
|
||||
border-color: var(--ifm-color-emphasis-300);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .searchInput:focus {
|
||||
border-color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
.tocButton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: var(--ifm-navbar-link-color);
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.tocButton:hover {
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
color: var(--ifm-navbar-link-hover-color);
|
||||
}
|
||||
|
||||
.tocIcon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tocDropdown {
|
||||
position: absolute;
|
||||
top: calc(100% + 5px);
|
||||
right: 0;
|
||||
width: 800px;
|
||||
max-width: 98vw;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
background-color: var(--ifm-background-surface-color);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16);
|
||||
z-index: 1000;
|
||||
padding: 1.5rem;
|
||||
border: 1px solid var(--ifm-color-emphasis-200);
|
||||
}
|
||||
|
||||
.tocTitle {
|
||||
font-size: 1.25rem;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid var(--ifm-color-emphasis-200);
|
||||
}
|
||||
|
||||
.tocContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.multiColumnLayout {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1.5rem;
|
||||
width: 100%;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.85rem;
|
||||
flex: 1;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.column:nth-child(1),
|
||||
.column:nth-child(2),
|
||||
.column:nth-child(3) {
|
||||
align-self: stretch;
|
||||
height: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.column:nth-child(4) {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.directoryItem {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.mainCategory {
|
||||
font-weight: 600;
|
||||
color: var(--ifm-color-primary);
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.subItemsContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 1.25rem;
|
||||
margin-top: 0.15rem;
|
||||
margin-bottom: 0.25rem;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.subCategory {
|
||||
font-weight: normal;
|
||||
color: var(--ifm-font-color-base);
|
||||
padding: 0.3rem 0.5rem;
|
||||
font-size: 0.92rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.subCategory:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: 50%;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--ifm-color-emphasis-400);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.docLink {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.docLink:hover {
|
||||
background-color: var(--ifm-color-emphasis-100);
|
||||
color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
.activeDoc .docLink {
|
||||
background-color: var(--ifm-color-emphasis-100);
|
||||
color: var(--ifm-color-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 响应式样式 */
|
||||
@media (max-width: 768px) {
|
||||
.tocDropdown {
|
||||
width: 640px;
|
||||
right: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
html[data-theme='dark'] .tocDropdown {
|
||||
background-color: var(--ifm-background-surface-color);
|
||||
border-color: var(--ifm-color-emphasis-300);
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
.tocDropdown::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.tocDropdown::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.tocDropdown::-webkit-scrollbar-thumb {
|
||||
background-color: var(--ifm-color-emphasis-300);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.tocDropdown::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--ifm-color-emphasis-400);
|
||||
}
|
||||
|
||||
.loadingMessage,
|
||||
.errorMessage,
|
||||
.emptyMessage {
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
color: var(--ifm-color-emphasis-600);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.errorMessage {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import React from 'react';
|
||||
import TableOfContentsButton from './TableOfContentsButton';
|
||||
|
||||
export default function TableOfContentsNavbarItem() {
|
||||
return <TableOfContentsButton />;
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
import React, { useState } from 'react';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
/**
|
||||
* 视频演示组件
|
||||
* @param {Object} props
|
||||
* @param {string} props.title - 视频标题
|
||||
* @param {string} props.description - 视频描述
|
||||
* @param {string} props.platform - 视频平台 (bilibili, youku, youtube, local)
|
||||
* @param {string} props.videoId - 视频ID或本地视频路径
|
||||
* @param {Object} props.options - 其他选项
|
||||
*/
|
||||
function VideoDemo({
|
||||
title,
|
||||
description,
|
||||
platform = 'bilibili',
|
||||
videoId,
|
||||
options = {}
|
||||
}) {
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
|
||||
// 构建视频 URL
|
||||
const getVideoSrc = () => {
|
||||
switch (platform.toLowerCase()) {
|
||||
case 'bilibili':
|
||||
return `//player.bilibili.com/player.html?bvid=${videoId}&page=1&high_quality=1&danmaku=0${options.autoplay ? '&autoplay=1' : ''}`;
|
||||
case 'youku':
|
||||
return `//player.youku.com/embed/${videoId}${options.autoplay ? '?autoplay=1' : ''}`;
|
||||
case 'youtube':
|
||||
return `//www.youtube.com/embed/${videoId}${options.autoplay ? '?autoplay=1' : ''}`;
|
||||
case 'local':
|
||||
return videoId; // 本地视频路径
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const handleIframeLoad = () => {
|
||||
setIsLoaded(true);
|
||||
};
|
||||
|
||||
const handleVideoLoad = () => {
|
||||
setIsLoaded(true);
|
||||
};
|
||||
|
||||
// 渲染本地视频播放器
|
||||
const renderLocalVideo = () => {
|
||||
return (
|
||||
<video
|
||||
className={styles.videoFrame}
|
||||
controls
|
||||
preload="metadata"
|
||||
onLoadedData={handleVideoLoad}
|
||||
autoPlay={options.autoplay}
|
||||
muted={options.muted}
|
||||
>
|
||||
<source src={getVideoSrc()} type="video/mp4" />
|
||||
您的浏览器不支持 HTML5 视频播放。
|
||||
</video>
|
||||
);
|
||||
};
|
||||
|
||||
// 渲染在线视频播放器
|
||||
const renderOnlineVideo = () => {
|
||||
return (
|
||||
<iframe
|
||||
src={getVideoSrc()}
|
||||
className={styles.videoFrame}
|
||||
frameBorder="0"
|
||||
allowFullScreen
|
||||
onLoad={handleIframeLoad}
|
||||
title={title}
|
||||
></iframe>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.videoDemo}>
|
||||
<h3 className={styles.videoTitle}>{title}</h3>
|
||||
{description && <p className={styles.videoDescription}>{description}</p>}
|
||||
|
||||
<div className={styles.videoWrapper}>
|
||||
{!isLoaded && <div className={styles.loadingIndicator}>加载中...</div>}
|
||||
{platform.toLowerCase() === 'local'
|
||||
? renderLocalVideo()
|
||||
: renderOnlineVideo()
|
||||
}
|
||||
</div>
|
||||
|
||||
{options.showTips && (
|
||||
<div className={styles.videoTips}>
|
||||
<p>提示: {options.tips || "可以使用播放器控制栏调整播放速度和画质"}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default VideoDemo;
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
.videoDemo {
|
||||
margin: 2rem 0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
background-color: var(--ifm-color-emphasis-0);
|
||||
}
|
||||
|
||||
.videoTitle {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
padding: 1rem;
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
color: var(--ifm-color-emphasis-800);
|
||||
border-bottom: 1px solid var(--ifm-color-emphasis-300);
|
||||
}
|
||||
|
||||
.videoDescription {
|
||||
padding: 0 1rem 1rem;
|
||||
font-size: 1rem;
|
||||
color: var(--ifm-color-emphasis-700);
|
||||
}
|
||||
|
||||
.videoWrapper {
|
||||
position: relative;
|
||||
padding-top: 56.25%; /* 16:9 宽高比 */
|
||||
width: 100%;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.videoFrame {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.loadingIndicator {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #000;
|
||||
color: white;
|
||||
font-size: 1.2rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.videoTips {
|
||||
padding: 0.75rem 1rem;
|
||||
background-color: var(--ifm-color-emphasis-100);
|
||||
border-top: 1px solid var(--ifm-color-emphasis-200);
|
||||
color: var(--ifm-color-emphasis-700);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* 深色模式调整 */
|
||||
html[data-theme='dark'] .videoDemo {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .videoTitle {
|
||||
background-color: var(--ifm-color-emphasis-300);
|
||||
color: var(--ifm-color-emphasis-900);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .videoTips {
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
}
|
||||
|
||||
/* 响应式样式 */
|
||||
@media (max-width: 768px) {
|
||||
.videoTitle {
|
||||
font-size: 1.25rem;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.videoDescription {
|
||||
font-size: 0.9rem;
|
||||
padding: 0 0.75rem 0.75rem;
|
||||
}
|
||||
|
||||
.videoTips {
|
||||
font-size: 0.8rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
|
||||
.videoDemo {
|
||||
margin: 1.5rem 0;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.videoTitle {
|
||||
font-size: 1.1rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.loadingIndicator {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.videoDemo {
|
||||
margin: 1rem 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
|
@ -57,6 +57,7 @@ html[data-theme='dark'] .docusaurus-highlight-code-line {
|
|||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.footer__bottom .margin-bottom--sm{
|
||||
position: absolute;
|
||||
|
|
|
|||
|
|
@ -18,131 +18,131 @@ const description = 'Security Building Blocks for Developers';
|
|||
|
||||
const IndexPage = () => {
|
||||
return (
|
||||
<Layout title={title} description={description}>
|
||||
<HeroSection
|
||||
title="Security Building Blocks for Developers"
|
||||
description="Reduce Time to Market without sacrificing your security posture! BoxyHQ’s suite of APIs for security and privacy helps engineering teams build and ship compliant cloud applications faster."
|
||||
image="/img/home-hero.svg"
|
||||
buttons={[
|
||||
{
|
||||
title: 'Get Started',
|
||||
href: 'https://boxyhq.com/docs',
|
||||
className: 'button--primary',
|
||||
},
|
||||
{
|
||||
title: 'Book a demo',
|
||||
href: 'https://meetings.hubspot.com/deepakprab/demo?__hstc=213510283.9a563789bb583fca1e9fb20a629c5c94.1651597904536.1664893584285.1664895920328.169&__hssc=213510283.1.1664895920328&__hsfp=498882655',
|
||||
className: 'button--primary button--outline',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Layout title={title} description={description}>
|
||||
<HeroSection
|
||||
title="Security Building Blocks for Developers"
|
||||
description="Reduce Time to Market without sacrificing your security posture! BoxyHQ's suite of APIs for security and privacy helps engineering teams build and ship compliant cloud applications faster."
|
||||
image="/img/home-hero.svg"
|
||||
buttons={[
|
||||
{
|
||||
title: 'Get Started',
|
||||
href: 'https://boxyhq.com/docs',
|
||||
className: 'button--primary',
|
||||
},
|
||||
{
|
||||
title: 'Book a demo',
|
||||
href: 'https://meetings.hubspot.com/deepakprab/demo?__hstc=213510283.9a563789bb583fca1e9fb20a629c5c94.1651597904536.1664893584285.1664895920328.169&__hssc=213510283.1.1664895920328&__hsfp=498882655',
|
||||
className: 'button--primary button--outline',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* <CustomersSection />
|
||||
{/* <CustomersSection />
|
||||
<ProductsSection /> */}
|
||||
|
||||
<section className="page__section">
|
||||
<div className="container">
|
||||
<div className="row" style={{ gap: '10px', marginTop: '20px' }}>
|
||||
<div className="col col--5 col--offset-1">
|
||||
<div className="col-demo">
|
||||
<div className="card-demo" style={{}}>
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3
|
||||
className="text--center"
|
||||
style={{ whiteSpace: 'pre-line' }}
|
||||
>
|
||||
The Importance of Developer Security
|
||||
</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p className="text--center">
|
||||
Cyber crimes are predicted to cost $10.5 trillion
|
||||
annually by 2025, but time pressures often cause 70% of
|
||||
development teams to skip crucial security steps.
|
||||
</p>
|
||||
<p>
|
||||
In today's world, it is no longer sufficient to
|
||||
prioritize productivity alone. The faster a developer
|
||||
moves, the more potential security holes will be left
|
||||
unaddressed.{' '}
|
||||
</p>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<Link
|
||||
className={clsx('button button--primary button--block')}
|
||||
href="https://meetings.hubspot.com/deepakprab/demo?__hstc=213510283.9a563789bb583fca1e9fb20a629c5c94.1651597904536.1664893584285.1664895920328.169&__hssc=213510283.1.1664895920328&__hsfp=498882655"
|
||||
>
|
||||
Book a free developer-security session
|
||||
</Link>
|
||||
<section className="page__section">
|
||||
<div className="container">
|
||||
<div className="row" style={{ gap: '10px', marginTop: '20px' }}>
|
||||
<div className="col col--5 col--offset-1">
|
||||
<div className="col-demo">
|
||||
<div className="card-demo" style={{}}>
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3
|
||||
className="text--center"
|
||||
style={{ whiteSpace: 'pre-line' }}
|
||||
>
|
||||
The Importance of Developer Security
|
||||
</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p className="text--center">
|
||||
Cyber crimes are predicted to cost $10.5 trillion
|
||||
annually by 2025, but time pressures often cause 70% of
|
||||
development teams to skip crucial security steps.
|
||||
</p>
|
||||
<p>
|
||||
In today's world, it is no longer sufficient to
|
||||
prioritize productivity alone. The faster a developer
|
||||
moves, the more potential security holes will be left
|
||||
unaddressed.{' '}
|
||||
</p>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<Link
|
||||
className={clsx('button button--primary button--block')}
|
||||
href="https://meetings.hubspot.com/deepakprab/demo?__hstc=213510283.9a563789bb583fca1e9fb20a629c5c94.1651597904536.1664893584285.1664895920328.169&__hssc=213510283.1.1664895920328&__hsfp=498882655"
|
||||
>
|
||||
Book a free developer-security session
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--5">
|
||||
<div className="col-demo">
|
||||
<div className="card-demo">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3
|
||||
className="text--center"
|
||||
style={{ whiteSpace: 'pre-line' }}
|
||||
>
|
||||
Build or buy?
|
||||
</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p className="text--center">
|
||||
Save time and money with BoxyHQ's free open-source
|
||||
solution. Available under an Apache 2.0 license, our
|
||||
solutions make it easy for developers to collaborate and
|
||||
innovate, without the need for custom building or
|
||||
expensive fees.
|
||||
</p>
|
||||
<p className="text--center">
|
||||
Our solutions run in your environment, giving you full
|
||||
control. We simply provide the building blocks to help
|
||||
you succeed.
|
||||
</p>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<Link
|
||||
className={clsx('button button--primary button--block')}
|
||||
href="mailto:hello@boxyhq.com"
|
||||
>
|
||||
Contact Us
|
||||
</Link>
|
||||
<div className="col col--5">
|
||||
<div className="col-demo">
|
||||
<div className="card-demo">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3
|
||||
className="text--center"
|
||||
style={{ whiteSpace: 'pre-line' }}
|
||||
>
|
||||
Build or buy?
|
||||
</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p className="text--center">
|
||||
Save time and money with BoxyHQ's free open-source
|
||||
solution. Available under an Apache 2.0 license, our
|
||||
solutions make it easy for developers to collaborate and
|
||||
innovate, without the need for custom building or
|
||||
expensive fees.
|
||||
</p>
|
||||
<p className="text--center">
|
||||
Our solutions run in your environment, giving you full
|
||||
control. We simply provide the building blocks to help
|
||||
you succeed.
|
||||
</p>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<Link
|
||||
className={clsx('button button--primary button--block')}
|
||||
href="mailto:hello@boxyhq.com"
|
||||
>
|
||||
Contact Us
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<FeatureSection
|
||||
title="Developer Security Tools"
|
||||
btnLink="https://awesome-oss-devsec.boxyhq.com/"
|
||||
btnText="Read More"
|
||||
image={Icon3}
|
||||
direction="right"
|
||||
>
|
||||
<p>
|
||||
We have curated a list of awesome open-source developer security
|
||||
tools.
|
||||
</p>
|
||||
<p>
|
||||
It includes security principles and controls relevant to popular
|
||||
compliance certifications (like ISO27001, SOC2, MVSP, etc.)
|
||||
</p>
|
||||
</FeatureSection>
|
||||
<FeatureSection
|
||||
title="Developer Security Tools"
|
||||
btnLink="https://awesome-oss-devsec.boxyhq.com/"
|
||||
btnText="Read More"
|
||||
image={Icon3}
|
||||
direction="right"
|
||||
>
|
||||
<p>
|
||||
We have curated a list of awesome open-source developer security
|
||||
tools.
|
||||
</p>
|
||||
<p>
|
||||
It includes security principles and controls relevant to popular
|
||||
compliance certifications (like ISO27001, SOC2, MVSP, etc.)
|
||||
</p>
|
||||
</FeatureSection>
|
||||
|
||||
{/* <NewsSection />
|
||||
{/* <NewsSection />
|
||||
<InvestorsSection />
|
||||
<DeveloperCommunitySection /> */}
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
import React from 'react';
|
||||
|
||||
const wechatGroups = [
|
||||
{ img: '/img/question/wechat1.png', label: '微信技术交流答疑群1' },
|
||||
{ img: '/img/question/wechat2.png', label: '微信技术交流答疑群2' },
|
||||
];
|
||||
|
||||
const qqGroups = [
|
||||
{ img: '/img/question/qq1.png', label: 'QQ技术交流答疑群1' },
|
||||
{ img: '/img/question/qq2.png', label: 'QQ技术交流答疑群2' },
|
||||
];
|
||||
|
||||
export default function QA() {
|
||||
return (
|
||||
<div style={{
|
||||
minHeight: '100vh',
|
||||
background: 'linear-gradient(135deg, #e0e7ff 0%, #f8fafc 100%)',
|
||||
padding: '0 0 48px 0',
|
||||
}}>
|
||||
<div style={{
|
||||
maxWidth: 1000,
|
||||
margin: '0 auto',
|
||||
padding: '40px 24px 24px 24px',
|
||||
}}>
|
||||
<h1 style={{ textAlign: 'center', fontSize: 32, fontWeight: 700, marginBottom: 40, color: '#2d3a4b', letterSpacing: 2 }}>疑问解答与交流群</h1>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 32, justifyContent: 'center', marginBottom: 48 }}>
|
||||
<div style={{ flex: '1 1 320px', background: '#fff', borderRadius: 16, boxShadow: '0 4px 24px rgba(70,106,255,0.08)', padding: 32, minWidth: 320 }}>
|
||||
<h2 style={{ textAlign: 'center', color: '#466aff', fontSize: 22, marginBottom: 24 }}>微信交流群</h2>
|
||||
<div style={{ display: 'flex', justifyContent: 'center', gap: 24 }}>
|
||||
{wechatGroups.map((g, i) => (
|
||||
<div key={i} style={{ textAlign: 'center' }}>
|
||||
<img src={g.img} alt={g.label} style={{ width: 120, height: 120, borderRadius: 12, marginBottom: 8, boxShadow: '0 2px 8px rgba(70,106,255,0.10)' }} />
|
||||
<div style={{ fontSize: 15, color: '#2d3a4b' }}>{g.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 320px', background: '#fff', borderRadius: 16, boxShadow: '0 4px 24px rgba(70,106,255,0.08)', padding: 32, minWidth: 320 }}>
|
||||
<h2 style={{ textAlign: 'center', color: '#466aff', fontSize: 22, marginBottom: 24 }}>QQ交流群</h2>
|
||||
<div style={{ display: 'flex', justifyContent: 'center', gap: 24 }}>
|
||||
{qqGroups.map((g, i) => (
|
||||
<div key={i} style={{ textAlign: 'center' }}>
|
||||
<img src={g.img} alt={g.label} style={{ width: 120, height: 120, borderRadius: 12, marginBottom: 8, boxShadow: '0 2px 8px rgba(70,106,255,0.10)' }} />
|
||||
<div style={{ fontSize: 15, color: '#2d3a4b' }}>{g.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{
|
||||
background: '#fff',
|
||||
borderRadius: 16,
|
||||
boxShadow: '0 4px 24px rgba(70,106,255,0.08)',
|
||||
padding: 32,
|
||||
maxWidth: 600,
|
||||
margin: '0 auto',
|
||||
textAlign: 'center',
|
||||
}}>
|
||||
<h2 style={{ color: '#466aff', fontSize: 22, marginBottom: 24 }}>官网论坛</h2>
|
||||
<a
|
||||
href="https://forum.gitlink.org.cn/forums"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
background: '#466aff',
|
||||
color: '#fff',
|
||||
borderRadius: 6,
|
||||
padding: '12px 40px',
|
||||
fontSize: 18,
|
||||
textDecoration: 'none',
|
||||
fontWeight: 600,
|
||||
boxShadow: '0 2px 8px rgba(70,106,255,0.10)',
|
||||
letterSpacing: 1,
|
||||
}}
|
||||
>
|
||||
访问官网论坛
|
||||
</a>
|
||||
</div>
|
||||
<div style={{ textAlign: 'center', marginTop: 56 }}>
|
||||
<img src="/img/gitlink.png" alt="GitLink Logo" style={{ width: 80, opacity: 0.12 }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import Footer from '@theme-original/DocItem/Footer';
|
||||
import RatingSystem from '../../../components/RatingSystem';
|
||||
import RatingStats from '../../../components/RatingStats';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
export default function FooterWrapper(props) {
|
||||
return (
|
||||
<>
|
||||
<Footer {...props} />
|
||||
<div className={styles.ratingWrapper}>
|
||||
<RatingStats />
|
||||
<RatingSystem />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
.ratingWrapper {
|
||||
margin-top: 2rem;
|
||||
padding-top: 1rem;
|
||||
border-top: 1px solid var(--ifm-color-emphasis-200);
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import DocItem from '@theme-original/DocItem';
|
||||
|
||||
export default function DocItemWrapper(props) {
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined') return;
|
||||
const key = 'scroll-pos:' + window.location.pathname;
|
||||
|
||||
// 恢复滚动位置
|
||||
const saved = localStorage.getItem(key);
|
||||
if (saved) {
|
||||
window.scrollTo(0, parseInt(saved, 10));
|
||||
}
|
||||
|
||||
// 保存滚动位置
|
||||
const handler = () => {
|
||||
localStorage.setItem(key, window.scrollY);
|
||||
};
|
||||
window.addEventListener('scroll', handler);
|
||||
|
||||
// 卸载时清理
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handler);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <DocItem {...props} />;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem';
|
||||
import DocNavbarItem from '@theme/NavbarItem/DocNavbarItem';
|
||||
import DocSidebarNavbarItem from '@theme/NavbarItem/DocSidebarNavbarItem';
|
||||
import DocsVersionNavbarItem from '@theme/NavbarItem/DocsVersionNavbarItem';
|
||||
import DocsVersionDropdownNavbarItem from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
|
||||
import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem';
|
||||
import LocaleDropdownNavbarItem from '@theme/NavbarItem/LocaleDropdownNavbarItem';
|
||||
import SearchNavbarItem from '@theme/NavbarItem/SearchNavbarItem';
|
||||
|
||||
import PdfExportNavbarItem from '../../components/PdfExportNavbarItem';
|
||||
import PdfBackToTopNavbarItem from '../../components/PdfBackToTopNavbarItem';
|
||||
import BackToBottomNavbarItem from '../../components/BackToBottomNavbarItem';
|
||||
import QAButtonNavbarItem from '../../components/QAButtonNavbarItem';
|
||||
import TableOfContentsNavbarItem from '../../components/TableOfContentsNavbarItem';
|
||||
|
||||
const ComponentTypes = {
|
||||
default: DefaultNavbarItem,
|
||||
localeDropdown: LocaleDropdownNavbarItem,
|
||||
search: SearchNavbarItem,
|
||||
dropdown: DropdownNavbarItem,
|
||||
docsVersionDropdown: DocsVersionDropdownNavbarItem,
|
||||
docsVersion: DocsVersionNavbarItem,
|
||||
doc: DocNavbarItem,
|
||||
docSidebar: DocSidebarNavbarItem,
|
||||
'custom-pdf-export': PdfExportNavbarItem,
|
||||
'custom-back-to-top': PdfBackToTopNavbarItem,
|
||||
'custom-back-to-bottom': BackToBottomNavbarItem,
|
||||
'custom-qa-button': QAButtonNavbarItem,
|
||||
'custom-table-of-contents': TableOfContentsNavbarItem,
|
||||
};
|
||||
|
||||
export default ComponentTypes;
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import React from 'react';
|
||||
import NavbarItem from '@theme-original/NavbarItem';
|
||||
import PdfExportNavbarItem from '../../components/PdfExportNavbarItem';
|
||||
import PdfBackToTopNavbarItem from '../../components/PdfBackToTopNavbarItem';
|
||||
import BackToBottomNavbarItem from '../../components/BackToBottomNavbarItem';
|
||||
import QAButtonNavbarItem from '../../components/QAButtonNavbarItem';
|
||||
|
||||
export default function NavbarItemWrapper(props) {
|
||||
if (props.type === 'custom-pdf-export') {
|
||||
return <PdfExportNavbarItem />;
|
||||
}
|
||||
if (props.type === 'custom-back-to-top') {
|
||||
return <PdfBackToTopNavbarItem />;
|
||||
}
|
||||
if (props.type === 'custom-back-to-bottom') {
|
||||
return <BackToBottomNavbarItem />;
|
||||
}
|
||||
if (props.type === 'custom-qa-button') {
|
||||
return <QAButtonNavbarItem />;
|
||||
}
|
||||
return <NavbarItem {...props} />;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
ceshi
|
||||
|
|
@ -0,0 +1 @@
|
|||
这是一个用来测试pr操作的文件
|
||||
|
|
@ -0,0 +1 @@
|
|||
这是用于测试流水线的文档
|
||||
|
|
@ -2,6 +2,74 @@
|
|||
sidebar_label: 'bot安装'
|
||||
sidebar_position: 1
|
||||
---
|
||||
import MyButton from './mybutton';
|
||||
|
||||
<MyButton onClick={() => {
|
||||
var pElements = document.getElementsByTagName('p');
|
||||
var hElements = document.getElementsByTagName('h1');
|
||||
var aElements = document.getElementsByTagName('a');
|
||||
var hzh = ['bot安装','bot安装'];
|
||||
var hen = ['Bot Installation','Bot Installation'];
|
||||
var azh = ['跳到主要内容','','帮助中心','','','','','','','','','','','','','','','','','','','','','机器人(Bot)','编辑此页','上一页 bot市场','下一页bot 配置','网站首页','关于我们','教学实践','合作伙伴','API文档','Git常用命令','引擎使用手册','服务协议','官网邮箱:gitlink@ccf.org.cn','QQ群','公众号'];
|
||||
var aen = ['Jump to main content','','Help Center','','','','','','','','','','','','','','','','','','','','','Robot (Bot)','Edit this page','last page Bot market','next page Bot configuration','Website homepage','About Us','Teaching practice','Partners','API documentation','Common Git commands','Engine User Manual','Service Agreement','Official website email: gitlink@ccf.org.cn','QQ group','Official Account'];
|
||||
var zhtranalate = ['Bot安装是进行bot安装和管理控制的重要模块,主要包括bot安装、安装查询、安装管理等功能。','在bot详情页,用户点击“安装此Bot”按钮后,可以看到该bot工作所需的各项权限信息。若用户同意授予bot所需的相关权限即可进行安装。用户可选择将bot安装到所有仓库(用户拥有的所有仓库)中,也可以选择指定的仓库进行安装。','','在个人“设置”或者“仓库设置”中,用户可以看到目前已经安装的Bot情况,点击“配置”按钮可以对bot安装情况进行配置,点击“卸载”按钮可以进行卸载。','','在bot安装配置页中,用户可以掌握该bot的安装位置和工作状态。若用户需要更改bot的工作仓库时,可以进行更改安装位置。bot的工作状态包括激活和挂起,用户可根据需要对bot的状态进行调整,将其挂起或者激活,会影响到bot对仓库数据的访问权限。','','©Copyright 2024 CCF 开源发展委员会','Powered by Trustie& IntelliDE 京ICP备13000930号'];
|
||||
var entranslate = ['Bot installation is an important module for bot installation and management control, which mainly includes functions such as bot installation, installation queries, and installation management.','On the bot details page, after clicking the "Install this bot" button, users can see the necessary permission information for the bot to work. If the user agrees to grant the necessary permissions to the bot, installation can proceed. Users can choose to install the bot in all warehouses (all warehouses owned by the user) or select a specified warehouse for installation.','','In personal "settings" or "warehouse settings", users can see the current installation status of bots. Click the "configure" button to configure the bot installation status, and click the "uninstall" button to uninstall.','','In the bot installation configuration page, users can grasp the installation location and working status of the bot. If the user needs to change the workspace of the bot, they can change the installation location. The working status of bots includes activation and suspension. Users can adjust the status of bots as needed. Suspending or activating bots can affect their access to warehouse data.','','© Copyright 2024 CCF Open Source Development Committee','Powered by Trust&IntelliDE Beijing ICP Preparation No. 13000930'];
|
||||
if (pElements[0].innerText == zhtranalate[0]){
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = entranslate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = zhtranalate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hElements[0].innerText == hzh[0]){
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hen[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hzh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aElements[0].innerText == azh[0]){
|
||||
for (var i = 0; i < aElements.length; i++) {
|
||||
if (aElements[i].innerText != ''){
|
||||
if (i < aElements.length){
|
||||
aElements[i].innerText = aen[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < aElements.length; i++) {
|
||||
if (aElements[i].innerText != ''){
|
||||
if (i < aElements.length){
|
||||
aElements[i].innerText = azh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}>中/英</MyButton>
|
||||
|
||||
|
||||
# bot安装
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,52 @@
|
|||
sidebar_label: 'bot市场'
|
||||
sidebar_position: 4
|
||||
---
|
||||
import MyButton from './mybutton';
|
||||
|
||||
<MyButton onClick={() => {
|
||||
var pElements = document.getElementsByTagName('p');
|
||||
var hElements = document.getElementsByTagName('h1');
|
||||
var hzh = ['bot市场','bot市场'];
|
||||
var hen = ['Bot Market','Bot Market'];
|
||||
var zhtranalate = ['Bot市场是进行Bot分享与复用的重要模块,主要包括bot的搜索发现,详情查看等功能。','Bot市场主页中展示了目前所有已经上架市场的bot简要信息,包括bot的头像,名称,开发者,简介和安装次数等信息,用户可根据这些基本信息初步判断该bot是否符合自己的项目需求。','在bot市场主页中,用户可以选择指定的bot种类,筛选出特定分类的bot,在这个种类范围内进行搜索与选择。','此外,用户通过在搜索栏中输入关键字进行搜索,可检索出内容包含指定关键字的相关bot。','用户可结合种类筛选和关键字搜索缩小范围,在市场中快速找到符合项目相关需求的bot。','','在bot市场页中,用户点击指定的bot卡片即可进入该bot的详情页。Bot的详情页包含bot的头像,名称,开发者,种类和详细介绍等信息,用户可在此掌握该bot的各项介绍,进一步判断是否将其安装到指定仓库中。','','在bot详情页中,若用户认为该bot满足自己的项目需求,可点击“安装此Bot”按钮,了解该bot的权限信息,将其安装到指定的仓库中,关于安装的更多介绍可见“Bot安装”部分。','去市场看看吧!','©Copyright 2024 CCF 开源发展委员会','Powered by Trustie& IntelliDE 京ICP备13000930号'];
|
||||
var entranslate = ['The bot market is an important module for sharing and reusing bots, mainly including functions such as searching, discovering, and viewing details of bots.' , 'The Bot Market homepage displays brief information about all bots that have been put on the market, including their avatars, names, developers, introductions, and installation times. Users can use this basic information to preliminarily determine whether the bot meets their project requirements.' , 'On the bot market homepage, users can select a specific type of bot, filter out specific categories of bots, and search and select within this category range.' , 'In addition, users can search for relevant bots containing specified keywords by entering keywords in the search bar.' , 'Users can combine category filtering and keyword search to narrow down the scope and quickly find bots that meet project related needs in the market.' , '' , 'In the bot market page, users can click on the specified bot card to enter the details page of the bot. The details page of the bot includes information such as the bot avatar, name, developer, type, and detailed introduction. Users can grasp the various introductions of the bot here and further determine whether to install it in the designated warehouse.' , '' , 'In the bot details page, if users believe that the bot meets their project requirements, they can click the "Install this bot" button to learn about the bots permission information and install it in the designated warehouse. For more information on installation, please refer to the "Bot Installation" section' , 'Go take a look at the market!' , '©Copyright 2024 CCF Open Source Development Committee' , 'Powered by Trustie& IntelliDE 京ICP备13000930号'];
|
||||
if (pElements[0].innerText == zhtranalate[0]){
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = entranslate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = zhtranalate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hElements[0].innerText == hzh[0]){
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hen[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hzh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}>中/英</MyButton>
|
||||
|
||||
# Bot市场
|
||||
|
||||
|
|
@ -21,4 +67,16 @@ Bot市场主页中展示了目前所有已经上架市场的bot简要信息,
|
|||
|
||||

|
||||
|
||||
在bot详情页中,若用户认为该bot满足自己的项目需求,可点击“安装此Bot”按钮,了解该bot的权限信息,将其安装到指定的仓库中,关于安装的更多介绍可见“Bot安装”部分。
|
||||
在bot详情页中,若用户认为该bot满足自己的项目需求,可点击“安装此Bot”按钮,了解该bot的权限信息,将其安装到指定的仓库中,关于安装的更多介绍可见“Bot安装”部分。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
去市场看看吧!
|
||||
|
||||
<MyButton onClick={() => {
|
||||
location.href = "https://www.gitlink.org.cn/softbot";
|
||||
}}>Bot市场</MyButton>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,52 @@
|
|||
sidebar_label: 'bot开发'
|
||||
sidebar_position: 3
|
||||
---
|
||||
import MyButton from './mybutton';
|
||||
|
||||
<MyButton onClick={() => {
|
||||
var pElements = document.getElementsByTagName('p');
|
||||
var hElements = document.getElementsByTagName('h1');
|
||||
var hzh = ['bot开发','bot开发'];
|
||||
var hen = ['Bot Development','Bot Development'];
|
||||
var zhtranalate = ['Bot开发是开发者进行bot注册的重要模块。' , '在个人“设置”中,用户可以看到目前已经注册的bot列表,点击对应bot的“编辑”按钮可以对已注册的bot进行配置;点击“Bot注册”按钮开始注册新的bot。' , '' , '在注册页中,开发者需要填写bot注册的相关信息,包括bot的名称、Webhook 地址,详细介绍等,系统将对开发者输入的信息进行合法性校验,确保bot各项信息的完整性和有效性。此外,系统将自动生成bot的唯一标识,同时调用 GitLink 平台的相关接口生成bot的身份凭证信息,包括客户端密钥和私钥等。' , '开发者需通过这些身份信息结合平台接口进行bot身份认证后,调用相关接口完成bot的相关功能。' , '平台开发API链接(待完善):https://www.gitlink.org.cn/docs/api#introduction' , '' , '' , '©Copyright 2024 CCF 开源发展委员会' , 'Powered by Trustie& IntelliDE 京ICP备13000930号'];
|
||||
var entranslate = ['Bot development is an important module for developers to register their bots.' , 'In personal settings, users can see a list of registered bots and click the "Edit" button on the corresponding bot to configure the registered bots; Click the "Bot Registration" button to start registering a new bot.' , '' , 'In the registration page, developers need to fill in the relevant information for bot registration, including the name of the bot, Webhook address, detailed introduction, etc. The system will verify the legality of the information entered by the developer to ensure the completeness and validity of all bot information. In addition, the system will automatically generate a unique identifier for the bot, and call the relevant interfaces of the GitLink platform to generate the identity credential information of the bot, including the client key and private key.' , 'Developers need to use these identity information in combination with the platform interface for bot identity authentication, and then call the relevant interface to complete the relevant functions of the bot.' , 'Platform development API link (to be improved): https://www.gitlink.org.cn/docs/api#introduction' , '' , '' , '© Copyright 2024 CCF Open Source Development Committee' , 'Powered by Trust&IntelliDE Beijing ICP Preparation No. 13000930'];
|
||||
if (pElements[0].innerText == zhtranalate[0]){
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = entranslate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = zhtranalate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hElements[0].innerText == hzh[0]){
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hen[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hzh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}>中/英</MyButton>
|
||||
|
||||
# Bot开发
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,52 @@
|
|||
sidebar_label: 'bot配置'
|
||||
sidebar_position: 2
|
||||
---
|
||||
import MyButton from './mybutton';
|
||||
|
||||
<MyButton onClick={() => {
|
||||
var pElements = document.getElementsByTagName('p');
|
||||
var hElements = document.getElementsByTagName('h1');
|
||||
var hzh = ['bot配置','bot配置'];
|
||||
var hen = ['Bot Configure','Bot Configure'];
|
||||
var zhtranalate = ['Bot配置是开发者进行bot维护和配置的重要模块,主要包括bot基本信息维护、权限&订阅事件管理、高级选项配置等功能。','Bot的基本信息维护中,开发者可以看到bot的各项基本信息,并可以根据需要对bot的头像,名称,Webhook地址等进行修改。','','Bot的权限&订阅事件管理中,开发者可根据对仓库资源的访问需要为bot分配不同的权限和等级,比如增加代码库权限,将拉取请求的写权限变为读权限等。开发者还能更改当前bot订阅的事件列表,比如订阅代码库推送,取消拉取请求分配订阅等,以实现bot功能的更新与升级。','','Bot高级选项配置中,开发者可以改变bot的公私有状态,从而影响到bot的使用范围。需要注意的是,公开状态下的bot在已有其他仓库安装的情况下不能变成私有。开发者可选择将bot上架到市场,需要填写上架信息,包括市场简介,主要功能,次要功能等各项信息。','开发者还能进行bot的删除和转让操作,发起转让意味着更改bot的所有权,需要输入接受者的用户名。在接受者确定接受后,即可完成bot的所有权变更,拒绝则会取消本次的转让操作。','','©Copyright 2024 CCF 开源发展委员会','Powered by Trustie& IntelliDE 京ICP备13000930号'];
|
||||
var entranslate = ['Bot configuration is an important module for developers to maintain and configure bots, mainly including basic bot information maintenance, permission&subscription event management, advanced option configuration, and other functions.' , 'In the basic information maintenance of bots, developers can see various basic information of bots and modify their avatars, names, Webhook addresses, etc. as needed.' , '' , 'In the permission and subscription event management of bots, developers can assign different permissions and levels to bots based on their access needs to warehouse resources, such as adding code library permissions, changing write permissions for pull requests to read permissions, etc. Developers can also modify the event list of the current bot subscription, such as subscribing to code library push notifications, canceling pull request allocation subscriptions, etc., to achieve updates and upgrades of bot functionality.' , '' , 'In the advanced options configuration of bots, developers can change the public and private status of bots, thereby affecting their usage scope. It should be noted that bots in public status cannot become private when installed in other warehouses. Developers can choose to put their bots on the market and need to fill in the listing information, including market introduction, main functions, secondary functions, and other related information.' , 'Developers can also perform bot deletion and transfer operations, initiating transfer means changing the ownership of the bot, and the recipients username needs to be entered. After the recipient confirms acceptance, the ownership change of the bot can be completed. Refusal will cancel the transfer operation.' , '' , '© Copyright 2024 CCF Open Source Development Committee' , 'Powered by Trust&IntelliDE Beijing ICP Preparation No. 13000930'];
|
||||
if (pElements[0].innerText == zhtranalate[0]){
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = entranslate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = zhtranalate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hElements[0].innerText == hzh[0]){
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hen[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hzh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}>中/英</MyButton>
|
||||
|
||||
# Bot配置
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react';
|
||||
import styles from './mybutton.module.css'; // 假设你有一个CSS模块文件来定义样式
|
||||
|
||||
const MyButton = ({ onClick, children, className = '' }) => (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className={`${styles.myButton} ${className}`} // 使用CSS模块样式
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
|
||||
export default MyButton;
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
.myButton {
|
||||
background-color: #30a834; /* Green */
|
||||
border: none;
|
||||
color: #fff; /* 改为白色或其他与绿色背景对比明显的颜色 */
|
||||
padding: 15px 32px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
margin: 4px 2px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
/* 还可以添加其他样式,比如过渡效果、阴影等 */
|
||||
transition: background-color 0.3s ease; /* 背景色变化的过渡效果 */
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 简单的阴影效果 */
|
||||
}
|
||||
|
||||
.myButton:hover {
|
||||
background-color: #288f2c; /* 鼠标悬停时改变背景色 */
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
---
|
||||
sidebar_label: "介绍"
|
||||
label: "介绍"
|
||||
sidebar_position: 1
|
||||
sidebar_position: 0
|
||||
slug: /
|
||||
---
|
||||
|
||||
# 关于GitLink
|
||||
GitLink(确实开源)是CCF官方指定的开源创新服务平台,旨在以“为开源创新服务”为使命,以“成为开源创新的汇聚地”为愿景,秉承“创新、开放、协作、共享”的价值观,致力于为大规模开源开放协同创新助力赋能,打造创新成果孵化和新工科人才培养的开源创新生态!
|
||||
|
||||

|
||||

|
||||
|
||||
# 平台功能
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ GitLink(确实开源)是CCF官方指定的开源创新服务平台,旨在
|
|||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/代码库管理/仓库创建">
|
||||
<h2 class="text--truncate cardTitle" title="代码库管理">代码库管理</h2>
|
||||
<p>代码库使用及设置[8个文档]</p>
|
||||
<p>代码库使用及设置[9个文档]</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/组织管理/组织简介">
|
||||
|
|
@ -69,26 +69,26 @@ GitLink(确实开源)是CCF官方指定的开源创新服务平台,旨在
|
|||
<h2 class="text--truncate cardTitle" title="第三方服务">第三方服务</h2>
|
||||
<p>第三方服务使用及设置[3个文档]</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/通知/通知简介">
|
||||
<h2 class="text--truncate cardTitle" title="通知">通知</h2>
|
||||
<p>通知使用及设置[2个文档]</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/个人主页建站/站点创建流程">
|
||||
<h2 class="text--truncate cardTitle" title="个人主页建站">个人主页建站</h2>
|
||||
<p>个人主页建站使用及设置[2个文档]</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/平台公告/">
|
||||
<h2 class="text--truncate cardTitle" title="平台公告">平台公告</h2>
|
||||
<p>平台公告使用及设置</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/服务协议/GitLink服务协议">
|
||||
<h2 class="text--truncate cardTitle" title="服务协议">服务协议</h2>
|
||||
<p>服务协议使用及设置[1个文档]</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/通知/通知简介">
|
||||
<h2 class="text--truncate cardTitle" title="通知">通知</h2>
|
||||
<p>通知简介及设置[2个文档]</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/个人主页建站/站点创建流程">
|
||||
<h2 class="text--truncate cardTitle" title="个人主页建站">个人主页建站</h2>
|
||||
<p>个人主页建站使用及设置[2个文档]</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/平台公告">
|
||||
<h2 class="text--truncate cardTitle" title="平台公告">平台公告</h2>
|
||||
<p>平台公告[1个文档]</p>
|
||||
</a></article>
|
||||
<article class="col col--6 margin-bottom--lg">
|
||||
<a class="card padding--lg cardContainer" href="/服务协议/GitLink服务协议">
|
||||
<h2 class="text--truncate cardTitle" title="服务协议">服务协议</h2>
|
||||
<p>GitLink服务协议[1个文档]</p>
|
||||
</a></article>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ sidebar_position: 9
|
|||
---
|
||||
|
||||
### **1. 语言服务**
|
||||
● 支持近 40 种语言的语法高亮
|
||||
● 支持 JavaScript/TypeScript、HTML、CSS、JSON、Markdown 的基于 LSP (Language Server Protocol) 语言特性功能,具备智能提示和大纲信息以及单文件内跳转。
|
||||
● 支持 Java、Go、Python、C++、Php 的基于 Tree Sitter 的在线语言服务能力,提供查看引用、符号搜索等特性
|
||||
● 支持近 40 种语言的语法高亮
|
||||
● 支持 JavaScript/TypeScript、HTML、CSS、JSON、Markdown 的基于 LSP (Language Server Protocol) 语言特性功能,具备智能提示和大纲信息以及单文件内跳转。
|
||||
● 支持 Java、Go、Python、C++、Php 的基于 Tree Sitter 的在线语言服务能力,提供查看引用、符号搜索等特性
|
||||
|
||||
### **2. WebIDE 入口**
|
||||
从 Gitlink 仓库首页 ,点击Web IDE 按键即可进入
|
||||
|
|
@ -36,6 +36,6 @@ sidebar_position: 9
|
|||
可以在极速版新建分支,修改代码后在 SCM 面板看到变更文件列表,写完 commit message 后提交到 Gitlink 上。如果想快速修改一些文件可以不用在本地修改,直接通过极速版修改代码一次性提交。
|
||||
|
||||
### **9. 代码在线运行**
|
||||
● 集成了基于 skypack 的更加轻量的 CodeSwing 插件,可以在极速版去运行前端代码。
|
||||
● 集成了基于 Pyodide 的 Code-Runner-For-Web 插件,可以将 Python 的运行搬到浏览器上。
|
||||
● 集成了基于 skypack 的更加轻量的 CodeSwing 插件,可以在极速版去运行前端代码。
|
||||
● 集成了基于 Pyodide 的 Code-Runner-For-Web 插件,可以将 Python 的运行搬到浏览器上。
|
||||
<br/>
|
||||
|
|
@ -1,4 +1,11 @@
|
|||
---
|
||||
sidebar_label: '代码提交'
|
||||
sidebar_position: 3
|
||||
---
|
||||
---
|
||||
### **1. 代码提交入口**
|
||||
用户可以通过项目代码库中间的文件下的“上传文件”按键来上传文件。
|
||||
<br/>
|
||||
|
||||
### **2. 上传文件**
|
||||
进入上传文件页面后,如下图所示,拖动文件,选择提交变更的分支的单击”创建项目“按键即可完成创建。
|
||||
<br/>
|
||||
|
|
@ -1,4 +1,13 @@
|
|||
---
|
||||
sidebar_label: '分支管理'
|
||||
sidebar_position: 5
|
||||
---
|
||||
---
|
||||
### **1. 查看分支**
|
||||
在代码库栏下,如下图所示,用户可以点击代码库分支从而查看当前项目的所有分支,并且选择对其进行操作。
|
||||
<br/>
|
||||
|
||||
### **2. 合并分支**
|
||||
在“和并请求(PR)”下点击“新建合并请求”后,
|
||||
<br/>
|
||||
如下图所示,用户可以选择源分支与目标分支以及填写分支信息后提交分支合并请求。
|
||||
<br/>
|
||||
|
|
@ -1,4 +1,19 @@
|
|||
---
|
||||
sidebar_label: '文件管理'
|
||||
sidebar_position: 4
|
||||
---
|
||||
---
|
||||
### **1. 文件管理位置**
|
||||
在代码库界面,可直接对代码库中该分支下的文件进行操作,如下图所示。
|
||||
<br/>
|
||||
|
||||
### **2. 进入目录**
|
||||
点击进入相关目录,找到要编辑的文件,如下图所示。
|
||||
<br/>
|
||||
|
||||
### **3. 进入文件编辑页面**
|
||||
在线编辑文件,单击文件,即可进入编辑文件页面,如下图所示。
|
||||
<br/>
|
||||
|
||||
### **4. 编辑文件**
|
||||
编辑界面右侧有三个按钮,分别是“下载”、“编辑”和“删除”,点击下载即可将文件下载到本地,编辑则可在线编辑文档,删除则将文件从代码库中删除,按钮位置如下图所示。
|
||||
<br/>
|
||||
|
|
@ -3,4 +3,11 @@ sidebar_label: '代码评审'
|
|||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# 代码评审
|
||||
# 代码评审
|
||||
### **1. 进入代码评审**
|
||||
如下图所示,点击“代码评审”按钮可以进入代码评审
|
||||
<br/>
|
||||
|
||||
### **2. 代码评审界面**
|
||||
如下图所示,用户可以在该界面下查看该PR操作要合并的新的代码,并对其进行评审。
|
||||
<br/>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ sidebar_position: 2
|
|||
|
||||
1. 进入需要发起合并请求的项目的“**合并请求(PR)**”界面,点击上方的“**新建合并请求**”按钮后,进入合并请求发布界面,如下所示:
|
||||
|
||||

|
||||
|
||||

|
||||
<br/>
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
2. 选择需要合并的**源分支**和**目标分支**,其中源分支为已完成代码开发、需要合并其代码变更的分支,目标分支为要并入代码变更的分支,既可以是同一仓库下的其他分支(branch),也可以是被复刻的源仓库下的分支;
|
||||
|
||||
|
|
@ -19,4 +21,5 @@ sidebar_position: 2
|
|||
|
||||
5. 最后信息填写完毕后,点击底部的“**创建**”按钮即可提交您的第一个合并请求了🎉🎉🎉!
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -9,7 +9,8 @@ sidebar_position: 4
|
|||
|
||||
然而,对于不同分支间的提交合并,存在多种合并模式,下图为GitLink中支持的合并模式,包括**合并请求**、**变基并合并**、**变基合并 --no-ff**以及**压缩提交并合并**四种。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
1. **合并请求**
|
||||
|
||||
|
|
@ -17,11 +18,13 @@ sidebar_position: 4
|
|||
|
||||
快进合并前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
快进合并后:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**注意**:可以看到,合并的过程就是直接把`master`指针移动到了`dev`指针处,这种合并被称为**快进(fast-forward)**,之所以出现这种情形是因为在提交3之后,`master`分支上没有新的提交,所以通过直接快进`master`指针就可以完成合并;但如果在`master`分支上也有新的提交,就需要进行实质性的合并了,如下面两幅图所示:
|
||||
|
||||
|
|
@ -29,18 +32,21 @@ sidebar_position: 4
|
|||
|
||||
非快进合并前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
合并之后,提交A、B、C都会按时间线加入`master`的提交记录中,并且会生成一个新的提交D,用于记录合并这件事情;此外,如果合并过程中发生了冲突,即两个分支对同一个文件进行了修改,则需要手动处理冲突;这种合并方式就是**非快进(no fast-forward)**,这也是**合并请求**模式下的默认方式!
|
||||
|
||||
非快进合并后:
|
||||
|
||||

|
||||
|
||||
)<br/>
|
||||
|
||||
为了方便理解,可以以线性方式查看合并后的`master`分支上的提交记录
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**总结**:在**合并请求**模式下,默认采用**非快进**合并开发分支到`master`分支上,而**非快进**方式会生成一个特殊的提交用于记录此次合并事件!
|
||||
|
||||
|
|
@ -52,18 +58,21 @@ sidebar_position: 4
|
|||
|
||||
变基前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
变基后、合并前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
`dev`分支变基之后,`master`分支就没有“更新”的提交了,所以此时进行合并,就得到了如下的结果
|
||||
|
||||
合并后:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**总结**:在**变基并合并**模式下,开发分支`dev`可以先进行变基操作,使其上的提交看起来都是在`master`分支最新的提交基础上进行的,然后再通过**快进**方式合并回`master`分支,从而起到整理提交记录的作用!
|
||||
|
||||
|
|
@ -73,11 +82,13 @@ sidebar_position: 4
|
|||
|
||||
`--no-ff`合并前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
`--no-ff`合并后:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**总结**:通过`--no-ff`选项,可以显式声明在合并时采用**非快进**方式,这样就可以在`master`分支中添加一个记录合并事件的提交!
|
||||
|
||||
|
|
@ -87,14 +98,17 @@ sidebar_position: 4
|
|||
|
||||
压缩前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
压缩后、提交前:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
提交后:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**总结**:在合并前,先对开发分支上的琐碎提交进行压缩,可以使`master`分支上的提交信息更简洁,但是要注意,这种合并模式本质上是`master`分支一次性保存`dev`上的变更,并创建新的提交记录这些变更,所以提交者发生了变化!
|
||||
|
|
@ -3,4 +3,15 @@ sidebar_label: '合并请求关联疑修'
|
|||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# 合并请求关联疑修
|
||||
# 合并请求关联疑修
|
||||
#(开发中预告)
|
||||
|
||||
📌 **当前状态**:该功能预计于202X年发布,正在[GitLink Engine X.X](https://roadmap.gitlink.org)进行集成测试。
|
||||
🔗 **进度追踪**:关注疑修 [#462347](https://issues.gitlink.org/462347) 获取最新动态
|
||||
|
||||
### 功能预览
|
||||
- **核心能力**:
|
||||
- 在合并请求(MR)描述中通过`#ID`关联疑修(如`#123`)
|
||||
- 自动同步MR状态到关联疑修(关闭/重新开启)
|
||||
- 权限控制:仓库管理员可配置强制关联策略
|
||||
- **技术依赖**:需升级至GitLink Engine ≥X.X
|
||||
|
|
@ -15,4 +15,5 @@ GitLink中的 **合并请求(PR)** 模块提供合并请求创建和管理两方
|
|||
|
||||
如下图所示为合并请求(PR)管理模块:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
sidebar_label: '平台公告'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
sidebar_label: '平台公告说明'
|
||||
sidebar_position: 1
|
||||
---
|
||||
GitLink 平台公告
|
||||
发布日期:2024年X月X日
|
||||
公告类型:版本更新与维护通知
|
||||
影响范围:所有GitLink用户
|
||||
|
||||
📢 最新动态
|
||||
1. 版本升级至 vX.X.X
|
||||
更新概要:
|
||||
|
||||
DevOps引擎增强:支持自定义流水线模板,新增10种预置任务节点(含SonarQube代码扫描、Kubernetes部署)。
|
||||
安全升级:修复CVE-2024-1234漏洞,强制启用双因素认证(2FA)选项。
|
||||
性能优化:仓库克隆速度提升40%,大型文件(>1GB)传输稳定性增强。
|
||||
升级指南:
|
||||
|
||||
服务端升级命令:
|
||||
|
||||
gitlinkctl upgrade --version 2.3.0
|
||||
客户端兼容性:需更新至vX.X.X及以上版本,下载地址
|
||||
|
||||
🛠️ 维护计划
|
||||
1. 系统维护窗口
|
||||
时间:202X年X月X日 02:00 - 05:00 (UTC+8)
|
||||
影响:
|
||||
|
||||
期间代码推送、流水线触发功能暂停(仓库只读访问正常)。
|
||||
建议用户提前完成关键操作。
|
||||
2. 数据迁移通知
|
||||
对象:使用旧版存储引擎(vX.X)的用户
|
||||
截止日期:202X年X月X日
|
||||
操作步骤:
|
||||
|
||||
进入「控制台 -> 存储管理」发起迁移任务。
|
||||
验证数据完整性(支持SHA-256校验)。
|
||||
删除旧存储卷释放资源。
|
||||
⚠️ 重要提示
|
||||
1. 弃用旧版API
|
||||
时间:202X年X月X日起
|
||||
影响接口:
|
||||
|
||||
/api/v1/repos → 替换为 /api/v2/repositories
|
||||
/api/v1/pipelines → 替换为 /api/v2/ci-cd
|
||||
兼容性策略:旧版API保留至202X年底,查看迁移指南
|
||||
2. 第三方服务证书更新
|
||||
涉及服务:GitLink与Jenkins、Docker Hub的集成接口
|
||||
操作要求:
|
||||
|
||||
更新TLS证书至202X年CA根证书链。
|
||||
测试流水线中第三方服务调用。
|
||||
🆕 新功能速递
|
||||
1. 智能代码评审助手
|
||||
功能亮点:
|
||||
|
||||
AI自动分析代码风格违规(PEP8/ESLint规则)。
|
||||
支持自定义评审规则模板。
|
||||
使用路径:仓库设置 -> 代码评审 -> 启用AI助手
|
||||
2. 资源配额可视化
|
||||
监控指标:
|
||||
|
||||
实时显示仓库存储用量、流水线执行时长配额。
|
||||
预警阈值设置(邮件/钉钉通知)。
|
||||
访问路径:控制台 -> 资源监控
|
||||
📞 支持与反馈
|
||||
文档中心:访问帮助中心获取最新指南。
|
||||
社区支持:
|
||||
论坛提问:GitLink开发者社区
|
||||
紧急工单:登录后提交「在线支持」工单(响应时间<1小时)。
|
||||
漏洞报告:security@gitlink.org(遵循漏洞披露政策)
|
||||
GitLink 团队
|
||||
持续为开发者提供高效、安全的协作体验 🌟
|
||||
本公告最终解释权归GitLink开源社区所有
|
||||
|
||||
|
|
@ -9,16 +9,19 @@ sidebar_position: 2
|
|||
|
||||
平台提供了“新建”按钮,用户可以通过点击快速从零开始创建新的公开或者私有项目。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 2. 填写项目信息
|
||||
|
||||
填写项目基本信息。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 3. 创建成功
|
||||
|
||||
点击创建项目,创建成功后进入项目主页。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -9,19 +9,22 @@ sidebar_position: 5
|
|||
|
||||
在首页选择**导入项目**
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 2. 填写信息
|
||||
|
||||
填写需要导入的第三方Git项目地址和项目信息,如果导入项目为私有仓库,则需输入目标平台用户token进行授权。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 3. 授权验证
|
||||
|
||||
在使用GitLink平台导入其他平台(如GitHub、Gitee)的开源项目时,如果项目为私有,则无法通过正常途径导入,需要输入对应平台有权限的token值进行校验。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
下面将列举一些典型开源平台的token获取方式。
|
||||
|
||||
|
|
@ -32,6 +35,7 @@ sidebar_position: 5
|
|||
2. 访问用户头像下的settings菜单
|
||||
|
||||

|
||||
|
||||
|
||||
3. 访问最下方的Developer settings
|
||||
|
||||
|
|
@ -85,8 +89,10 @@ sidebar_position: 5
|
|||
|
||||
提示正在从第三方Git项目地址迁移
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
迁移成功则导入项目成功
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -5,18 +5,21 @@ sidebar_position: 3
|
|||
|
||||
# 提交第一行代码
|
||||
|
||||
# 1. 编辑代码
|
||||
## 1. 编辑代码
|
||||
|
||||
点击编辑按钮,开始编辑代码。
|
||||
|
||||

|
||||
|
||||
# 2. 提交代码
|
||||
<br/>
|
||||
|
||||
## 2. 提交代码
|
||||
|
||||
在编辑框中编写代码,编写完成后填写变更信息后提交变更。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
## 3. 代码更新成功
|
||||
|
||||
提交成功后代码代码更新成功。
|
||||
提交成功后代码更新成功。
|
||||
<br/>
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
---
|
||||
sidebar_label: '搜索开源项目'
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# 搜索开源项目
|
||||
|
||||
## 1. 开源项目页面介绍
|
||||
|
||||
项目”模块汇聚和管理了所有 GitLink 平台上的托管项目和镜像项目,用户可以输入项目名称关键字进行搜索,也可以根据项目类别对项目进行筛选。
|
||||
|
||||
进入“项目”模块,左侧列出了项目类型和项目类别。其中,项目类型主要包括开源托管项目和开源镜像项目两类。项目类别主要包括:云计算、大数据、区块链、物联网、机器学习、人工智能、智慧医疗、其他。
|
||||
|
||||

|
||||
|
||||
右侧展示了所有项目的基本信息,包括创建者、项目名、项目简介、浏览量、项目类别、更新时间、点赞数量、Fork 数量等信息,用户可以通过关键字搜索查找特定的项目,也可以按照更新时间、创建时间、Fork 数量、点赞数量等对项目进行排序。
|
||||
|
||||

|
||||
|
||||
用户点击项目名称,即可进入到项目详情,查看和参与开源项目开发。
|
||||
|
||||
## 2. 搜索开源项目
|
||||
|
||||
有两处搜索框可以搜索
|
||||
|
||||
### 开源项目搜索框
|
||||
|
||||
搜索项目:
|
||||
|
||||

|
||||
|
||||
搜索结果:
|
||||
|
||||

|
||||
|
||||
### 菜单栏搜索框
|
||||
|
||||
搜索项目:
|
||||
|
||||

|
||||
|
||||
搜索结果:
|
||||
|
||||

|
||||
|
|
@ -18,7 +18,9 @@ GitLink默认疑修共有缺陷、功能、疑问、支持、任务、协助、
|
|||
- **文档:** 表示文档材料补充;
|
||||
- **测试:** 表示需要测试的需求;
|
||||
- **重复:** 表示已存在类似的疑修。
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
另外,**项目成员**可以根据需求或习惯,进行标记含义或颜色标志的修改、新建标记和删除标记操作。
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -6,8 +6,8 @@ sidebar_position: 4
|
|||
|
||||
对于项目开发过程中创建的所有疑修,可以在**疑修(Issue)** 界面统一查看,如下图所示为[确实开源](https://www.gitlink.org.cn/Gitlink/forgeplus)项目下的疑修列表。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
+ **创建疑修**:在疑修列表界面下,点击“**创建疑修**”按钮,同样可以创建疑修,具体见 ***疑修创建*** 一节;
|
||||
|
||||
+ **筛选疑修**:疑修列表支持不同条件筛选,包括发布人、标记(见 ***标记管理*** 一节)、里程碑(见 ***里程碑管理*** 一节),负责人、状态和开始/结束日期等;同时支持关键字搜索,以及按多种排序规则对疑修进行排序。
|
||||
|
|
@ -6,16 +6,19 @@ sidebar_position: 2
|
|||
|
||||
1. 进入需要发布疑修的项目的“**代码库**”界面,点击上方的“**+疑修**”按钮即可进入疑修发布界面,如下图所示:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
2. 开始创建疑修,包括疑修标题、内容,输入疑修内容时既可以采用简单灵活的[Markdown语法](https://markdown.com.cn/),同时可以点击上方的功能按钮;然后上传需要的附件内容;最后点击“**创建**”按钮提交你的第一个疑修🎉🎉🎉
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
3. 此外,在创建疑修时,可以通过符号 **`#`** 快速添加需要引用的疑修,进而为当前疑修提供辅助的信息;如下图所示,键入 **`#`** 后会弹出可引用的疑修列表,通过鼠标下滑或者键盘输入疑修编号选择需要引用的疑修后,会自动添加引用疑修的链接🔗
|
||||
|
||||

|
||||
|
||||

|
||||
<br/>
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ sidebar_position: 3
|
|||
|
||||
**疑修**本质上是开发任务,而开发任务随着开发活动的进行,其状态也会发生改变,而“**状态**”便是用于跟踪记录开发活动的变更。如图所示,GitLink中疑修的**状态**包括“新增”、“正在解决”、“已解决”、“关闭”和“拒绝“五类,用于表示开发任务的处理进度。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
+ **新增**:新创建的疑修默认状态为“新增”;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ sidebar_position: 1
|
|||
|
||||
**疑修(Issue)** 管理模块主要为项目组成员提供**开发任务**发布、指派、跟踪等功能服务。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**说明事项**
|
||||
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@ sidebar_position: 5
|
|||
# 评论及操作记录
|
||||
### 评论
|
||||
每个疑修都相当于一个可以进度追踪的帖子,因此支持评论和回复,不仅仅是项目成员,所有人都可以在某个疑修下进行评论和回复,发表疑问或是见解,进行交流。
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
### 疑修声明
|
||||
用户可以对任意疑修发布“疑修声明”,留言自己对于该疑修的解决思路。点击疑修详情右侧的“声明”后,可以编辑留言,编辑完成后点击“确认”即可发布声明,如下图所示:
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
### 操作记录
|
||||
所有人都可以创建疑修,但是要注意,非项目成员仅可以修改自己创建的疑修,而项目成员有权限修改所有的疑修。
|
||||
对于某个疑修的所有编辑操作,包括**创建疑修、添加负责人、移除负责人、更改状态、更改优先级、添加标记、移除标记、添加里程碑、移除里程碑、设置关联分支、移除关联分支、设置开始日期和设置结束日期**,均被记录在操作记录中。
|
||||

|
||||
|
||||
<br/>
|
||||
|
|
@ -12,16 +12,19 @@ sidebar_position: 7
|
|||
项目成员可以基于以下步骤创建里程碑:
|
||||
1. 进入目标项目的 **“里程碑”** 界面,此时界面所示为已创建的里程碑的列表,所有已创建里程碑分为 **“已关闭”** 和 **“开启中”** 两类;
|
||||
2. 点击上方的 **“+创建里程碑”** 按钮即可进入里程碑创建界面;
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
3. 填写标题(必填)、描述(必填)、截止日期(选填)后,点击右下角的 **“创建里程碑”** 即可以完成一个新的里程碑的创建。
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
### 关联里程碑
|
||||
项目成员可以将疑修关联到里程碑,从而使里程碑包含明确的疑修列表,主要步骤如下:
|
||||
1. 在疑修列表中点击目标疑修;
|
||||
2. 编辑“里程碑”属性,选择需要关联的里程碑。
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
### 其他操作
|
||||
- **开启里程碑**
|
||||
|
|
@ -30,5 +33,8 @@ sidebar_position: 7
|
|||
- **删除里程碑**
|
||||
|
||||
上述操作均可以在里程碑列表中,对目标里程碑进行处理实现,如下图所示:
|
||||

|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
<br/>
|
||||
|
|
@ -1,40 +1,45 @@
|
|||
---
|
||||
sidebar_label: 'WebIDE'
|
||||
sidebar_position: 9
|
||||
|
||||
sidebar_label: 'WebIDE'
|
||||
sidebar_position: 9
|
||||
|
||||
---
|
||||
|
||||
import VideoDemo from '../../../src/components/VideoDemo';
|
||||
|
||||
## WebIDE背景
|
||||
传统的代码托管平台提供了代码仓库的 Git/SVN 的管理,可以在平台上做代码浏览、代码评审、缺陷管理、CI 流水线等和代码相关的活动。其中代码浏览、代码评审所用的编辑器组件一般为 CodeMirror,代码高亮使用 highlight.js,常常只提供了读代码的场景。蚂蚁研发效能部门云研发团队通过自研的 OpenSumi 框架及基于 OpenSumi 框架做的专门针对于 Web IDE(无远程容器)场景的极速版 Web IDE 框架,与内部代码托管平台碰撞出了创新型的、只依赖浏览器的、IDE 风格的代码阅读、代码编写、代码提交、代码运行、代码评审等场景,极大的提高了用户在代码托管平台阅读代码、代码评审、轻研发等场景的效率。本次蚂蚁研发效能云研发团队和 CCF(中国计算机学会)GitLink 代码托管平台合作,将内部极速版 Web IDE 应用到了 Gitlink 代码托管平台上,解决了长久以来的用户反馈的很多体验问题。
|
||||
|
||||
## Web IDE 核心能力
|
||||
对标有容器的标准版,极速版 IDE 主要在读、写、运行、提交等方面进行了探索:
|
||||
|
||||
**1. 读:**
|
||||
**1. 读:**
|
||||
- a. 适配了多种代码托管平台,例如 Gitlink、Github、Gitlab 等代码托管平台,业务可以非常方便的使用代码服务的能力
|
||||
- b. 内置了包括 Java、TS/JS、C++、Go、Python、Rust 等几十种常见语言的语法高亮支持
|
||||
- c. 支持了如 Git Blame、GitGraph 等代码阅读辅助插件
|
||||
|
||||
**2. 写:**
|
||||
|
||||
**2. 写:**
|
||||
- a. 支持 HTML/CSS/JS/Markdown 等在线语言服务能力,支持错误诊断能力
|
||||
- b. 浏览器文件系统
|
||||
|
||||
**3. 运行:**
|
||||
**3. 运行:**
|
||||
- a. 支持基于 Skypack 的前端代码运行方案
|
||||
- b. 支持基于 Pyodide 的 Python 运行
|
||||
|
||||
**4. 提交:**
|
||||
|
||||
**4. 提交:**
|
||||
- a. 支持 WebSCM,提供分支切换/新增、代码提交等能力
|
||||
|
||||
如果说以 CodeMirror、Monaco 为代表的浏览器 IDE 组件为 Web IDE 1.0,那拥有上述能力的极速版 Web IDE 就是 Web IDE 2.0。极速版 Web IDE 方案在蚂蚁内部与 2021 年 4 月上线,承接了代码阅读、代码评审、在线笔试、代码检查结果反馈、轻量在线研发等众多场景,同年 8 月 vscode.dev 和 github.dev 上线,与之相比,极速版 Web IDE 利用 OpenSumi 框架的高扩展性,业务可以更加深度的定制模块与插件,让业务有多的想象空间。
|
||||
|
||||
## 代码阅读
|
||||
在代码托管平台上进行代码阅读时经常需要查看当前方法在哪里被引用、当前接口在哪里被实现,极速版 Web IDE 提供编辑器 + 插件的能力,解决了上述用户需求:
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
<center>代码引用查看</center>
|
||||
Gitlink 通过实现 Blame 插件,完成了编辑器 Blame 查看的能力:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>当前代码行作者、修改日期查看</center>
|
||||
|
||||
|
||||
|
|
@ -44,7 +49,8 @@ Gitlink 通过实现 Blame 插件,完成了编辑器 Blame 查看的能力:
|
|||
- 1.语言服务缺失,阅读效率低:缺少代码高亮、提示、跳转、查看引用及大纲功能
|
||||
- 2.大 PR 浏览体验不佳:统计显示 Gitlink PR 平均有 14-17 个变更文件,传统代码评审交互一般为代码 Diff 组件流式展示,对于一些变更文件多、文件内部较大的场景 Review 体验不佳,常常要等待很久。
|
||||
- 3.代码修改流程重,耗时久:代码 Diff 组件只有读能力,无法快速修改一些拼写或 lint 错误,需要在本地找到对应文件后修改提交 针对于上述需求,蚂蚁云研发团队和 Gitlink 打造了 IDE 风格的代码评审场景:
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
<center>IDE模式的代码评审</center>
|
||||
- 1.变更树 a. 提供平铺和树状两种浏览方式 b. 变更树使用 OpenSumi Recycle 组件,对于大 PR 也能通过虚拟滚动高性能的查看变更文件
|
||||
|
|
@ -52,16 +58,41 @@ Gitlink 通过实现 Blame 插件,完成了编辑器 Blame 查看的能力:
|
|||
- 3.编辑器 a. 通过 monaco fold 能力完成非变更内容的折叠 b. 自定义评论组件嵌入编辑器
|
||||
- 4.插件 a. 复用代码浏览 Blame 插件能力进行代码行 Git 信息查看 除了上述能力,Gitlink 还支持了在代码评审时快速修改代码:
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>代码评审时可修改代码</center>
|
||||
|
||||
## WebIDE 功能演示
|
||||
|
||||
下面是 GitLink WebIDE 的功能演示视频,通过观看视频,您可以直观地了解如何使用 WebIDE 进行代码浏览、编辑和提交等操作。
|
||||
|
||||
<VideoDemo
|
||||
title="GitLink WebIDE 使用教程"
|
||||
platform="bilibili"
|
||||
videoId="BV1Hkr7YYEh8"
|
||||
options={{
|
||||
showTips: false
|
||||
}}
|
||||
/>
|
||||
|
||||
### 在线运行演示
|
||||
|
||||
<VideoDemo
|
||||
title="WebIDE 在线运行演示"
|
||||
platform="bilibili"
|
||||
videoId="BV15a411o72i"
|
||||
options={{ showTips: true }}
|
||||
/>
|
||||
|
||||
## Gitlink Web IDE
|
||||
Gitlink 代码阅读场景虽然接入极速版 IDE 编辑器,但文件树、代码搜索、快捷键、IDE 皮肤、等均和平时开发时使用习惯的 IDE 差异较大,更有大部分用户仅仅是为了代码阅读将代码克隆到本地,尽管保证了一致的体验,但整个链路繁琐费时。
|
||||
基于这个洞察,蚂蚁云研发团队和 Gitlink 推出 Gitlink Web IDE,可以一键快速打开 Web IDE 访问阅读项目仓库代码,实现项目与 IDE 的无缝衔接,保持研发同学的日常偏好习惯,同时完美兼容 Gitlink 代码托管平台。更重要的是,通过无容器在浏览器上直接运行一个极速版 IDE,确保「秒开」的即时体验。
|
||||
|
||||
#### **1. 快速体验**
|
||||
从 Gitlink 仓库首页 Web IDE 入口即可体验
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
<center>Gitlink WebIDE 入口</center>
|
||||
|
||||
#### **2. 代码浏览体验**
|
||||
|
|
@ -69,54 +100,64 @@ Gitlink 代码阅读场景虽然接入极速版 IDE 编辑器,但文件树、
|
|||
#### **3. 语言功能**
|
||||
- 1.支持近 40 种语言的语法高亮
|
||||
- 2.支持 JavaScript/TypeScript、HTML、CSS、JSON、Markdown 的基于 LSP (Language Server Protocol) 语言特性功能,具备智能提示和大纲信息以及单文件内跳转。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>JS语言服务提示</center>
|
||||
|
||||
- 3. 提供了 Java、Go、Python、C++、Php 的在线语言服务能力,支持简单的定义跳转、查找引用等功能,让大家更加方便的阅读代码
|
||||
- 3.提供了 Java、Go、Python、C++、Php 的在线语言服务能力,支持简单的定义跳转、查找引用等功能,让大家更加方便的阅读代码
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>Python 查看引用</center>
|
||||
|
||||
#### **4. 分支新建与切换**
|
||||
点击左下角分支名即可新建/切换分支。
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>分支新建与切换</center>
|
||||
|
||||
|
||||
#### **5. 文件搜索**
|
||||
使用 CMD/Ctrl + P 唤起文件搜索面板
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
<center>文件搜索面板</center>
|
||||
|
||||
#### **6. 行高亮**
|
||||
持单行或多行高亮,点击行号即可高亮行,按住 Shift 可选中连续多行。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>多选行高亮</center>
|
||||
|
||||
#### **7. Blame**
|
||||
支持查看单行 blame 信息,hover 后可展示详细信息。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>Blame详细信息</center>
|
||||
|
||||
#### **8. Graph**
|
||||
支持 graph 视图,可查看分支 commits 历史以及每个 commit 详细文件变更,并支持文件 diff 查看。底部状态栏左下角点击 Git Graph 或在命令面板输入 View Git Graph,即可打开 Git Graph 视图。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>Graph 详细信息</center>
|
||||
|
||||
|
||||
#### **9.WebSCM**
|
||||
对于开发来说日常多个需求并行开发是非常常见的事,经常修改一些很小但必要的逻辑,而也许你本地环境已经在开发下一个需求,频繁的分支切换并行修改又容易出错。通过 Gitlink Web IDE 极速切换分支修改提交一气呵成,无需打断本地开发流程。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>WebSCM</center>
|
||||
|
||||
|
||||
#### **10.代码在线运行**
|
||||
目前如果在没有容器的情况下,大部分应用只能运行前端代码。Gitlink Web IDE 集成了基于 skypack 的更加轻量的 CodeSwing 插件,可以在极速版去运行前端代码,并且代码版本是使用 Gitlink 来管理。结合上述 WebSCM 能力,甚至能在一分钟完成前端代码初始化、编写、预览和代码提交。
|
||||

|
||||
|
||||
<br/>
|
||||
<center>前端代码运行</center>
|
||||
|
||||
随着 Webassembly 技术的发展,一些后端语言也可以运行在浏览器里,在 2021 年 Google IO 大会上,StackBlitz 展示了他们最近做的技术:WebContainer,该能力可以将语言运行时编译为 Webassembly 从而运行在浏览器上。Code-Runner-For-Web 插件结合 Pyodide,已经将 Python 的运行搬到了浏览器上,新版极速版也默认集成了该插件。
|
||||

|
||||
<center>Python代码运行</center>
|
||||
|
||||
<br/>
|
||||
<center>Python代码运行</center>
|
||||
|
|
@ -62,6 +62,6 @@ sidebar_position: 1
|
|||
|
||||
## 用户操作流程
|
||||
|
||||
<br/>
|
||||
.png)<br/>
|
||||
|
||||
<center>用户操作流程</center><br/>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue