diff --git a/README.md b/README.md
index a73f3be33..a3546ad46 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,48 @@
-[English](README.md)
-
-
OpenData - open data project management
-
-[](https://drone.gitea.io/go-gitea/gitea)
-[](https://discord.gg/Gitea)
-[](https://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
-[](https://codecov.io/gh/go-gitea/gitea)
-[](https://godoc.org/code.gitea.io/gitea)
-[](https://github.com/go-gitea/gitea/releases/latest)
-[](https://www.codetriage.com/go-gitea/gitea)
-[](https://opencollective.com/gitea)
+
+
+
AiForge - 启智AI开发协作平台
+
+[](https://git.openi.org.cn/OpenI/aiforge/releases/latest)
[](https://opensource.org/licenses/MIT)
-[](https://crowdin.com/project/gitea)
-## 目标
-OpenData 的首要目标是提供对开源数据的大存储支持和管理,旨在为国家开源项目的建设贡献力量。为软件行业中的开源项目的发展提供助力。
+## AiForge
+
+启智AI开发协作平台是一个在线Web应用,旨在为人工智能算法、模型开发提供在线协同工作环境,它提供了代码托管、数据集管理与共享、免费云端算力资源支持(GPU/NPU)、共享镜像等功能。
+
+[启智AI开发协作平台](https://git.openi.org.cn) 是使用本项目构建的在线服务,您可以直接点击链接访问试用。
+
+本项目是基于[Gitea](https://github.com/go-gitea/gitea)发展而来的,我们对其进行了Fork并基于此扩展了人工智能开发中需要的功能,如数据集管理和模型训练等。对于和代码托管相关的功能,您可以参考[Gitea的文档](https://docs.gitea.io/zh-cn/)。
+
+### 系统总体架构
+下图展示了系统总体架构,本项目分为Web前端和服务后端,Web页面面向算法开发者、应用开发者、科研工作者、学生等用户群体,通过统一的Web页面入口,使用系统提供的系统服务。
+
+后端服务涵盖了AI模型开发流水线,包括代码协同开发、数据管理、模型调试、训练、推理和部署等(*目前尚未支持模型部署*)。在不同的开发阶段,我们还将提供丰富的开发工具供用户使用,如数据标注、数据筛选、模型转换、模型压缩、代码监测等。我们也欢迎社区提供更多丰富的工具接入,提高利用平台进行开发的效率。
+
+## 在线服务使用
+本项目的在线服务平台的详细使用帮助文档,可参阅本项目[百科](https://git.openi.org.cn/OpenI/aiforge/wiki)内容。
+- 如何创建账号
+- 如何创建组织及管理成员权限
+- 如何创建项目仓库
+- 如何使用数据集功能
+- 如何使用计算资源进行模型调试和训练
+- 使用小技巧
+- 常见问题(FAQ)
+## 安装
+您也可以基于本项目代码,在本地环境安装部署服务。
+### 数据库准备
+[数据库准备说明](https://docs.gitea.io/zh-cn/database-prep/)
+### 从源代码安装
+- node版本 >= v10.13.0
+- golang版本 >= 1.13.3
+
+[从源代码安装说明](https://docs.gitea.io/zh-cn/install-from-source/)
-## 我们所提供的
+## 授权许可
+本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://git.openi.org.cn/OpenI/aiforge/src/branch/develop/LICENSE) 文件中。
-- 项目管理
-- git代码管理
-- 大数据集存储管理,最高单个数据集限制为1TB
-- 初期为社区项目免费提供30PB的算力,后续根据使用情况逐步增加
\ No newline at end of file
+## 需要帮助?
+如果您在使用或者开发过程中遇到问题,可以在以下渠道咨询:
+ - 点击[这里](https://git.openi.org.cn/OpenI/aiforge/issues)在线提交问题(点击页面右上角绿色按钮**创建任务**)
+ - 加入微信群实时交流,获得进一步的支持
+
diff --git a/assets/OPENI平台系统架构图.jpg b/assets/OPENI平台系统架构图.jpg
new file mode 100755
index 000000000..e2e2e3449
Binary files /dev/null and b/assets/OPENI平台系统架构图.jpg differ
diff --git a/assets/架构图.png b/assets/架构图.png
new file mode 100644
index 000000000..d03a01a4d
Binary files /dev/null and b/assets/架构图.png differ
diff --git a/models/custom_migrations.go b/models/custom_migrations.go
new file mode 100644
index 000000000..b196c5a8b
--- /dev/null
+++ b/models/custom_migrations.go
@@ -0,0 +1,36 @@
+package models
+
+import (
+ "code.gitea.io/gitea/modules/log"
+ "xorm.io/xorm"
+)
+
+type CustomMigration struct {
+ Description string
+ Migrate func(*xorm.Engine) error
+}
+
+var customMigrations = []CustomMigration{
+ {"Custom v1 Topic struct change to support chinese", syncTopicStruct},
+}
+
+func MigrateCustom(x *xorm.Engine) {
+
+ for _, m := range customMigrations {
+ log.Info("Migration: %s", m.Description)
+ if err := m.Migrate(x); err != nil {
+
+ log.Error("Migration: %v", err)
+
+ }
+ }
+
+}
+
+func syncTopicStruct(x *xorm.Engine) error {
+
+ query := "ALTER TABLE topic ALTER COLUMN name TYPE varchar(105);"
+
+ _, err := x.Exec(query)
+ return err
+}
diff --git a/models/models.go b/models/models.go
index 0e06c60b3..67892399a 100755
--- a/models/models.go
+++ b/models/models.go
@@ -185,6 +185,8 @@ func SetEngine() (err error) {
x.SetMaxOpenConns(setting.Database.MaxOpenConns)
x.SetMaxIdleConns(setting.Database.MaxIdleConns)
x.SetConnMaxLifetime(setting.Database.ConnMaxLifetime)
+ x.Sync2(tables...)
+ MigrateCustom(x)
return nil
}
diff --git a/models/topic.go b/models/topic.go
index 4a5bffa08..b8d3d9d85 100644
--- a/models/topic.go
+++ b/models/topic.go
@@ -8,6 +8,7 @@ import (
"fmt"
"regexp"
"strings"
+ "unicode/utf8"
"code.gitea.io/gitea/modules/timeutil"
@@ -21,12 +22,12 @@ func init() {
)
}
-var topicPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`)
+var topicPattern = regexp.MustCompile(`^[\x{4e00}-\x{9fa5}a-z0-9][\x{4e00}-\x{9fa5}a-z0-9-]*$`)
// Topic represents a topic of repositories
type Topic struct {
ID int64
- Name string `xorm:"UNIQUE VARCHAR(25)"`
+ Name string `xorm:"UNIQUE VARCHAR(105)"`
RepoCount int
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
@@ -56,7 +57,7 @@ func (err ErrTopicNotExist) Error() string {
// ValidateTopic checks a topic by length and match pattern rules
func ValidateTopic(topic string) bool {
- return len(topic) <= 35 && topicPattern.MatchString(topic)
+ return utf8.RuneCountInString(topic) <= 35 && topicPattern.MatchString(topic)
}
// SanitizeAndValidateTopics sanitizes and checks an array or topics
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 61a233589..56cf564e7 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -1815,7 +1815,7 @@ branch.included = Included
topic.manage_topics = Manage Topics
topic.done = Done
topic.count_prompt = You can not select more than 25 topics
-topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
+topic.format_prompt = Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.
[org]
org_name_holder = Organization Name
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 4a3e910f9..47fa8d2bb 100755
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -1817,7 +1817,7 @@ branch.included=已包含
topic.manage_topics=管理主题
topic.done=保存
topic.count_prompt=您最多选择25个主题
-topic.format_prompt=主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
+topic.format_prompt=主题必须以中文、字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
[org]
org_name_holder=组织名称
diff --git a/web_src/js/index.js b/web_src/js/index.js
index 991a13c21..2cc622cc0 100755
--- a/web_src/js/index.js
+++ b/web_src/js/index.js
@@ -4113,11 +4113,7 @@ function initTopicbar() {
$.fn.form.settings.rules.validateTopic = function (_values, regExp) {
const topics = topicDropdown.children('a.ui.label');
const status =
- topics.length === 0 ||
- topics
- .last()
- .attr('data-value')
- .match(regExp);
+ topics.length === 0 || (topics.last().attr('data-value').match(regExp) !== null && topics.last().attr('data-value').length <= 35);
if (!status) {
topics
.last()
@@ -4136,7 +4132,7 @@ function initTopicbar() {
rules: [
{
type: 'validateTopic',
- value: /^[a-z0-9][a-z0-9-]{0,35}$/,
+ value: /^[\u4e00-\u9fa5a-z0-9][\u4e00-\u9fa5a-z0-9-]{0,105}$/,
prompt: topicPrompts.formatPrompt
},
{