Compare commits
66 Commits
standalone
...
standalone
| Author | SHA1 | Date |
|---|---|---|
|
|
96b0f2d167 | |
|
|
8e4e6fc0ac | |
|
|
75f3166ffa | |
|
|
04bf423fcb | |
|
|
51e8c9d908 | |
|
|
4304a35b80 | |
|
|
076375633a | |
|
|
dbf5e711a5 | |
|
|
4432e65683 | |
|
|
dcf44a78f0 | |
|
|
12edc620df | |
|
|
4ce03145df | |
|
|
3e04a37ece | |
|
|
78f464ccba | |
|
|
64423f1999 | |
|
|
05c3f60dab | |
|
|
0083ef33cb | |
|
|
36b68df273 | |
|
|
e1a5918c22 | |
|
|
26ae9b35df | |
|
|
8e79b43aaf | |
|
|
c2bd78d70d | |
|
|
d28eba6423 | |
|
|
688be1bb7d | |
|
|
df69dee282 | |
|
|
fae8313df6 | |
|
|
45a77e5c07 | |
|
|
7849bd0ebf | |
|
|
ab361d8009 | |
|
|
3649bf1fd0 | |
|
|
a24d33d2ee | |
|
|
6ffc2938a1 | |
|
|
aa60de1dac | |
|
|
29f98513e2 | |
|
|
e35cdf39fb | |
|
|
af160084c4 | |
|
|
e51b86538b | |
|
|
da4fd3a762 | |
|
|
8a34699acd | |
|
|
efc82b9841 | |
|
|
e3df503dd2 | |
|
|
6a2ad67386 | |
|
|
3d12db3a07 | |
|
|
1d13b3686b | |
|
|
1faaf1d7d1 | |
|
|
f8a6f62342 | |
|
|
d48700d200 | |
|
|
66d1246a6c | |
|
|
f79beef3f9 | |
|
|
81e6691632 | |
|
|
38d6519381 | |
|
|
16418675ac | |
|
|
102858bc8c | |
|
|
0d64768e4b | |
|
|
beccac652f | |
|
|
30eb1958c1 | |
|
|
33e17e8439 | |
|
|
1c19c05fd8 | |
|
|
657e2cf169 | |
|
|
e0c47c2abd | |
|
|
ba9e74f373 | |
|
|
93dd5b5d84 | |
|
|
422549f9e7 | |
|
|
0358229b95 | |
|
|
c4586fbb36 | |
|
|
e25e2fdd77 |
|
|
@ -23,7 +23,7 @@
|
|||
* Fix 版本库中附件下载400(#51625)
|
||||
* Fix loading页面优化(#51588)
|
||||
* Fix 提交详情页面优化(#51577)
|
||||
* Fix 修复易修复制功能(#51569)
|
||||
* Fix 修复疑修复制功能(#51569)
|
||||
* Fix 修复新建发行版用户信息显示错误的问题(#51665)
|
||||
* Fix 修复查看文件详细信息报错的问题(#51561)
|
||||
* Fix 修复提交记录中时间显示格式问题(#51526)
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
## [v3.0.3](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-05-08
|
||||
|
||||
* BUGFIXES
|
||||
* Fix 解决易修标题过长导致的排版问题(45469)
|
||||
* Fix 解决疑修标题过长导致的排版问题(45469)
|
||||
* Fix 解决合并请求详情页面排版错误的问题(45457)
|
||||
* FIX 解决转移仓库界面专有名词描述错误的问题(45455)
|
||||
* Fix 解决markdown格式文件自动生成数字排序的问题(45454)
|
||||
|
|
|
|||
143
README.md
|
|
@ -1,30 +1,17 @@
|
|||
# GitLink - CCF开源创新服务平台
|
||||
Trustie (确实)是一个以大众化协同开发、开放式资源共享、持续性可信评估为核心机理,面向高校创新实践的在线协作平台。
|
||||
|
||||
GitLink(确实开源)是中国计算机学会(CCF)官方指定的开源创新服务平台,旨在以“为开源创新服务”为使命,以“成为开源创新的汇聚地”为愿景,秉承“创新、开放、协作、共享”的价值观,致力于为大规模开源开放协同创新助力赋能,打造创新成果孵化和新工科人才培养的开源创新生态!
|
||||
## 特性
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/gitlink.png?raw=true" width=80% />
|
||||
</center>
|
||||
|
||||
## 特色功能
|
||||
- 软件创作与生产深度融合的软件开发环境体系结构 软件自由创作和工程生产的高效衔接,适于软件开发中群体智慧的有效汇聚。
|
||||
|
||||
- **分布式协作开发**:基于Git打造分布式代码托管环境,提供免费公、私有代码仓库,支持在线文件编辑、代码分支管理、协作贡献统计、代码仓库复刻(Fork)、贡献合并请求(PR)、群智贡献审阅等功能,让您的项目在这里健康、快速的成长!
|
||||
- 构件化协同开发环境的可扩展运行框架多样化工具的集成和联动,形成了强动态扩展能力的平台框架。
|
||||
|
||||
- **一站式过程管理**:提供易修(Issue)、里程碑、通知提醒、标签归档等多样化任务管理工具,支持各类开发任务的发布、指派与跟踪,同时提供在线Wiki文档、组织多粒度管理等功能,为您搭建一站式的项目过程管理环境,让您的团队协作更高效、过程更透明!
|
||||
- “互联网即资源库”的全新软件复用模式 成长式软件资源管理系统,实现了分散资源的知识融合、资源的可持续增长和有效复用。
|
||||
|
||||
- **高效流水线运维**:融合DevOps思想,提供轻量级的工作流引擎(Engine),打通编码、测试、构建、部署等开发运维环节;支持自定义配置、代码静态扫描、构建自动触发、容器镜像托管等功能,同时支持接入第三方运维工具,让您的代码更加快速、可靠地形成高质量的产品!
|
||||
|
||||
- **多层次代码分析**:提供软件软代码和芯片RTL代码的溯源分析、文件级和组件级许可证识别及风险分析、输入性开源漏洞检测和加固建议,支持分析结果的多层次可视化展示,帮助您实施有效开源治理,厘清代码引用链,发现并消除漏洞感染链,为安全合规的开源引用保驾护航!
|
||||
|
||||
- **多维度用户画像**:实时采集和分析平台中的各类开源资源数据,搭建多维度用户画像评估系统,提供开发活动统计、贡献度日历、用户能力建模、角色与专业定位分析等功能,让您在个人主页展示开发动态与创新能力!
|
||||
|
||||
## 第三方组件
|
||||
## 部署
|
||||
|
||||
|
||||
## 部署流程
|
||||
|
||||
|
||||
### 依赖库
|
||||
### Depends Versions
|
||||
|
||||
* Ruby 2.4.5
|
||||
|
||||
|
|
@ -36,19 +23,22 @@ GitLink(确实开源)是中国计算机学会(CCF)官方指定的开源
|
|||
|
||||
* imagemagick
|
||||
|
||||
### 步骤
|
||||
### Steps
|
||||
|
||||
(1)克隆稳定版本
|
||||
#### 1. 克隆稳定版本
|
||||
```
|
||||
git clone -b standalone https://git.trustie.net/jasder/forgeplus.git
|
||||
```
|
||||
|
||||
(2)安装依赖包
|
||||
#### 2. 安装依赖包
|
||||
|
||||
```bash
|
||||
cd forgeplus && bundle install
|
||||
```
|
||||
|
||||
(3)配置初始化文件:进入项目根目录执行以下命令
|
||||
#### 3. 配置初始化文件
|
||||
进入项目根目录执行一下命令:
|
||||
|
||||
```bash
|
||||
cp config/configuration.yml.example config/configuration.yml
|
||||
cp config/database.yml.example config/database.yml
|
||||
|
|
@ -56,7 +46,11 @@ touch config/redis.yml
|
|||
touch config/elasticsearch.yml
|
||||
```
|
||||
|
||||
(4)配置数据库:数据库配置信息请查看/config/database.yml文件,项目默认采用mysql数据库, 如需更改,请自行修改配置信息,默认配置如下
|
||||
#### 4. 配置数据库
|
||||
数据库配置信息请查看/config/database.yml文件,
|
||||
项目默认采用mysql数据库, 如需更改,请自行修改配置信息,
|
||||
默认配置如下:
|
||||
|
||||
```bash
|
||||
default: &default
|
||||
adapter: mysql2
|
||||
|
|
@ -66,13 +60,14 @@ default: &default
|
|||
password: 123456
|
||||
```
|
||||
|
||||
(5)配置gitea服务(可选):如需要部署自己的gitea平台,请参考[gitea官方平台文档](https://docs.gitea.io/zh-cn/install-from-binary/)。因目前gitea平台api受限,暂时推荐从forge平台获取[gitea部署文件](https://forgeplus.trustie.net/projects/Trustie/gitea-binary)进行部署
|
||||
#### 5. 配置gitea服务(可选)
|
||||
**如需要部署自己的gitea平台,请参考gitea官方平台:https://docs.gitea.io/zh-cn/install-from-binary/**
|
||||
|
||||
- 配置gitea服务步骤:
|
||||
|
||||
-- 部署gitea服务,并注册root账户
|
||||
|
||||
-- 修改forge平台的 config/configuration.yml中的gitea服务指向地址,如:
|
||||
**因目前gitea平台api受限,暂时推荐从forge平台获取gitea部署文件进行部署:https://forgeplus.trustie.net/projects/Trustie/gitea-binary**
|
||||
|
||||
**配置gitea服务步骤**
|
||||
1. 部署gitea服务,并注册root账户
|
||||
2. 修改forge平台的 config/configuration.yml中的gitea服务指向地址,如:
|
||||
|
||||
```ruby
|
||||
gitea:
|
||||
|
|
@ -82,9 +77,10 @@ gitea:
|
|||
base_url: '/api/v1'
|
||||
```
|
||||
|
||||
(6)安装redis环境:请自行搜索各平台如何安装部署redis环境
|
||||
#### 6. 安装redis环境
|
||||
**请自行搜索各平台如何安装部署redis环境**
|
||||
|
||||
(7)安装imagemagick插件:
|
||||
#### 7. 安装imagemagick插件
|
||||
- Mac OS X
|
||||
```bash
|
||||
brew install imagemagick ghostscript
|
||||
|
|
@ -95,95 +91,88 @@ gitea:
|
|||
sudo apt-get install -y imagemagick
|
||||
```
|
||||
|
||||
(8)创建数据库:开发环境为development, 生成环境为production
|
||||
#### 8. 创建数据库
|
||||
**开发环境为development, 生成环境为production**
|
||||
```bash
|
||||
rails db:create RAILS_ENV=development
|
||||
```
|
||||
|
||||
(9)导入数据表结构
|
||||
#### 9. 导入数据表结构
|
||||
|
||||
```bash
|
||||
bundle exec rake sync_table_structure:import_csv
|
||||
```
|
||||
|
||||
(10)执行migrate迁移文件:开发环境为development, 生成环境为production
|
||||
#### 10. 执行migrate迁移文件
|
||||
**开发环境为development, 生成环境为production**
|
||||
```bash
|
||||
rails db:migrate RAILS_ENV=development
|
||||
```
|
||||
|
||||
(11)clone前端代码:将前端代码克隆到public/react目录下,目录结构应该是: public/react/build
|
||||
#### 11. clone前端代码
|
||||
**将前端代码克隆到public/react目录下,目录结构应该是: public/react/build**
|
||||
```bash
|
||||
git clone -b standalone https://git.trustie.net/jasder/build.git
|
||||
```
|
||||
|
||||
(12)启动redis(此处以macOS系统为例)
|
||||
#### 12. 启动redis(此处已mac系统为例)
|
||||
```bash
|
||||
redis-server&
|
||||
```
|
||||
|
||||
(13)启动sidekiq:开发环境为development, 生成环境为production
|
||||
#### 13. 启动sidekiq
|
||||
**开发环境为development, 生成环境为production**
|
||||
```bash
|
||||
bundle exec sidekiq -C config/sidekiq.yml -e production -d
|
||||
```
|
||||
|
||||
(14)启动rails服务
|
||||
#### 14. 启动rails服务
|
||||
```bash
|
||||
rails s
|
||||
```
|
||||
|
||||
(15)浏览器访问:在浏览器中输入如下地址访问
|
||||
#### 15. 浏览器访问
|
||||
在浏览器中输入如下地址访问:
|
||||
```bash
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
(16)其他说明:通过页面注册以第一个用户为平台管理员用户
|
||||
|
||||
#### 16. 其他说明
|
||||
通过页面注册都第一个用户为平台管理员用户
|
||||
|
||||
## 页面展示
|
||||
|
||||
- 项目列表
|
||||
- 代码库
|
||||
|
||||

|
||||
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/project_list.png?raw=true" width=50% />
|
||||
</center>
|
||||
|
||||
- 代码仓库
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/repo.png?raw=true" width=50% />
|
||||
</center>
|
||||
|
||||
- 任务管理
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/issues.png?raw=true" width=50% />
|
||||
</center>
|
||||
|
||||
- 合并请求
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/PR.png?raw=true" width=50% />
|
||||
</center>
|
||||
|
||||
- 引擎配置
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/engine.png?raw=true" width=50% />
|
||||
</center>
|
||||

|
||||
|
||||
- 任务查看
|
||||
|
||||

|
||||
|
||||
- 任务指派
|
||||
|
||||

|
||||
|
||||
- 里程碑
|
||||
|
||||

|
||||
|
||||
### API
|
||||
- [API文档](https://forgeplus.trustie.net/docs/api)
|
||||
- [API](showdoc.com.cn)
|
||||
账号:forgeplus@admin.com 密码:forge123
|
||||
|
||||
## 贡献代码
|
||||
|
||||
我们期待您向GitLink提交贡献!在您贡献时,请遵循以下流程:
|
||||
|
||||
1. Fork 项目
|
||||
2. 创建本地分支(git checkout -b my-new-feature)
|
||||
3. 提交更改 (git commit -am 'Add some feature')
|
||||
4. 推送到分支 (git push origin my-new-feature)
|
||||
5. 向源项目的 **develop** 分支发起 Pull Request
|
||||
|
||||
#### 指导文档
|
||||
- [API文档](https://www.gitlink.org.cn/docs/api)
|
||||
- [Git常用命令](https://git-scm.com/)
|
||||
|
||||
## 许可证协议
|
||||
## License
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ class AccountsController < ApplicationController
|
|||
|
||||
# 其他平台同步注册的用户
|
||||
def remote_register
|
||||
Register::RemoteForm.new(remote_register_params).validate!
|
||||
username = params[:username]&.gsub(/\s+/, "")
|
||||
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
||||
email = params[:email]&.gsub(/\s+/, "")
|
||||
|
|
@ -375,5 +376,9 @@ class AccountsController < ApplicationController
|
|||
phone_or_mail = strip(reset_password_params[:login])
|
||||
User.where("phone = :search OR mail = :search", search: phone_or_mail).last
|
||||
end
|
||||
|
||||
def remote_register_params
|
||||
params.permit(:username, :email, :password, :platform)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,138 @@
|
|||
#coding=utf-8
|
||||
class ClaimsController < ApplicationController
|
||||
# skip_before_action :verify_authenticity_token
|
||||
protect_from_forgery with: :null_session
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :set_issue
|
||||
|
||||
def index
|
||||
@user_claimed = 0
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
|
||||
@claims.each do |claim|
|
||||
if claim.user_id == current_user.id
|
||||
@user_claimed = 1
|
||||
break
|
||||
end
|
||||
end
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
end
|
||||
|
||||
def create
|
||||
@claim = Claim.find_by_sql(["select id from claims where issue_id=? and user_id=?",params[:issue_id], current_user.id])
|
||||
if @claim.present?
|
||||
return normal_status(-1,"您已经声明过该易修")
|
||||
end
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@claim = Claim.new(parse_issue_params(params))
|
||||
if @claim.save
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
@user_claimed = 1
|
||||
|
||||
journal_params = {
|
||||
journalized_id: params[:issue_id],
|
||||
journalized_type: "Issue",
|
||||
user_id: current_user.id ,
|
||||
notes: "新建声明: #{params[:claim_note]}",
|
||||
}
|
||||
|
||||
journal = Journal.new(journal_params)
|
||||
if journal.save
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
else
|
||||
normal_status(-1,"新建声明关联评论操作失败")
|
||||
end
|
||||
|
||||
else
|
||||
normal_status(-1,"新建声明操作失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@claim = Claim.find_by_id(params[:claim_id])
|
||||
if @claim.blank?
|
||||
return normal_status(-1,"易修不存在")
|
||||
end
|
||||
|
||||
if @claim.user_id != current_user.id
|
||||
return normal_status(-1,"你不能更新别人的声明")
|
||||
end
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
if @claim.update_attribute(:note,params[:claim_note])
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
@user_claimed = 1
|
||||
|
||||
journal_params = {
|
||||
journalized_id: params[:issue_id],
|
||||
journalized_type: "Issue",
|
||||
user_id: current_user.id ,
|
||||
notes: "更新声明: #{params[:claim_note]}",
|
||||
}
|
||||
|
||||
journal = Journal.new(journal_params)
|
||||
if journal.save
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
else
|
||||
normal_status(-1,"新建声明关联评论操作失败")
|
||||
end
|
||||
|
||||
else
|
||||
normal_status(-1,"声明更新操作失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@claim = Claim.find_by_sql(["select id from claims where issue_id=? and user_id=?",params[:issue_id], current_user.id])
|
||||
if @claim.blank?
|
||||
normal_status(-1,"您未曾声明过该易修")
|
||||
else
|
||||
@claim = @claim[0]
|
||||
# 判断current user是否是claimer
|
||||
ActiveRecord::Base.transaction do
|
||||
if @claim.destroy
|
||||
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
@user_claimed = 0
|
||||
|
||||
journal_params = {
|
||||
journalized_id: params[:issue_id],
|
||||
journalized_type: "Issue",
|
||||
user_id: current_user.id ,
|
||||
notes: "取消声明",
|
||||
}
|
||||
|
||||
journal = Journal.new(journal_params)
|
||||
if journal.save
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
else
|
||||
normal_status(-1,"新建声明关联评论操作失败")
|
||||
end
|
||||
|
||||
else
|
||||
normal_status(-1,"取消声明操作失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def parse_issue_params(params)
|
||||
{
|
||||
issue_id: params[:issue_id],
|
||||
user_id: current_user.id,
|
||||
note: params[:claim_note],
|
||||
}
|
||||
end
|
||||
|
||||
def set_issue
|
||||
@issue = Issue.find_by_id(params[:issue_id])
|
||||
unless @issue.present?
|
||||
normal_status(-1, "易修不存在")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -42,12 +42,14 @@ class CompareController < ApplicationController
|
|||
end
|
||||
|
||||
def load_compare_params
|
||||
@base = Addressable::URI.unescape(params[:base])
|
||||
# @base = Addressable::URI.unescape(params[:base])
|
||||
@base = Base64.decode64(params[:base])
|
||||
@head = params[:head].include?('.json') ? params[:head][0..-6] : params[:head]
|
||||
|
||||
# @head = Addressable::URI.unescape(@head)
|
||||
@head = Base64.decode64(@head)
|
||||
end
|
||||
|
||||
def gitea_compare(base, head)
|
||||
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base, head, current_user.gitea_token)
|
||||
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, CGI.escape(base), CGI.escape(head), current_user.gitea_token)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -486,7 +486,8 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
|
||||
def operate_issue_permission
|
||||
return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || @project.is_public?)
|
||||
@issue = Issue.find_by_id(params[:id]) unless @issue.present?
|
||||
return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || (@project.is_public && @issue.nil?) || (@project.is_public && @issue.present? && @issue.author_id == current_user.id))
|
||||
end
|
||||
|
||||
def export_issues(issues)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
|
|||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.check_exists?(organization_params[:name])
|
||||
Organizations::CreateForm.new(organization_params).validate!
|
||||
Organizations::CreateForm.new(organization_params.merge(original_name: "")).validate!
|
||||
@organization = Organizations::CreateService.call(current_user, organization_params)
|
||||
Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
|
||||
end
|
||||
|
|
@ -39,7 +39,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
|
|||
|
||||
def update
|
||||
ActiveRecord::Base.transaction do
|
||||
Organizations::CreateForm.new(organization_params).validate!
|
||||
Organizations::CreateForm.new(organization_params.merge(original_name: @organization.login)).validate!
|
||||
login = @organization.login
|
||||
@organization.login = organization_params[:name] if organization_params[:name].present?
|
||||
@organization.nickname = organization_params[:nickname] if organization_params[:nickname].present?
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class Organizations::TeamUsersController < Organizations::BaseController
|
|||
ActiveRecord::Base.transaction do
|
||||
@team_user = TeamUser.build(@organization.id, @operate_user.id, @team.id)
|
||||
@organization_user = OrganizationUser.build(@organization.id, @operate_user.id)
|
||||
SendTemplateMessageJob.perform_later('OrganizationRole', @operate_user.id, @organization.id, @team.authorize_name) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later('TeamJoined', @operate_user.id, @organization.id, @team.id) if Site.has_notice_menu?
|
||||
Gitea::Organization::TeamUser::CreateService.call(@organization.gitea_token, @team.gtid, @operate_user.login)
|
||||
end
|
||||
rescue Exception => e
|
||||
|
|
@ -31,6 +31,7 @@ class Organizations::TeamUsersController < Organizations::BaseController
|
|||
ActiveRecord::Base.transaction do
|
||||
@team_user.destroy!
|
||||
Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, @operate_user.login)
|
||||
SendTemplateMessageJob.perform_later('TeamLeft', @operate_user.id, @organization.id, @team.id) if Site.has_notice_menu?
|
||||
org_team_users = @organization.team_users.where(user_id: @operate_user.id)
|
||||
unless org_team_users.present?
|
||||
@organization.organization_users.find_by(user_id: @operate_user.id).destroy!
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ class ProjectTrendsController < ApplicationController
|
|||
before_action :check_project_public
|
||||
|
||||
def index
|
||||
project_trends = @project.project_trends.preload(:user, trend: :user)
|
||||
project_trends = @project.project_trends.preload(:user, trend: :user, project: :owner)
|
||||
|
||||
check_time = params[:time] #时间的筛选
|
||||
check_type = params[:type] #动态类型的筛选,目前已知的有 Issue, PullRequest, Version
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ class ProjectsController < ApplicationController
|
|||
menu.append(menu_hash_by_name("home"))
|
||||
menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code")
|
||||
menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues")
|
||||
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls")
|
||||
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki")
|
||||
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops")
|
||||
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls") && @project.forge?
|
||||
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops") && @project.forge?
|
||||
menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions")
|
||||
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources")
|
||||
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge?
|
||||
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources") && @project.forge?
|
||||
menu.append(menu_hash_by_name("activity"))
|
||||
menu.append(menu_hash_by_name("settings")) if current_user.admin? || @project.manager?(current_user)
|
||||
menu.append(menu_hash_by_name("settings")) if (current_user.admin? || @project.manager?(current_user)) && @project.forge?
|
||||
|
||||
render json: menu
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class PullRequestsController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user)
|
||||
# return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user)
|
||||
ActiveRecord::Base.transaction do
|
||||
@pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params)
|
||||
if @gitea_pull_request[:status] == :success
|
||||
|
|
@ -89,6 +89,7 @@ class PullRequestsController < ApplicationController
|
|||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
return normal_status(-1, "title不能超过255个字符") if params[:title].length > 255
|
||||
merge_params
|
||||
|
||||
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
|
||||
|
|
|
|||
|
|
@ -1,368 +1,387 @@
|
|||
class RepositoriesController < ApplicationController
|
||||
include RepositoriesHelper
|
||||
include ApplicationHelper
|
||||
include OperateProjectAbilityAble
|
||||
include Repository::LanguagesPercentagable
|
||||
|
||||
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
|
||||
before_action :require_profile_completed, only: [:create_file]
|
||||
before_action :load_repository
|
||||
before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive]
|
||||
before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror]
|
||||
before_action :get_ref, only: %i[entries sub_entries top_counts file archive]
|
||||
before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
|
||||
before_action :get_statistics, only: %i[top_counts]
|
||||
|
||||
def files
|
||||
result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token)
|
||||
render json: result
|
||||
end
|
||||
|
||||
# 新版项目详情
|
||||
def detail
|
||||
@user = current_user
|
||||
@result = Repositories::DetailService.call(@owner, @repository, @user)
|
||||
@project_fork_id = @project.try(:forked_from_project_id)
|
||||
if @project_fork_id.present?
|
||||
@fork_project = Project.find_by(id: @project_fork_id)
|
||||
@fork_project_user = @fork_project.owner
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def show
|
||||
@user = current_user
|
||||
@repo = @project.repository
|
||||
@result = @project.forge? ? Gitea::Repository::GetService.new(@owner, @project.identifier).call : nil
|
||||
@project_fork_id = @project.try(:forked_from_project_id)
|
||||
if @project_fork_id.present?
|
||||
@fork_project = Project.find_by(id: @project_fork_id)
|
||||
@fork_project_user = @fork_project.owner
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def entries
|
||||
@project.increment!(:visits)
|
||||
CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id)
|
||||
if @project.educoder?
|
||||
@entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name)
|
||||
else
|
||||
@entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call
|
||||
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
||||
end
|
||||
end
|
||||
|
||||
def top_counts
|
||||
@result = @project.educoder? ? nil : Gitea::Repository::GetService.new(@project.owner, @project.identifier).call
|
||||
end
|
||||
|
||||
def sub_entries
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
|
||||
if @project.educoder?
|
||||
if params[:type] === 'file'
|
||||
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
|
||||
logger.info "######### sub_entries: #{@sub_entries}"
|
||||
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
|
||||
|
||||
tmp_entries = [{
|
||||
"content" => @sub_entries['data']['content'],
|
||||
"type" => "blob"
|
||||
}]
|
||||
@sub_entries = {
|
||||
"trees"=>tmp_entries,
|
||||
"commits" => [{}]
|
||||
}
|
||||
else
|
||||
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
|
||||
end
|
||||
else
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
||||
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref)
|
||||
if interactor.success?
|
||||
result = interactor.result
|
||||
@sub_entries = result.is_a?(Array) ? result.sort_by{ |hash| hash['type'] } : result
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def commits
|
||||
if @project.educoder?
|
||||
@hash_commit = nil
|
||||
else
|
||||
if params[:filepath].present?
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
@hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
||||
else
|
||||
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def commits_slice
|
||||
@hash_commit = Gitea::Repository::Commits::ListSliceService.call(@owner&.login, @project.identifier,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def commit
|
||||
@sha = params[:sha]
|
||||
if @project.educoder?
|
||||
@commit = {}
|
||||
@commit_diff ={}
|
||||
else
|
||||
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
|
||||
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
|
||||
end
|
||||
end
|
||||
|
||||
def tags
|
||||
result = Gitea::Repository::Tags::ListService.call(current_user&.gitea_token, @owner.login, @project.identifier, {page: params[:page], limit: params[:limit]})
|
||||
|
||||
@tags = result.is_a?(Hash) && result.key?(:status) ? [] : result
|
||||
end
|
||||
|
||||
def contributors
|
||||
if params[:filepath].present?
|
||||
@contributors = []
|
||||
else
|
||||
@contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
return render_forbidden if !@project.manager?(current_user) && !current_user.admin?
|
||||
end
|
||||
|
||||
def create_file
|
||||
interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params)
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
# create_new_pr(params)
|
||||
#如果是更新流水线文件
|
||||
if params[:pipeline_id]
|
||||
update_pipeline(params[:pipeline_id])
|
||||
end
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def update_pipeline(pipeline_id)
|
||||
pipeline = Ci::Pipeline.find(pipeline_id)
|
||||
if pipeline
|
||||
pipeline.update!(sync: 1)
|
||||
end
|
||||
end
|
||||
|
||||
def update_file
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
# TODO: 是否创建pr
|
||||
# create_new_pr(params)
|
||||
render_result(1, "更新成功")
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def delete_file
|
||||
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
render_result(1, "文件删除成功")
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def repo_hook
|
||||
|
||||
end
|
||||
|
||||
def sync_mirror
|
||||
return render_error("正在镜像中..") if @repository.mirror.waiting?
|
||||
|
||||
@repository.sync_mirror!
|
||||
SyncMirroredRepositoryJob.perform_later(@repository.id, current_user.id)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def readme
|
||||
if params[:filepath].present?
|
||||
result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], current_user&.gitea_token)
|
||||
else
|
||||
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
|
||||
end
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
|
||||
@readme = result[:status] === :success ? result[:body] : nil
|
||||
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path)
|
||||
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
|
||||
rescue
|
||||
render json: nil
|
||||
end
|
||||
|
||||
def languages
|
||||
render json: languages_precentagable
|
||||
end
|
||||
|
||||
def archive
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{params[:archive]}"
|
||||
|
||||
file_path = [domain, api_url, archive_url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
|
||||
|
||||
return render_not_found if !request.format.zip? && !request.format.gzip?
|
||||
|
||||
redirect_to file_path
|
||||
end
|
||||
|
||||
def raw
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
|
||||
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{params[:filepath]}?ref=#{params[:ref]}"
|
||||
file_path = [domain, api_url, url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&") if @repository.hidden?
|
||||
|
||||
redirect_to URI.escape(file_path)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_project
|
||||
@project = Project.find params[:id]
|
||||
render_not_found("未找到相关的仓库") unless @project
|
||||
end
|
||||
|
||||
def find_project_with_includes
|
||||
@project = Project.includes(:repository, :owner, :watchers, :praise_treads).find params[:id]
|
||||
end
|
||||
|
||||
def authorizate!
|
||||
return if current_user && current_user.admin?
|
||||
if @project.repository.hidden? && !@project.member?(current_user)
|
||||
render_forbidden
|
||||
end
|
||||
end
|
||||
|
||||
# TODO 获取最新commit信息
|
||||
def project_commits
|
||||
if params[:filepath].present?
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri,
|
||||
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
|
||||
else
|
||||
Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier,
|
||||
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
|
||||
end
|
||||
end
|
||||
|
||||
def get_statistics
|
||||
@branches_count = @project.educoder? ? 0 : Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size
|
||||
@tags_count = @project.educoder? ? 0 : Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier).call&.size
|
||||
end
|
||||
|
||||
def get_ref
|
||||
@ref = params[:ref] || @project&.default_branch
|
||||
end
|
||||
|
||||
def get_latest_commit
|
||||
latest_commit = @project.educoder? ? nil : project_commits
|
||||
@latest_commit = latest_commit.present? ? latest_commit[:body][0] : nil
|
||||
@commits_count = latest_commit.present? ? latest_commit[:total_count] : 0
|
||||
end
|
||||
|
||||
def content_params
|
||||
{
|
||||
filepath: params[:filepath],
|
||||
branch: params[:branch],
|
||||
new_branch: params[:new_branch],
|
||||
content: params[:content],
|
||||
message: params[:message],
|
||||
committer: {
|
||||
email: current_user.mail,
|
||||
name: current_user.login
|
||||
},
|
||||
identifier: @project.identifier
|
||||
}
|
||||
end
|
||||
|
||||
def hook_params(hook_type, params)
|
||||
# if hook_type == "push"
|
||||
# # TODO hook返回的记录中,暂时没有文件代码数量的增减,暂时根据 commits数量来计算
|
||||
# uploadPushInfo = {
|
||||
# "sha": params["commits"].present? ? params["commits"].last : "",
|
||||
# "branch": params["ref"].to_s.split("/").last,
|
||||
# "modification_lines": params["commits"].length
|
||||
# }
|
||||
# elsif hook_type == "pull_request" && params["action"].to_s == "closed" #合并请求合并后才会有上链操作
|
||||
# uploadPushInfo = {
|
||||
# "branch": params["base"]["ref"].to_s.split("/").last,
|
||||
# "sha": params["pull_request"]["merge_base"],
|
||||
# "modification_lines": 1 #pull_request中没有commits数量
|
||||
# }
|
||||
# else
|
||||
# uploadPushInfo = {}
|
||||
# end
|
||||
|
||||
# uploadPushInfo
|
||||
end
|
||||
|
||||
def create_new_pr(params)
|
||||
if params[:new_branch].present? && params[:new_branch] != params[:branch]
|
||||
local_params = {
|
||||
title: params[:message], #标题
|
||||
body: params[:content], #内容
|
||||
head: params[:new_branch], #源分支
|
||||
base: params[:branch], #目标分支
|
||||
milestone: 0 #里程碑,未与本地的里程碑关联
|
||||
|
||||
}
|
||||
requests_params = local_params.merge({
|
||||
assignee: current_user.try(:login),
|
||||
assignees: [],
|
||||
labels: [],
|
||||
due_date: Time.now
|
||||
})
|
||||
|
||||
issue_params = {
|
||||
author_id: current_user.id,
|
||||
project_id: @project.id,
|
||||
subject: params[:message],
|
||||
description: params[:content],
|
||||
assigned_to_id: nil,
|
||||
fixed_version_id: nil,
|
||||
issue_tags_value: nil,
|
||||
issue_classify: "pull_request",
|
||||
issue_type: "1",
|
||||
tracker_id: 2,
|
||||
status_id: 1,
|
||||
priority_id: params[:priority_id] || "2"
|
||||
}
|
||||
@pull_issue = Issue.new(issue_params)
|
||||
if @pull_issue.save!
|
||||
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
|
||||
if local_requests.save
|
||||
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
|
||||
if gitea_request[:status] == :success && local_requests.update_attributes(gitea_number: gitea_request["body"]["number"], gpid: gitea_request["body"]["number"])
|
||||
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
class RepositoriesController < ApplicationController
|
||||
include RepositoriesHelper
|
||||
include ApplicationHelper
|
||||
include OperateProjectAbilityAble
|
||||
include Repository::LanguagesPercentagable
|
||||
|
||||
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
|
||||
before_action :require_profile_completed, only: [:create_file]
|
||||
before_action :load_repository
|
||||
before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive]
|
||||
before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror]
|
||||
before_action :get_ref, only: %i[entries sub_entries top_counts file archive]
|
||||
before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
|
||||
before_action :get_statistics, only: %i[top_counts]
|
||||
|
||||
def files
|
||||
result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token)
|
||||
render json: result
|
||||
end
|
||||
|
||||
# 新版项目详情
|
||||
def detail
|
||||
@user = current_user
|
||||
@result = Repositories::DetailService.call(@owner, @repository, @user)
|
||||
@project_fork_id = @project.try(:forked_from_project_id)
|
||||
if @project_fork_id.present?
|
||||
@fork_project = Project.find_by(id: @project_fork_id)
|
||||
@fork_project_user = @fork_project.owner
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def show
|
||||
@user = current_user
|
||||
@repo = @project.repository
|
||||
@result = @project.forge? ? Gitea::Repository::GetService.new(@owner, @project.identifier).call : nil
|
||||
@project_fork_id = @project.try(:forked_from_project_id)
|
||||
if @project_fork_id.present?
|
||||
@fork_project = Project.find_by(id: @project_fork_id)
|
||||
@fork_project_user = @fork_project.owner
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def entries
|
||||
@project.increment!(:visits)
|
||||
CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id)
|
||||
if @project.educoder?
|
||||
@entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name)
|
||||
else
|
||||
@entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call
|
||||
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
||||
end
|
||||
end
|
||||
|
||||
def top_counts
|
||||
@result = @project.educoder? ? nil : Gitea::Repository::GetService.new(@project.owner, @project.identifier).call
|
||||
end
|
||||
|
||||
def sub_entries
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
|
||||
if @project.educoder?
|
||||
if params[:type] === 'file'
|
||||
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
|
||||
logger.info "######### sub_entries: #{@sub_entries}"
|
||||
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
|
||||
|
||||
tmp_entries = {
|
||||
"content" => @sub_entries['data']['content'],
|
||||
"type" => "blob"
|
||||
}
|
||||
@sub_entries = {
|
||||
"trees"=>tmp_entries,
|
||||
"commits" => [{}]
|
||||
}
|
||||
else
|
||||
begin
|
||||
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
|
||||
if @sub_entries.blank? || @sub_entries['status'].to_i === -1
|
||||
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
|
||||
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
|
||||
tmp_entries = {
|
||||
"content" => @sub_entries['data']['content'],
|
||||
"type" => "blob"
|
||||
}
|
||||
@sub_entries = {
|
||||
"trees"=>tmp_entries,
|
||||
"commits" => [{}]
|
||||
}
|
||||
end
|
||||
rescue
|
||||
return render_error('该文件暂未开放,敬请期待.')
|
||||
end
|
||||
end
|
||||
else
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
||||
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref)
|
||||
if interactor.success?
|
||||
result = interactor.result
|
||||
@sub_entries = result.is_a?(Array) ? result.sort_by{ |hash| hash['type'] } : result
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def commits
|
||||
if @project.educoder?
|
||||
@commits = Educoder::Repository::Commits::ListService.call(@project&.project_educoder&.repo_name)
|
||||
else
|
||||
if params[:filepath].present?
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
@hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
||||
else
|
||||
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def commits_slice
|
||||
@hash_commit = Gitea::Repository::Commits::ListSliceService.call(@owner.login, @project.identifier,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def commit
|
||||
@sha = params[:sha]
|
||||
if @project.educoder?
|
||||
return render_error('暂未开放,敬请期待.')
|
||||
else
|
||||
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
|
||||
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
|
||||
end
|
||||
end
|
||||
|
||||
def tags
|
||||
result = Gitea::Repository::Tags::ListService.call(current_user&.gitea_token, @owner.login, @project.identifier, {page: params[:page], limit: params[:limit]})
|
||||
|
||||
@tags = result.is_a?(Hash) && result.key?(:status) ? [] : result
|
||||
end
|
||||
|
||||
def contributors
|
||||
if params[:filepath].present? || @project.educoder?
|
||||
@contributors = []
|
||||
else
|
||||
@contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
return render_forbidden if !@project.manager?(current_user) && !current_user.admin?
|
||||
end
|
||||
|
||||
def create_file
|
||||
interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params)
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
# create_new_pr(params)
|
||||
#如果是更新流水线文件
|
||||
if params[:pipeline_id]
|
||||
update_pipeline(params[:pipeline_id])
|
||||
end
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def update_pipeline(pipeline_id)
|
||||
pipeline = Ci::Pipeline.find(pipeline_id)
|
||||
if pipeline
|
||||
pipeline.update!(sync: 1)
|
||||
end
|
||||
end
|
||||
|
||||
def update_file
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
# TODO: 是否创建pr
|
||||
# create_new_pr(params)
|
||||
render_result(1, "更新成功")
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def delete_file
|
||||
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
render_result(1, "文件删除成功")
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def repo_hook
|
||||
|
||||
end
|
||||
|
||||
def sync_mirror
|
||||
return render_error("正在镜像中..") if @repository.mirror.waiting?
|
||||
|
||||
@repository.sync_mirror!
|
||||
SyncMirroredRepositoryJob.perform_later(@repository.id, current_user.id)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def readme
|
||||
if params[:filepath].present?
|
||||
result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], current_user&.gitea_token)
|
||||
else
|
||||
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
|
||||
end
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
|
||||
@readme = result[:status] === :success ? result[:body] : nil
|
||||
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path)
|
||||
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
|
||||
rescue
|
||||
render json: nil
|
||||
end
|
||||
|
||||
def languages
|
||||
if @project.educoder?
|
||||
render json: {}
|
||||
else
|
||||
render json: languages_precentagable
|
||||
end
|
||||
end
|
||||
|
||||
def archive
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{CGI.escape(params[:archive])}"
|
||||
|
||||
file_path = [domain, api_url, archive_url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
|
||||
|
||||
return render_not_found if !request.format.zip? && !request.format.gzip?
|
||||
|
||||
redirect_to file_path
|
||||
end
|
||||
|
||||
def raw
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
|
||||
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{URI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}"
|
||||
file_path = [domain, api_url, url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&")
|
||||
|
||||
redirect_to file_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_project
|
||||
@project = Project.find params[:id]
|
||||
render_not_found("未找到相关的仓库") unless @project
|
||||
end
|
||||
|
||||
def find_project_with_includes
|
||||
@project = Project.includes(:repository, :owner, :watchers, :praise_treads).find params[:id]
|
||||
end
|
||||
|
||||
def authorizate!
|
||||
return if current_user && current_user.admin?
|
||||
if @project.repository.hidden? && !@project.member?(current_user)
|
||||
render_forbidden
|
||||
end
|
||||
end
|
||||
|
||||
# TODO 获取最新commit信息
|
||||
def project_commits
|
||||
if params[:filepath].present?
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri,
|
||||
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
|
||||
else
|
||||
Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier,
|
||||
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
|
||||
end
|
||||
end
|
||||
|
||||
def get_statistics
|
||||
@branches_count = @project.educoder? ? 0 : Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size
|
||||
@tags_count = @project.educoder? ? 0 : Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier).call&.size
|
||||
end
|
||||
|
||||
def get_ref
|
||||
@ref = params[:ref] || @project&.default_branch
|
||||
end
|
||||
|
||||
def get_latest_commit
|
||||
latest_commit = @project.educoder? ? nil : project_commits
|
||||
@latest_commit = latest_commit.present? ? latest_commit[:body][0] : nil
|
||||
@commits_count = latest_commit.present? ? latest_commit[:total_count] : 0
|
||||
end
|
||||
|
||||
def content_params
|
||||
{
|
||||
filepath: params[:filepath],
|
||||
branch: params[:branch],
|
||||
new_branch: params[:new_branch],
|
||||
content: params[:content],
|
||||
message: params[:message],
|
||||
committer: {
|
||||
email: current_user.mail,
|
||||
name: current_user.login
|
||||
},
|
||||
identifier: @project.identifier
|
||||
}
|
||||
end
|
||||
|
||||
def hook_params(hook_type, params)
|
||||
# if hook_type == "push"
|
||||
# # TODO hook返回的记录中,暂时没有文件代码数量的增减,暂时根据 commits数量来计算
|
||||
# uploadPushInfo = {
|
||||
# "sha": params["commits"].present? ? params["commits"].last : "",
|
||||
# "branch": params["ref"].to_s.split("/").last,
|
||||
# "modification_lines": params["commits"].length
|
||||
# }
|
||||
# elsif hook_type == "pull_request" && params["action"].to_s == "closed" #合并请求合并后才会有上链操作
|
||||
# uploadPushInfo = {
|
||||
# "branch": params["base"]["ref"].to_s.split("/").last,
|
||||
# "sha": params["pull_request"]["merge_base"],
|
||||
# "modification_lines": 1 #pull_request中没有commits数量
|
||||
# }
|
||||
# else
|
||||
# uploadPushInfo = {}
|
||||
# end
|
||||
|
||||
# uploadPushInfo
|
||||
end
|
||||
|
||||
def create_new_pr(params)
|
||||
if params[:new_branch].present? && params[:new_branch] != params[:branch]
|
||||
local_params = {
|
||||
title: params[:message], #标题
|
||||
body: params[:content], #内容
|
||||
head: params[:new_branch], #源分支
|
||||
base: params[:branch], #目标分支
|
||||
milestone: 0 #里程碑,未与本地的里程碑关联
|
||||
|
||||
}
|
||||
requests_params = local_params.merge({
|
||||
assignee: current_user.try(:login),
|
||||
assignees: [],
|
||||
labels: [],
|
||||
due_date: Time.now
|
||||
})
|
||||
|
||||
issue_params = {
|
||||
author_id: current_user.id,
|
||||
project_id: @project.id,
|
||||
subject: params[:message],
|
||||
description: params[:content],
|
||||
assigned_to_id: nil,
|
||||
fixed_version_id: nil,
|
||||
issue_tags_value: nil,
|
||||
issue_classify: "pull_request",
|
||||
issue_type: "1",
|
||||
tracker_id: 2,
|
||||
status_id: 1,
|
||||
priority_id: params[:priority_id] || "2"
|
||||
}
|
||||
@pull_issue = Issue.new(issue_params)
|
||||
if @pull_issue.save!
|
||||
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
|
||||
if local_requests.save
|
||||
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
|
||||
if gitea_request[:status] == :success && local_requests.update_attributes(gpid: gitea_request["body"]["number"])
|
||||
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,852 @@
|
|||
# Projects
|
||||
|
||||
## 申请加入项目
|
||||
申请加入项目
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/applied_projects.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/appliedr_projects.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/applied_projects.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|applied_project.code |是| |string |邀请码 |
|
||||
|applied_project.role |否| |string |项目权限,reporter: 报告者, developer: 开发者,manager:管理员 |
|
||||
|
||||
> 请求的JSON示例
|
||||
|
||||
```json
|
||||
{
|
||||
"applied_project": {
|
||||
"code": "1una34",
|
||||
"role": "developer"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |申请id |
|
||||
|status |string |申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝|
|
||||
|time_ago |string |项目申请创建的时间 |
|
||||
|project.id |int |申请项目的id |
|
||||
|project.identifier |string |申请项目的标识 |
|
||||
|project.name |string |申请项目的名称 |
|
||||
|project.description |string |申请项目的描述 |
|
||||
|project.is_public |bool |申请项目是否公开 |
|
||||
|project.owner.id |bool |申请项目拥有者id |
|
||||
|project.owner.type |string |申请项目拥有者类型 |
|
||||
|project.owner.name |string |申请项目拥有者昵称 |
|
||||
|project.owner.login |string |申请项目拥有者标识 |
|
||||
|project.owner.image_url |string |申请项目拥有者头像 |
|
||||
|user.id |int |申请创建者的id |
|
||||
|user.type |string |申请创建者的类型 |
|
||||
|user.name |string |申请创建者的名称 |
|
||||
|user.login |string |申请创建者的标识 |
|
||||
|user.image_url |string |申请创建者头像 |
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"project": {
|
||||
"id": 74,
|
||||
"identifier": "hehuisssjssjjsjs",
|
||||
"name": "hehuisssjssjjsjs",
|
||||
"description": "wwww",
|
||||
"is_public": false,
|
||||
"owner": {
|
||||
"id": 10,
|
||||
"type": "User",
|
||||
"name": "testforge1",
|
||||
"login": "testforge1",
|
||||
"image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"id": 6,
|
||||
"type": "User",
|
||||
"name": "何慧",
|
||||
"login": "yystopf",
|
||||
"image_url": "images/avatars/User/6?t=1622513134"
|
||||
},
|
||||
"id": 7,
|
||||
"status": "common",
|
||||
"created_at": "2021-06-09 16:41",
|
||||
"time_ago": "1分钟前"
|
||||
}
|
||||
```
|
||||
|
||||
## 获取项目列表
|
||||
获取项目列表,也可以更加相关条件过滤搜素
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
-d "page=1" \
|
||||
-d "limit=5" \
|
||||
http://localhost:3000/api/projects | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/projects')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET api/projects`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
page | false | 1 | string | 页数,第几页
|
||||
limit | false | 15 | string | 每页多少条数据,默认15条
|
||||
sort_by | false | | string | 排序类型, 取值:updated_on、created_on、forked_count、praises_count; updated_on: 更新时间排序,created_on: 创建时间排序,forked_count: fork数据排序,praises_count: 点赞数量排序,默认为updated_on更新时间排序
|
||||
sort_direction| false | | string | 排序方式,取值为: desc、asc; desc: 降序排序, asc: 升序排序, 默认为:desc
|
||||
search | false | | string | 按照项目名称搜索
|
||||
category_id | false | | int | 项目类别id
|
||||
language_id | false | | int | 项目语言id
|
||||
project_type | false | | string | 项目类型, 取值为:common、mirror; common:开源托管项目, mirror:开源镜像项目
|
||||
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
total_count | int | 项目总条数
|
||||
id | string | 项目id
|
||||
name | string | 项目名称
|
||||
description | string | 项目简介
|
||||
visits | int | 流量数
|
||||
forked_count | int | 被fork的数量
|
||||
praises_count | int | star数量
|
||||
is_public | boolean | 是否公开, true:公开,false:未公开
|
||||
mirror_url | string | 镜像url
|
||||
last_update_time| int | 最后更新时间,为UNIX格式的时间戳
|
||||
author | object | 项目创建者
|
||||
-- name | string | 用户名,也是用户标识
|
||||
category | object | 项目类别
|
||||
-- id | int | 项目类型id
|
||||
-- name | string | 项目类型名称
|
||||
language | object | 项目语言
|
||||
-- id | int | 项目语言id
|
||||
-- name | string | 项目语言名称
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"total_count": 3096,
|
||||
"projects": [
|
||||
{
|
||||
"id": 1400794,
|
||||
"repo_id": 1402452,
|
||||
"identifier": "cscw_2021_sponsor",
|
||||
"name": "Sponsor机制下的开源贡献",
|
||||
"description": "CSCW 2021 sponsor机制研究",
|
||||
"visits": 5,
|
||||
"praises_count": 0,
|
||||
"forked_count": 0,
|
||||
"is_public": true,
|
||||
"mirror_url": null,
|
||||
"type": 0,
|
||||
"last_update_time": 1611971671,
|
||||
"time_ago": "2天前",
|
||||
"forked_from_project_id": null,
|
||||
"open_devops": false,
|
||||
"platform": "forge",
|
||||
"author": {
|
||||
"name": "张迅晖",
|
||||
"login": "Nigel",
|
||||
"image_url": "images/avatars/User/3675?t=1611832880"
|
||||
},
|
||||
"category": {
|
||||
"id": 13,
|
||||
"name": "云计算和大数据"
|
||||
},
|
||||
"language": {
|
||||
"id": 34,
|
||||
"name": "Python3.6"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Remember — a happy kitten is an authenticated kitten!
|
||||
</aside>
|
||||
|
||||
|
||||
## 推荐项目
|
||||
获取推荐项目列表
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/projects/recommend | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/projects/recommend.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET api/projects/recommend`
|
||||
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
total_count |int |项目总条数
|
||||
id |string |项目id
|
||||
name |string|项目名称
|
||||
description |string|项目简介
|
||||
visits |int|流量数
|
||||
forked_count |int|被fork的数量
|
||||
praises_count |int|star数量
|
||||
is_public |boolean|是否公开, true:公开,false:未公开
|
||||
mirror_url |string|镜像url
|
||||
last_update_time|int|最后更新时间,为UNIX格式的时间戳
|
||||
author |object|项目创建者
|
||||
-- name |string|用户名,也是用户标识
|
||||
category |object|项目类别
|
||||
-- id |int|项目类型id
|
||||
-- name |string|项目类型名称
|
||||
language |object|项目语言
|
||||
-- id |int|项目语言id
|
||||
-- name |string|项目语言名称
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 20,
|
||||
"repo_id": 2,
|
||||
"identifier": "PNAekinmH",
|
||||
"name": "FNILL",
|
||||
"visits": 13567,
|
||||
"author": {
|
||||
"name": "王一达",
|
||||
"login": "wangyida",
|
||||
"image_url": "avatars/User/b"
|
||||
},
|
||||
"category": {
|
||||
"id": 8,
|
||||
"name": "其他"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
<aside class="success">
|
||||
Remember — a happy kitten is an authenticated kitten!
|
||||
</aside>
|
||||
|
||||
|
||||
## 项目导航
|
||||
获取项目导航信息
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/yystopf/ceshi/menu_list | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/yystopf/ceshi/menu_list')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET api/:owner/:repo/menu_list`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
owner |是| |string |用户登录名
|
||||
repo |是| |string |项目标识identifier
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
menu_name |string|导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"menu_name": "home"
|
||||
},
|
||||
{
|
||||
"menu_name": "code"
|
||||
},
|
||||
{
|
||||
"menu_name": "pulls"
|
||||
},
|
||||
{
|
||||
"menu_name": "activity"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
## 项目主页
|
||||
获取项目主页信息
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/jasder/forgeplus/about | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/jasder/forgeplus/about')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET api/:owner/:repo/about`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
owner |是| |string |用户登录名
|
||||
repo |是| |string |项目标识identifier
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
identifier |string|project's identifier
|
||||
content |string|主页内容
|
||||
attachments |array|附件
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"content": "",
|
||||
"identifier": "forgeplus",
|
||||
attachments: []
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Remember — a happy kitten is an authenticated kitten!
|
||||
</aside>
|
||||
|
||||
## 项目模块信息
|
||||
项目模块信息
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/yystopf/ceshi/project_units.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/yystopf/ceshi/project_units')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET /api/yystopf/ceshi/project_units`
|
||||
|
||||
### 返回字段说明:
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|type |string|模块名称 |
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"type": "code"
|
||||
},
|
||||
{
|
||||
"type": "pulls"
|
||||
},
|
||||
{
|
||||
"type": "issues"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 更改项目模块展示
|
||||
更改项目模块展示
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST \
|
||||
-H "accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{ \"unit_typs\": [\"code\", \"pulls\"]}" \
|
||||
http://localhost:3000/api/yystopf/ceshi/project_units.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/yystopf/ceshi/project_units')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/yystopf/ceshi/project_units`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|unit_types |是| |array | 项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑 |
|
||||
|
||||
|
||||
### 返回字段说明:
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|status |int|返回状态, 0: 表示操作成功 |
|
||||
|message |string|返回信息说明|
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
## 创建项目
|
||||
创建项目
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST \
|
||||
-d "user_id=36401" \
|
||||
-d "name=hnfl_demo" \
|
||||
-d "description=my first project" \
|
||||
-d "repository_name=hnfl_demo" \
|
||||
-d "project_category_id=1" \
|
||||
-d "project_language_id=2" \
|
||||
-d "ignore_id=2" \
|
||||
-d "license_id=1" \
|
||||
http://localhost:3000/api/projects.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/projects.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST api/projects`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|user_id |是| |int |用户id或者组织id |
|
||||
|name |是| |string |项目名称 |
|
||||
|description |是| |string |项目描述 |
|
||||
|repository_name |是| |string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
||||
|project_category_id|是| |int |项目类别id |
|
||||
|project_language_id|是| |int |项目语言id |
|
||||
|ignore_id |否| |int |gitignore相关id |
|
||||
|license_id |否| |int |开源许可证id |
|
||||
|private |否| |boolean|项目是否私有, true:为私有,false: 公开,默认为公开 |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |id |
|
||||
|name |string|项目名称|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3240,
|
||||
"name": "好项目"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 创建镜像项目
|
||||
创建镜像项目
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST \
|
||||
-d "user_id=36408" \
|
||||
-d "clone_addr=https://gitea.com/mx8090alex/golden.git" \
|
||||
-d "name=golden_mirror1" \
|
||||
-d "description=golden_mirror" \
|
||||
-d "project_category_id=1" \
|
||||
-d "project_language_id=2" \
|
||||
http://localhost:3000/api/projects/migrate.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/projects/migrate.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST api/projects/migrate.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|user_id |是| |int |用户id或者组织id |
|
||||
|name |是| |string |项目名称 |
|
||||
|clone_addr |是| |string |镜像项目clone地址 |
|
||||
|description |否| |string |项目描述 |
|
||||
|repository_name |是| |string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
||||
|project_category_id|是| |int |项目类别id |
|
||||
|project_language_id|是| |int |项目语言id |
|
||||
|is_mirror |否| |boolean|是否设置为镜像, true:是, false:否,默认为否 |
|
||||
|auth_username |否| |string|镜像源仓库的登录用户名 |
|
||||
|auth_password |否| |string|镜像源仓库的登录秘密 |
|
||||
|private |否| |boolean|项目是否私有, true:为私有,false: 非私有,默认为公开 |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |id |
|
||||
|name |string|项目名称|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3241,
|
||||
"name": "这是一个镜像项目"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 同步镜像
|
||||
手动同步镜像
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/repositories/1244/sync_mirror.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/repositories/1244/sync_mirror.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST api/repositories/:id/sync_mirror.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|id |是| |int |仓库id |
|
||||
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|status |int |状态码, 0:标识请求成功 |
|
||||
|message |string|服务端返回的信息说明|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Fork项目
|
||||
fork项目
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/jasder/forgeplus/forks.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/jaser/jasder_test/forks.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST api/:owner/:repo/forks.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| |string |用户登录名 |
|
||||
|repo |是| |string |项目标识identifier |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |项目id |
|
||||
|identifier |string|项目标识|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3290,
|
||||
"identifier": "newadm"
|
||||
}
|
||||
```
|
||||
|
||||
## 用户管理的组织列表
|
||||
用户管理的组织列表
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizations.json | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/:owner/:repo/applied_transfer_projects/organizations')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET api/:owner/:repo/applied_transfer_projects/organizations`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
owner |是| |string |用户登录名
|
||||
repo |是| |string |项目标识identifier
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
name |string|组织标识
|
||||
nickname |string|组织名称
|
||||
description|string|组织描述
|
||||
avatar_url|string|组织头像
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"total_count": 3,
|
||||
"organizations": [
|
||||
{
|
||||
"id": 9,
|
||||
"name": "ceshi_org",
|
||||
"nickname": "测试组织",
|
||||
"description": "测试组织",
|
||||
"avatar_url": "images/avatars/Organization/9?t=1612706073"
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"name": "ceshi",
|
||||
"nickname": "测试组织哈哈哈",
|
||||
"description": "23212312",
|
||||
"avatar_url": "images/avatars/Organization/51?t=1618800723"
|
||||
},
|
||||
{
|
||||
"id": 52,
|
||||
"name": "ceshi1",
|
||||
"nickname": "身份卡手动阀",
|
||||
"description": "1231手动阀是的",
|
||||
"avatar_url": "images/avatars/Organization/52?t=1618805056"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 迁移项目
|
||||
迁移项目,edit接口is_transfering为true表示正在迁移
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/:owner/:repo/applied_transfer_projects.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/:owner/:repo/applied_transfer_projects.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| |string |用户登录名 |
|
||||
|repo |是| |string |项目标识identifier |
|
||||
|owner_name|是| |string |迁移对象标识 |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |项目id |
|
||||
|status |string |项目迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
|
||||
|time_ago |string |项目迁移创建的时间 |
|
||||
|project.id |int |迁移项目的id |
|
||||
|project.identifier |string |迁移项目的标识 |
|
||||
|project.name |string |迁移项目的名称 |
|
||||
|project.description |string |迁移项目的描述 |
|
||||
|project.is_public |bool |迁移项目是否公开 |
|
||||
|project.owner.id |bool |迁移项目拥有者id |
|
||||
|project.owner.type |string |迁移项目拥有者类型 |
|
||||
|project.owner.name |string |迁移项目拥有者昵称 |
|
||||
|project.owner.login |string |迁移项目拥有者标识 |
|
||||
|project.owner.image_url |string |迁移项目拥有者头像 |
|
||||
|user.id |int |迁移创建者的id |
|
||||
|user.type |string |迁移创建者的类型 |
|
||||
|user.name |string |迁移创建者的名称 |
|
||||
|user.login |string |迁移创建者的标识 |
|
||||
|user.image_url |string |迁移创建者头像 |
|
||||
|owner.id |int |迁移接受者的id |
|
||||
|owner.type |string |迁移接受者的类型 |
|
||||
|owner.name |string |迁移接受者的名称 |
|
||||
|owner.login |string |迁移接受者的标识 |
|
||||
|owner.image_url |string |迁移接受者头像 |
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"project": {
|
||||
"id": 86,
|
||||
"identifier": "ceshi_repo1",
|
||||
"name": "测试项目啊1",
|
||||
"description": "二十多",
|
||||
"is_public": true,
|
||||
"owner": {
|
||||
"id": 52,
|
||||
"type": "Organization",
|
||||
"name": "身份卡手动阀",
|
||||
"login": "ceshi1",
|
||||
"image_url": "images/avatars/Organization/52?t=1618805056"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"id": 6,
|
||||
"type": "User",
|
||||
"name": "yystopf",
|
||||
"login": "yystopf",
|
||||
"image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
|
||||
},
|
||||
"owner": {
|
||||
"id": 9,
|
||||
"type": "Organization",
|
||||
"name": "测试组织",
|
||||
"login": "ceshi_org",
|
||||
"image_url": "images/avatars/Organization/9?t=1612706073"
|
||||
},
|
||||
"id": 4,
|
||||
"status": "common",
|
||||
"created_at": "2021-04-26 09:54",
|
||||
"time_ago": "1分钟前"
|
||||
}
|
||||
```
|
||||
|
||||
## 取消迁移项目
|
||||
迁移项目,edit接口is_transfering为true表示正在迁移
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/cancel.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/:owner/:repo/applied_transfer_projects/cancel.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/:owner/:repo/applied_transfer_projects/cancel.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| |string |用户登录名 |
|
||||
|repo |是| |string |项目标识identifier |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |迁移id |
|
||||
|status |string |迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
|
||||
|time_ago |string |迁移创建的时间 |
|
||||
|project.id |int |迁移项目的id |
|
||||
|project.identifier |string |迁移项目的标识 |
|
||||
|project.name |string |迁移项目的名称 |
|
||||
|project.description |string |迁移项目的描述 |
|
||||
|project.is_public |bool |迁移项目是否公开 |
|
||||
|project.owner.id |bool |迁移项目拥有者id |
|
||||
|project.owner.type |string |迁移项目拥有者类型 |
|
||||
|project.owner.name |string |迁移项目拥有者昵称 |
|
||||
|project.owner.login |string |迁移项目拥有者标识 |
|
||||
|project.owner.image_url |string |迁移项目拥有者头像 |
|
||||
|user.id |int |迁移创建者的id |
|
||||
|user.type |string |迁移创建者的类型 |
|
||||
|user.name |string |迁移创建者的名称 |
|
||||
|user.login |string |迁移创建者的标识 |
|
||||
|user.image_url |string |迁移创建者头像 |
|
||||
|owner.id |int |迁移接受者的id |
|
||||
|owner.type |string |迁移接受者的类型 |
|
||||
|owner.name |string |迁移接受者的名称 |
|
||||
|owner.login |string |迁移接受者的标识 |
|
||||
|owner.image_url |string |迁移接受者头像 |
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"project": {
|
||||
"id": 86,
|
||||
"identifier": "ceshi_repo1",
|
||||
"name": "测试项目啊1",
|
||||
"description": "二十多",
|
||||
"is_public": true,
|
||||
"owner": {
|
||||
"id": 52,
|
||||
"type": "Organization",
|
||||
"name": "身份卡手动阀",
|
||||
"login": "ceshi1",
|
||||
"image_url": "images/avatars/Organization/52?t=1618805056"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"id": 6,
|
||||
"type": "User",
|
||||
"name": "yystopf",
|
||||
"login": "yystopf",
|
||||
"image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
|
||||
},
|
||||
"owner": {
|
||||
"id": 9,
|
||||
"type": "Organization",
|
||||
"name": "测试组织",
|
||||
"login": "ceshi_org",
|
||||
"image_url": "images/avatars/Organization/9?t=1612706073"
|
||||
},
|
||||
"id": 4,
|
||||
"status": "common",
|
||||
"created_at": "2021-04-26 09:54",
|
||||
"time_ago": "1分钟前"
|
||||
}
|
||||
```
|
||||
|
|
@ -1240,11 +1240,11 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json')
|
|||
|delete|分支或标签删除|
|
||||
|fork|仓库被fork|
|
||||
|push|git仓库推送|
|
||||
|issue|易修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|易修被指派|
|
||||
|issue_label|易修标签被更新或删除|
|
||||
|issue_milestone|易修被收入里程碑|
|
||||
|issue_comment|易修评论|
|
||||
|issue|疑修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|疑修被指派|
|
||||
|issue_label|疑修标签被更新或删除|
|
||||
|issue_milestone|疑修被收入里程碑|
|
||||
|issue_comment|疑修评论|
|
||||
|pull_request|合并请求|
|
||||
|pull_request_assign|合并请求被指派|
|
||||
|pull_request_label|合并请求被贴上标签|
|
||||
|
|
@ -1337,11 +1337,11 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json')
|
|||
|delete|分支或标签删除|
|
||||
|fork|仓库被fork|
|
||||
|push|git仓库推送|
|
||||
|issue|易修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|易修被指派|
|
||||
|issue_label|易修标签被更新或删除|
|
||||
|issue_milestone|易修被收入里程碑|
|
||||
|issue_comment|易修评论|
|
||||
|issue|疑修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|疑修被指派|
|
||||
|issue_label|疑修标签被更新或删除|
|
||||
|issue_milestone|疑修被收入里程碑|
|
||||
|issue_comment|疑修评论|
|
||||
|pull_request|合并请求|
|
||||
|pull_request_assign|合并请求被指派|
|
||||
|pull_request_label|合并请求被贴上标签|
|
||||
|
|
@ -1440,11 +1440,11 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json')
|
|||
|delete|分支或标签删除|
|
||||
|fork|仓库被fork|
|
||||
|push|git仓库推送|
|
||||
|issue|易修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|易修被指派|
|
||||
|issue_label|易修标签被更新或删除|
|
||||
|issue_milestone|易修被收入里程碑|
|
||||
|issue_comment|易修评论|
|
||||
|issue|疑修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|疑修被指派|
|
||||
|issue_label|疑修标签被更新或删除|
|
||||
|issue_milestone|疑修被收入里程碑|
|
||||
|issue_comment|疑修评论|
|
||||
|pull_request|合并请求|
|
||||
|pull_request_assign|合并请求被指派|
|
||||
|pull_request_label|合并请求被贴上标签|
|
||||
|
|
|
|||
|
|
@ -90,13 +90,13 @@ await octokit.request('GET /api/users/:login/messages.json')
|
|||
#### 消息来源source字段说明
|
||||
类型|说明
|
||||
--------- | -----------
|
||||
|IssueAssigned | 有新指派给我的易修 |
|
||||
|IssueAssignerExpire | 我负责的易修截止日期到达最后一天 |
|
||||
|IssueAtme | 在易修中@我 |
|
||||
|IssueChanged | 我创建或负责的易修状态变更 |
|
||||
|IssueCreatorExpire | 我创建的易修截止日期到达最后一天 |
|
||||
|IssueDeleted | 我创建或负责的易修删除 |
|
||||
|IssueJournal | 我创建或负责的易修有新的评论 |
|
||||
|IssueAssigned | 有新指派给我的疑修 |
|
||||
|IssueAssignerExpire | 我负责的疑修截止日期到达最后一天 |
|
||||
|IssueAtme | 在疑修中@我 |
|
||||
|IssueChanged | 我创建或负责的疑修状态变更 |
|
||||
|IssueCreatorExpire | 我创建的疑修截止日期到达最后一天 |
|
||||
|IssueDeleted | 我创建或负责的疑修删除 |
|
||||
|IssueJournal | 我创建或负责的疑修有新的评论 |
|
||||
|LoginIpTip | 登录异常提示 |
|
||||
|OrganizationJoined | 账号被拉入组织 |
|
||||
|OrganizationLeft | 账号被移出组织 |
|
||||
|
|
@ -104,7 +104,7 @@ await octokit.request('GET /api/users/:login/messages.json')
|
|||
|ProjectDeleted | 我关注的仓库被删除 |
|
||||
|ProjectFollowed | 我管理的仓库被关注 |
|
||||
|ProjectForked | 我管理的仓库被复刻 |
|
||||
|ProjectIssue | 我管理/关注的仓库有新的易修 |
|
||||
|ProjectIssue | 我管理/关注的仓库有新的疑修 |
|
||||
|ProjectJoined | 账号被拉入项目 |
|
||||
|ProjectLeft | 账号被移出项目 |
|
||||
|ProjectMemberJoined | 我管理的仓库有成员加入 |
|
||||
|
|
@ -250,7 +250,7 @@ await octokit.request('POST /api/users/:login/messages.json')
|
|||
--------- | ----------- | -----------
|
||||
|type | string | 消息类型 |
|
||||
|receivers_login | array | 需要发送消息的用户名数组|
|
||||
|atmeable_type | string | atme消息对象,是从哪里@我的,比如评论:Journal、易修:Issue、合并请求:PullRequest |
|
||||
|atmeable_type | string | atme消息对象,是从哪里@我的,比如评论:Journal、疑修:Issue、合并请求:PullRequest |
|
||||
|atmeable_id | integer | atme消息对象id |
|
||||
|
||||
> 请求的JSON示例:
|
||||
|
|
@ -469,7 +469,7 @@ await octokit.request('GET /api/template_message_settings.json')
|
|||
"total_settings_count": 4,
|
||||
"settings": [
|
||||
{
|
||||
"name": "易修被指派",
|
||||
"name": "疑修被指派",
|
||||
"key": "IssueAssigned",
|
||||
"notification_disabled": true,
|
||||
"email_disabled": false
|
||||
|
|
@ -488,7 +488,7 @@ await octokit.request('GET /api/template_message_settings.json')
|
|||
"total_settings_count": 4,
|
||||
"settings": [
|
||||
{
|
||||
"name": "有新的易修",
|
||||
"name": "有新的疑修",
|
||||
"key": "Issue",
|
||||
"notification_disabled": true,
|
||||
"email_disabled": false
|
||||
|
|
@ -875,7 +875,7 @@ await octokit.request('GET /api/users/:login/statistics/activity.json')
|
|||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|dates |array |时间 |
|
||||
|issues_count |array |易修数量|
|
||||
|issues_count |array |疑修数量|
|
||||
|pull_requests_count |array |合并请求数量|
|
||||
|commtis_count |array |贡献数量|
|
||||
|
||||
|
|
@ -1084,7 +1084,7 @@ await octokit.request('GET /api/users/:login/project_trends.json')
|
|||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|total_count |int |所选时间内的总动态数 |
|
||||
|project_trends.trend_type |string|动态类型,Issue:易修,VersionRelease:版本发布,PullRequest:合并请求|
|
||||
|project_trends.trend_type |string|动态类型,Issue:疑修,VersionRelease:版本发布,PullRequest:合并请求|
|
||||
|project_trends.action_type |string|操作类型|
|
||||
|project_trends.trend_id |integer|动态id|
|
||||
|project_trends.user_name |string|用户名称|
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
class Organizations::CreateForm < BaseForm
|
||||
NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||
attr_accessor :name, :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, :nickname
|
||||
attr_accessor :name, :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, :nickname, :original_name
|
||||
|
||||
validates :name, :nickname, :visibility, presence: true
|
||||
validates :name, :nickname, length: { maximum: 100 }
|
||||
|
|
@ -9,7 +9,7 @@ class Organizations::CreateForm < BaseForm
|
|||
validates :name, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
||||
|
||||
validate do
|
||||
check_name(name) unless name.blank?
|
||||
check_name(name) unless name.blank? || name == original_name
|
||||
end
|
||||
|
||||
def check_name(name)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
module Register
|
||||
class RemoteForm < Register::BaseForm
|
||||
# login 登陆方式,支持邮箱、登陆、手机号等
|
||||
attr_accessor :username, :email, :password, :platform
|
||||
|
||||
validates :username, :email, :password, presence: true
|
||||
validate :check!
|
||||
|
||||
def check!
|
||||
Rails.logger.info "Register::RemoteForm params: username: #{username}; email: #{email}; password: #{password}; platform: #{platform}"
|
||||
check_login(username)
|
||||
check_mail(email)
|
||||
check_password(password)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,5 +4,5 @@ class Users::LoginForm
|
|||
attr_accessor :password, :login
|
||||
|
||||
validates :login, presence: true
|
||||
validates :password, presence: true, length: { minimum: 8, maximum: 16 }, format: { with: CustomRegexp::PASSWORD, message: "8~16位,支持字母数字和符号" }
|
||||
validates :password, presence: true, length: { minimum: 6, maximum: 16 }, format: { with: CustomRegexp::LOGIN_PASSWORD, message: "6~16位,支持字母数字和符号" }
|
||||
end
|
||||
|
|
@ -45,7 +45,7 @@ module RepositoriesHelper
|
|||
end
|
||||
end
|
||||
|
||||
def readme_render_decode64_content(str, path)
|
||||
def readme_render_decode64_content(str, owner, repo, ref)
|
||||
return nil if str.blank?
|
||||
begin
|
||||
content = Base64.decode64(str).force_encoding('UTF-8')
|
||||
|
|
@ -63,13 +63,16 @@ module RepositoriesHelper
|
|||
if remove_title.length > 0
|
||||
r_content = r_content.gsub(/#{remove_title[0]}/, "").strip
|
||||
end
|
||||
if r_content.include?("?")
|
||||
new_r_content = r_content + "&raw=true"
|
||||
else
|
||||
new_r_content = r_content + "?raw=true"
|
||||
end
|
||||
# if r_content.include?("?")
|
||||
# new_r_content = r_content + "&raw=true"
|
||||
# else
|
||||
# new_r_content = r_content + "?raw=true"
|
||||
# end
|
||||
new_r_content = r_content
|
||||
|
||||
unless r_content.include?("http://") || r_content.include?("https://") || r_content.include?("mailto:")
|
||||
new_r_content = "#{path}" + new_r_content
|
||||
# new_r_content = "#{path}" + new_r_content
|
||||
new_r_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{r_content}&ref=#{ref}"].join
|
||||
end
|
||||
content = content.gsub(/#{r_content}/, new_r_content)
|
||||
end
|
||||
|
|
@ -94,7 +97,7 @@ module RepositoriesHelper
|
|||
def decode64_content(entry, owner, repo, ref, path=nil)
|
||||
if is_readme?(entry['type'], entry['name'])
|
||||
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
|
||||
readme_render_decode64_content(content, path)
|
||||
readme_render_decode64_content(content, owner, repo, ref)
|
||||
else
|
||||
file_type = File.extname(entry['name'].to_s)[1..-1]
|
||||
if image_type?(file_type)
|
||||
|
|
|
|||
|
|
@ -26,8 +26,12 @@ module TagChosenHelper
|
|||
end
|
||||
|
||||
def render_branches(project)
|
||||
branches = Gitea::Repository::Branches::ListService.call(project&.owner, project.identifier)
|
||||
branches.collect{|i| i["name"] if i.is_a?(Hash)}
|
||||
if project.educoder?
|
||||
return ['master']
|
||||
else
|
||||
branches = Gitea::Repository::Branches::ListService.call(project&.owner, project.identifier)
|
||||
branches.collect{|i| i["name"] if i.is_a?(Hash)}
|
||||
end
|
||||
end
|
||||
|
||||
def render_cache_trackers
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
issue = Issue.find_by_id(issue_id)
|
||||
return unless operator.present? && issue.present?
|
||||
# receivers = receivers.where.not(id: operator&.id)
|
||||
receivers = User.where(id: receivers)
|
||||
receivers_string, content, notification_url = MessageTemplate::IssueAtme.get_message_content(receivers, operator, issue)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_id: issue.id}, 2, operator_id)
|
||||
when 'IssueChanged'
|
||||
|
|
@ -93,18 +94,6 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
receivers_email_string, email_title, email_content = MessageTemplate::OrganizationLeft.get_email_message_content(receiver, organization)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'OrganizationRole'
|
||||
user_id, organization_id, role = args[0], args[1], args[2]
|
||||
user = User.find_by_id(user_id)
|
||||
organization = Organization.find_by_id(organization_id)
|
||||
return unless user.present? && organization.present?
|
||||
receivers = User.where(id: user.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::OrganizationRole.get_message_content(receivers, organization, role)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user.id, organization_id: organization.id, role: role})
|
||||
receivers.find_each do |receiver|
|
||||
receivers_email_string, email_title, email_content = MessageTemplate::OrganizationRole.get_email_message_content(receiver, organization, role)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'ProjectIssue'
|
||||
operator_id, issue_id = args[0], args[1]
|
||||
operator = User.find_by_id(operator_id)
|
||||
|
|
@ -235,6 +224,7 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
pull_request = PullRequest.find_by_id(pull_request_id)
|
||||
return unless operator.present? && pull_request.present?
|
||||
# receivers = receivers.where.not(id: operator&.id)
|
||||
receivers = User.where(id: receivers)
|
||||
receivers_string, content, notification_url = MessageTemplate::PullRequestAtme.get_message_content(receivers, operator, pull_request)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, pull_request_id: pull_request.id}, 2, operator_id)
|
||||
when 'PullRequestChanged'
|
||||
|
|
@ -274,6 +264,32 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
receivers_email_string, email_title, email_content = MessageTemplate::PullRequestMerged.get_email_message_content(receiver, operator, pull_request)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'TeamJoined'
|
||||
user_id, organization_id, team_id = args[0], args[1], args[2]
|
||||
user = User.find_by_id(user_id)
|
||||
organization = Organization.find_by_id(organization_id)
|
||||
team = Team.find_by_id(team_id)
|
||||
return unless user.present? && organization.present? && team.present?
|
||||
receivers = User.where(id: user.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::TeamJoined.get_message_content(receivers, organization, team)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user.id, organization_id: organization.id, team_id: team.id})
|
||||
receivers.find_each do |receiver|
|
||||
receivers_email_string, email_title, email_content = MessageTemplate::TeamJoined.get_email_message_content(receiver, organization, team)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'TeamLeft'
|
||||
user_id, organization_id, team_id = args[0], args[1], args[2]
|
||||
user = User.find_by_id(user_id)
|
||||
organization = Organization.find_by_id(organization_id)
|
||||
team = Team.find_by_id(team_id)
|
||||
return unless user.present? && organization.present? && team.present?
|
||||
receivers = User.where(id: user.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::TeamLeft.get_message_content(receivers, organization, team)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user.id, organization_id: organization.id, team_id: team.id})
|
||||
receivers.find_each do |receiver|
|
||||
receivers_email_string, email_title, email_content = MessageTemplate::TeamLeft.get_email_message_content(receiver, organization, team)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -5,6 +5,7 @@ module CustomRegexp
|
|||
LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/
|
||||
NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/
|
||||
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
|
||||
LOGIN_PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{6,16}\z/
|
||||
URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/
|
||||
IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: claims
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# issue_id :integer
|
||||
# user_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# note :text(65535)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_claims_on_issue_id (issue_id)
|
||||
# index_claims_on_user_id (user_id)
|
||||
#
|
||||
|
||||
class Claim < ApplicationRecord
|
||||
belongs_to :user, foreign_key: :user_id
|
||||
scope :claim_includes, ->{includes(:user)}
|
||||
end
|
||||
|
|
@ -21,13 +21,37 @@ module ProjectOperable
|
|||
end
|
||||
|
||||
def add_member!(user_id, role_name='Developer')
|
||||
member = members.create!(user_id: user_id)
|
||||
if self.owner.is_a?(Organization)
|
||||
case role_name
|
||||
when 'Manager'
|
||||
team = self.owner.teams.admin.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = TeamUser.build(self.user_id, user_id, team.id)
|
||||
when 'Developer'
|
||||
team = self.owner.teams.write.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = TeamUser.build(self.user_id, user_id, team.id)
|
||||
when 'Reporter'
|
||||
team = self.owner.teams.read.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = TeamUser.build(self.user_id, user_id, team.id)
|
||||
end
|
||||
end
|
||||
member = members.create!(user_id: user_id, team_user_id: team_user&.id)
|
||||
set_developer_role(member, role_name)
|
||||
end
|
||||
|
||||
def remove_member!(user_id)
|
||||
member = members.find_by(user_id: user_id)
|
||||
member.destroy! if member && self.user_id != user_id
|
||||
team_user = TeamUser.find_by_id(member&.team_user_id)
|
||||
team_user.destroy! if team_user
|
||||
end
|
||||
|
||||
def member?(user_id)
|
||||
|
|
@ -47,6 +71,28 @@ module ProjectOperable
|
|||
|
||||
def change_member_role!(user_id, role)
|
||||
member = self.member(user_id)
|
||||
if self.owner.is_a?(Organization) && member.team_user.present?
|
||||
case role&.name
|
||||
when 'Manager'
|
||||
team = self.owner.teams.admin.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = member.team_user.update(team_id: team&.id)
|
||||
when 'Developer'
|
||||
team = self.owner.teams.write.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = member.team_user.update(team_id: team&.id)
|
||||
when 'Reporter'
|
||||
team = self.owner.teams.read.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = member.team_user.update(team_id: team&.id)
|
||||
end
|
||||
end
|
||||
member.member_roles.last.update_attributes!(role: role)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ class Issue < ApplicationRecord
|
|||
# has_many :memos
|
||||
has_many :journals, :as => :journalized, :dependent => :destroy
|
||||
has_many :journal_details, through: :journals
|
||||
has_many :claims, :dependent => :destroy
|
||||
has_many :issue_tags_relates, dependent: :destroy
|
||||
has_many :issue_tags, through: :issue_tags_relates
|
||||
has_many :issue_times, dependent: :destroy
|
||||
|
|
@ -154,7 +155,7 @@ class Issue < ApplicationRecord
|
|||
end
|
||||
|
||||
def is_collaborators?
|
||||
self.assigned_to_id.present? ? self.project.members.where(user_id: self.assigned_to_id).present? : false
|
||||
self.assigned_to_id.present? ? self.project.member?(self.assigned_to_id) : false
|
||||
end
|
||||
|
||||
def get_issue_tags_name
|
||||
|
|
|
|||
|
|
@ -11,23 +11,26 @@
|
|||
# course_group_id :integer default("0")
|
||||
# is_collect :integer default("1")
|
||||
# graduation_group_id :integer default("0")
|
||||
# team_user_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_members_on_course_id (course_id)
|
||||
# index_members_on_project_id (project_id)
|
||||
# index_members_on_team_user_id (team_user_id)
|
||||
# index_members_on_user_id (user_id)
|
||||
# index_members_on_user_id_and_project_id (user_id,project_id,course_id) UNIQUE
|
||||
#
|
||||
|
||||
class Member < ApplicationRecord
|
||||
belongs_to :user
|
||||
# belongs_to :course, optional: true
|
||||
belongs_to :project, optional: true
|
||||
|
||||
has_many :member_roles, dependent: :destroy
|
||||
has_many :roles, through: :member_roles
|
||||
|
||||
validates :user_id, :project_id, presence: true
|
||||
|
||||
end
|
||||
class Member < ApplicationRecord
|
||||
belongs_to :user
|
||||
# belongs_to :course, optional: true
|
||||
belongs_to :project, optional: true
|
||||
belongs_to :team_user, optional: true
|
||||
|
||||
has_many :member_roles, dependent: :destroy
|
||||
has_many :roles, through: :member_roles
|
||||
|
||||
validates :user_id, :project_id, presence: true
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,27 +17,25 @@ class MessageTemplate < ApplicationRecord
|
|||
def self.build_init_data
|
||||
self.create(type: 'MessageTemplate::FollowedTip', sys_notice: '<b>{nickname}</b> 关注了你', notification_url: '{baseurl}/{login}')
|
||||
email_html = File.read("#{email_template_html_dir}/issue_assigned.html")
|
||||
self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个易修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个易修')
|
||||
self.create(type: 'MessageTemplate::IssueAssignerExpire', sys_notice: '您负责的易修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueAtme', sys_notice: '<b>{nickname}</b> 在易修 <b>{title}</b> 中@我', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个疑修')
|
||||
self.create(type: 'MessageTemplate::IssueAssignerExpire', sys_notice: '您负责的疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueAtme', sys_notice: '<b>{nickname}</b> 在疑修 <b>{title}</b> 中@我', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/issue_changed.html")
|
||||
self.create(type: 'MessageTemplate::IssueChanged', sys_notice: '在项目 <b>{nickname2}/{repository}</b> 的易修 <b>{title}</b> 中:{ifassigner}{nickname1}将负责人从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifstatus}{nickname1}将状态从 <b>{status1}</b> 修改为 <b>{status2}</b> {endstatus}{iftracker}{nickname1}将类型从 <b>{tracker1}</b> 修改为 <b>{tracker2}</b> {endtracker}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifdoneratio}{nickname1}将完成度从 <b>{doneratio1}</b> 修改为 <b>{doneratio2}</b> {enddoneratio}{ifbranch}{nickname1}将指定分支从 <b>{branch1}</b> 修改为 <b>{branch2}</b> {endbranch}{ifstartdate}{nickname1}将开始日期从 <b>{startdate1}</b> 修改为 <b>{startdate2}</b> {endstartdate}{ifduedate}{nickname1}将结束日期从 <b>{duedate1}</b> 修改为 <b>{duedate2}</b> {endduedate}', email: email_html, email_title: 'GitLink: 易修 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueCreatorExpire', sys_notice: '您发布的易修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueChanged', sys_notice: '在项目 <b>{nickname2}/{repository}</b> 的疑修 <b>{title}</b> 中:{ifassigner}{nickname1}将负责人从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifstatus}{nickname1}将状态从 <b>{status1}</b> 修改为 <b>{status2}</b> {endstatus}{iftracker}{nickname1}将类型从 <b>{tracker1}</b> 修改为 <b>{tracker2}</b> {endtracker}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifdoneratio}{nickname1}将完成度从 <b>{doneratio1}</b> 修改为 <b>{doneratio2}</b> {enddoneratio}{ifbranch}{nickname1}将指定分支从 <b>{branch1}</b> 修改为 <b>{branch2}</b> {endbranch}{ifstartdate}{nickname1}将开始日期从 <b>{startdate1}</b> 修改为 <b>{startdate2}</b> {endstartdate}{ifduedate}{nickname1}将结束日期从 <b>{duedate1}</b> 修改为 <b>{duedate2}</b> {endduedate}', email: email_html, email_title: 'GitLink: 疑修 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueCreatorExpire', sys_notice: '您发布的疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/issue_deleted.html")
|
||||
self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将易修 <b>{title}</b> 删除', email: email_html, email_title: 'GitLink: 易修 {title} 有状态变更', notification_url: '')
|
||||
self.create(type: 'MessageTemplate::IssueJournal', sys_notice: '{nickname}评论易修{title}:<b>{notes}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将疑修 <b>{title}</b> 删除', email: email_html, email_title: 'GitLink: 疑修 {title} 有状态变更', notification_url: '')
|
||||
self.create(type: 'MessageTemplate::IssueJournal', sys_notice: '{nickname}评论疑修{title}:<b>{notes}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::LoginIpTip', sys_notice: '您的账号{nickname}于{login_time)在非常用的IP地址{ip}登录,如非本人操作,请立即修改密码', notification_url: '')
|
||||
email_html = File.read("#{email_template_html_dir}/organization_joined.html")
|
||||
self.create(type: 'MessageTemplate::OrganizationJoined', sys_notice: '你已加入 <b>{organization}</b> 组织', notification_url: '{baseurl}/{login}', email: email_html, email_title: 'GitLink: 你已加入 {organization} 组织')
|
||||
email_html = File.read("#{email_template_html_dir}/organization_left.html")
|
||||
self.create(type: 'MessageTemplate::OrganizationLeft', sys_notice: '你已被移出 <b>{organization}</b> 组织', notification_url: '', email: email_html, email_title: 'GitLink: 你已被移出 {organization} 组织')
|
||||
email_html = File.read("#{email_template_html_dir}/organization_role.html")
|
||||
self.create(type: 'MessageTemplate::OrganizationRole', sys_notice: '组织 <b>{organization}</b> 已把你的角色改为 <b>{role}</b>', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
|
||||
self.create(type: 'MessageTemplate::ProjectDeleted', sys_notice: '你关注的仓库{nickname}/{repository}已被删除', notification_url: '')
|
||||
self.create(type: 'MessageTemplate::ProjectFollowed', sys_notice: '<b>{nickname}</b> 关注了你管理的仓库', notification_url: '{baseurl}/{login}')
|
||||
self.create(type: 'MessageTemplate::ProjectForked', sys_notice: '<b>{nickname1}</b> 复刻了你管理的仓库{nickname1}/{repository1}到{nickname2}/{repository2}', notification_url: '{baseurl}/{owner}/{identifier}')
|
||||
email_html = File.read("#{email_template_html_dir}/project_issue.html")
|
||||
self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 新建易修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 新建了一个易修')
|
||||
self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 新建疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 新建了一个疑修')
|
||||
email_html = File.read("#{email_template_html_dir}/project_joined.html")
|
||||
self.create(type: 'MessageTemplate::ProjectJoined', sys_notice: '你已加入 <b>{repository}</b> 项目', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: 你已加入 {repository} 项目')
|
||||
email_html = File.read("#{email_template_html_dir}/project_left.html")
|
||||
|
|
@ -66,6 +64,10 @@ class MessageTemplate < ApplicationRecord
|
|||
self.create(type: 'MessageTemplate::PullRequestJournal', sys_notice: '{nickname}评论合并请求{title}:<b>{notes}</b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/pull_request_merged.html")
|
||||
self.create(type: 'MessageTemplate::PullRequestMerged', sys_notice: '你提交的合并请求:{title} <b>已通过</b>', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/team_joined.html")
|
||||
self.create(type: 'MessageTemplate::TeamJoined', sys_notice: '你已被拉入组织 <b>{organization}</b> 的 <b>{team}</b> 团队,拥有<b>{role}</b>权限', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
|
||||
email_html = File.read("#{email_template_html_dir}/team_left.html")
|
||||
self.create(type: 'MessageTemplate::TeamLeft', sys_notice: '你已被移出组织 <b>{organization}</b> 的 <b>{team}</b> 团队', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
|
||||
end
|
||||
|
||||
def self.sys_notice
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 有新指派给我的易修
|
||||
# 有新指派给我的疑修
|
||||
class MessageTemplate::IssueAssigned < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueAssigned.get_message_content(User.where(login: 'yystopf'), User.last, Issue.last)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我负责的易修截止日期到达最后一天
|
||||
# 我负责的疑修截止日期到达最后一天
|
||||
class MessageTemplate::IssueAssignerExpire < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueAssignerExpire.get_message_content(User.where(login: 'yystopf'), Issue.last)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 在易修中@我
|
||||
# 在疑修中@我
|
||||
class MessageTemplate::IssueAtme < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueAtme.get_message_content(User.where(login: 'yystopf'), User.last, Issue.last)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我创建或负责的易修状态变更
|
||||
# 我创建或负责的疑修状态变更
|
||||
class MessageTemplate::IssueChanged < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueChanged.get_message_content(User.where(login: 'yystopf'), User.last, Issue.last, {status_id: [1, 2], assigned_to_id: [nil, 203], tracker_id: [4, 3], priority_id: [2, 4], fixed_version_id: [nil, 5], due_date: ['', '2021-09-11'], done_ratio: [0, 40], issue_tags_value: ["", "7"], branch_name: ["", "master"]})
|
||||
|
|
@ -29,7 +29,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
content = MessageTemplate::IssueChanged.sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
change_count = change_params.keys.size
|
||||
# 易修负责人修改
|
||||
# 疑修负责人修改
|
||||
if change_params[:assigned_to_id].present?
|
||||
assigner1 = User.find_by_id(change_params[:assigned_to_id][0])
|
||||
assigner2 = User.find_by_id(change_params[:assigned_to_id][1])
|
||||
|
|
@ -44,7 +44,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
|
||||
end
|
||||
# 易修状态修改
|
||||
# 疑修状态修改
|
||||
if change_params[:status_id].present?
|
||||
status1 = IssueStatus.find_by_id(change_params[:status_id][0])
|
||||
status2 = IssueStatus.find_by_id(change_params[:status_id][1])
|
||||
|
|
@ -59,7 +59,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifstatus})(.*)({endstatus})/, '')
|
||||
end
|
||||
# 易修类型修改
|
||||
# 疑修类型修改
|
||||
if change_params[:tracker_id].present?
|
||||
tracker1 = Tracker.find_by_id(change_params[:tracker_id][0])
|
||||
tracker2 = Tracker.find_by_id(change_params[:tracker_id][1])
|
||||
|
|
@ -74,7 +74,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({iftracker})(.*)({endtracker})/, '')
|
||||
end
|
||||
# 易修里程碑修改
|
||||
# 疑修里程碑修改
|
||||
if change_params[:fixed_version_id].present?
|
||||
fix_version1 = Version.find_by_id(change_params[:fixed_version_id][0])
|
||||
fix_version2 = Version.find_by_id(change_params[:fixed_version_id][1])
|
||||
|
|
@ -89,7 +89,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifmilestone})(.*)({endmilestone})/, '')
|
||||
end
|
||||
# 易修标记修改
|
||||
# 疑修标记修改
|
||||
if change_params[:issue_tags_value].present?
|
||||
issue_tags1 = IssueTag.where(id: change_params[:issue_tags_value][0]).distinct
|
||||
issue_tags2 = IssueTag.where(id: change_params[:issue_tags_value][1]).distinct
|
||||
|
|
@ -106,7 +106,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({iftag})(.*)({endtag})()/, '')
|
||||
end
|
||||
# 易修优先级修改
|
||||
# 疑修优先级修改
|
||||
if change_params[:priority_id].present?
|
||||
priority1 = IssuePriority.find_by_id(change_params[:priority_id][0])
|
||||
priority2 = IssuePriority.find_by_id(change_params[:priority_id][1])
|
||||
|
|
@ -121,7 +121,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifpriority})(.*)({endpriority})/, '')
|
||||
end
|
||||
# 易修完成度修改
|
||||
# 疑修完成度修改
|
||||
if change_params[:done_ratio].present?
|
||||
doneratio1 = change_params[:done_ratio][0]
|
||||
doneratio2 = change_params[:done_ratio][1]
|
||||
|
|
@ -136,7 +136,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifdoneratio})(.*)({enddoneratio})/, '')
|
||||
end
|
||||
# 易修指定分支修改
|
||||
# 疑修指定分支修改
|
||||
if change_params[:branch_name].present?
|
||||
branch1 = change_params[:branch_name][0].blank? ? '分支未指定' : change_params[:branch_name][0]
|
||||
branch2 = change_params[:branch_name][1].blank? ? '分支未指定' : change_params[:branch_name][1]
|
||||
|
|
@ -151,7 +151,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifbranch})(.*)({endbranch})/, '')
|
||||
end
|
||||
# 易修开始日期修改
|
||||
# 疑修开始日期修改
|
||||
if change_params[:start_date].present?
|
||||
startdate1 = change_params[:start_date][0].blank? ? "未选择开始日期" : change_params[:start_date][0]
|
||||
startdate2 = change_params[:start_date][1].blank? ? "未选择开始日期" : change_params[:start_date][1]
|
||||
|
|
@ -166,7 +166,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifstartdate})(.*)({endstartdate})/, '')
|
||||
end
|
||||
# 易修结束日期修改
|
||||
# 疑修结束日期修改
|
||||
if change_params[:due_date].present?
|
||||
duedate1 = change_params[:due_date][0].blank? ? '未选择结束日期' : change_params[:due_date][0]
|
||||
duedate2 = change_params[:due_date][1].blank? ? '未选择结束日期' : change_params[:due_date][1]
|
||||
|
|
@ -207,7 +207,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
content.gsub!('{title}', issue&.subject)
|
||||
content.gsub!('{id}', issue&.id.to_s)
|
||||
change_count = change_params.keys.size
|
||||
# 易修负责人修改
|
||||
# 疑修负责人修改
|
||||
if change_params[:assigned_to_id].present?
|
||||
assigner1 = User.find_by_id(change_params[:assigned_to_id][0])
|
||||
assigner2 = User.find_by_id(change_params[:assigned_to_id][1])
|
||||
|
|
@ -222,7 +222,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
|
||||
end
|
||||
# 易修状态修改
|
||||
# 疑修状态修改
|
||||
if change_params[:status_id].present?
|
||||
status1 = IssueStatus.find_by_id(change_params[:status_id][0])
|
||||
status2 = IssueStatus.find_by_id(change_params[:status_id][1])
|
||||
|
|
@ -237,7 +237,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifstatus})(.*)({endstatus})/, '')
|
||||
end
|
||||
# 易修类型修改
|
||||
# 疑修类型修改
|
||||
if change_params[:tracker_id].present?
|
||||
tracker1 = Tracker.find_by_id(change_params[:tracker_id][0])
|
||||
tracker2 = Tracker.find_by_id(change_params[:tracker_id][1])
|
||||
|
|
@ -252,7 +252,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({iftracker})(.*)({endtracker})/, '')
|
||||
end
|
||||
# 易修里程碑修改
|
||||
# 疑修里程碑修改
|
||||
if change_params[:fixed_version_id].present?
|
||||
fix_version1 = Version.find_by_id(change_params[:fixed_version_id][0])
|
||||
fix_version2 = Version.find_by_id(change_params[:fixed_version_id][1])
|
||||
|
|
@ -267,7 +267,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifmilestone})(.*)({endmilestone})/, '')
|
||||
end
|
||||
# 易修标记修改
|
||||
# 疑修标记修改
|
||||
if change_params[:issue_tags_value].present?
|
||||
issue_tags1 = IssueTag.where(id: change_params[:issue_tags_value][0]).distinct
|
||||
issue_tags2 = IssueTag.where(id: change_params[:issue_tags_value][1]).distinct
|
||||
|
|
@ -284,7 +284,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({iftag})(.*)({endtag})()/, '')
|
||||
end
|
||||
# 易修优先级修改
|
||||
# 疑修优先级修改
|
||||
if change_params[:priority_id].present?
|
||||
priority1 = IssuePriority.find_by_id(change_params[:priority_id][0])
|
||||
priority2 = IssuePriority.find_by_id(change_params[:priority_id][1])
|
||||
|
|
@ -299,7 +299,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifpriority})(.*)({endpriority})/, '')
|
||||
end
|
||||
# 易修完成度修改
|
||||
# 疑修完成度修改
|
||||
if change_params[:done_ratio].present?
|
||||
doneratio1 = change_params[:done_ratio][0]
|
||||
doneratio2 = change_params[:done_ratio][1]
|
||||
|
|
@ -314,7 +314,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifdoneratio})(.*)({enddoneratio})/, '')
|
||||
end
|
||||
# 易修指定分支修改
|
||||
# 疑修指定分支修改
|
||||
if change_params[:branch_name].present?
|
||||
branch1 = change_params[:branch_name][0].blank? ? '分支未指定' : change_params[:branch_name][0]
|
||||
branch2 = change_params[:branch_name][1].blank? ? '分支未指定' : change_params[:branch_name][1]
|
||||
|
|
@ -329,7 +329,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifbranch})(.*)({endbranch})/, '')
|
||||
end
|
||||
# 易修开始日期修改
|
||||
# 疑修开始日期修改
|
||||
if change_params[:start_date].present?
|
||||
startdate1 = change_params[:start_date][0].blank? ? "未选择开始日期" : change_params[:start_date][0]
|
||||
startdate2 = change_params[:start_date][1].blank? ? "未选择开始日期" : change_params[:start_date][1]
|
||||
|
|
@ -344,7 +344,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifstartdate})(.*)({endstartdate})/, '')
|
||||
end
|
||||
# 易修结束日期修改
|
||||
# 疑修结束日期修改
|
||||
if change_params[:due_date].present?
|
||||
duedate1 = change_params[:due_date][0].blank? ? '未选择结束日期' : change_params[:due_date][0]
|
||||
duedate2 = change_params[:due_date][1].blank? ? '未选择结束日期' : change_params[:due_date][1]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我创建的易修截止日期到达最后一天
|
||||
# 我创建的疑修截止日期到达最后一天
|
||||
class MessageTemplate::IssueCreatorExpire < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueCreatorExpire.get_message_content(User.where(login: 'yystopf'), Issue.last)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我创建或负责的易修删除
|
||||
# 我创建或负责的疑修删除
|
||||
class MessageTemplate::IssueDeleted < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueDeleted.get_message_content(User.where(login: 'yystopf'), User.last, "hahah")
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# TODO 我创建或负责的易修有新的评论
|
||||
# TODO 我创建或负责的疑修有新的评论
|
||||
class MessageTemplate::IssueJournal < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueJournal.get_message_content(User.where(login: 'yystopf'))
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# TODO 我管理/关注的仓库有新的易修
|
||||
# TODO 我管理/关注的仓库有新的疑修
|
||||
class MessageTemplate::ProjectIssue < MessageTemplate
|
||||
|
||||
# MessageTemplate::ProjectIssue.get_message_content(User.where(login: 'yystopf'), User.where(login: 'forgetest1'), User.last, Issue.last)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
# 我管理的仓库项目设置被更改
|
||||
class MessageTemplate::ProjectSettingChanged < MessageTemplate
|
||||
|
||||
# MessageTemplate::ProjectSettingChanged.get_message_content(User.where(login: 'yystopf'), User.last, Project.last, {description: '测试修改项目简介', category: '大数据', language: 'Ruby', permission: '公有', navbar: '易修, 合并请求'})
|
||||
# MessageTemplate::ProjectSettingChanged.get_message_content(User.where(login: 'yystopf'), User.last, Project.last, {description: '测试修改项目简介', category: '大数据', language: 'Ruby', permission: '公有', navbar: '疑修, 合并请求'})
|
||||
def self.get_message_content(receivers, operator, project, change_params)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
|
|
@ -135,7 +135,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate
|
|||
unit_types.unshift('主页')
|
||||
unit_types.append('动态')
|
||||
navbar = unit_types.join(',')
|
||||
navbar.gsub!('issues', '易修')
|
||||
navbar.gsub!('issues', '疑修')
|
||||
navbar.gsub!('pulls', '合并请求')
|
||||
navbar.gsub!('wiki', 'Wiki')
|
||||
navbar.gsub!('devops', '工作流')
|
||||
|
|
@ -284,7 +284,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate
|
|||
unit_types.unshift('主页')
|
||||
unit_types.append('动态')
|
||||
navbar = unit_types.join(',')
|
||||
navbar.gsub!('issues', '易修')
|
||||
navbar.gsub!('issues', '疑修')
|
||||
navbar.gsub!('pulls', '合并请求')
|
||||
navbar.gsub!('wiki', 'Wiki')
|
||||
navbar.gsub!('devops', '工作流')
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 账号被拉入组织团队
|
||||
class MessageTemplate::TeamJoined < MessageTemplate
|
||||
|
||||
# MessageTemplate::TeamJoined.get_message_content(User.where(login: 'yystopf'), Organization.last, Organization.last.teams.take)
|
||||
def self.get_message_content(receivers, organization, team)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Permission"]
|
||||
end
|
||||
end
|
||||
return '', '', '' if receivers.blank?
|
||||
content = sys_notice.gsub('{organization}', organization&.real_name).gsub('{team}', team&.nickname).gsub('{role}', team&.authorize_name)
|
||||
url = notification_url.gsub('{login}', organization&.login)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::TeamJoined.get_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
def self.get_email_message_content(receiver, organization, role)
|
||||
if receiver.user_template_message_setting.present?
|
||||
return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Permission"]
|
||||
title = email_title
|
||||
title.gsub!('{organization}', organization&.real_name)
|
||||
title.gsub!('{team}', team&.nickname)
|
||||
title.gsub!('{role}', team&.authorize_name)
|
||||
content = email
|
||||
content.gsub!('{receiver}', receiver&.real_name)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{login}', organization&.login)
|
||||
content.gsub!('{organization}', organization&.real_name)
|
||||
content.gsub!('{team}', team&.nickname)
|
||||
content.gsub!('{role}', team&.authorize_name)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::TeamJoined.get_email_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 账号被移出组织团队
|
||||
class MessageTemplate::TeamLeft < MessageTemplate
|
||||
|
||||
# MessageTemplate::TeamLeft.get_message_content(User.where(login: 'yystopf'), Organization.last, Organization.last.teams.take)
|
||||
def self.get_message_content(receivers, organization, team)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Permission"]
|
||||
end
|
||||
end
|
||||
return '', '', '' if receivers.blank?
|
||||
content = sys_notice.gsub('{organization}', organization&.real_name).gsub('{team}', team&.nickname).gsub('{role}', team&.authorize_name)
|
||||
url = notification_url.gsub('{login}', organization&.login)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::TeamLeft.get_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
def self.get_email_message_content(receiver, organization, team)
|
||||
if receiver.user_template_message_setting.present?
|
||||
return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Permission"]
|
||||
title = email_title
|
||||
title.gsub!('{organization}', organization&.real_name)
|
||||
title.gsub!('{team}', team&.nickname)
|
||||
title.gsub!('{role}', team&.authorize_name)
|
||||
content = email
|
||||
content.gsub!('{receiver}', receiver&.real_name)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{login}', organization&.login)
|
||||
content.gsub!('{organization}', organization&.real_name)
|
||||
content.gsub!('{team}', team&.nickname)
|
||||
content.gsub!('{role}', team&.authorize_name)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::TeamLeft.get_email_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
@ -77,6 +77,9 @@
|
|||
# index_projects_on_updated_on (updated_on)
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
class Project < ApplicationRecord
|
||||
include Matchable
|
||||
include Publicable
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ class Team < ApplicationRecord
|
|||
|
||||
def authorize_name
|
||||
case self.authorize
|
||||
when 'read' then '报告者'
|
||||
when 'write' then '开发者'
|
||||
when 'read' then '读取'
|
||||
when 'write' then '写入'
|
||||
when 'admin' then '管理员'
|
||||
when 'owner' then '拥有者'
|
||||
when 'owner' then '管理员'
|
||||
else
|
||||
''
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,9 +22,17 @@ class TeamUser < ApplicationRecord
|
|||
belongs_to :team, counter_cache: :num_users
|
||||
belongs_to :user
|
||||
|
||||
has_one :member
|
||||
|
||||
validates :user_id, uniqueness: {scope: [:organization_id, :team_id]}
|
||||
|
||||
before_destroy :remove_project_member
|
||||
|
||||
def self.build(organization_id, user_id, team_id)
|
||||
self.create!(organization_id: organization_id, user_id: user_id, team_id: team_id)
|
||||
end
|
||||
|
||||
def remove_project_member
|
||||
member.destroy if member.present?
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class TemplateMessageSetting::CreateOrAssign < TemplateMessageSetting
|
|||
end
|
||||
|
||||
def self.build_init_data
|
||||
self.find_or_create_by(name: "易修状态变更", key: "IssueChanged")
|
||||
self.find_or_create_by(name: "疑修状态变更", key: "IssueChanged")
|
||||
self.find_or_create_by(name: "合并请求状态变更", key: "PullRequestChanged")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class TemplateMessageSetting::ManageProject < TemplateMessageSetting
|
|||
end
|
||||
|
||||
def self.build_init_data
|
||||
self.find_or_create_by(name: "有新的易修", key: "Issue")
|
||||
self.find_or_create_by(name: "有新的疑修", key: "Issue")
|
||||
self.find_or_create_by(name: "有新的合并请求", key: "PullRequest")
|
||||
self.find_or_create_by(name: "有成员变动", key: "Member")
|
||||
self.find_or_create_by(name: "仓库设置被更改", key: "SettingChanged")
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class TemplateMessageSetting::Normal < TemplateMessageSetting
|
|||
self.find_or_create_by(name: "账号有权限变更", key: "Permission")
|
||||
self.find_or_create_by(name: "被拉入或移出组织", key: "Organization")
|
||||
self.find_or_create_by(name: "被拉入或移出项目", key: "Project")
|
||||
self.find_or_create_by(name: "有新的易修指派给我", key: "IssueAssigned")
|
||||
self.find_or_create_by(name: "有新的疑修指派给我", key: "IssueAssigned")
|
||||
self.find_or_create_by(name: "有新的合并请求指派给我", key: "PullRequestAssigned")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -786,7 +786,7 @@ class User < Owner
|
|||
end
|
||||
|
||||
def profile_is_completed?
|
||||
self.nickname.present? && self.gender.present? && self.mail.present? && self.custom_department.present?
|
||||
self.nickname.present? && self.mail.present?
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
|||
|
|
@ -32,6 +32,6 @@ class AtmeService < ApplicationService
|
|||
else
|
||||
return
|
||||
end
|
||||
SendTemplateMessageJob.perform_now(message_source, receivers, user.id, @atmeable.id) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later(message_source, receivers.pluck(:id), user.id, @atmeable.id) if Site.has_notice_menu?
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class Gitea::Organization::UpdateService < Gitea::ClientService
|
|||
def request_params
|
||||
update_params = {
|
||||
name: org.login,
|
||||
full_name: org.nickname,
|
||||
description: org.description,
|
||||
location: org.location,
|
||||
repo_admin_change_team_access: org.repo_admin_change_team_access,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,12 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
|
|||
when 201 then success(json_parse!(body))
|
||||
when 403 then error("你没有权限操作!")
|
||||
when 404 then error("你操作的链接不存在!")
|
||||
when 422 then error("#{filepath}文件已存在,不能重复创建!")
|
||||
when 422
|
||||
if @body[:new_branch].include?('/') || @body[:new_branch].include?('\'') || @body[:new_branch].include?('^') || @body[:new_branch].include?('*')
|
||||
error("不合法的分支名称!")
|
||||
else
|
||||
error("#{filepath}文件已存在,不能重复创建!")
|
||||
end
|
||||
else error("系统错误!")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ class Notice::Write::ClientService < ApplicationService
|
|||
req.request :url_encoded
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.adapter Faraday.default_adapter
|
||||
req.options.timeout = 100 # open/read timeout in seconds
|
||||
req.options.open_timeout = 10 # connection open timeout in seconds
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ class PullRequests::CreateService < ApplicationService
|
|||
|
||||
def validate!
|
||||
raise "title参数不能为空" if @params[:title].blank?
|
||||
raise "title不能超过255个字符" if @params[:title].length > 255
|
||||
raise "head参数不能为空" if @params[:head].blank?
|
||||
raise "base参数不能为空" if @params[:base].blank?
|
||||
raise "fork_project_id参数错误" if is_original && !@project.forked_projects.pluck(:id).include?(@params[:fork_project_id].to_i)
|
||||
|
|
|
|||
|
|
@ -10,20 +10,12 @@ class Repositories::DetailService < ApplicationService
|
|||
def call
|
||||
return {
|
||||
repo: repo_suitable,
|
||||
contributor: contributor_suitable,
|
||||
language: language_suitable,
|
||||
branch_tag_total_count: branch_tag_total_count
|
||||
}
|
||||
rescue
|
||||
return {
|
||||
repo: {},
|
||||
release: [],
|
||||
branch: [],
|
||||
branch_type: [],
|
||||
tag: [],
|
||||
contributor: [],
|
||||
language: {},
|
||||
readme: {}
|
||||
branch_tag_total_count: {}
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -35,14 +27,4 @@ class Repositories::DetailService < ApplicationService
|
|||
def repo_suitable
|
||||
Gitea::Repository::GetService.call(@owner, @repo.identifier)
|
||||
end
|
||||
|
||||
def contributor_suitable
|
||||
contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repo.identifier)
|
||||
contributors.is_a?(Hash) && contributors.key?(:status) ? [] : contributors
|
||||
end
|
||||
|
||||
def language_suitable
|
||||
result = Gitea::Repository::Languages::ListService.call(@owner.login, @repo.identifier, @user&.gitea_token)
|
||||
result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
json.user_name claimer.user.try(:show_real_name)
|
||||
json.user_login claimer.user.try(:login)
|
||||
json.user_picture url_to_avatar(claimer.user)
|
||||
json.created_at time_from_now(claimer.created_at)
|
||||
json.note_body claimer.note
|
||||
json.claim_id claimer.id
|
||||
json.visible false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
json.partial! "commons/success"
|
||||
json.currentUserclaimed @user_claimed
|
||||
json.claimers do
|
||||
json.array! @claims do |claimer|
|
||||
json.partial! "claims/claim_item", claimer: claimer
|
||||
end
|
||||
end
|
||||
|
|
@ -13,6 +13,7 @@ json.tracker @issue.tracker.try(:name)
|
|||
json.issue_status @issue.issue_status.try(:name)
|
||||
json.priority @issue.priority.try(:name)
|
||||
json.version @issue.version.try(:name)
|
||||
json.version_id @issue.version.try(:id)
|
||||
json.issue_tags @issue.get_issue_tags
|
||||
json.done_ratio @issue.done_ratio.to_s + "%"
|
||||
json.issue_type @issue.issue_type
|
||||
|
|
|
|||
|
|
@ -3,15 +3,26 @@ owner_common = $redis_cache.hgetall("v2-owner-common:#{project_common["owner_id"
|
|||
json.id item[0]
|
||||
json.score item[1]
|
||||
json.name project_common["name"]
|
||||
json.identifier project_common["identifier"]
|
||||
json.description project_common["description"]
|
||||
json.owner do
|
||||
json.id project_common["owner_id"]
|
||||
json.type owner_common["type"]
|
||||
json.name owner_common["name"]
|
||||
json.login owner_common["login"]
|
||||
json.avatar_url owner_common["avatar_url"]
|
||||
if project_common['identifier'].include?("/")
|
||||
json.identifier project_common["identifier"].split('/')[1]
|
||||
json.owner do
|
||||
json.id nil
|
||||
json.type 'User'
|
||||
json.name project_common["identifier"].split('/')[0]
|
||||
json.login project_common["identifier"].split('/')[0]
|
||||
json.avatar_url User::Avatar.get_letter_avatar_url(project_common["identifier"].split('/')[0])
|
||||
end
|
||||
else
|
||||
json.identifier project_common["identifier"]
|
||||
json.owner do
|
||||
json.id project_common["owner_id"]
|
||||
json.type owner_common["type"]
|
||||
json.name owner_common["name"]
|
||||
json.login owner_common["login"]
|
||||
json.avatar_url owner_common["avatar_url"]
|
||||
end
|
||||
end
|
||||
json.description project_common["description"]
|
||||
json.visits project_common["visits"]
|
||||
json.forks project_common["forks"]
|
||||
json.watchers project_common["watchers"]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@ json.user_name trend.user.try(:show_real_name)
|
|||
json.user_login trend.user.login
|
||||
json.user_avatar url_to_avatar(trend.user)
|
||||
json.action_time time_from_now(trend.created_at)
|
||||
json.project do
|
||||
json.owner do
|
||||
json.partial! 'users/user_simple', locals: {user: trend&.project&.owner}
|
||||
end
|
||||
json.identifier trend&.project&.identifier
|
||||
json.description trend&.project&.description
|
||||
end
|
||||
|
||||
if trend.trend_type == "Issue"
|
||||
json.partial! "issues/simple_issue_item", locals: {issue: trend.trend}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,27 @@
|
|||
json.author do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Author']), name: commit['Author']['Name'] }
|
||||
end
|
||||
if commit['Status'].present?
|
||||
json.author do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Author']), name: commit['Author']['Name'] }
|
||||
end
|
||||
|
||||
json.committer do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Committer']), name: commit['Committer']['Name'] }
|
||||
end
|
||||
json.timestamp render_unix_time(commit['Committer']['When'])
|
||||
json.time_from_now time_from_now(commit['Committer']['When'])
|
||||
json.created_at render_format_time_with_date(commit['Committer']['When'])
|
||||
json.message commit['CommitMessage']
|
||||
json.sha commit['Sha']
|
||||
else
|
||||
json.author do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['commit']['author']), name: commit['commit']['author']['name'] }
|
||||
end
|
||||
|
||||
json.committer do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Committer']), name: commit['Committer']['Name'] }
|
||||
end
|
||||
json.timestamp render_unix_time(commit['Committer']['When'])
|
||||
json.time_from_now time_from_now(commit['Committer']['When'])
|
||||
json.created_at render_format_time_with_date(commit['Committer']['When'])
|
||||
json.message commit['CommitMessage']
|
||||
json.sha commit['Sha']
|
||||
json.committer do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['commit']['committer']), name: commit['commit']['committer']['name'] }
|
||||
end
|
||||
json.timestamp render_unix_time(commit['commit']['committer']['date'])
|
||||
json.time_from_now time_from_now(commit['commit']['committer']['date'])
|
||||
json.created_at render_format_time_with_date(commit['commit']['committer']['date'])
|
||||
json.message commit['commit']['message']
|
||||
json.sha commit['sha']
|
||||
end
|
||||
|
|
@ -7,11 +7,22 @@ if @project.educoder?
|
|||
json.timestamp 0
|
||||
json.time_from_now commit[0]['time']
|
||||
end
|
||||
json.author do
|
||||
{}
|
||||
# json.partial! '/projects/author', user: render_commit_author(commit['author'])
|
||||
end
|
||||
json.committer {}
|
||||
if commit[0]['author'].present?
|
||||
json.author do
|
||||
json.id nil
|
||||
json.login commit[0]['author']['username']
|
||||
json.name commit[0]['author']['username']
|
||||
json.type nil
|
||||
json.image_url commit[0]['author']['image_url']
|
||||
end
|
||||
json.committer do
|
||||
json.id nil
|
||||
json.login commit[0]['author']['username']
|
||||
json.name commit[0]['author']['username']
|
||||
json.type nil
|
||||
json.image_url commit[0]['author']['image_url']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if @project.forge?
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ end
|
|||
|
||||
if @project.educoder?
|
||||
file_path = params[:filepath].present? ? [params[:filepath], entry['name']].join('/') : entry['name']
|
||||
file_type = File.extname(entry['name'].to_s)[1..-1]
|
||||
image_type = image_type?(file_type)
|
||||
|
||||
json.name entry['name']
|
||||
json.sha nil
|
||||
|
|
@ -42,7 +44,7 @@ if @project.educoder?
|
|||
json.target nil
|
||||
json.download_url nil
|
||||
json.direct_download false
|
||||
json.image_type false
|
||||
json.image_type image_type
|
||||
json.is_readme_file false
|
||||
json.commit do
|
||||
json.message entry['title']
|
||||
|
|
|
|||
|
|
@ -1,6 +1,26 @@
|
|||
if @hash_commit.blank? #如果有状态值,则表示报错了
|
||||
if @hash_commit.blank? || @project.educoder? #如果有状态值,则表示报错了
|
||||
json.total_count 0
|
||||
json.commits []
|
||||
json.commits do
|
||||
json.array! @commits do |commit|
|
||||
json.sha commit['id']
|
||||
json.message commit['title']
|
||||
json.time_from_now commit['time']
|
||||
json.author do
|
||||
json.id nil
|
||||
json.login commit['author']['username']
|
||||
json.name commit['author']['username']
|
||||
json.type nil
|
||||
json.image_url commit['author']['image_url']
|
||||
end
|
||||
json.committer do
|
||||
json.id nil
|
||||
json.login commit['author']['username']
|
||||
json.name commit['author']['username']
|
||||
json.type nil
|
||||
json.image_url commit['author']['image_url']
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
json.total_count @hash_commit[:total_count]
|
||||
json.commits do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
total_count = @contributors.size
|
||||
json.contributors @contributors.each do |contributor|
|
||||
json.list @contributors.each do |contributor|
|
||||
json.partial! 'contributor', locals: { contributor: contributor }
|
||||
end
|
||||
json.total_count total_count
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ end
|
|||
if @result[:repo]
|
||||
json.size replace_bytes_to_b(number_to_human_size(@result[:repo]['size'].to_i*1024))
|
||||
json.ssh_url @result[:repo]['ssh_url']
|
||||
json.clone_url @result[:repo]['clone_url']
|
||||
json.clone_url @project.educoder? ? "#{Rails.application.config_for(:configuration)['educoder']['git_site']}/#{@project&.project_educoder&.repo_name}.git" : @result[:repo]['clone_url']
|
||||
json.default_branch @project.educoder? ? "master" : @result[:repo]['default_branch']
|
||||
json.empty @result[:repo]['empty']
|
||||
json.full_name @result[:repo]['full_name']
|
||||
|
|
@ -53,13 +53,13 @@ end
|
|||
json.license_name @project.license_name
|
||||
json.branches_count @result[:branch_tag_total_count].present? ? (@result[:branch_tag_total_count]['branch_count'] || 0) : 0
|
||||
json.tags_count @result[:branch_tag_total_count].present? ? (@result[:branch_tag_total_count]['tag_count'] || 0) : 0
|
||||
json.contributors do
|
||||
total_count = @result[:contributor].size
|
||||
json.list @result[:contributor].each do |contributor|
|
||||
json.partial! 'contributor', locals: { contributor: contributor }
|
||||
end
|
||||
json.total_count total_count
|
||||
end
|
||||
json.languages @result[:language].blank? ? nil : @result[:language]
|
||||
# json.contributors do
|
||||
# total_count = @result[:contributor].size
|
||||
# json.list @result[:contributor].each do |contributor|
|
||||
# json.partial! 'contributor', locals: { contributor: contributor }
|
||||
# end
|
||||
# json.total_count total_count
|
||||
# end
|
||||
# json.languages @result[:language].blank? ? nil : @result[:language]
|
||||
|
||||
json.partial! 'author', locals: { user: @project.owner }
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ if @project.educoder?
|
|||
end
|
||||
end
|
||||
json.commits_count @entries['commit_count']
|
||||
json.zip_url @entries['git_url']
|
||||
json.zip_url ''
|
||||
json.tar_url ''
|
||||
json.entries do
|
||||
json.array! @entries['trees'] do |entry|
|
||||
|
|
|
|||
|
|
@ -24,8 +24,12 @@ if @project.educoder?
|
|||
end
|
||||
end
|
||||
json.entries do
|
||||
json.array! @sub_entries['trees'] do |entry|
|
||||
json.partial! 'repositories/simple_entry', locals: { entry: entry }
|
||||
if @sub_entries['trees'].is_a?(Array)
|
||||
json.array! @sub_entries['trees'] do |entry|
|
||||
json.partial! 'repositories/simple_entry', locals: { entry: entry }
|
||||
end
|
||||
elsif @sub_entries['trees'].is_a?(Hash)
|
||||
json.partial! 'repositories/simple_entry', locals: { entry: @sub_entries['trees'] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ zh-CN:
|
|||
'refused': '已拒绝'
|
||||
'agreed': '已同意'
|
||||
trend:
|
||||
Issue: 易修(Issue)
|
||||
Issue: 疑修(Issue)
|
||||
PullRequest: 合并请求(PR)
|
||||
VersionRelease: 版本发布
|
||||
create: 创建了
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ Rails.application.routes.draw do
|
|||
# Serve websocket cable requests in-process
|
||||
mount ActionCable.server => '/cable'
|
||||
|
||||
|
||||
get 'attachments/entries/get_file', to: 'attachments#get_file'
|
||||
get 'attachments/download/:id', to: 'attachments#show'
|
||||
get 'attachments/download/:id/:filename', to: 'attachments#show'
|
||||
|
|
@ -146,6 +147,16 @@ Rails.application.routes.draw do
|
|||
get :get_children_journals
|
||||
end
|
||||
end
|
||||
|
||||
resources :claims, only: [:index] do
|
||||
collection do
|
||||
post :create
|
||||
delete :destroy
|
||||
get :index
|
||||
put :update
|
||||
end
|
||||
end
|
||||
|
||||
resources :issue_times, only: [:create] do
|
||||
collection do
|
||||
post :end_work
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
class CreateClaims < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :claims do |t|
|
||||
t.integer :issue_id
|
||||
t.integer :user_id
|
||||
t.timestamps
|
||||
t.index :issue_id
|
||||
t.index :user_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class AddNoteToClaim < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :claims, :note, :text
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class AddTeamUserToMembers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_reference :members, :team_user
|
||||
end
|
||||
end
|
||||
2
dir.md
|
|
@ -87,7 +87,7 @@ forgeplus
|
|||
│ │ │ │ └── tags(标签)
|
||||
│ │ │ ├── user(用户)
|
||||
│ │ │ └── versions(发行版)
|
||||
│ │ ├── issues(易修)
|
||||
│ │ ├── issues(疑修)
|
||||
│ │ ├── libraries
|
||||
│ │ ├── oauth
|
||||
│ │ ├── organizations(组织)
|
||||
|
|
|
|||
BIN
docs/figs/PR.png
|
Before Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 316 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 199 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 375 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
Before Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 472 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
|
@ -1138,31 +1138,31 @@ Success — a happy kitten is an authenticated kitten!
|
|||
</thead><tbody>
|
||||
<tr>
|
||||
<td>IssueAssigned</td>
|
||||
<td>有新指派给我的易修</td>
|
||||
<td>有新指派给我的疑修</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueAssignerExpire</td>
|
||||
<td>我负责的易修截止日期到达最后一天</td>
|
||||
<td>我负责的疑修截止日期到达最后一天</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueAtme</td>
|
||||
<td>在易修中@我</td>
|
||||
<td>在疑修中@我</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueChanged</td>
|
||||
<td>我创建或负责的易修状态变更</td>
|
||||
<td>我创建或负责的疑修状态变更</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueCreatorExpire</td>
|
||||
<td>我创建的易修截止日期到达最后一天</td>
|
||||
<td>我创建的疑修截止日期到达最后一天</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueDeleted</td>
|
||||
<td>我创建或负责的易修删除</td>
|
||||
<td>我创建或负责的疑修删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueJournal</td>
|
||||
<td>我创建或负责的易修有新的评论</td>
|
||||
<td>我创建或负责的疑修有新的评论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LoginIpTip</td>
|
||||
|
|
@ -1194,7 +1194,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
</tr>
|
||||
<tr>
|
||||
<td>ProjectIssue</td>
|
||||
<td>我管理/关注的仓库有新的易修</td>
|
||||
<td>我管理/关注的仓库有新的疑修</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ProjectJoined</td>
|
||||
|
|
@ -1403,7 +1403,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
<tr>
|
||||
<td>atmeable_type</td>
|
||||
<td>string</td>
|
||||
<td>atme消息对象,是从哪里@我的,比如评论:Journal、易修:Issue、合并请求:PullRequest</td>
|
||||
<td>atme消息对象,是从哪里@我的,比如评论:Journal、疑修:Issue、合并请求:PullRequest</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>atmeable_id</td>
|
||||
|
|
@ -1706,7 +1706,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
</span><span class="nl">"total_settings_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"settings"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
|
||||
</span><span class="p">{</span><span class="w">
|
||||
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"易修被指派"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"疑修被指派"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"IssueAssigned"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"notification_disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"email_disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
|
||||
|
|
@ -1725,7 +1725,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
</span><span class="nl">"total_settings_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"settings"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
|
||||
</span><span class="p">{</span><span class="w">
|
||||
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"有新的易修"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"有新的疑修"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Issue"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"notification_disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"email_disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
|
||||
|
|
@ -2245,7 +2245,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
<tr>
|
||||
<td>issues_count</td>
|
||||
<td>array</td>
|
||||
<td>易修数量</td>
|
||||
<td>疑修数量</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pull_requests_count</td>
|
||||
|
|
@ -2493,7 +2493,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
<tr>
|
||||
<td>project_trends.trend_type</td>
|
||||
<td>string</td>
|
||||
<td>动态类型,Issue:易修,VersionRelease:版本发布,PullRequest:合并请求</td>
|
||||
<td>动态类型,Issue:疑修,VersionRelease:版本发布,PullRequest:合并请求</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>project_trends.action_type</td>
|
||||
|
|
@ -4968,7 +4968,7 @@ http://localhost:3000/api/yystopf/ceshi/menu_list | jq
|
|||
<tr>
|
||||
<td>menu_name</td>
|
||||
<td>string</td>
|
||||
<td>导航名称, home:主页,code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置</td>
|
||||
<td>导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
|
|
@ -5131,7 +5131,7 @@ http://localhost:3000/api/yystopf/ceshi/project_units.json
|
|||
<td>是</td>
|
||||
<td></td>
|
||||
<td>array</td>
|
||||
<td>项目模块内容, 支持以下参数:code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑</td>
|
||||
<td>项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3 id='7447e4874e-2'>返回字段说明:</h3>
|
||||
|
|
@ -8346,23 +8346,23 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.json
|
|||
</tr>
|
||||
<tr>
|
||||
<td>issue</td>
|
||||
<td>易修已打开、已关闭、已重新打开或编辑</td>
|
||||
<td>疑修已打开、已关闭、已重新打开或编辑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_assign</td>
|
||||
<td>易修被指派</td>
|
||||
<td>疑修被指派</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_label</td>
|
||||
<td>易修标签被更新或删除</td>
|
||||
<td>疑修标签被更新或删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_milestone</td>
|
||||
<td>易修被收入里程碑</td>
|
||||
<td>疑修被收入里程碑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_comment</td>
|
||||
<td>易修评论</td>
|
||||
<td>疑修评论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pull_request</td>
|
||||
|
|
@ -8568,23 +8568,23 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json
|
|||
</tr>
|
||||
<tr>
|
||||
<td>issue</td>
|
||||
<td>易修已打开、已关闭、已重新打开或编辑</td>
|
||||
<td>疑修已打开、已关闭、已重新打开或编辑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_assign</td>
|
||||
<td>易修被指派</td>
|
||||
<td>疑修被指派</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_label</td>
|
||||
<td>易修标签被更新或删除</td>
|
||||
<td>疑修标签被更新或删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_milestone</td>
|
||||
<td>易修被收入里程碑</td>
|
||||
<td>疑修被收入里程碑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_comment</td>
|
||||
<td>易修评论</td>
|
||||
<td>疑修评论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pull_request</td>
|
||||
|
|
@ -8833,23 +8833,23 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/7.json
|
|||
</tr>
|
||||
<tr>
|
||||
<td>issue</td>
|
||||
<td>易修已打开、已关闭、已重新打开或编辑</td>
|
||||
<td>疑修已打开、已关闭、已重新打开或编辑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_assign</td>
|
||||
<td>易修被指派</td>
|
||||
<td>疑修被指派</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_label</td>
|
||||
<td>易修标签被更新或删除</td>
|
||||
<td>疑修标签被更新或删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_milestone</td>
|
||||
<td>易修被收入里程碑</td>
|
||||
<td>疑修被收入里程碑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_comment</td>
|
||||
<td>易修评论</td>
|
||||
<td>疑修评论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pull_request</td>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>有新的易修指派给我</title>
|
||||
<title>有新的疑修指派给我</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>在 {nickname2}/{repository} 指派给你一个易修:<a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a><br/>
|
||||
<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>在 {nickname2}/{repository} 指派给你一个疑修:<a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a><br/>
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>有新的易修指派给我</title>
|
||||
<title>有新的疑修指派给我</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
在项目 <a href="{baseurl}/{login2}/{identifier}" style="font-weight:bold;color:#3b94d6;">{nickname2}/{repository}</a> 的易修 <a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a> 中:
|
||||
在项目 <a href="{baseurl}/{login2}/{identifier}" style="font-weight:bold;color:#3b94d6;">{nickname2}/{repository}</a> 的疑修 <a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a> 中:
|
||||
{ifassigner}<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>将负责人从 {assigner1} 修改为 {assigner2}{endassigner}
|
||||
{ifstatus}<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>将状态从 {status1} 修改为 {status2}{endstatus}
|
||||
{iftracker}<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>将类型从 {tracker1} 修改为 {tracker2}{endtracker}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>易修状态改变</title>
|
||||
<title>疑修状态改变</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
<a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{nickname}</a>已将易修 {title} 删除
|
||||
<a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{nickname}</a>已将疑修 {title} 删除
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>管理的仓库有新的易修</title>
|
||||
<title>管理的仓库有新的疑修</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>在 {nickname2}/{repository} 新建了一个易修:<a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a><br/>
|
||||
<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>在 {nickname2}/{repository} 新建了一个疑修:<a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a><br/>
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>被拉入组织团队</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
div,img,tr,td,table{ border:0;}
|
||||
table,tr,td{border:0;}
|
||||
ol,ul,li{ list-style-type:none}
|
||||
.new_content{ background:#fff; width: 100%;}
|
||||
.email-page-link{ }
|
||||
.email-link-top{ }
|
||||
.c_white{ color:#fff;}
|
||||
.email-link-con{ }
|
||||
.email-link-line{ }
|
||||
.email-link-footer{ padding:15px; color:#333; line-height: 1.9; }
|
||||
.c_grey02{ color: #888;}
|
||||
.fb{ font-weight: normal;}
|
||||
.f14{ }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="background:#fff;">
|
||||
<div class="new_content">
|
||||
<div style="width: 598px; background:#fff; margin:20px auto;">
|
||||
<div style="height:50px; width: 578px; background:#3b94d6; padding:9px 10px 6px;border:1px solid #ddd; border-bottom:none;">
|
||||
<a href="{baseurl}"><img src="{baseurl}/images/email_logo.png" height="45" ></a>
|
||||
<p style="color:#fff; float:right; margin-top:15px;">确实开源,协同创新</p>
|
||||
<div style="clear:both; overflow:hidden;"></div>
|
||||
</div>
|
||||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
你已被拉入组织 <a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{organization}</a> 的 <a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{team}</a> 团队,拥有{role}权限
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
<div style="padding:20px; color:#333; line-height: 1.9;background: #eee;border:1px solid #ddd; border-top:none; width: 558px;">
|
||||
<p style="color:#888; float:left;">如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见<br/>
|
||||
QQ群:1071514693</p>
|
||||
<p style="color:#888; float:right;font-weight: bold;font-size: 16px;">GitLink团队</p>
|
||||
<div style="clear:both; overflow:hidden;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>被移出组织团队</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
div,img,tr,td,table{ border:0;}
|
||||
table,tr,td{border:0;}
|
||||
ol,ul,li{ list-style-type:none}
|
||||
.new_content{ background:#fff; width: 100%;}
|
||||
.email-page-link{ }
|
||||
.email-link-top{ }
|
||||
.c_white{ color:#fff;}
|
||||
.email-link-con{ }
|
||||
.email-link-line{ }
|
||||
.email-link-footer{ padding:15px; color:#333; line-height: 1.9; }
|
||||
.c_grey02{ color: #888;}
|
||||
.fb{ font-weight: normal;}
|
||||
.f14{ }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="background:#fff;">
|
||||
<div class="new_content">
|
||||
<div style="width: 598px; background:#fff; margin:20px auto;">
|
||||
<div style="height:50px; width: 578px; background:#3b94d6; padding:9px 10px 6px;border:1px solid #ddd; border-bottom:none;">
|
||||
<a href="{baseurl}"><img src="{baseurl}/images/email_logo.png" height="45" ></a>
|
||||
<p style="color:#fff; float:right; margin-top:15px;">确实开源,协同创新</p>
|
||||
<div style="clear:both; overflow:hidden;"></div>
|
||||
</div>
|
||||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
你已被移出组织 <a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{organization}</a> 的 <a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{team}</a> 团队
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
<div style="padding:20px; color:#333; line-height: 1.9;background: #eee;border:1px solid #ddd; border-top:none; width: 558px;">
|
||||
<p style="color:#888; float:left;">如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见<br/>
|
||||
QQ群:1071514693</p>
|
||||
<p style="color:#888; float:right;font-weight: bold;font-size: 16px;">GitLink团队</p>
|
||||
<div style="clear:both; overflow:hidden;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -4,382 +4,304 @@
|
|||
"static/css/1.0ba7a726.chunk.css": "/react/build/static/css/1.0ba7a726.chunk.css",
|
||||
"./static/js/1.9de07cbc.chunk.js": "/react/build/./static/js/1.9de07cbc.chunk.js",
|
||||
"./static/js/2.d659edf3.chunk.js": "/react/build/./static/js/2.d659edf3.chunk.js",
|
||||
"static/css/3.d01698e8.chunk.css": "/react/build/static/css/3.d01698e8.chunk.css",
|
||||
"./static/js/3.1f347c4c.chunk.js": "/react/build/./static/js/3.1f347c4c.chunk.js",
|
||||
"static/css/4.2254a4a8.chunk.css": "/react/build/static/css/4.2254a4a8.chunk.css",
|
||||
"./static/js/4.4d2d662b.chunk.js": "/react/build/./static/js/4.4d2d662b.chunk.js",
|
||||
"./static/js/5.6f9f87c6.chunk.js": "/react/build/./static/js/5.6f9f87c6.chunk.js",
|
||||
"static/css/6.8bc7b323.chunk.css": "/react/build/static/css/6.8bc7b323.chunk.css",
|
||||
"./static/js/6.c04051a2.chunk.js": "/react/build/./static/js/6.c04051a2.chunk.js",
|
||||
"static/css/7.bbfdfc43.chunk.css": "/react/build/static/css/7.bbfdfc43.chunk.css",
|
||||
"./static/js/7.8462b447.chunk.js": "/react/build/./static/js/7.8462b447.chunk.js",
|
||||
"static/css/8.1632b9c8.chunk.css": "/react/build/static/css/8.1632b9c8.chunk.css",
|
||||
"./static/js/8.882648e1.chunk.js": "/react/build/./static/js/8.882648e1.chunk.js",
|
||||
"static/css/9.6e0686d9.chunk.css": "/react/build/static/css/9.6e0686d9.chunk.css",
|
||||
"./static/js/9.fd42b255.chunk.js": "/react/build/./static/js/9.fd42b255.chunk.js",
|
||||
"static/css/10.d4345223.chunk.css": "/react/build/static/css/10.d4345223.chunk.css",
|
||||
"./static/js/10.08552af4.chunk.js": "/react/build/./static/js/10.08552af4.chunk.js",
|
||||
"static/css/11.ae349a22.chunk.css": "/react/build/static/css/11.ae349a22.chunk.css",
|
||||
"./static/js/11.69f940df.chunk.js": "/react/build/./static/js/11.69f940df.chunk.js",
|
||||
"static/css/12.1c5f3a58.chunk.css": "/react/build/static/css/12.1c5f3a58.chunk.css",
|
||||
"./static/js/12.72a62b66.chunk.js": "/react/build/./static/js/12.72a62b66.chunk.js",
|
||||
"static/css/3.2254a4a8.chunk.css": "/react/build/static/css/3.2254a4a8.chunk.css",
|
||||
"./static/js/3.c021d738.chunk.js": "/react/build/./static/js/3.c021d738.chunk.js",
|
||||
"./static/js/4.5d0131e6.chunk.js": "/react/build/./static/js/4.5d0131e6.chunk.js",
|
||||
"static/css/5.d01698e8.chunk.css": "/react/build/static/css/5.d01698e8.chunk.css",
|
||||
"./static/js/5.ba9c3134.chunk.js": "/react/build/./static/js/5.ba9c3134.chunk.js",
|
||||
"static/css/6.bbfdfc43.chunk.css": "/react/build/static/css/6.bbfdfc43.chunk.css",
|
||||
"./static/js/6.69ca2fc8.chunk.js": "/react/build/./static/js/6.69ca2fc8.chunk.js",
|
||||
"static/css/7.e821a490.chunk.css": "/react/build/static/css/7.e821a490.chunk.css",
|
||||
"./static/js/7.a1394f8d.chunk.js": "/react/build/./static/js/7.a1394f8d.chunk.js",
|
||||
"static/css/8.6e0686d9.chunk.css": "/react/build/static/css/8.6e0686d9.chunk.css",
|
||||
"./static/js/8.7ad76529.chunk.js": "/react/build/./static/js/8.7ad76529.chunk.js",
|
||||
"static/css/9.d4345223.chunk.css": "/react/build/static/css/9.d4345223.chunk.css",
|
||||
"./static/js/9.74545efc.chunk.js": "/react/build/./static/js/9.74545efc.chunk.js",
|
||||
"static/css/10.1868f004.chunk.css": "/react/build/static/css/10.1868f004.chunk.css",
|
||||
"./static/js/10.b3f0a06d.chunk.js": "/react/build/./static/js/10.b3f0a06d.chunk.js",
|
||||
"static/css/11.1c5f3a58.chunk.css": "/react/build/static/css/11.1c5f3a58.chunk.css",
|
||||
"./static/js/11.5c1d2c2d.chunk.js": "/react/build/./static/js/11.5c1d2c2d.chunk.js",
|
||||
"static/css/12.ae349a22.chunk.css": "/react/build/static/css/12.ae349a22.chunk.css",
|
||||
"./static/js/12.732d3701.chunk.js": "/react/build/./static/js/12.732d3701.chunk.js",
|
||||
"static/css/13.30f998e5.chunk.css": "/react/build/static/css/13.30f998e5.chunk.css",
|
||||
"./static/js/13.7de262c1.chunk.js": "/react/build/./static/js/13.7de262c1.chunk.js",
|
||||
"./static/js/13.87577dfb.chunk.js": "/react/build/./static/js/13.87577dfb.chunk.js",
|
||||
"static/css/14.1e970b46.chunk.css": "/react/build/static/css/14.1e970b46.chunk.css",
|
||||
"./static/js/14.47d6b04d.chunk.js": "/react/build/./static/js/14.47d6b04d.chunk.js",
|
||||
"static/css/15.cf56d612.chunk.css": "/react/build/static/css/15.cf56d612.chunk.css",
|
||||
"./static/js/15.5eff19c4.chunk.js": "/react/build/./static/js/15.5eff19c4.chunk.js",
|
||||
"static/css/16.74ea968f.chunk.css": "/react/build/static/css/16.74ea968f.chunk.css",
|
||||
"./static/js/16.29ac39ca.chunk.js": "/react/build/./static/js/16.29ac39ca.chunk.js",
|
||||
"static/css/17.d0c774b5.chunk.css": "/react/build/static/css/17.d0c774b5.chunk.css",
|
||||
"./static/js/17.de7604c0.chunk.js": "/react/build/./static/js/17.de7604c0.chunk.js",
|
||||
"static/css/18.7bd7b9f3.chunk.css": "/react/build/static/css/18.7bd7b9f3.chunk.css",
|
||||
"./static/js/18.99b2f967.chunk.js": "/react/build/./static/js/18.99b2f967.chunk.js",
|
||||
"static/css/19.012aec0d.chunk.css": "/react/build/static/css/19.012aec0d.chunk.css",
|
||||
"./static/js/19.c80c661b.chunk.js": "/react/build/./static/js/19.c80c661b.chunk.js",
|
||||
"static/css/20.e5544bad.chunk.css": "/react/build/static/css/20.e5544bad.chunk.css",
|
||||
"./static/js/20.bfbd5ffe.chunk.js": "/react/build/./static/js/20.bfbd5ffe.chunk.js",
|
||||
"./static/js/21.6da4d475.chunk.js": "/react/build/./static/js/21.6da4d475.chunk.js",
|
||||
"static/css/22.330fa4e3.chunk.css": "/react/build/static/css/22.330fa4e3.chunk.css",
|
||||
"./static/js/22.709de7d8.chunk.js": "/react/build/./static/js/22.709de7d8.chunk.js",
|
||||
"static/css/23.db9266b0.chunk.css": "/react/build/static/css/23.db9266b0.chunk.css",
|
||||
"./static/js/23.54c1c605.chunk.js": "/react/build/./static/js/23.54c1c605.chunk.js",
|
||||
"static/css/24.0b7937b6.chunk.css": "/react/build/static/css/24.0b7937b6.chunk.css",
|
||||
"./static/js/24.567dac3f.chunk.js": "/react/build/./static/js/24.567dac3f.chunk.js",
|
||||
"./static/js/25.edd1a409.chunk.js": "/react/build/./static/js/25.edd1a409.chunk.js",
|
||||
"static/css/26.92df39ea.chunk.css": "/react/build/static/css/26.92df39ea.chunk.css",
|
||||
"./static/js/26.4ca0a6c7.chunk.js": "/react/build/./static/js/26.4ca0a6c7.chunk.js",
|
||||
"./static/js/27.a37917ce.chunk.js": "/react/build/./static/js/27.a37917ce.chunk.js",
|
||||
"static/css/28.75aaa133.chunk.css": "/react/build/static/css/28.75aaa133.chunk.css",
|
||||
"./static/js/28.25a3467c.chunk.js": "/react/build/./static/js/28.25a3467c.chunk.js",
|
||||
"static/css/29.646401a4.chunk.css": "/react/build/static/css/29.646401a4.chunk.css",
|
||||
"./static/js/29.9433bca2.chunk.js": "/react/build/./static/js/29.9433bca2.chunk.js",
|
||||
"./static/js/30.71048987.chunk.js": "/react/build/./static/js/30.71048987.chunk.js",
|
||||
"static/css/31.93537df9.chunk.css": "/react/build/static/css/31.93537df9.chunk.css",
|
||||
"./static/js/31.3aa5d702.chunk.js": "/react/build/./static/js/31.3aa5d702.chunk.js",
|
||||
"static/css/32.33342a61.chunk.css": "/react/build/static/css/32.33342a61.chunk.css",
|
||||
"./static/js/32.aa9f51bb.chunk.js": "/react/build/./static/js/32.aa9f51bb.chunk.js",
|
||||
"static/css/33.3201edcb.chunk.css": "/react/build/static/css/33.3201edcb.chunk.css",
|
||||
"./static/js/33.be67ceb0.chunk.js": "/react/build/./static/js/33.be67ceb0.chunk.js",
|
||||
"static/css/34.4dcfd44a.chunk.css": "/react/build/static/css/34.4dcfd44a.chunk.css",
|
||||
"./static/js/34.b06d630a.chunk.js": "/react/build/./static/js/34.b06d630a.chunk.js",
|
||||
"static/css/35.a673f3dd.chunk.css": "/react/build/static/css/35.a673f3dd.chunk.css",
|
||||
"./static/js/35.d6dd0530.chunk.js": "/react/build/./static/js/35.d6dd0530.chunk.js",
|
||||
"static/css/36.c831b4d8.chunk.css": "/react/build/static/css/36.c831b4d8.chunk.css",
|
||||
"./static/js/36.6afb23fc.chunk.js": "/react/build/./static/js/36.6afb23fc.chunk.js",
|
||||
"static/css/37.010bbe87.chunk.css": "/react/build/static/css/37.010bbe87.chunk.css",
|
||||
"./static/js/37.22d2c30b.chunk.js": "/react/build/./static/js/37.22d2c30b.chunk.js",
|
||||
"static/css/38.69edc38b.chunk.css": "/react/build/static/css/38.69edc38b.chunk.css",
|
||||
"./static/js/38.c9830d31.chunk.js": "/react/build/./static/js/38.c9830d31.chunk.js",
|
||||
"static/css/39.69edc38b.chunk.css": "/react/build/static/css/39.69edc38b.chunk.css",
|
||||
"./static/js/39.2b68156d.chunk.js": "/react/build/./static/js/39.2b68156d.chunk.js",
|
||||
"static/css/40.543b24f4.chunk.css": "/react/build/static/css/40.543b24f4.chunk.css",
|
||||
"./static/js/40.7df4fd1f.chunk.js": "/react/build/./static/js/40.7df4fd1f.chunk.js",
|
||||
"static/css/41.69edc38b.chunk.css": "/react/build/static/css/41.69edc38b.chunk.css",
|
||||
"./static/js/41.f8ec75a6.chunk.js": "/react/build/./static/js/41.f8ec75a6.chunk.js",
|
||||
"static/css/42.69edc38b.chunk.css": "/react/build/static/css/42.69edc38b.chunk.css",
|
||||
"./static/js/42.72b65f6f.chunk.js": "/react/build/./static/js/42.72b65f6f.chunk.js",
|
||||
"static/css/43.69edc38b.chunk.css": "/react/build/static/css/43.69edc38b.chunk.css",
|
||||
"./static/js/43.a85f629f.chunk.js": "/react/build/./static/js/43.a85f629f.chunk.js",
|
||||
"static/css/44.0fb95ac8.chunk.css": "/react/build/static/css/44.0fb95ac8.chunk.css",
|
||||
"./static/js/44.9b637cdd.chunk.js": "/react/build/./static/js/44.9b637cdd.chunk.js",
|
||||
"./static/js/45.c7182e05.chunk.js": "/react/build/./static/js/45.c7182e05.chunk.js",
|
||||
"static/css/46.88cc3b5e.chunk.css": "/react/build/static/css/46.88cc3b5e.chunk.css",
|
||||
"./static/js/46.cd44eee7.chunk.js": "/react/build/./static/js/46.cd44eee7.chunk.js",
|
||||
"static/css/47.88cc3b5e.chunk.css": "/react/build/static/css/47.88cc3b5e.chunk.css",
|
||||
"./static/js/47.45010480.chunk.js": "/react/build/./static/js/47.45010480.chunk.js",
|
||||
"static/css/48.88cc3b5e.chunk.css": "/react/build/static/css/48.88cc3b5e.chunk.css",
|
||||
"./static/js/48.2b0072e9.chunk.js": "/react/build/./static/js/48.2b0072e9.chunk.js",
|
||||
"static/css/49.5c81fe74.chunk.css": "/react/build/static/css/49.5c81fe74.chunk.css",
|
||||
"./static/js/49.52f41fd7.chunk.js": "/react/build/./static/js/49.52f41fd7.chunk.js",
|
||||
"./static/js/50.925643ee.chunk.js": "/react/build/./static/js/50.925643ee.chunk.js",
|
||||
"static/css/51.080d6958.chunk.css": "/react/build/static/css/51.080d6958.chunk.css",
|
||||
"./static/js/51.5ee89aa0.chunk.js": "/react/build/./static/js/51.5ee89aa0.chunk.js",
|
||||
"./static/js/52.d514755b.chunk.js": "/react/build/./static/js/52.d514755b.chunk.js",
|
||||
"./static/js/53.31e60498.chunk.js": "/react/build/./static/js/53.31e60498.chunk.js",
|
||||
"static/css/54.c9adf574.chunk.css": "/react/build/static/css/54.c9adf574.chunk.css",
|
||||
"./static/js/54.5192af32.chunk.js": "/react/build/./static/js/54.5192af32.chunk.js",
|
||||
"static/css/55.b299cb62.chunk.css": "/react/build/static/css/55.b299cb62.chunk.css",
|
||||
"./static/js/55.ce4bb066.chunk.js": "/react/build/./static/js/55.ce4bb066.chunk.js",
|
||||
"static/css/56.4f215d24.chunk.css": "/react/build/static/css/56.4f215d24.chunk.css",
|
||||
"./static/js/56.c0cb6388.chunk.js": "/react/build/./static/js/56.c0cb6388.chunk.js",
|
||||
"static/css/57.19d38f88.chunk.css": "/react/build/static/css/57.19d38f88.chunk.css",
|
||||
"./static/js/57.d3e720bf.chunk.js": "/react/build/./static/js/57.d3e720bf.chunk.js",
|
||||
"static/css/58.e8001192.chunk.css": "/react/build/static/css/58.e8001192.chunk.css",
|
||||
"./static/js/58.e2d064c3.chunk.js": "/react/build/./static/js/58.e2d064c3.chunk.js",
|
||||
"static/css/59.ff2c3b14.chunk.css": "/react/build/static/css/59.ff2c3b14.chunk.css",
|
||||
"./static/js/59.10c3d9dd.chunk.js": "/react/build/./static/js/59.10c3d9dd.chunk.js",
|
||||
"static/css/60.c0f62e1a.chunk.css": "/react/build/static/css/60.c0f62e1a.chunk.css",
|
||||
"./static/js/60.40b41e97.chunk.js": "/react/build/./static/js/60.40b41e97.chunk.js",
|
||||
"static/css/61.cd48c477.chunk.css": "/react/build/static/css/61.cd48c477.chunk.css",
|
||||
"./static/js/61.59c84ed6.chunk.js": "/react/build/./static/js/61.59c84ed6.chunk.js",
|
||||
"static/css/62.1b6ed5c5.chunk.css": "/react/build/static/css/62.1b6ed5c5.chunk.css",
|
||||
"./static/js/62.ec026a1a.chunk.js": "/react/build/./static/js/62.ec026a1a.chunk.js",
|
||||
"static/css/63.67a9b0d6.chunk.css": "/react/build/static/css/63.67a9b0d6.chunk.css",
|
||||
"./static/js/63.eef6a7a2.chunk.js": "/react/build/./static/js/63.eef6a7a2.chunk.js",
|
||||
"static/css/64.859e5099.chunk.css": "/react/build/static/css/64.859e5099.chunk.css",
|
||||
"./static/js/64.fcef2b45.chunk.js": "/react/build/./static/js/64.fcef2b45.chunk.js",
|
||||
"static/css/65.1d3b7a8d.chunk.css": "/react/build/static/css/65.1d3b7a8d.chunk.css",
|
||||
"./static/js/65.26785650.chunk.js": "/react/build/./static/js/65.26785650.chunk.js",
|
||||
"static/css/66.1ff4022b.chunk.css": "/react/build/static/css/66.1ff4022b.chunk.css",
|
||||
"./static/js/66.afc9f09c.chunk.js": "/react/build/./static/js/66.afc9f09c.chunk.js",
|
||||
"static/css/67.f8123c09.chunk.css": "/react/build/static/css/67.f8123c09.chunk.css",
|
||||
"./static/js/67.59faa180.chunk.js": "/react/build/./static/js/67.59faa180.chunk.js",
|
||||
"./static/js/68.7902a094.chunk.js": "/react/build/./static/js/68.7902a094.chunk.js",
|
||||
"static/css/69.05177416.chunk.css": "/react/build/static/css/69.05177416.chunk.css",
|
||||
"./static/js/69.c59f6352.chunk.js": "/react/build/./static/js/69.c59f6352.chunk.js",
|
||||
"static/css/70.520bfea6.chunk.css": "/react/build/static/css/70.520bfea6.chunk.css",
|
||||
"./static/js/70.53ffff10.chunk.js": "/react/build/./static/js/70.53ffff10.chunk.js",
|
||||
"static/css/71.a5678b8f.chunk.css": "/react/build/static/css/71.a5678b8f.chunk.css",
|
||||
"./static/js/71.83e736e7.chunk.js": "/react/build/./static/js/71.83e736e7.chunk.js",
|
||||
"static/css/72.9d206204.chunk.css": "/react/build/static/css/72.9d206204.chunk.css",
|
||||
"./static/js/72.a7cc2a03.chunk.js": "/react/build/./static/js/72.a7cc2a03.chunk.js",
|
||||
"./static/js/73.bc81d326.chunk.js": "/react/build/./static/js/73.bc81d326.chunk.js",
|
||||
"static/css/74.ea97577b.chunk.css": "/react/build/static/css/74.ea97577b.chunk.css",
|
||||
"./static/js/74.b4295353.chunk.js": "/react/build/./static/js/74.b4295353.chunk.js",
|
||||
"static/css/75.2cfa3592.chunk.css": "/react/build/static/css/75.2cfa3592.chunk.css",
|
||||
"./static/js/75.6f46e072.chunk.js": "/react/build/./static/js/75.6f46e072.chunk.js",
|
||||
"static/css/76.b2109eb4.chunk.css": "/react/build/static/css/76.b2109eb4.chunk.css",
|
||||
"./static/js/76.d42f3d17.chunk.js": "/react/build/./static/js/76.d42f3d17.chunk.js",
|
||||
"static/css/77.1819b82d.chunk.css": "/react/build/static/css/77.1819b82d.chunk.css",
|
||||
"./static/js/77.fe5da44a.chunk.js": "/react/build/./static/js/77.fe5da44a.chunk.js",
|
||||
"static/css/78.61b37499.chunk.css": "/react/build/static/css/78.61b37499.chunk.css",
|
||||
"./static/js/78.ce83ec22.chunk.js": "/react/build/./static/js/78.ce83ec22.chunk.js",
|
||||
"static/css/79.61b37499.chunk.css": "/react/build/static/css/79.61b37499.chunk.css",
|
||||
"./static/js/79.5342dbfc.chunk.js": "/react/build/./static/js/79.5342dbfc.chunk.js",
|
||||
"static/css/80.802376aa.chunk.css": "/react/build/static/css/80.802376aa.chunk.css",
|
||||
"./static/js/80.3f5ef3a2.chunk.js": "/react/build/./static/js/80.3f5ef3a2.chunk.js",
|
||||
"static/css/16.d0c774b5.chunk.css": "/react/build/static/css/16.d0c774b5.chunk.css",
|
||||
"./static/js/16.f5587995.chunk.js": "/react/build/./static/js/16.f5587995.chunk.js",
|
||||
"static/css/17.7bd7b9f3.chunk.css": "/react/build/static/css/17.7bd7b9f3.chunk.css",
|
||||
"./static/js/17.deaa743d.chunk.js": "/react/build/./static/js/17.deaa743d.chunk.js",
|
||||
"static/css/18.012aec0d.chunk.css": "/react/build/static/css/18.012aec0d.chunk.css",
|
||||
"./static/js/18.e32fb44a.chunk.js": "/react/build/./static/js/18.e32fb44a.chunk.js",
|
||||
"static/css/19.e5544bad.chunk.css": "/react/build/static/css/19.e5544bad.chunk.css",
|
||||
"./static/js/19.4fd41f28.chunk.js": "/react/build/./static/js/19.4fd41f28.chunk.js",
|
||||
"static/css/20.330fa4e3.chunk.css": "/react/build/static/css/20.330fa4e3.chunk.css",
|
||||
"./static/js/20.ecc2a430.chunk.js": "/react/build/./static/js/20.ecc2a430.chunk.js",
|
||||
"static/css/21.db9266b0.chunk.css": "/react/build/static/css/21.db9266b0.chunk.css",
|
||||
"./static/js/21.bb7cd174.chunk.js": "/react/build/./static/js/21.bb7cd174.chunk.js",
|
||||
"static/css/22.0b7937b6.chunk.css": "/react/build/static/css/22.0b7937b6.chunk.css",
|
||||
"./static/js/22.b6cf24cd.chunk.js": "/react/build/./static/js/22.b6cf24cd.chunk.js",
|
||||
"static/css/23.92df39ea.chunk.css": "/react/build/static/css/23.92df39ea.chunk.css",
|
||||
"./static/js/23.68eb83f5.chunk.js": "/react/build/./static/js/23.68eb83f5.chunk.js",
|
||||
"./static/js/24.df9a463e.chunk.js": "/react/build/./static/js/24.df9a463e.chunk.js",
|
||||
"./static/js/25.a529f43e.chunk.js": "/react/build/./static/js/25.a529f43e.chunk.js",
|
||||
"static/css/26.75aaa133.chunk.css": "/react/build/static/css/26.75aaa133.chunk.css",
|
||||
"./static/js/26.fa022337.chunk.js": "/react/build/./static/js/26.fa022337.chunk.js",
|
||||
"static/css/27.9891cdaa.chunk.css": "/react/build/static/css/27.9891cdaa.chunk.css",
|
||||
"./static/js/27.fc2d3a1f.chunk.js": "/react/build/./static/js/27.fc2d3a1f.chunk.js",
|
||||
"./static/js/28.ed6116f2.chunk.js": "/react/build/./static/js/28.ed6116f2.chunk.js",
|
||||
"static/css/29.93537df9.chunk.css": "/react/build/static/css/29.93537df9.chunk.css",
|
||||
"./static/js/29.d6441045.chunk.js": "/react/build/./static/js/29.d6441045.chunk.js",
|
||||
"static/css/30.33342a61.chunk.css": "/react/build/static/css/30.33342a61.chunk.css",
|
||||
"./static/js/30.883ca83b.chunk.js": "/react/build/./static/js/30.883ca83b.chunk.js",
|
||||
"static/css/31.4ffe335c.chunk.css": "/react/build/static/css/31.4ffe335c.chunk.css",
|
||||
"./static/js/31.750c280e.chunk.js": "/react/build/./static/js/31.750c280e.chunk.js",
|
||||
"static/css/32.ed9fcfe7.chunk.css": "/react/build/static/css/32.ed9fcfe7.chunk.css",
|
||||
"./static/js/32.1e7fc633.chunk.js": "/react/build/./static/js/32.1e7fc633.chunk.js",
|
||||
"static/css/33.1868f004.chunk.css": "/react/build/static/css/33.1868f004.chunk.css",
|
||||
"./static/js/33.ea85fea8.chunk.js": "/react/build/./static/js/33.ea85fea8.chunk.js",
|
||||
"static/css/34.b0c83d65.chunk.css": "/react/build/static/css/34.b0c83d65.chunk.css",
|
||||
"./static/js/34.cf9cb12d.chunk.js": "/react/build/./static/js/34.cf9cb12d.chunk.js",
|
||||
"./static/js/35.671a8fbb.chunk.js": "/react/build/./static/js/35.671a8fbb.chunk.js",
|
||||
"static/css/36.88cc3b5e.chunk.css": "/react/build/static/css/36.88cc3b5e.chunk.css",
|
||||
"./static/js/36.55c48284.chunk.js": "/react/build/./static/js/36.55c48284.chunk.js",
|
||||
"static/css/37.88cc3b5e.chunk.css": "/react/build/static/css/37.88cc3b5e.chunk.css",
|
||||
"./static/js/37.297dfdc5.chunk.js": "/react/build/./static/js/37.297dfdc5.chunk.js",
|
||||
"static/css/38.88cc3b5e.chunk.css": "/react/build/static/css/38.88cc3b5e.chunk.css",
|
||||
"./static/js/38.23688a87.chunk.js": "/react/build/./static/js/38.23688a87.chunk.js",
|
||||
"static/css/39.5c81fe74.chunk.css": "/react/build/static/css/39.5c81fe74.chunk.css",
|
||||
"./static/js/39.7fd250d3.chunk.js": "/react/build/./static/js/39.7fd250d3.chunk.js",
|
||||
"./static/js/40.446027b0.chunk.js": "/react/build/./static/js/40.446027b0.chunk.js",
|
||||
"static/css/41.080d6958.chunk.css": "/react/build/static/css/41.080d6958.chunk.css",
|
||||
"./static/js/41.107c3622.chunk.js": "/react/build/./static/js/41.107c3622.chunk.js",
|
||||
"static/css/42.b299cb62.chunk.css": "/react/build/static/css/42.b299cb62.chunk.css",
|
||||
"./static/js/42.0340c68c.chunk.js": "/react/build/./static/js/42.0340c68c.chunk.js",
|
||||
"./static/js/43.30765c77.chunk.js": "/react/build/./static/js/43.30765c77.chunk.js",
|
||||
"./static/js/44.6d29f257.chunk.js": "/react/build/./static/js/44.6d29f257.chunk.js",
|
||||
"static/css/45.4f215d24.chunk.css": "/react/build/static/css/45.4f215d24.chunk.css",
|
||||
"./static/js/45.dfb39cec.chunk.js": "/react/build/./static/js/45.dfb39cec.chunk.js",
|
||||
"static/css/46.05cdcfdb.chunk.css": "/react/build/static/css/46.05cdcfdb.chunk.css",
|
||||
"./static/js/46.642919a0.chunk.js": "/react/build/./static/js/46.642919a0.chunk.js",
|
||||
"static/css/47.e8001192.chunk.css": "/react/build/static/css/47.e8001192.chunk.css",
|
||||
"./static/js/47.f10f966d.chunk.js": "/react/build/./static/js/47.f10f966d.chunk.js",
|
||||
"static/css/48.0379bdda.chunk.css": "/react/build/static/css/48.0379bdda.chunk.css",
|
||||
"./static/js/48.9755c57d.chunk.js": "/react/build/./static/js/48.9755c57d.chunk.js",
|
||||
"static/css/49.535eede4.chunk.css": "/react/build/static/css/49.535eede4.chunk.css",
|
||||
"./static/js/49.84b70947.chunk.js": "/react/build/./static/js/49.84b70947.chunk.js",
|
||||
"static/css/50.32ee9943.chunk.css": "/react/build/static/css/50.32ee9943.chunk.css",
|
||||
"./static/js/50.e0e6fc22.chunk.js": "/react/build/./static/js/50.e0e6fc22.chunk.js",
|
||||
"static/css/51.67a9b0d6.chunk.css": "/react/build/static/css/51.67a9b0d6.chunk.css",
|
||||
"./static/js/51.74dc3aee.chunk.js": "/react/build/./static/js/51.74dc3aee.chunk.js",
|
||||
"static/css/52.75d3df4f.chunk.css": "/react/build/static/css/52.75d3df4f.chunk.css",
|
||||
"./static/js/52.2db0cda9.chunk.js": "/react/build/./static/js/52.2db0cda9.chunk.js",
|
||||
"static/css/53.f7d2a825.chunk.css": "/react/build/static/css/53.f7d2a825.chunk.css",
|
||||
"./static/js/53.6c48cfaf.chunk.js": "/react/build/./static/js/53.6c48cfaf.chunk.js",
|
||||
"static/css/54.1d3b7a8d.chunk.css": "/react/build/static/css/54.1d3b7a8d.chunk.css",
|
||||
"./static/js/54.ee1deb94.chunk.js": "/react/build/./static/js/54.ee1deb94.chunk.js",
|
||||
"static/css/55.55132a20.chunk.css": "/react/build/static/css/55.55132a20.chunk.css",
|
||||
"./static/js/55.2d70fec6.chunk.js": "/react/build/./static/js/55.2d70fec6.chunk.js",
|
||||
"static/css/56.1ff4022b.chunk.css": "/react/build/static/css/56.1ff4022b.chunk.css",
|
||||
"./static/js/56.1d16b6e6.chunk.js": "/react/build/./static/js/56.1d16b6e6.chunk.js",
|
||||
"static/css/57.f8123c09.chunk.css": "/react/build/static/css/57.f8123c09.chunk.css",
|
||||
"./static/js/57.d364dbd1.chunk.js": "/react/build/./static/js/57.d364dbd1.chunk.js",
|
||||
"static/css/58.90f11182.chunk.css": "/react/build/static/css/58.90f11182.chunk.css",
|
||||
"./static/js/58.32f00509.chunk.js": "/react/build/./static/js/58.32f00509.chunk.js",
|
||||
"./static/js/59.3ead551c.chunk.js": "/react/build/./static/js/59.3ead551c.chunk.js",
|
||||
"static/css/60.520bfea6.chunk.css": "/react/build/static/css/60.520bfea6.chunk.css",
|
||||
"./static/js/60.096696d0.chunk.js": "/react/build/./static/js/60.096696d0.chunk.js",
|
||||
"static/css/61.a5678b8f.chunk.css": "/react/build/static/css/61.a5678b8f.chunk.css",
|
||||
"./static/js/61.106f2931.chunk.js": "/react/build/./static/js/61.106f2931.chunk.js",
|
||||
"static/css/62.9d206204.chunk.css": "/react/build/static/css/62.9d206204.chunk.css",
|
||||
"./static/js/62.0c2fc9f5.chunk.js": "/react/build/./static/js/62.0c2fc9f5.chunk.js",
|
||||
"./static/js/63.27779735.chunk.js": "/react/build/./static/js/63.27779735.chunk.js",
|
||||
"static/css/64.ea97577b.chunk.css": "/react/build/static/css/64.ea97577b.chunk.css",
|
||||
"./static/js/64.168b2757.chunk.js": "/react/build/./static/js/64.168b2757.chunk.js",
|
||||
"static/css/65.2cfa3592.chunk.css": "/react/build/static/css/65.2cfa3592.chunk.css",
|
||||
"./static/js/65.bb731ca7.chunk.js": "/react/build/./static/js/65.bb731ca7.chunk.js",
|
||||
"static/css/66.b2109eb4.chunk.css": "/react/build/static/css/66.b2109eb4.chunk.css",
|
||||
"./static/js/66.02a9e4c3.chunk.js": "/react/build/./static/js/66.02a9e4c3.chunk.js",
|
||||
"static/css/67.b26a06ba.chunk.css": "/react/build/static/css/67.b26a06ba.chunk.css",
|
||||
"./static/js/67.c06e0c2a.chunk.js": "/react/build/./static/js/67.c06e0c2a.chunk.js",
|
||||
"static/css/68.61b37499.chunk.css": "/react/build/static/css/68.61b37499.chunk.css",
|
||||
"./static/js/68.d1c952c6.chunk.js": "/react/build/./static/js/68.d1c952c6.chunk.js",
|
||||
"static/css/69.61b37499.chunk.css": "/react/build/static/css/69.61b37499.chunk.css",
|
||||
"./static/js/69.ad0246bd.chunk.js": "/react/build/./static/js/69.ad0246bd.chunk.js",
|
||||
"static/css/70.802376aa.chunk.css": "/react/build/static/css/70.802376aa.chunk.css",
|
||||
"./static/js/70.0cefe909.chunk.js": "/react/build/./static/js/70.0cefe909.chunk.js",
|
||||
"static/css/71.1926e8da.chunk.css": "/react/build/static/css/71.1926e8da.chunk.css",
|
||||
"./static/js/71.8d37ad43.chunk.js": "/react/build/./static/js/71.8d37ad43.chunk.js",
|
||||
"static/css/72.72690062.chunk.css": "/react/build/static/css/72.72690062.chunk.css",
|
||||
"./static/js/72.8066a00e.chunk.js": "/react/build/./static/js/72.8066a00e.chunk.js",
|
||||
"static/css/73.4054f41b.chunk.css": "/react/build/static/css/73.4054f41b.chunk.css",
|
||||
"./static/js/73.16a53e3b.chunk.js": "/react/build/./static/js/73.16a53e3b.chunk.js",
|
||||
"static/css/74.d16cbade.chunk.css": "/react/build/static/css/74.d16cbade.chunk.css",
|
||||
"./static/js/74.d409058a.chunk.js": "/react/build/./static/js/74.d409058a.chunk.js",
|
||||
"static/css/75.131374a7.chunk.css": "/react/build/static/css/75.131374a7.chunk.css",
|
||||
"./static/js/75.fd253f94.chunk.js": "/react/build/./static/js/75.fd253f94.chunk.js",
|
||||
"static/css/76.c2f5b906.chunk.css": "/react/build/static/css/76.c2f5b906.chunk.css",
|
||||
"./static/js/76.691766f4.chunk.js": "/react/build/./static/js/76.691766f4.chunk.js",
|
||||
"static/css/77.fd3fa2e9.chunk.css": "/react/build/static/css/77.fd3fa2e9.chunk.css",
|
||||
"./static/js/77.b84fec71.chunk.js": "/react/build/./static/js/77.b84fec71.chunk.js",
|
||||
"static/css/78.f4de1d43.chunk.css": "/react/build/static/css/78.f4de1d43.chunk.css",
|
||||
"./static/js/78.a8bd2e81.chunk.js": "/react/build/./static/js/78.a8bd2e81.chunk.js",
|
||||
"./static/js/79.8dcee5cb.chunk.js": "/react/build/./static/js/79.8dcee5cb.chunk.js",
|
||||
"static/css/80.45444cfc.chunk.css": "/react/build/static/css/80.45444cfc.chunk.css",
|
||||
"./static/js/80.05713831.chunk.js": "/react/build/./static/js/80.05713831.chunk.js",
|
||||
"static/css/81.92df39ea.chunk.css": "/react/build/static/css/81.92df39ea.chunk.css",
|
||||
"./static/js/81.ba015d38.chunk.js": "/react/build/./static/js/81.ba015d38.chunk.js",
|
||||
"static/css/82.1926e8da.chunk.css": "/react/build/static/css/82.1926e8da.chunk.css",
|
||||
"./static/js/82.a1a65dfb.chunk.js": "/react/build/./static/js/82.a1a65dfb.chunk.js",
|
||||
"static/css/83.72690062.chunk.css": "/react/build/static/css/83.72690062.chunk.css",
|
||||
"./static/js/83.0887adae.chunk.js": "/react/build/./static/js/83.0887adae.chunk.js",
|
||||
"./static/js/84.94bfd72f.chunk.js": "/react/build/./static/js/84.94bfd72f.chunk.js",
|
||||
"static/css/85.4054f41b.chunk.css": "/react/build/static/css/85.4054f41b.chunk.css",
|
||||
"./static/js/85.d6f1cefb.chunk.js": "/react/build/./static/js/85.d6f1cefb.chunk.js",
|
||||
"static/css/86.f4de1d43.chunk.css": "/react/build/static/css/86.f4de1d43.chunk.css",
|
||||
"./static/js/86.50073a17.chunk.js": "/react/build/./static/js/86.50073a17.chunk.js",
|
||||
"static/css/87.d16cbade.chunk.css": "/react/build/static/css/87.d16cbade.chunk.css",
|
||||
"./static/js/87.b8390d79.chunk.js": "/react/build/./static/js/87.b8390d79.chunk.js",
|
||||
"static/css/88.2276e27f.chunk.css": "/react/build/static/css/88.2276e27f.chunk.css",
|
||||
"./static/js/88.dea70be9.chunk.js": "/react/build/./static/js/88.dea70be9.chunk.js",
|
||||
"static/css/89.131374a7.chunk.css": "/react/build/static/css/89.131374a7.chunk.css",
|
||||
"./static/js/89.291ce5a8.chunk.js": "/react/build/./static/js/89.291ce5a8.chunk.js",
|
||||
"static/css/90.c2f5b906.chunk.css": "/react/build/static/css/90.c2f5b906.chunk.css",
|
||||
"./static/js/90.d3038559.chunk.js": "/react/build/./static/js/90.d3038559.chunk.js",
|
||||
"static/css/91.fd3fa2e9.chunk.css": "/react/build/static/css/91.fd3fa2e9.chunk.css",
|
||||
"./static/js/91.f18b6c1b.chunk.js": "/react/build/./static/js/91.f18b6c1b.chunk.js",
|
||||
"./static/js/92.3ad04ab0.chunk.js": "/react/build/./static/js/92.3ad04ab0.chunk.js",
|
||||
"static/css/93.45444cfc.chunk.css": "/react/build/static/css/93.45444cfc.chunk.css",
|
||||
"./static/js/93.65332b80.chunk.js": "/react/build/./static/js/93.65332b80.chunk.js",
|
||||
"static/css/94.92df39ea.chunk.css": "/react/build/static/css/94.92df39ea.chunk.css",
|
||||
"./static/js/94.2eb46321.chunk.js": "/react/build/./static/js/94.2eb46321.chunk.js",
|
||||
"static/css/95.92df39ea.chunk.css": "/react/build/static/css/95.92df39ea.chunk.css",
|
||||
"./static/js/95.6a4663c6.chunk.js": "/react/build/./static/js/95.6a4663c6.chunk.js",
|
||||
"./static/js/96.33c3003a.chunk.js": "/react/build/./static/js/96.33c3003a.chunk.js",
|
||||
"./static/js/97.4d58f6ed.chunk.js": "/react/build/./static/js/97.4d58f6ed.chunk.js",
|
||||
"./static/js/98.cf8af97d.chunk.js": "/react/build/./static/js/98.cf8af97d.chunk.js",
|
||||
"static/css/99.3598c90d.chunk.css": "/react/build/static/css/99.3598c90d.chunk.css",
|
||||
"./static/js/99.7a29bea0.chunk.js": "/react/build/./static/js/99.7a29bea0.chunk.js",
|
||||
"static/css/100.b6f629c2.chunk.css": "/react/build/static/css/100.b6f629c2.chunk.css",
|
||||
"./static/js/100.003304fc.chunk.js": "/react/build/./static/js/100.003304fc.chunk.js",
|
||||
"static/css/101.632d7855.chunk.css": "/react/build/static/css/101.632d7855.chunk.css",
|
||||
"./static/js/101.6fb0ee37.chunk.js": "/react/build/./static/js/101.6fb0ee37.chunk.js",
|
||||
"static/css/102.f243baca.chunk.css": "/react/build/static/css/102.f243baca.chunk.css",
|
||||
"./static/js/102.1ba8c377.chunk.js": "/react/build/./static/js/102.1ba8c377.chunk.js",
|
||||
"static/css/103.e2a8a600.chunk.css": "/react/build/static/css/103.e2a8a600.chunk.css",
|
||||
"./static/js/103.aeee29a1.chunk.js": "/react/build/./static/js/103.aeee29a1.chunk.js",
|
||||
"static/css/104.9d206204.chunk.css": "/react/build/static/css/104.9d206204.chunk.css",
|
||||
"./static/js/104.b122bfac.chunk.js": "/react/build/./static/js/104.b122bfac.chunk.js",
|
||||
"static/css/105.9d206204.chunk.css": "/react/build/static/css/105.9d206204.chunk.css",
|
||||
"./static/js/105.acdf0245.chunk.js": "/react/build/./static/js/105.acdf0245.chunk.js",
|
||||
"static/css/106.92df39ea.chunk.css": "/react/build/static/css/106.92df39ea.chunk.css",
|
||||
"./static/js/106.6ddaec4e.chunk.js": "/react/build/./static/js/106.6ddaec4e.chunk.js",
|
||||
"static/css/107.92df39ea.chunk.css": "/react/build/static/css/107.92df39ea.chunk.css",
|
||||
"./static/js/107.b74153ec.chunk.js": "/react/build/./static/js/107.b74153ec.chunk.js",
|
||||
"./static/js/108.a0a22f46.chunk.js": "/react/build/./static/js/108.a0a22f46.chunk.js",
|
||||
"static/css/109.11a04942.chunk.css": "/react/build/static/css/109.11a04942.chunk.css",
|
||||
"./static/js/109.0b0b354a.chunk.js": "/react/build/./static/js/109.0b0b354a.chunk.js",
|
||||
"static/css/110.9d206204.chunk.css": "/react/build/static/css/110.9d206204.chunk.css",
|
||||
"./static/js/110.67808dac.chunk.js": "/react/build/./static/js/110.67808dac.chunk.js",
|
||||
"./static/js/111.dbfb317d.chunk.js": "/react/build/./static/js/111.dbfb317d.chunk.js",
|
||||
"./static/js/112.a09bbdae.chunk.js": "/react/build/./static/js/112.a09bbdae.chunk.js",
|
||||
"./static/js/113.2e4a5519.chunk.js": "/react/build/./static/js/113.2e4a5519.chunk.js",
|
||||
"./static/js/114.2a2238be.chunk.js": "/react/build/./static/js/114.2a2238be.chunk.js",
|
||||
"static/css/115.3edde0c7.chunk.css": "/react/build/static/css/115.3edde0c7.chunk.css",
|
||||
"./static/js/115.b47d0776.chunk.js": "/react/build/./static/js/115.b47d0776.chunk.js",
|
||||
"./static/js/81.9e9bf3fd.chunk.js": "/react/build/./static/js/81.9e9bf3fd.chunk.js",
|
||||
"static/css/82.92df39ea.chunk.css": "/react/build/static/css/82.92df39ea.chunk.css",
|
||||
"./static/js/82.fd712587.chunk.js": "/react/build/./static/js/82.fd712587.chunk.js",
|
||||
"./static/js/83.b9f283c4.chunk.js": "/react/build/./static/js/83.b9f283c4.chunk.js",
|
||||
"./static/js/84.9bb7165f.chunk.js": "/react/build/./static/js/84.9bb7165f.chunk.js",
|
||||
"./static/js/85.bfbe6043.chunk.js": "/react/build/./static/js/85.bfbe6043.chunk.js",
|
||||
"static/css/86.a8f06a40.chunk.css": "/react/build/static/css/86.a8f06a40.chunk.css",
|
||||
"./static/js/86.2f9efa27.chunk.js": "/react/build/./static/js/86.2f9efa27.chunk.js",
|
||||
"static/css/87.b6f629c2.chunk.css": "/react/build/static/css/87.b6f629c2.chunk.css",
|
||||
"./static/js/87.e348ac7d.chunk.js": "/react/build/./static/js/87.e348ac7d.chunk.js",
|
||||
"static/css/88.632d7855.chunk.css": "/react/build/static/css/88.632d7855.chunk.css",
|
||||
"./static/js/88.6a467b5d.chunk.js": "/react/build/./static/js/88.6a467b5d.chunk.js",
|
||||
"static/css/89.f243baca.chunk.css": "/react/build/static/css/89.f243baca.chunk.css",
|
||||
"./static/js/89.b2ac706b.chunk.js": "/react/build/./static/js/89.b2ac706b.chunk.js",
|
||||
"static/css/90.3433735d.chunk.css": "/react/build/static/css/90.3433735d.chunk.css",
|
||||
"./static/js/90.d1263828.chunk.js": "/react/build/./static/js/90.d1263828.chunk.js",
|
||||
"static/css/91.9d206204.chunk.css": "/react/build/static/css/91.9d206204.chunk.css",
|
||||
"./static/js/91.b7150f8a.chunk.js": "/react/build/./static/js/91.b7150f8a.chunk.js",
|
||||
"static/css/92.9d206204.chunk.css": "/react/build/static/css/92.9d206204.chunk.css",
|
||||
"./static/js/92.eb12337b.chunk.js": "/react/build/./static/js/92.eb12337b.chunk.js",
|
||||
"static/css/93.92df39ea.chunk.css": "/react/build/static/css/93.92df39ea.chunk.css",
|
||||
"./static/js/93.6098cd94.chunk.js": "/react/build/./static/js/93.6098cd94.chunk.js",
|
||||
"./static/js/94.590a09ed.chunk.js": "/react/build/./static/js/94.590a09ed.chunk.js",
|
||||
"static/css/95.11a04942.chunk.css": "/react/build/static/css/95.11a04942.chunk.css",
|
||||
"./static/js/95.fa090474.chunk.js": "/react/build/./static/js/95.fa090474.chunk.js",
|
||||
"static/css/96.9d206204.chunk.css": "/react/build/static/css/96.9d206204.chunk.css",
|
||||
"./static/js/96.58181535.chunk.js": "/react/build/./static/js/96.58181535.chunk.js",
|
||||
"./static/js/97.ecf134b1.chunk.js": "/react/build/./static/js/97.ecf134b1.chunk.js",
|
||||
"./static/js/98.d0eedbe0.chunk.js": "/react/build/./static/js/98.d0eedbe0.chunk.js",
|
||||
"./static/js/99.3ec78a01.chunk.js": "/react/build/./static/js/99.3ec78a01.chunk.js",
|
||||
"./static/js/100.afd86b44.chunk.js": "/react/build/./static/js/100.afd86b44.chunk.js",
|
||||
"./static/js/101.f94be57e.chunk.js": "/react/build/./static/js/101.f94be57e.chunk.js",
|
||||
"static/css/102.3edde0c7.chunk.css": "/react/build/static/css/102.3edde0c7.chunk.css",
|
||||
"./static/js/102.b599d68b.chunk.js": "/react/build/./static/js/102.b599d68b.chunk.js",
|
||||
"static/css/103.93537df9.chunk.css": "/react/build/static/css/103.93537df9.chunk.css",
|
||||
"./static/js/103.37711bf4.chunk.js": "/react/build/./static/js/103.37711bf4.chunk.js",
|
||||
"./static/js/104.a849ee5d.chunk.js": "/react/build/./static/js/104.a849ee5d.chunk.js",
|
||||
"static/css/105.18309b6c.chunk.css": "/react/build/static/css/105.18309b6c.chunk.css",
|
||||
"./static/js/105.834e0f24.chunk.js": "/react/build/./static/js/105.834e0f24.chunk.js",
|
||||
"./static/js/106.581458cf.chunk.js": "/react/build/./static/js/106.581458cf.chunk.js",
|
||||
"./static/js/107.61313aba.chunk.js": "/react/build/./static/js/107.61313aba.chunk.js",
|
||||
"./static/js/108.7162ad9d.chunk.js": "/react/build/./static/js/108.7162ad9d.chunk.js",
|
||||
"./static/js/109.b6b83b49.chunk.js": "/react/build/./static/js/109.b6b83b49.chunk.js",
|
||||
"static/css/110.1ff4022b.chunk.css": "/react/build/static/css/110.1ff4022b.chunk.css",
|
||||
"./static/js/110.19c181c9.chunk.js": "/react/build/./static/js/110.19c181c9.chunk.js",
|
||||
"static/css/111.acf78e2c.chunk.css": "/react/build/static/css/111.acf78e2c.chunk.css",
|
||||
"./static/js/111.fc28ee3c.chunk.js": "/react/build/./static/js/111.fc28ee3c.chunk.js",
|
||||
"static/css/112.28bf6b3d.chunk.css": "/react/build/static/css/112.28bf6b3d.chunk.css",
|
||||
"./static/js/112.fe75aa10.chunk.js": "/react/build/./static/js/112.fe75aa10.chunk.js",
|
||||
"static/css/113.2d9ce95a.chunk.css": "/react/build/static/css/113.2d9ce95a.chunk.css",
|
||||
"./static/js/113.6e2f7811.chunk.js": "/react/build/./static/js/113.6e2f7811.chunk.js",
|
||||
"static/css/114.93537df9.chunk.css": "/react/build/static/css/114.93537df9.chunk.css",
|
||||
"./static/js/114.36172f9e.chunk.js": "/react/build/./static/js/114.36172f9e.chunk.js",
|
||||
"static/css/115.93537df9.chunk.css": "/react/build/static/css/115.93537df9.chunk.css",
|
||||
"./static/js/115.d1207bdb.chunk.js": "/react/build/./static/js/115.d1207bdb.chunk.js",
|
||||
"static/css/116.93537df9.chunk.css": "/react/build/static/css/116.93537df9.chunk.css",
|
||||
"./static/js/116.b81ed987.chunk.js": "/react/build/./static/js/116.b81ed987.chunk.js",
|
||||
"./static/js/117.7fff8d1f.chunk.js": "/react/build/./static/js/117.7fff8d1f.chunk.js",
|
||||
"./static/js/118.90196e17.chunk.js": "/react/build/./static/js/118.90196e17.chunk.js",
|
||||
"./static/js/119.8ca783c3.chunk.js": "/react/build/./static/js/119.8ca783c3.chunk.js",
|
||||
"./static/js/120.dfad4f45.chunk.js": "/react/build/./static/js/120.dfad4f45.chunk.js",
|
||||
"./static/js/121.7e4e15f6.chunk.js": "/react/build/./static/js/121.7e4e15f6.chunk.js",
|
||||
"static/css/122.1ff4022b.chunk.css": "/react/build/static/css/122.1ff4022b.chunk.css",
|
||||
"./static/js/122.b9661dd4.chunk.js": "/react/build/./static/js/122.b9661dd4.chunk.js",
|
||||
"static/css/123.acf78e2c.chunk.css": "/react/build/static/css/123.acf78e2c.chunk.css",
|
||||
"./static/js/123.2b4bea2a.chunk.js": "/react/build/./static/js/123.2b4bea2a.chunk.js",
|
||||
"static/css/124.28bf6b3d.chunk.css": "/react/build/static/css/124.28bf6b3d.chunk.css",
|
||||
"./static/js/124.0efba3cd.chunk.js": "/react/build/./static/js/124.0efba3cd.chunk.js",
|
||||
"static/css/125.af9850ad.chunk.css": "/react/build/static/css/125.af9850ad.chunk.css",
|
||||
"./static/js/125.c9bdba80.chunk.js": "/react/build/./static/js/125.c9bdba80.chunk.js",
|
||||
"static/css/126.93537df9.chunk.css": "/react/build/static/css/126.93537df9.chunk.css",
|
||||
"./static/js/126.1e1c6b0d.chunk.js": "/react/build/./static/js/126.1e1c6b0d.chunk.js",
|
||||
"static/css/127.93537df9.chunk.css": "/react/build/static/css/127.93537df9.chunk.css",
|
||||
"./static/js/127.ce9a385e.chunk.js": "/react/build/./static/js/127.ce9a385e.chunk.js",
|
||||
"static/css/128.93537df9.chunk.css": "/react/build/static/css/128.93537df9.chunk.css",
|
||||
"./static/js/128.7c3345ad.chunk.js": "/react/build/./static/js/128.7c3345ad.chunk.js",
|
||||
"static/css/129.f2060fe7.chunk.css": "/react/build/static/css/129.f2060fe7.chunk.css",
|
||||
"./static/js/129.e53ef67f.chunk.js": "/react/build/./static/js/129.e53ef67f.chunk.js",
|
||||
"static/css/130.0485185f.chunk.css": "/react/build/static/css/130.0485185f.chunk.css",
|
||||
"./static/js/130.0612b9b9.chunk.js": "/react/build/./static/js/130.0612b9b9.chunk.js",
|
||||
"static/css/131.9d206204.chunk.css": "/react/build/static/css/131.9d206204.chunk.css",
|
||||
"./static/js/131.4f4d8f60.chunk.js": "/react/build/./static/js/131.4f4d8f60.chunk.js",
|
||||
"./static/js/132.34a2259c.chunk.js": "/react/build/./static/js/132.34a2259c.chunk.js",
|
||||
"./static/js/133.85d8a606.chunk.js": "/react/build/./static/js/133.85d8a606.chunk.js",
|
||||
"./static/js/134.c846ec39.chunk.js": "/react/build/./static/js/134.c846ec39.chunk.js",
|
||||
"./static/js/135.42dc9e35.chunk.js": "/react/build/./static/js/135.42dc9e35.chunk.js",
|
||||
"./static/js/136.e713bbda.chunk.js": "/react/build/./static/js/136.e713bbda.chunk.js",
|
||||
"./static/js/137.9a584547.chunk.js": "/react/build/./static/js/137.9a584547.chunk.js",
|
||||
"./static/js/138.30c9bf3e.chunk.js": "/react/build/./static/js/138.30c9bf3e.chunk.js",
|
||||
"./static/js/139.471b727e.chunk.js": "/react/build/./static/js/139.471b727e.chunk.js",
|
||||
"./static/js/140.2cf678ec.chunk.js": "/react/build/./static/js/140.2cf678ec.chunk.js",
|
||||
"./static/js/141.0c37428d.chunk.js": "/react/build/./static/js/141.0c37428d.chunk.js",
|
||||
"./static/js/142.90447ba1.chunk.js": "/react/build/./static/js/142.90447ba1.chunk.js",
|
||||
"./static/js/143.a728fd15.chunk.js": "/react/build/./static/js/143.a728fd15.chunk.js",
|
||||
"./static/js/144.da3d7cb2.chunk.js": "/react/build/./static/js/144.da3d7cb2.chunk.js",
|
||||
"./static/js/145.5ff39369.chunk.js": "/react/build/./static/js/145.5ff39369.chunk.js",
|
||||
"./static/js/146.9055d194.chunk.js": "/react/build/./static/js/146.9055d194.chunk.js",
|
||||
"./static/js/147.67ae26a3.chunk.js": "/react/build/./static/js/147.67ae26a3.chunk.js",
|
||||
"./static/js/148.469d55ff.chunk.js": "/react/build/./static/js/148.469d55ff.chunk.js",
|
||||
"./static/js/149.82ddc723.chunk.js": "/react/build/./static/js/149.82ddc723.chunk.js",
|
||||
"./static/js/150.d9806ad6.chunk.js": "/react/build/./static/js/150.d9806ad6.chunk.js",
|
||||
"./static/js/151.aa27b140.chunk.js": "/react/build/./static/js/151.aa27b140.chunk.js",
|
||||
"./static/js/152.f27906a3.chunk.js": "/react/build/./static/js/152.f27906a3.chunk.js",
|
||||
"./static/js/153.a95c448d.chunk.js": "/react/build/./static/js/153.a95c448d.chunk.js",
|
||||
"./static/js/154.75dff73a.chunk.js": "/react/build/./static/js/154.75dff73a.chunk.js",
|
||||
"./static/js/155.bf7b3b90.chunk.js": "/react/build/./static/js/155.bf7b3b90.chunk.js",
|
||||
"./static/js/156.a5d3cd4c.chunk.js": "/react/build/./static/js/156.a5d3cd4c.chunk.js",
|
||||
"./static/js/157.3bf78dcc.chunk.js": "/react/build/./static/js/157.3bf78dcc.chunk.js",
|
||||
"./static/js/158.2ac8f8b0.chunk.js": "/react/build/./static/js/158.2ac8f8b0.chunk.js",
|
||||
"./static/js/159.4c65dad8.chunk.js": "/react/build/./static/js/159.4c65dad8.chunk.js",
|
||||
"./static/js/160.8fe98dbd.chunk.js": "/react/build/./static/js/160.8fe98dbd.chunk.js",
|
||||
"./static/js/161.81b3dc53.chunk.js": "/react/build/./static/js/161.81b3dc53.chunk.js",
|
||||
"./static/js/162.80cba987.chunk.js": "/react/build/./static/js/162.80cba987.chunk.js",
|
||||
"./static/js/163.431c740e.chunk.js": "/react/build/./static/js/163.431c740e.chunk.js",
|
||||
"./static/js/164.9fe89370.chunk.js": "/react/build/./static/js/164.9fe89370.chunk.js",
|
||||
"./static/js/165.6a20768f.chunk.js": "/react/build/./static/js/165.6a20768f.chunk.js",
|
||||
"./static/js/166.ced1b182.chunk.js": "/react/build/./static/js/166.ced1b182.chunk.js",
|
||||
"./static/js/167.49b56732.chunk.js": "/react/build/./static/js/167.49b56732.chunk.js",
|
||||
"./static/js/168.b9bf1e06.chunk.js": "/react/build/./static/js/168.b9bf1e06.chunk.js",
|
||||
"./static/js/169.d85c0071.chunk.js": "/react/build/./static/js/169.d85c0071.chunk.js",
|
||||
"./static/js/170.fc532980.chunk.js": "/react/build/./static/js/170.fc532980.chunk.js",
|
||||
"./static/js/171.b062dc4f.chunk.js": "/react/build/./static/js/171.b062dc4f.chunk.js",
|
||||
"./static/js/172.10fae3a9.chunk.js": "/react/build/./static/js/172.10fae3a9.chunk.js",
|
||||
"./static/js/173.9252f343.chunk.js": "/react/build/./static/js/173.9252f343.chunk.js",
|
||||
"./static/js/174.3a5ed8e6.chunk.js": "/react/build/./static/js/174.3a5ed8e6.chunk.js",
|
||||
"./static/js/175.9babcf3f.chunk.js": "/react/build/./static/js/175.9babcf3f.chunk.js",
|
||||
"./static/js/176.a70acaca.chunk.js": "/react/build/./static/js/176.a70acaca.chunk.js",
|
||||
"./static/js/177.dbfa5850.chunk.js": "/react/build/./static/js/177.dbfa5850.chunk.js",
|
||||
"./static/js/178.eed56d06.chunk.js": "/react/build/./static/js/178.eed56d06.chunk.js",
|
||||
"./static/js/179.6b354d9a.chunk.js": "/react/build/./static/js/179.6b354d9a.chunk.js",
|
||||
"./static/js/180.af942319.chunk.js": "/react/build/./static/js/180.af942319.chunk.js",
|
||||
"./static/js/181.70e499f1.chunk.js": "/react/build/./static/js/181.70e499f1.chunk.js",
|
||||
"./static/js/182.e7c64d3e.chunk.js": "/react/build/./static/js/182.e7c64d3e.chunk.js",
|
||||
"./static/js/183.093ee74f.chunk.js": "/react/build/./static/js/183.093ee74f.chunk.js",
|
||||
"./static/js/184.7ed09e68.chunk.js": "/react/build/./static/js/184.7ed09e68.chunk.js",
|
||||
"./static/js/185.e07e87d8.chunk.js": "/react/build/./static/js/185.e07e87d8.chunk.js",
|
||||
"./static/js/186.609d9b25.chunk.js": "/react/build/./static/js/186.609d9b25.chunk.js",
|
||||
"./static/js/187.b08cc870.chunk.js": "/react/build/./static/js/187.b08cc870.chunk.js",
|
||||
"./static/js/188.9d3f7b7c.chunk.js": "/react/build/./static/js/188.9d3f7b7c.chunk.js",
|
||||
"./static/js/189.3fbef684.chunk.js": "/react/build/./static/js/189.3fbef684.chunk.js",
|
||||
"./static/js/190.95b861fa.chunk.js": "/react/build/./static/js/190.95b861fa.chunk.js",
|
||||
"./static/js/191.dd01864e.chunk.js": "/react/build/./static/js/191.dd01864e.chunk.js",
|
||||
"./static/js/192.f1caa1fa.chunk.js": "/react/build/./static/js/192.f1caa1fa.chunk.js",
|
||||
"./static/js/193.bc21c27e.chunk.js": "/react/build/./static/js/193.bc21c27e.chunk.js",
|
||||
"./static/js/194.fdf7dc7d.chunk.js": "/react/build/./static/js/194.fdf7dc7d.chunk.js",
|
||||
"main.css": "/react/build/static/css/main.bdb06a8e.chunk.css",
|
||||
"main.js": "/react/build/./static/js/main.eae036cf.chunk.js",
|
||||
"runtime~main.js": "/react/build/./static/js/runtime~main.cbbbfc02.js",
|
||||
"./static/js/147.67ae26a3.chunk.js.LICENSE.txt": "/react/build/./static/js/147.67ae26a3.chunk.js.LICENSE.txt",
|
||||
"./static/js/189.3fbef684.chunk.js.LICENSE.txt": "/react/build/./static/js/189.3fbef684.chunk.js.LICENSE.txt",
|
||||
"./static/js/116.f43de2f8.chunk.js": "/react/build/./static/js/116.f43de2f8.chunk.js",
|
||||
"static/css/117.f2060fe7.chunk.css": "/react/build/static/css/117.f2060fe7.chunk.css",
|
||||
"./static/js/117.11936524.chunk.js": "/react/build/./static/js/117.11936524.chunk.js",
|
||||
"static/css/118.7d2667aa.chunk.css": "/react/build/static/css/118.7d2667aa.chunk.css",
|
||||
"./static/js/118.3bad926a.chunk.js": "/react/build/./static/js/118.3bad926a.chunk.js",
|
||||
"static/css/119.9d206204.chunk.css": "/react/build/static/css/119.9d206204.chunk.css",
|
||||
"./static/js/119.d6089266.chunk.js": "/react/build/./static/js/119.d6089266.chunk.js",
|
||||
"./static/js/120.0b5693b9.chunk.js": "/react/build/./static/js/120.0b5693b9.chunk.js",
|
||||
"./static/js/121.5b1672a5.chunk.js": "/react/build/./static/js/121.5b1672a5.chunk.js",
|
||||
"./static/js/122.cf4115ae.chunk.js": "/react/build/./static/js/122.cf4115ae.chunk.js",
|
||||
"./static/js/123.1891b573.chunk.js": "/react/build/./static/js/123.1891b573.chunk.js",
|
||||
"./static/js/124.9f4ca700.chunk.js": "/react/build/./static/js/124.9f4ca700.chunk.js",
|
||||
"./static/js/125.7f20b68d.chunk.js": "/react/build/./static/js/125.7f20b68d.chunk.js",
|
||||
"./static/js/126.bee7c937.chunk.js": "/react/build/./static/js/126.bee7c937.chunk.js",
|
||||
"./static/js/127.d073db41.chunk.js": "/react/build/./static/js/127.d073db41.chunk.js",
|
||||
"./static/js/128.878acdba.chunk.js": "/react/build/./static/js/128.878acdba.chunk.js",
|
||||
"./static/js/129.b738aa28.chunk.js": "/react/build/./static/js/129.b738aa28.chunk.js",
|
||||
"./static/js/130.85565d42.chunk.js": "/react/build/./static/js/130.85565d42.chunk.js",
|
||||
"./static/js/131.f0748961.chunk.js": "/react/build/./static/js/131.f0748961.chunk.js",
|
||||
"./static/js/132.3d7bf2f1.chunk.js": "/react/build/./static/js/132.3d7bf2f1.chunk.js",
|
||||
"./static/js/133.751e5873.chunk.js": "/react/build/./static/js/133.751e5873.chunk.js",
|
||||
"./static/js/134.091df8c8.chunk.js": "/react/build/./static/js/134.091df8c8.chunk.js",
|
||||
"./static/js/135.781429cf.chunk.js": "/react/build/./static/js/135.781429cf.chunk.js",
|
||||
"./static/js/136.92778520.chunk.js": "/react/build/./static/js/136.92778520.chunk.js",
|
||||
"./static/js/137.93988170.chunk.js": "/react/build/./static/js/137.93988170.chunk.js",
|
||||
"./static/js/138.44f95a6c.chunk.js": "/react/build/./static/js/138.44f95a6c.chunk.js",
|
||||
"./static/js/139.04825aa2.chunk.js": "/react/build/./static/js/139.04825aa2.chunk.js",
|
||||
"./static/js/140.9300e577.chunk.js": "/react/build/./static/js/140.9300e577.chunk.js",
|
||||
"./static/js/141.7fe85b5c.chunk.js": "/react/build/./static/js/141.7fe85b5c.chunk.js",
|
||||
"./static/js/142.4986be2c.chunk.js": "/react/build/./static/js/142.4986be2c.chunk.js",
|
||||
"./static/js/143.8deca8a8.chunk.js": "/react/build/./static/js/143.8deca8a8.chunk.js",
|
||||
"./static/js/144.e3a19259.chunk.js": "/react/build/./static/js/144.e3a19259.chunk.js",
|
||||
"./static/js/145.11e1109e.chunk.js": "/react/build/./static/js/145.11e1109e.chunk.js",
|
||||
"./static/js/146.88651818.chunk.js": "/react/build/./static/js/146.88651818.chunk.js",
|
||||
"./static/js/147.76ae369e.chunk.js": "/react/build/./static/js/147.76ae369e.chunk.js",
|
||||
"./static/js/148.bf2227d8.chunk.js": "/react/build/./static/js/148.bf2227d8.chunk.js",
|
||||
"./static/js/149.42933dea.chunk.js": "/react/build/./static/js/149.42933dea.chunk.js",
|
||||
"./static/js/150.f2e48d21.chunk.js": "/react/build/./static/js/150.f2e48d21.chunk.js",
|
||||
"./static/js/151.b66da5bb.chunk.js": "/react/build/./static/js/151.b66da5bb.chunk.js",
|
||||
"./static/js/152.5b33b737.chunk.js": "/react/build/./static/js/152.5b33b737.chunk.js",
|
||||
"./static/js/153.f20f94ab.chunk.js": "/react/build/./static/js/153.f20f94ab.chunk.js",
|
||||
"./static/js/154.1dcd577d.chunk.js": "/react/build/./static/js/154.1dcd577d.chunk.js",
|
||||
"./static/js/155.1b354e97.chunk.js": "/react/build/./static/js/155.1b354e97.chunk.js",
|
||||
"./static/js/156.f051c4e9.chunk.js": "/react/build/./static/js/156.f051c4e9.chunk.js",
|
||||
"./static/js/157.75e7240f.chunk.js": "/react/build/./static/js/157.75e7240f.chunk.js",
|
||||
"./static/js/158.dc0da031.chunk.js": "/react/build/./static/js/158.dc0da031.chunk.js",
|
||||
"./static/js/159.0444bc4e.chunk.js": "/react/build/./static/js/159.0444bc4e.chunk.js",
|
||||
"./static/js/160.54a63cf6.chunk.js": "/react/build/./static/js/160.54a63cf6.chunk.js",
|
||||
"./static/js/161.5fcc2993.chunk.js": "/react/build/./static/js/161.5fcc2993.chunk.js",
|
||||
"./static/js/162.3d05705b.chunk.js": "/react/build/./static/js/162.3d05705b.chunk.js",
|
||||
"./static/js/163.999b2cd6.chunk.js": "/react/build/./static/js/163.999b2cd6.chunk.js",
|
||||
"./static/js/164.bc1a4e19.chunk.js": "/react/build/./static/js/164.bc1a4e19.chunk.js",
|
||||
"./static/js/165.26955e70.chunk.js": "/react/build/./static/js/165.26955e70.chunk.js",
|
||||
"./static/js/166.e6fa2f04.chunk.js": "/react/build/./static/js/166.e6fa2f04.chunk.js",
|
||||
"./static/js/167.73863021.chunk.js": "/react/build/./static/js/167.73863021.chunk.js",
|
||||
"./static/js/168.9e6be64f.chunk.js": "/react/build/./static/js/168.9e6be64f.chunk.js",
|
||||
"./static/js/169.97340bbd.chunk.js": "/react/build/./static/js/169.97340bbd.chunk.js",
|
||||
"./static/js/170.8b9b7fbc.chunk.js": "/react/build/./static/js/170.8b9b7fbc.chunk.js",
|
||||
"./static/js/171.51b25453.chunk.js": "/react/build/./static/js/171.51b25453.chunk.js",
|
||||
"./static/js/172.a9f3bab1.chunk.js": "/react/build/./static/js/172.a9f3bab1.chunk.js",
|
||||
"./static/js/173.24903936.chunk.js": "/react/build/./static/js/173.24903936.chunk.js",
|
||||
"./static/js/174.bcec984e.chunk.js": "/react/build/./static/js/174.bcec984e.chunk.js",
|
||||
"./static/js/175.ead87ea5.chunk.js": "/react/build/./static/js/175.ead87ea5.chunk.js",
|
||||
"./static/js/176.3591636e.chunk.js": "/react/build/./static/js/176.3591636e.chunk.js",
|
||||
"./static/js/177.40ade417.chunk.js": "/react/build/./static/js/177.40ade417.chunk.js",
|
||||
"./static/js/178.bf3dac42.chunk.js": "/react/build/./static/js/178.bf3dac42.chunk.js",
|
||||
"./static/js/179.55d44588.chunk.js": "/react/build/./static/js/179.55d44588.chunk.js",
|
||||
"./static/js/180.1ff60c84.chunk.js": "/react/build/./static/js/180.1ff60c84.chunk.js",
|
||||
"./static/js/181.3011cf53.chunk.js": "/react/build/./static/js/181.3011cf53.chunk.js",
|
||||
"./static/js/182.e2f6713c.chunk.js": "/react/build/./static/js/182.e2f6713c.chunk.js",
|
||||
"./static/js/183.0a31f275.chunk.js": "/react/build/./static/js/183.0a31f275.chunk.js",
|
||||
"./static/js/184.d84e2682.chunk.js": "/react/build/./static/js/184.d84e2682.chunk.js",
|
||||
"./static/js/185.4c3bd620.chunk.js": "/react/build/./static/js/185.4c3bd620.chunk.js",
|
||||
"./static/js/186.610bb516.chunk.js": "/react/build/./static/js/186.610bb516.chunk.js",
|
||||
"./static/js/187.a15540eb.chunk.js": "/react/build/./static/js/187.a15540eb.chunk.js",
|
||||
"main.css": "/react/build/static/css/main.ceb94a14.chunk.css",
|
||||
"main.js": "/react/build/./static/js/main.516632e1.chunk.js",
|
||||
"runtime~main.js": "/react/build/./static/js/runtime~main.677b7222.js",
|
||||
"./static/js/140.9300e577.chunk.js.LICENSE.txt": "/react/build/./static/js/140.9300e577.chunk.js.LICENSE.txt",
|
||||
"./static/js/182.e2f6713c.chunk.js.LICENSE.txt": "/react/build/./static/js/182.e2f6713c.chunk.js.LICENSE.txt",
|
||||
"./static/js/2.d659edf3.chunk.js.LICENSE.txt": "/react/build/./static/js/2.d659edf3.chunk.js.LICENSE.txt",
|
||||
"./static/js/34.b06d630a.chunk.js.LICENSE.txt": "/react/build/./static/js/34.b06d630a.chunk.js.LICENSE.txt",
|
||||
"./static/js/35.d6dd0530.chunk.js.LICENSE.txt": "/react/build/./static/js/35.d6dd0530.chunk.js.LICENSE.txt",
|
||||
"./static/js/8.882648e1.chunk.js.LICENSE.txt": "/react/build/./static/js/8.882648e1.chunk.js.LICENSE.txt",
|
||||
"./static/js/main.eae036cf.chunk.js.LICENSE.txt": "/react/build/./static/js/main.eae036cf.chunk.js.LICENSE.txt",
|
||||
"./static/js/27.fc2d3a1f.chunk.js.LICENSE.txt": "/react/build/./static/js/27.fc2d3a1f.chunk.js.LICENSE.txt",
|
||||
"./static/js/7.a1394f8d.chunk.js.LICENSE.txt": "/react/build/./static/js/7.a1394f8d.chunk.js.LICENSE.txt",
|
||||
"./static/js/main.516632e1.chunk.js.LICENSE.txt": "/react/build/./static/js/main.516632e1.chunk.js.LICENSE.txt",
|
||||
"css.worker.js": "/react/build/css.worker.js",
|
||||
"editor.worker.js": "/react/build/editor.worker.js",
|
||||
"html.worker.js": "/react/build/html.worker.js",
|
||||
"index.html": "/react/build/index.html",
|
||||
"json.worker.js": "/react/build/json.worker.js",
|
||||
"static/media/Index.scss": "/react/build/static/media/typebg.b2b0ea32.png",
|
||||
"static/media/2-2-1.png": "/react/build/static/media/2-2-1.afd0f2f5.png",
|
||||
"static/media/2-2-2.png": "/react/build/static/media/2-2-2.26bc3301.png",
|
||||
"static/media/2-2-3.png": "/react/build/static/media/2-2-3.6d6ce99c.png",
|
||||
"static/media/2-2-head.png": "/react/build/static/media/2-2-head.5e69dbb2.png",
|
||||
"static/media/2-3-1.png": "/react/build/static/media/2-3-1.bcb33d47.png",
|
||||
"static/media/2-3-2.png": "/react/build/static/media/2-3-2.84718f27.png",
|
||||
"static/media/2-3-3.png": "/react/build/static/media/2-3-3.db9fe021.png",
|
||||
"static/media/2-3-4.png": "/react/build/static/media/2-3-4.15673036.png",
|
||||
"static/media/2-6-1.png": "/react/build/static/media/2-6-1.302b729e.png",
|
||||
"static/media/2-6-2.png": "/react/build/static/media/2-6-2.b262b91e.png",
|
||||
"static/media/3-1.png": "/react/build/static/media/3-1.9fdda521.png",
|
||||
"static/media/3-2.png": "/react/build/static/media/3-2.47050941.png",
|
||||
"static/media/3-3.png": "/react/build/static/media/3-3.c767aae7.png",
|
||||
"static/media/3-4.png": "/react/build/static/media/3-4.92820cbc.png",
|
||||
"static/media/4-1.png": "/react/build/static/media/4-1.79fa159d.png",
|
||||
"static/media/4-2.png": "/react/build/static/media/4-2.9c066e75.png",
|
||||
"static/media/4-3.png": "/react/build/static/media/4-3.a1487a5b.png",
|
||||
"static/media/4-4.png": "/react/build/static/media/4-4.5eb40734.png",
|
||||
"static/media/BJHKHT.png": "/react/build/static/media/BJHKHT.f065403a.png",
|
||||
"static/media/CEC.png": "/react/build/static/media/CEC.3b748059.png",
|
||||
"static/media/GFKJ.png": "/react/build/static/media/GFKJ.eb30c414.png",
|
||||
"static/media/HSKY.png": "/react/build/static/media/HSKY.2e76ba44.png",
|
||||
"static/media/ISCAS.png": "/react/build/static/media/ISCAS.851fcfda.png",
|
||||
"static/media/KYRJLM.png": "/react/build/static/media/KYRJLM.2d659e5c.png",
|
||||
"static/media/katex.min.css": "/react/build/static/media/KaTeX_Typewriter-Regular.d3c8e68f.woff",
|
||||
"static/media/LC.png": "/react/build/static/media/LC.f247fdb8.png",
|
||||
"static/media/LSLM.png": "/react/build/static/media/LSLM.99387946.png",
|
||||
"static/media/ML.png": "/react/build/static/media/ML.08d278e2.png",
|
||||
"static/media/NJDX.png": "/react/build/static/media/NJDX.bb34b326.png",
|
||||
"static/media/QH.png": "/react/build/static/media/QH.b57a0131.png",
|
||||
"static/media/SHJT.png": "/react/build/static/media/SHJT.426bf0c7.png",
|
||||
"static/media/TX.png": "/react/build/static/media/TX.b703476c.png",
|
||||
"static/media/WXYJY.png": "/react/build/static/media/WXYJY.21e40191.png",
|
||||
"static/media/XH.png": "/react/build/static/media/XH.a0a88f17.png",
|
||||
"static/media/XJY.png": "/react/build/static/media/XJY.b4c57bf1.png",
|
||||
"static/media/YKD.png": "/react/build/static/media/YKD.4f7e2766.png",
|
||||
"static/media/ZC.png": "/react/build/static/media/ZC.ad056aa5.png",
|
||||
"static/media/achievements.png": "/react/build/static/media/achievements.f20b7e39.png",
|
||||
"static/media/ball.png": "/react/build/static/media/ball.24214b6e.png",
|
||||
"static/media/AboutUs.scss": "/react/build/static/media/joinUs.26ec28cd.png",
|
||||
"static/media/banner.png": "/react/build/static/media/banner.f7da2db1.png",
|
||||
"static/media/banner_list.jpg": "/react/build/static/media/banner_list.e02c5e16.jpg",
|
||||
"static/media/beijing.png": "/react/build/static/media/beijing.bfcd5b0e.png",
|
||||
"static/media/beijintulogontwo.png": "/react/build/static/media/beijintulogontwo.41076faf.png",
|
||||
"static/media/LoginRegisterPage.scss": "/react/build/static/media/rightBg.55f14f0c.png",
|
||||
"static/media/codeafter.png": "/react/build/static/media/codeafter.c3088c74.png",
|
||||
"static/media/computer.png": "/react/build/static/media/computer.4fe86b12.png",
|
||||
"static/media/earth.png": "/react/build/static/media/earth.050b1435.png",
|
||||
"static/media/fun1.png": "/react/build/static/media/fun1.c99ffa49.png",
|
||||
"static/media/fun2.png": "/react/build/static/media/fun2.12f22bca.png",
|
||||
"static/media/fun3.png": "/react/build/static/media/fun3.75c280e6.png",
|
||||
"static/media/fun4.png": "/react/build/static/media/fun4.f499794e.png",
|
||||
"static/media/fun5.png": "/react/build/static/media/fun5.96b44942.png",
|
||||
"static/media/huake.png": "/react/build/static/media/huake.63b6a34d.png",
|
||||
"static/media/huawei.png": "/react/build/static/media/huawei.73ec7c22.png",
|
||||
"static/media/img1.png": "/react/build/static/media/img1.8560258f.png",
|
||||
"static/media/img2.png": "/react/build/static/media/img2.ae303051.png",
|
||||
"static/media/jijinhui.png": "/react/build/static/media/jijinhui.041fb524.png",
|
||||
"static/media/logo.png": "/react/build/static/media/logo.35cca493.png",
|
||||
"static/media/mulan.png": "/react/build/static/media/mulan.690d2289.png",
|
||||
"static/media/Index.scss": "/react/build/static/media/bg.401bf2cf.png",
|
||||
"static/media/educoder.png": "/react/build/static/media/educoder.695bfe08.png",
|
||||
"static/media/logo.png": "/react/build/static/media/logo.1c60f36c.png",
|
||||
"static/media/slick-theme.css": "/react/build/static/media/slick.c94f7671.ttf",
|
||||
"static/media/subtitle.png": "/react/build/static/media/subtitle.5019e086.png",
|
||||
"static/media/index.scss": "/react/build/static/media/taskbar.49a40f3a.png",
|
||||
"static/media/xigongye.png": "/react/build/static/media/xigongye.d51231d3.png",
|
||||
"static/media/xiuos.png": "/react/build/static/media/xiuos.67682257.png",
|
||||
"ts.worker.js": "/react/build/ts.worker.js",
|
||||
"ts.worker.js.LICENSE.txt": "/react/build/ts.worker.js.LICENSE.txt"
|
||||
}
|
||||
|
|
@ -1268,17 +1268,11 @@ a.shixun-task-btn {
|
|||
|
||||
|
||||
/*-----------实训配置、评测脚本-------------*/
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1631773579834') format('woff2'),
|
||||
url('iconfont.woff?t=1631773579834') format('woff'),
|
||||
url('iconfont.ttf?t=1631773579834') format('truetype');
|
||||
}
|
||||
html body {
|
||||
font-size: 14px;
|
||||
line-height: 2.0;
|
||||
background: #fafafa;
|
||||
font-family: "iconfont";
|
||||
font-family: "Microsoft YaHei", "SimSun";
|
||||
color: #05101a;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
|
@ -3947,7 +3941,7 @@ html>body #ajax-indicator {
|
|||
}
|
||||
.head-nav {
|
||||
text-align: center;
|
||||
height: 58px;
|
||||
height: 70px;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
|
@ -3959,14 +3953,14 @@ html>body #ajax-indicator {
|
|||
position: absolute;
|
||||
top: 0px;
|
||||
z-index: 3;
|
||||
height: 58px;
|
||||
height: 70px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li {
|
||||
float: left;
|
||||
height: 58px;
|
||||
line-height: 58px;
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
|
|
@ -3977,7 +3971,7 @@ html>body #ajax-indicator {
|
|||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
|
|
@ -3989,6 +3983,10 @@ html>body #ajax-indicator {
|
|||
margin-right: 0px
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active{
|
||||
/* background-color: #3B3B3B; */
|
||||
}
|
||||
|
||||
|
||||
.head-nav ul#header-nav li p:hover {
|
||||
color: #cccccc;
|
||||
|
|
@ -6707,10 +6705,13 @@ p{
|
|||
right: 0px;
|
||||
top:4px;
|
||||
color: #999;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
}
|
||||
.ant-input, .ant-input .ant-input-suffix{
|
||||
background-color: #fff!important;
|
||||
}
|
||||
.has-error .ant-input{
|
||||
background-color: #FEF1F0!important;
|
||||
>>>>>>> pre_develop
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1637544235157') format('woff2'),
|
||||
url('iconfont.woff?t=1637544235157') format('woff'),
|
||||
url('iconfont.ttf?t=1637544235157') format('truetype');
|
||||
src: url('iconfont.woff2?t=1634881729644') format('woff2'),
|
||||
url('iconfont.woff?t=1634881729644') format('woff'),
|
||||
url('iconfont.ttf?t=1634881729644') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
|
@ -13,106 +13,6 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-zhishitupu:before {
|
||||
content: "\e8fc";
|
||||
}
|
||||
|
||||
.icon-jisuanji1:before {
|
||||
content: "\e8fd";
|
||||
}
|
||||
|
||||
.icon-dianzi1:before {
|
||||
content: "\e8ff";
|
||||
}
|
||||
|
||||
.icon-junshililun1:before {
|
||||
content: "\e900";
|
||||
}
|
||||
|
||||
.icon-ruanjiangongcheng1:before {
|
||||
content: "\e901";
|
||||
}
|
||||
|
||||
.icon-yixue1:before {
|
||||
content: "\e902";
|
||||
}
|
||||
|
||||
.icon-tongxin1:before {
|
||||
content: "\e904";
|
||||
}
|
||||
|
||||
.icon-zhengcefagui1:before {
|
||||
content: "\e906";
|
||||
}
|
||||
|
||||
.icon-dashuju:before {
|
||||
content: "\e8f3";
|
||||
}
|
||||
|
||||
.icon-rengongzhineng:before {
|
||||
content: "\e8f6";
|
||||
}
|
||||
|
||||
.icon-a-shuangyinhao12x:before {
|
||||
content: "\e8f2";
|
||||
}
|
||||
|
||||
.icon-dingbu:before {
|
||||
content: "\e8ee";
|
||||
}
|
||||
|
||||
.icon-bangzhu1:before {
|
||||
content: "\e8ef";
|
||||
}
|
||||
|
||||
.icon-yijianfankui2:before {
|
||||
content: "\e8f0";
|
||||
}
|
||||
|
||||
.icon-fenxiang:before {
|
||||
content: "\e8f1";
|
||||
}
|
||||
|
||||
.icon-dizhi:before {
|
||||
content: "\e8eb";
|
||||
}
|
||||
|
||||
.icon-youxiang1:before {
|
||||
content: "\e8ec";
|
||||
}
|
||||
|
||||
.icon-dianhuaicon:before {
|
||||
content: "\e8ed";
|
||||
}
|
||||
|
||||
.icon-tianjiaicon:before {
|
||||
content: "\e8e8";
|
||||
}
|
||||
|
||||
.icon-lingshengicon:before {
|
||||
content: "\e8ea";
|
||||
}
|
||||
|
||||
.icon-gengduoicon:before {
|
||||
content: "\e8e5";
|
||||
}
|
||||
|
||||
.icon-shijianicon:before {
|
||||
content: "\e8e7";
|
||||
}
|
||||
|
||||
.icon-mimaicon:before {
|
||||
content: "\e8e1";
|
||||
}
|
||||
|
||||
.icon-gouicon:before {
|
||||
content: "\e8e2";
|
||||
}
|
||||
|
||||
.icon-zhankaiicon:before {
|
||||
content: "\e8e3";
|
||||
}
|
||||
|
||||
.icon-wenjian7:before {
|
||||
content: "\e8e0";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,181 +5,6 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "25748537",
|
||||
"name": "知识图谱",
|
||||
"font_class": "zhishitupu",
|
||||
"unicode": "e8fc",
|
||||
"unicode_decimal": 59644
|
||||
},
|
||||
{
|
||||
"icon_id": "25748551",
|
||||
"name": "计算机",
|
||||
"font_class": "jisuanji1",
|
||||
"unicode": "e8fd",
|
||||
"unicode_decimal": 59645
|
||||
},
|
||||
{
|
||||
"icon_id": "25748553",
|
||||
"name": "电子",
|
||||
"font_class": "dianzi1",
|
||||
"unicode": "e8ff",
|
||||
"unicode_decimal": 59647
|
||||
},
|
||||
{
|
||||
"icon_id": "25748554",
|
||||
"name": "军事理论",
|
||||
"font_class": "junshililun1",
|
||||
"unicode": "e900",
|
||||
"unicode_decimal": 59648
|
||||
},
|
||||
{
|
||||
"icon_id": "25748555",
|
||||
"name": "软件工程",
|
||||
"font_class": "ruanjiangongcheng1",
|
||||
"unicode": "e901",
|
||||
"unicode_decimal": 59649
|
||||
},
|
||||
{
|
||||
"icon_id": "25748556",
|
||||
"name": "医学",
|
||||
"font_class": "yixue1",
|
||||
"unicode": "e902",
|
||||
"unicode_decimal": 59650
|
||||
},
|
||||
{
|
||||
"icon_id": "25748558",
|
||||
"name": "通信",
|
||||
"font_class": "tongxin1",
|
||||
"unicode": "e904",
|
||||
"unicode_decimal": 59652
|
||||
},
|
||||
{
|
||||
"icon_id": "25748560",
|
||||
"name": "政策法规",
|
||||
"font_class": "zhengcefagui1",
|
||||
"unicode": "e906",
|
||||
"unicode_decimal": 59654
|
||||
},
|
||||
{
|
||||
"icon_id": "25748528",
|
||||
"name": "大数据",
|
||||
"font_class": "dashuju",
|
||||
"unicode": "e8f3",
|
||||
"unicode_decimal": 59635
|
||||
},
|
||||
{
|
||||
"icon_id": "25748531",
|
||||
"name": "人工智能",
|
||||
"font_class": "rengongzhineng",
|
||||
"unicode": "e8f6",
|
||||
"unicode_decimal": 59638
|
||||
},
|
||||
{
|
||||
"icon_id": "25733167",
|
||||
"name": "双引号(1)@2x",
|
||||
"font_class": "a-shuangyinhao12x",
|
||||
"unicode": "e8f2",
|
||||
"unicode_decimal": 59634
|
||||
},
|
||||
{
|
||||
"icon_id": "25701947",
|
||||
"name": "顶部",
|
||||
"font_class": "dingbu",
|
||||
"unicode": "e8ee",
|
||||
"unicode_decimal": 59630
|
||||
},
|
||||
{
|
||||
"icon_id": "25701948",
|
||||
"name": "帮助",
|
||||
"font_class": "bangzhu1",
|
||||
"unicode": "e8ef",
|
||||
"unicode_decimal": 59631
|
||||
},
|
||||
{
|
||||
"icon_id": "25701949",
|
||||
"name": "意见反馈",
|
||||
"font_class": "yijianfankui2",
|
||||
"unicode": "e8f0",
|
||||
"unicode_decimal": 59632
|
||||
},
|
||||
{
|
||||
"icon_id": "25701950",
|
||||
"name": "分享",
|
||||
"font_class": "fenxiang",
|
||||
"unicode": "e8f1",
|
||||
"unicode_decimal": 59633
|
||||
},
|
||||
{
|
||||
"icon_id": "25580217",
|
||||
"name": "地址",
|
||||
"font_class": "dizhi",
|
||||
"unicode": "e8eb",
|
||||
"unicode_decimal": 59627
|
||||
},
|
||||
{
|
||||
"icon_id": "25580218",
|
||||
"name": "邮箱",
|
||||
"font_class": "youxiang1",
|
||||
"unicode": "e8ec",
|
||||
"unicode_decimal": 59628
|
||||
},
|
||||
{
|
||||
"icon_id": "25580219",
|
||||
"name": "电话icon",
|
||||
"font_class": "dianhuaicon",
|
||||
"unicode": "e8ed",
|
||||
"unicode_decimal": 59629
|
||||
},
|
||||
{
|
||||
"icon_id": "25284174",
|
||||
"name": "添加icon",
|
||||
"font_class": "tianjiaicon",
|
||||
"unicode": "e8e8",
|
||||
"unicode_decimal": 59624
|
||||
},
|
||||
{
|
||||
"icon_id": "25284175",
|
||||
"name": "铃声icon",
|
||||
"font_class": "lingshengicon",
|
||||
"unicode": "e8ea",
|
||||
"unicode_decimal": 59626
|
||||
},
|
||||
{
|
||||
"icon_id": "25204490",
|
||||
"name": "更多icon",
|
||||
"font_class": "gengduoicon",
|
||||
"unicode": "e8e5",
|
||||
"unicode_decimal": 59621
|
||||
},
|
||||
{
|
||||
"icon_id": "25204491",
|
||||
"name": "时间icon",
|
||||
"font_class": "shijianicon",
|
||||
"unicode": "e8e7",
|
||||
"unicode_decimal": 59623
|
||||
},
|
||||
{
|
||||
"icon_id": "25188228",
|
||||
"name": "密码icon",
|
||||
"font_class": "mimaicon",
|
||||
"unicode": "e8e1",
|
||||
"unicode_decimal": 59617
|
||||
},
|
||||
{
|
||||
"icon_id": "25188229",
|
||||
"name": "钩icon",
|
||||
"font_class": "gouicon",
|
||||
"unicode": "e8e2",
|
||||
"unicode_decimal": 59618
|
||||
},
|
||||
{
|
||||
"icon_id": "25188230",
|
||||
"name": "展开icon",
|
||||
"font_class": "zhankaiicon",
|
||||
"unicode": "e8e3",
|
||||
"unicode_decimal": 59619
|
||||
},
|
||||
{
|
||||
"icon_id": "24656750",
|
||||
"name": "文件",
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 27 KiB |
|
|
@ -1 +1 @@
|
|||
<!doctype html><html lang="zh-CN" class="notranslate translated-ltr" translate="no"><head><meta charset="utf-8"><meta name="”Keywords”" content="”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″"><meta name="”Keywords”" content="”TrustieOpenSourceProject″"><meta name="”Keywords”" content="”issue,bug,tracker,软件工程,课程实践″"><meta name="”Description”" content="”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”"><meta name="theme-color" content="#000000"><link rel="manifest" href="/react/build//manifest.json"><link rel="stylesheet" href="/react/build/css/iconfont.css"><link rel="stylesheet" href="/react/build/css/edu-purge.css"><link rel="stylesheet" href="/react/build/css/editormd.min.css"><link rel="stylesheet" href="/react/build/css/merge.css"><link href="/react/build/static/css/main.bdb06a8e.chunk.css" rel="stylesheet"></head><body><div id="md_div" style="display:none"></div><div id="root" class="page -layout-v -fit widthunit"></div><div id="picture_display" style="display:none"></div><script src="/react/build/js/jquery-1.8.3.min.js"></script><script src="/react/build/js/js_min_all.js"></script><script src="/react/build/js/codemirror/codemirror.js"></script><script src="/react/build/js/editormd/editormd.min.js"></script><script src="/react/build/js/codemirror/merge/merge.js"></script><script src="/react/build/./static/js/runtime~main.cbbbfc02.js"></script><script src="/react/build/./static/js/main.eae036cf.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="zh-CN" class="notranslate translated-ltr" translate="no"><head><meta charset="utf-8"><meta name="”Keywords”" content="”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″"><meta name="”Keywords”" content="”TrustieOpenSourceProject″"><meta name="”Keywords”" content="”issue,bug,tracker,软件工程,课程实践″"><meta name="”Description”" content="”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”"><meta name="theme-color" content="#000000"><link rel="manifest" href="/react/build//manifest.json"><link rel="stylesheet" href="/react/build/css/iconfont.css"><link rel="stylesheet" href="/react/build/css/edu-purge.css"><link rel="stylesheet" href="/react/build/css/editormd.min.css"><link rel="stylesheet" href="/react/build/css/merge.css"><link href="/react/build/static/css/main.ceb94a14.chunk.css" rel="stylesheet"></head><body><div id="md_div" style="display:none"></div><div id="root" class="page -layout-v -fit widthunit"></div><div id="picture_display" style="display:none"></div><script src="/react/build/js/jquery-1.8.3.min.js"></script><script src="/react/build/js/js_min_all.js"></script><script src="/react/build/js/codemirror/codemirror.js"></script><script src="/react/build/js/editormd/editormd.min.js"></script><script src="/react/build/js/codemirror/merge/merge.js"></script><script src="/react/build/./static/js/runtime~main.677b7222.js"></script><script src="/react/build/./static/js/main.516632e1.chunk.js"></script></body></html>
|
||||