Browse Source

Merge branch 'master' of https://gitlink.org.cn/Gitlink/forgeplus into standalone_develop

pull/342/head
xxq250 3 years ago
parent
commit
69f8b43186
100 changed files with 42150 additions and 1031786 deletions
  1. +0
    -1
      .gitignore
  2. +47
    -0
      Dockerfile
  3. +3
    -5
      Gemfile
  4. +7
    -18
      Gemfile.lock
  5. +118
    -84
      README.md
  6. +1
    -0
      app/controllers/accounts_controller.rb
  7. +15
    -10
      app/controllers/oauth/educoder_controller.rb
  8. +12
    -1
      app/controllers/repositories_controller.rb
  9. +6
    -0
      app/models/import_repo.rb
  10. +8
    -0
      app/models/organization.rb
  11. +30
    -0
      app/models/project.rb
  12. +3
    -2
      app/models/user.rb
  13. +4
    -0
      app/services/admins/delete_organization_service.rb
  14. +1
    -0
      app/services/api/v1/users/update_email_service.rb
  15. +1
    -0
      app/services/api/v1/users/update_phone_service.rb
  16. +1
    -1
      app/services/gitea/client_service.rb
  17. +1
    -1
      app/services/gitea/repository/commits/file_list_service.rb
  18. +1
    -1
      app/views/admins/organizations/index.js.erb
  19. +3
    -3
      app/views/api/v1/projects/contributors/stat.json.jbuilder
  20. +1
    -2
      app/views/repositories/contributors.json.jbuilder
  21. +1
    -1
      app/views/repositories/detail.json.jbuilder
  22. +50
    -49
      config/application.rb
  23. +12
    -12
      config/sidekiq.yml
  24. +8
    -5
      docker-compose.yml
  25. BIN
      docs/figs/PR.png
  26. BIN
      docs/figs/code.png
  27. BIN
      docs/figs/engine.png
  28. BIN
      docs/figs/gitlink.png
  29. BIN
      docs/figs/issue_assign.png
  30. BIN
      docs/figs/issue_assign2.png
  31. BIN
      docs/figs/issue_manage.png
  32. BIN
      docs/figs/issue_view.png
  33. BIN
      docs/figs/issues.png
  34. BIN
      docs/figs/milestone.png
  35. BIN
      docs/figs/project_list.png
  36. BIN
      docs/figs/repo.png
  37. +61
    -0
      lib/tasks/batch_add_commits.rake
  38. +129
    -0
      lib/tasks/batch_add_contributors.rake
  39. +130
    -0
      lib/tasks/batch_add_issues.rake
  40. +63
    -0
      lib/tasks/batch_forked_project.rake
  41. +3
    -0
      lib/tasks/commit_log_to_db.rake
  42. +97
    -0
      lib/tasks/import_educoder_cource_repo.rake
  43. +26
    -0
      lib/tasks/init_project_topic.rake
  44. +44
    -0
      lib/tasks/special_commit.rake
  45. +79
    -0
      lib/tasks/sync_mindspore_contributors.rake
  46. +57
    -0
      lib/tasks/total_commit_count.rake
  47. +7
    -4
      lib/tasks/total_commit_to_db.rake
  48. +1
    -1
      lib/tasks/update_educoder_user.rake
  49. +0
    -1
      public/assets/.sprockets-manifest-7657344e1d61e579de6a996a4498d7a2.json
  50. +1
    -0
      public/assets/.sprockets-manifest-fcdcb36eff7e19f6646153ed2fcfd2b4.json
  51. +0
    -142257
      public/assets/admin-04ff7d4c76f406e0df9e02923038d175f26ee098d43e266c2138b07163a2da9e.js
  52. BIN
      public/assets/admin-04ff7d4c76f406e0df9e02923038d175f26ee098d43e266c2138b07163a2da9e.js.gz
  53. +0
    -26869
      public/assets/admin-15ad6e029d1195111f661b61d8252ec40b1e453c44c489c661c8fa3211ff62b2.css
  54. BIN
      public/assets/admin-15ad6e029d1195111f661b61d8252ec40b1e453c44c489c661c8fa3211ff62b2.css.gz
  55. +0
    -26215
      public/assets/admin-31e7cc6208d66802217e899555cd22920bb7d043578b1b16250e09dbe76b7bc6.css
  56. BIN
      public/assets/admin-31e7cc6208d66802217e899555cd22920bb7d043578b1b16250e09dbe76b7bc6.css.gz
  57. +0
    -26869
      public/assets/admin-343a62865a99bebf4247a945a48400b472f76196fb80e86b4cce6b2cc480d306.css
  58. BIN
      public/assets/admin-343a62865a99bebf4247a945a48400b472f76196fb80e86b4cce6b2cc480d306.css.gz
  59. +635
    -34
      public/assets/admin-3e4fde7de877298349280a53b1de578b155575be742d34a72de7574db7f26219.js
  60. BIN
      public/assets/admin-3e4fde7de877298349280a53b1de578b155575be742d34a72de7574db7f26219.js.gz
  61. +0
    -142260
      public/assets/admin-46d2460ea8c06a885f92df73240e8eb84d320402bbdf580ffe3e038d07fdda3d.js
  62. BIN
      public/assets/admin-46d2460ea8c06a885f92df73240e8eb84d320402bbdf580ffe3e038d07fdda3d.js.gz
  63. +8
    -2
      public/assets/admin-5fa03af0e91aea5a8125dc7a7bb31e7a8c4d0a480e2c09ccc7b6db230063c555.css
  64. BIN
      public/assets/admin-5fa03af0e91aea5a8125dc7a7bb31e7a8c4d0a480e2c09ccc7b6db230063c555.css.gz
  65. BIN
      public/assets/admin-719988f975840fa3b187ef2594aecb8494218f82342377a1f3c71731f68fbf61.css.gz
  66. BIN
      public/assets/admin-7c523d78203d02769553abade33413cdf663eea3fe1d15ee07ab449240a10a9a.js.gz
  67. +0
    -142309
      public/assets/admin-8cb0e9724b33e253621a5f1020bdc270f828cb7d602de8434d3cc606e0b4dbc2.js
  68. BIN
      public/assets/admin-8cb0e9724b33e253621a5f1020bdc270f828cb7d602de8434d3cc606e0b4dbc2.js.gz
  69. +0
    -142271
      public/assets/admin-8d7c2001aaf2599bddad06c5bc30526b059780d9fda2f01797524c0b8a1c43c3.js
  70. BIN
      public/assets/admin-8d7c2001aaf2599bddad06c5bc30526b059780d9fda2f01797524c0b8a1c43c3.js.gz
  71. +0
    -49
      public/assets/admin-b2526c7eefd8212cde88c53131e8a7dd02f4d96e6d9e262d31dbca516addc979.js
  72. BIN
      public/assets/admin-b2526c7eefd8212cde88c53131e8a7dd02f4d96e6d9e262d31dbca516addc979.js.gz
  73. +0
    -142301
      public/assets/admin-b8f26db185886f99021da91f0e2c1a8cc4ced4d1b895794751d11b7a9f45de98.js
  74. BIN
      public/assets/admin-b8f26db185886f99021da91f0e2c1a8cc4ced4d1b895794751d11b7a9f45de98.js.gz
  75. +40473
    -0
      public/assets/application-1852bb2a261b8a9ce0d4a83dcc076d63be1105549c174f335c1e0f466fa9f8c1.js
  76. BIN
      public/assets/application-1852bb2a261b8a9ce0d4a83dcc076d63be1105549c174f335c1e0f466fa9f8c1.js.gz
  77. BIN
      public/assets/application-346b678500708f3f4e9cd72c46d1e9e54aaf76e0478b766519ac083bf93fbcff.css.gz
  78. +0
    -17296
      public/assets/application-47eaf72a32e7cee15e04ee7632fbbaadd5efd1129bfe0978d28d9b84ecec913e.js
  79. BIN
      public/assets/application-47eaf72a32e7cee15e04ee7632fbbaadd5efd1129bfe0978d28d9b84ecec913e.js.gz
  80. +0
    -16
      public/assets/application-860dba70259cdc6c5c72c499f8be717c050d517f1fd6a1543c0b6863af987000.js
  81. BIN
      public/assets/application-860dba70259cdc6c5c72c499f8be717c050d517f1fd6a1543c0b6863af987000.js.gz
  82. +0
    -11520
      public/assets/application-8853af8ba870ca7fc8bdae048322f1c5a5caa26f1df87dbbf0c6d04232c4ac4e.css
  83. BIN
      public/assets/application-8853af8ba870ca7fc8bdae048322f1c5a5caa26f1df87dbbf0c6d04232c4ac4e.css.gz
  84. +0
    -11976
      public/assets/application-d3da385d89dfa7edfbecc09573322b132ffc5580cbd185d5f7a74d5358881815.css
  85. BIN
      public/assets/application-d3da385d89dfa7edfbecc09573322b132ffc5580cbd185d5f7a74d5358881815.css.gz
  86. +0
    -19833
      public/assets/application-d44f4301c7dfbe07bcb2788d7c006c22c184ae6b7016c09f7911b4962aacd767.js
  87. BIN
      public/assets/application-d44f4301c7dfbe07bcb2788d7c006c22c184ae6b7016c09f7911b4962aacd767.js.gz
  88. +0
    -11976
      public/assets/application-e194b45894d0c5240d954851211a86516ee6ad871ca99bf7783ce44aeb8c0687.css
  89. BIN
      public/assets/application-e194b45894d0c5240d954851211a86516ee6ad871ca99bf7783ce44aeb8c0687.css.gz
  90. +1
    -0
      public/assets/bootstrap/bootstrap-toggle.min.js-fac504e43bc81af46909bd71548406af8a8fee086aa3e6d0ef86fe93cafbc650.map
  91. +1
    -0
      public/assets/bootstrap/bootstrap2-toggle.min.js-b3598be8ca2991d3ae918a855c3b506702ddafb35ae5178f36473f2705ec4a9c.map
  92. +0
    -17366
      public/assets/college-2065ab3f84df62eb2ca345c83198920fad15cc3b93baf22c091f3c6bfced11b4.css
  93. BIN
      public/assets/college-2065ab3f84df62eb2ca345c83198920fad15cc3b93baf22c091f3c6bfced11b4.css.gz
  94. +0
    -115915
      public/assets/college-431d908264782ef54e90202095d4cf397c586f74d2b7879684348dc8b53d2cd2.js
  95. BIN
      public/assets/college-431d908264782ef54e90202095d4cf397c586f74d2b7879684348dc8b53d2cd2.js.gz
  96. +0
    -17366
      public/assets/college-461b4e52a77522c5ff4341992359aba660dc26d7d985e394b69d8b87db954a14.css
  97. BIN
      public/assets/college-461b4e52a77522c5ff4341992359aba660dc26d7d985e394b69d8b87db954a14.css.gz
  98. +0
    -16850
      public/assets/college-893ba916d2b043f4b751cacc104de43d14e0db0b4001822f996e803bacbda169.css
  99. BIN
      public/assets/college-893ba916d2b043f4b751cacc104de43d14e0db0b4001822f996e803bacbda169.css.gz
  100. +0
    -34
      public/assets/college-bd7fb1ab1da64733a0172f89c8b9d5cfe4db736bb3ee51e0ca0701b40e2e49cc.js

+ 0
- 1
.gitignore View File

@@ -81,7 +81,6 @@ db/bak/
docker/
educoder.sql
redis_data/
Dockerfile
dump.rdb
.tags*
ceshi_user.xlsx

+ 47
- 0
Dockerfile View File

@@ -0,0 +1,47 @@
FROM ubuntu:20.04
RUN apt-get update
# basics
RUN apt-get install -y libssl-dev curl libmysqlclient-dev imagemagick nodejs mysql-server redis-server tzdata
RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# confirm openssl version
RUN openssl version
RUN which openssl
# install RVM, Ruby, and Bundler
RUN \curl -L https://get.rvm.io | bash -s stable
RUN /bin/bash -l -c "rvm requirements"
# replace ruby mirror url, accelerate install ruby
RUN sed -i 's/rvm_remote_server_url2/#rvm_remote_server_url2/g' /usr/local/rvm/config/db
RUN sed -i 's/cache.ruby-lang.org/cache.ruby-china.com/g' /usr/local/rvm/config/db
# install ruby
RUN /bin/bash -l -c "rvm install 2.4.5"
# confirm ruby version
RUN /bin/bash -l -c "rvm list"
RUN /bin/bash -l -c "ruby -v"

#RUN apt-get install -y nodejs

WORKDIR /home/app/gitlink

ADD ./ /home/app/gitlink

RUN cd /home/app/gitlink

RUN /bin/bash -l -c 'gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/'

RUN /bin/bash -l -c 'gem update --system'

RUN /bin/bash -l -c 'gem install bundler -v 2.3.26'
RUN /bin/bash -l -c 'gem install rake'
RUN /bin/bash -l -c 'gem install puma -v 5.6.5'

RUN rm -rf Gemfile.lock

RUN cp config/configuration.yml.example config/configuration.yml
RUN cp config/database.yml.example config/database.yml
RUN touch config/redis.yml
RUN touch config/elasticsearch.yml

RUN /bin/bash -l -c 'bundle install'

#EXPOSE 4000
#RUN /bin/bash -l -c 'RAILS_ENV=production puma'

+ 3
- 5
Gemfile View File

@@ -70,9 +70,6 @@ group :development do
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'spring'
gem 'pry-rails'
gem 'pry-remote'
gem 'byebug', platforms: [:mri,:mingw,:x64_mingw]
gem 'spring-watcher-listen', '~> 2.0.0'
gem "annotate", "~> 2.6.0"
end
@@ -102,9 +99,10 @@ gem 'font-awesome-sass', '4.7.0'
gem 'rails-i18n', '~> 5.1'

# job
gem 'sidekiq'
gem 'sidekiq',"5.2.8"
gem 'sinatra'
gem "sidekiq-cron", "~> 1.1"
gem "sidekiq-cron", "1.2.0"
gem 'sidekiq-failures'

# batch insert
gem 'bulk_insert'


+ 7
- 18
Gemfile.lock View File

@@ -84,7 +84,6 @@ GEM
builder (3.2.4)
bulk_insert (1.7.0)
activerecord (>= 3.2.0)
byebug (11.1.3)
capybara (3.15.1)
addressable
mini_mime (>= 0.1.3)
@@ -100,7 +99,6 @@ GEM
archive-zip (~> 0.10)
nokogiri (~> 1.8)
chunky_png (1.3.11)
coderay (1.1.3)
concurrent-ruby (1.1.6)
connection_pool (2.2.2)
crass (1.0.6)
@@ -137,7 +135,7 @@ GEM
fugit (1.4.1)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.4)
gitea-client (1.4.1)
gitea-client (1.4.2)
rest-client (~> 2.1.0)
globalid (0.4.2)
activesupport (>= 4.2.0)
@@ -246,14 +244,6 @@ GEM
popper_js (1.16.0)
powerpack (0.1.2)
prettier (0.18.2)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
pry-remote (0.1.8)
pry (~> 0.9)
slop (~> 3.0)
public_suffix (4.0.3)
puma (3.12.2)
raabro (1.4.0)
@@ -407,6 +397,8 @@ GEM
sidekiq-cron (1.2.0)
fugit (~> 1.1)
sidekiq (>= 4.2.1)
sidekiq-failures (1.0.4)
sidekiq (>= 4.0.0)
simple_form (5.0.2)
actionpack (>= 5.0)
activemodel (>= 5.0)
@@ -418,7 +410,6 @@ GEM
rack (~> 2.0)
rack-protection (= 2.0.8.1)
tilt (~> 2.0)
slop (3.6.0)
solargraph (0.38.6)
backport (~> 1.1)
benchmark
@@ -490,7 +481,6 @@ DEPENDENCIES
bootsnap (>= 1.1.0)
bootstrap (~> 4.3.1)
bulk_insert
byebug
capybara (>= 2.15, < 4.0)
chartkick
chinese_pinyin
@@ -502,7 +492,7 @@ DEPENDENCIES
enumerize
faraday (~> 0.15.4)
font-awesome-sass (= 4.7.0)
gitea-client (~> 1.4.1)
gitea-client (~> 1.4.2)
grape-entity (~> 0.7.1)
groupdate (~> 4.1.0)
harmonious_dictionary (~> 0.0.1)
@@ -524,8 +514,6 @@ DEPENDENCIES
parallel (~> 1.19, >= 1.19.1)
pdfkit
prettier
pry-rails
pry-remote
puma (~> 3.11)
rack-cors
rack-mini-profiler
@@ -546,8 +534,9 @@ DEPENDENCIES
sass-rails (~> 5.0)
searchkick
selenium-webdriver
sidekiq
sidekiq-cron (~> 1.1)
sidekiq (= 5.2.8)
sidekiq-cron (= 1.2.0)
sidekiq-failures
simple_form
simple_xlsx_reader
sinatra


+ 118
- 84
README.md View File

@@ -1,17 +1,27 @@
Trustie (确实)是一个以大众化协同开发、开放式资源共享、持续性可信评估为核心机理,面向高校创新实践的在线协作平台。
# GitLink - CCF开源创新服务平台

## 特性
GitLink(确实开源)是中国计算机学会(CCF)官方指定的开源创新服务平台,旨在以“为开源创新服务”为使命,以“成为开源创新的汇聚地”为愿景,秉承“创新、开放、协作、共享”的价值观,致力于为大规模开源开放协同创新助力赋能,打造创新成果孵化和新工科人才培养的开源创新生态!

- 软件创作与生产深度融合的软件开发环境体系结构 软件自由创作和工程生产的高效衔接,适于软件开发中群体智慧的有效汇聚。
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/gitlink.png?raw=true" width=80% /></center>
## 特色功能

- 构件化协同开发环境的可扩展运行框架多样化工具的集成和联动,形成了强动态扩展能力的平台框架。
- **分布式协作开发**:基于Git打造分布式代码托管环境,提供免费公、私有代码仓库,支持在线文件编辑、代码分支管理、协作贡献统计、代码仓库复刻(Fork)、贡献合并请求(PR)、群智贡献审阅等功能,让您的项目在这里健康、快速的成长!

- “互联网即资源库”的全新软件复用模式 成长式软件资源管理系统,实现了分散资源的知识融合、资源的可持续增长和有效复用。
- **一站式过程管理**:提供疑修(Issue)、里程碑、通知提醒、标签归档等多样化任务管理工具,支持各类开发任务的发布、指派与跟踪,同时提供在线Wiki文档、组织多粒度管理等功能,为您搭建一站式的项目过程管理环境,让您的团队协作更高效、过程更透明!

## 部署
- **高效流水线运维**:融合DevOps思想,提供轻量级的工作流引擎(Engine),打通编码、测试、构建、部署等开发运维环节;支持自定义配置、代码静态扫描、构建自动触发、容器镜像托管等功能,同时支持接入第三方运维工具,让您的代码更加快速、可靠地形成高质量的产品!

- **多层次代码分析**:提供软件软代码和芯片RTL代码的溯源分析、文件级和组件级许可证识别及风险分析、输入性开源漏洞检测和加固建议,支持分析结果的多层次可视化展示,帮助您实施有效开源治理,厘清代码引用链,发现并消除漏洞感染链,为安全合规的开源引用保驾护航!

### Depends Versions
- **多维度用户画像**:实时采集和分析平台中的各类开源资源数据,搭建多维度用户画像评估系统,提供开发活动统计、贡献度日历、用户能力建模、角色与专业定位分析等功能,让您在个人主页展示开发动态与创新能力!


## 部署流程


### 依赖库

* Ruby 2.4.5

@@ -23,22 +33,53 @@ Trustie (确实)是一个以大众化协同开发、开放式资源共享、

* imagemagick

### Steps

#### 1. 克隆稳定版本
### 步骤
(1)安装 Rails 必要的一些三方库:
- Mac OS X
```bash
brew install imagemagick ghostscript libxml2 libxslt libiconv
```
git clone -b standalone https://git.trustie.net/jasder/forgeplus.git

- Ubuntu
```bash
sudo apt-get update
sudo apt-get install -y openssl libssl-dev imagemagick git ruby-dev nodejs libmariadb-dev libmysqlclient-dev shared-mime-info libpq-dev libxml2-dev libxslt-dev
sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y tzdata
sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
```

#### 2. 安装依赖包
(2)安装 Ruby, Rails 运行环境:[如何快速正确的安装 Ruby, Rails 运行环境](https://ruby-china.org/wiki/install_ruby_guide)
```bash
#检验环境是否正确
ruby -v
#ruby 2.4.x ...

gem -v
#3.x.x

bundle -v
#Bundler version 2.x.x

rails -v
#Rails 5.2.x
```

(3)克隆稳定版本
```bash
cd forgeplus && bundle install
git clone -b master https://gitlink.org.cn/Gitlink/forgeplus.git
```

#### 3. 配置初始化文件
进入项目根目录执行一下命令:
(4)安装依赖包
```bash
#进入目录
cd forgeplus
#删除Gemfile.lock
rm -rf Gemfile.lock
#安装依赖包
bundle install
```

(5)配置初始化文件:进入项目根目录执行以下命令
```bash
cp config/configuration.yml.example config/configuration.yml
cp config/database.yml.example config/database.yml
@@ -46,12 +87,8 @@ touch config/redis.yml
touch config/elasticsearch.yml
```

#### 4. 配置数据库
数据库配置信息请查看/config/database.yml文件,
项目默认采用mysql数据库, 如需更改,请自行修改配置信息,
默认配置如下:

```bash
(6)配置数据库:数据库配置信息请查看/config/database.yml文件,项目默认采用mysql数据库, 如需更改,请自行修改配置信息,默认配置如下
```yaml
default: &default
adapter: mysql2
host: 127.0.0.1
@@ -60,16 +97,15 @@ default: &default
password: 123456
```

#### 5. 配置gitea服务(可选)
**如需要部署自己的gitea平台,请参考gitea官方平台:https://docs.gitea.io/zh-cn/install-from-binary/**
(7)配置gitea服务(可选):如需要部署自己的gitea平台,请参考[gitea官方平台文档](https://docs.gitea.io/zh-cn/install-from-binary/)。因目前gitea平台api受限,暂时推荐从forge平台获取[gitea部署文件](https://www.gitlink.org.cn/Gitlink/gitea-binary)进行部署

**因目前gitea平台api受限,暂时推荐从forge平台获取gitea部署文件进行部署:https://forgeplus.trustie.net/projects/Trustie/gitea-binary**
- 配置gitea服务步骤:
-- 部署gitea服务,并注册root账户
-- 修改forge平台的 config/configuration.yml中的gitea服务指向地址,如:

**配置gitea服务步骤**
1. 部署gitea服务,并注册root账户
2. 修改forge平台的 config/configuration.yml中的gitea服务指向地址,如:

```ruby
```yaml
gitea:
access_key_id: 'root'
access_key_secret: 'password'
@@ -78,102 +114,100 @@ gitea:
hat_base_url: '/api/hat'
```

#### 6. 安装redis环境
**请自行搜索各平台如何安装部署redis环境**

#### 7. 安装imagemagick插件
- Mac OS X
```bash
brew install imagemagick ghostscript
```
(8)配置/config/database.yml文件(安装redis环境:请自行搜索各平台如何安装部署redis环境)
```yaml
default: &default
url: redis://localhost:6379
db: 1

- Linux
```bash
sudo apt-get install -y imagemagick
production:
<<: *default
url: redis://localhost:6379
```

#### 8. 创建数据库
**开发环境为development, 生成环境为production**
(9)创建数据库:开发环境为development, 生成环境为production
```bash
rails db:create RAILS_ENV=development
```

#### 9. 导入数据表结构
(10)导入数据表结构

```bash
bundle exec rake sync_table_structure:import_csv
```

#### 10. 执行migrate迁移文件
**开发环境为development, 生成环境为production**
(11)执行migrate迁移文件:开发环境为development, 生成环境为production
```bash
rails db:migrate RAILS_ENV=development
```

#### 11. clone前端代码
**将前端代码克隆到public/react目录下,目录结构应该是: public/react/build**
(12)clone前端代码:将前端代码克隆到public/react目录下,目录结构应该是: public/react/build
```bash
git clone -b standalone https://git.trustie.net/jasder/build.git
git clone -b master https://gitlink.org.cn/Gitlink/build.git
```

#### 12. 启动redis(此处已mac系统为例)
(13)启动redis(此处以macOS系统为例)
```bash
redis-server&
```

#### 13. 启动sidekiq
**开发环境为development, 生成环境为production**
(14)启动sidekiq:开发环境为development, 生成环境为production
```bash
bundle exec sidekiq -C config/sidekiq.yml -e production -d
```

#### 14. 启动rails服务
(15)启动rails服务
```bash
rails s
```

#### 15. 浏览器访问
在浏览器中输入如下地址访问:
(16)浏览器访问:在浏览器中输入如下地址访问
```bash
http://localhost:3000/
```

#### 16. 其他说明
通过页面注册都第一个用户为平台管理员用户

## 页面展示

- 代码库
(17)其他说明:通过页面注册以第一个用户为平台管理员用户

![](docs/figs/code.png?raw=true)

## 页面展示

- 项目列表

<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/project_list.png?raw=true" width=50% />
</center>
- 代码仓库
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/repo.png?raw=true" width=50% />
</center>
- 任务管理
![](docs/figs/issue_manage.png?raw=true)

- 任务查看

![](docs/figs/issue_view.png?raw=true)

- 任务指派
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/issues.png?raw=true" width=50% />
</center>
- 合并请求
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/PR.png?raw=true" width=50% />
</center>
- 引擎配置
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/engine.png?raw=true" width=50% />
</center>

![](docs/figs/issue_assign2.png?raw=true)

- 里程碑

![](docs/figs/milestone.png?raw=true)

### API
- [API文档](https://forgeplus.trustie.net/docs/api)
- [API](showdoc.com.cn)
账号:forgeplus@admin.com 密码:forge123

## 贡献代码

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
我们期待您向GitLink提交贡献!在您贡献时,请遵循流程:[【Wiki文档-GitLink协作开发流程】](https://www.gitlink.org.cn/Gitlink/forgeplus/wiki "【Wiki文档-GitLink协作开发流程】")

#### 指导文档
- [API文档](https://www.gitlink.org.cn/docs/api)
- [Git常用命令](https://git-scm.com/)

## License
## 许可证协议

+ 1
- 0
app/controllers/accounts_controller.rb View File

@@ -214,6 +214,7 @@ class AccountsController < ApplicationController

def change_password
@user = User.find_by(login: params[:login])
return render_error("此用户禁止修改密码!") if @user.id.to_i === 104691
return render_error("未找到相关用户!") if @user.blank?
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])



+ 15
- 10
app/controllers/oauth/educoder_controller.rb View File

@@ -49,24 +49,29 @@ class Oauth::EducoderController < Oauth::BaseController
open_user = OpenUsers::Educoder.find_by(uid: result['login'])
if open_user.present? && open_user.user.present?
successful_authentication(open_user.user)
redirect_to root_path(new_user: false)
return
else
if current_user.blank? || !current_user.logged?
new_user = true
login = User.generate_login('E')
reg_result = autologin_register(login,"#{login}@forge.com", "Ec#{login}2021#", 'educoder', true)
if reg_result[:message].blank?
open_user = OpenUsers::Educoder.create!(user_id: reg_result[:user][:id], uid: result['login'], extra: result)
autosync_register_trustie(login, "Ec#{login}2021#", "#{login}@forge.com")
successful_authentication(open_user.user)
else
render_error(reg_result[:message])
end
session[:unionid] = result['login']
# login = User.generate_login('E')
# reg_result = autologin_register(login,"#{login}@forge.com", "Ec#{login}2021#", 'educoder', true)
# if reg_result[:message].blank?
# open_user = OpenUsers::Educoder.create!(user_id: reg_result[:user][:id], uid: result['login'], extra: result)
# autosync_register_trustie(login, "Ec#{login}2021#", "#{login}@forge.com")
# successful_authentication(open_user.user)
# else
# render_error(reg_result[:message])
# end
else
OpenUsers::Educoder.create!(user: current_user, uid: result['login'], extra: result)
end
end
Rails.logger.info("[OAuth2] session[:unionid] -> #{session[:unionid]}")
redirect_to "/bindlogin/educoder"

redirect_to root_path(new_user: new_user)
# redirect_to root_path(new_user: new_user)
rescue Exception => ex
render_error(ex.message)
end


+ 12
- 1
app/controllers/repositories_controller.rb View File

@@ -22,6 +22,12 @@ class RepositoriesController < ApplicationController
def detail
@user = current_user
@result = Repositories::DetailService.call(@owner, @repository, @user)
cache_total_forks = $redis_cache.get("ProjectSpecialForks:#{@project.id}")
if cache_total_forks.present?
@project_forked_count = cache_total_forks.to_i
else
@project_forked_count = @project.forked_count.to_i
end
@project_fork_id = @project.try(:forked_from_project_id)
if @project_fork_id.present?
@fork_project = Project.find_by(id: @project_fork_id)
@@ -338,7 +344,12 @@ class RepositoriesController < ApplicationController
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
cache_total_commits = $redis_cache.get("ProjectSpecialCommit:#{@project.id}")
if cache_total_commits.present?
@commits_count = cache_total_commits.to_i
else
@commits_count = latest_commit.present? ? latest_commit[:total_count] : 0
end
end
def content_params


+ 6
- 0
app/models/import_repo.rb View File

@@ -0,0 +1,6 @@


# for oauth2 application
class ImportRepo < ApplicationRecord
self.table_name = "open_shixuns"
end

+ 8
- 0
app/models/organization.rb View File

@@ -161,6 +161,14 @@ class Organization < Owner
organization_users.count
end

def teams_count
teams.count
end

def organization_users_count
organization_users.count
end

def real_name
name = lastname + firstname
name = name.blank? ? (nickname.blank? ? login : nickname) : name


+ 30
- 0
app/models/project.rb View File

@@ -448,6 +448,36 @@ class Project < ApplicationRecord
$redis_cache.hdel("issue_cache_delete_count", self.id)
end

def self.mindspore_contributors
cache_result = $redis_cache.get("ProjectMindsporeContributors")
if cache_result.nil?
contributors = []
file = File.open('public/mindspore_authors', 'r')
file.each_line do |l|
itemArray = l.gsub("\r\n", "").split("|:|")
email = itemArray[0]
username = itemArray[1]
commits = itemArray[2].to_i
user = User.find_by(login: username, mail: email)
user = User.find_by(login: username) if user.nil?
user = User.find_by(mail: email) if user.nil?
# next if user.nil?
search_contributor = contributors.select{|con| con["id"]==user.id}[0]
if search_contributor.present?
search_contributor["contributions"] += commits
else
contributors << {contributions: commits, name: username, login: username, email: email, id: user&.id}.stringify_keys
end
end
file.close

$redis_cache.set("ProjectMindsporeContributors", contributors.to_json)

return contributors
else
return JSON.parse(cache_result)
end
end
def to_builder
Jbuilder.new do |project|
project.id self.id


+ 3
- 2
app/models/user.rb View File

@@ -877,11 +877,11 @@ class User < Owner
end
end

def self.develop_score(commit_count, user_id=User.current.id)
def self.develop_score(commit_count, code_line, user_id=User.current.id)
user_date_statistic_key = "v2-user-statistic:#{user_id}"
follow_count = $redis_cache.hget(user_date_statistic_key, "follow-count") || 0
pullrequest_count = $redis_cache.hget(user_date_statistic_key, "pullrequest-count").to_i || 0
issues_count = $redis_cache.hget(user_date_statistic_key, "issue-count") || 0
issues_count = $redis_cache.hget(user_date_statistic_key, "issue-count").to_i || 0
project_count = $redis_cache.hget(user_date_statistic_key, "project-count") || 0
fork_count = $redis_cache.hget(user_date_statistic_key, "fork-count") || 0
project_watchers_count = $redis_cache.hget(user_date_statistic_key, "project-watcher-count") || 0
@@ -889,6 +889,7 @@ class User < Owner
project_language = $redis_cache.hget(user_date_statistic_key, "project-language")
project_languages_count = project_language.nil? || project_language == "{}" ? 0 : JSON.parse(project_language).length
pullrequest_count += commit_count
issues_count += code_line
influence = (60.0 + follow_count.to_i / (follow_count.to_i + 20.0) * 40.0).to_i
contribution = (60.0 + pullrequest_count.to_i / (pullrequest_count.to_i + 20.0) * 40.0).to_i
activity = (60.0 + issues_count.to_i / (issues_count.to_i + 80.0) * 40.0).to_i


+ 4
- 0
app/services/admins/delete_organization_service.rb View File

@@ -6,9 +6,13 @@ class Admins::DeleteOrganizationService < Gitea::ClientService
end

def call
response = delete(url, params)
render_status(response)

Gitea::Organization::DeleteService.call(token,name)
end
private
def token
{


+ 1
- 0
app/services/api/v1/users/update_email_service.rb View File

@@ -18,6 +18,7 @@ class Api::V1::Users::UpdateEmailService < ApplicationService
end

def call
raise Error, "此用户禁止修改邮箱." if @user.id.to_i === 104691
raise Error, errors.full_messages.join(",") unless valid?
raise Error, "密码不正确." unless @user.check_password?(@password)
exist_owner = Owner.find_by(mail: @mail)


+ 1
- 0
app/services/api/v1/users/update_phone_service.rb View File

@@ -15,6 +15,7 @@ class Api::V1::Users::UpdatePhoneService < ApplicationService
end

def call
raise Error, "此用户禁止修改手机号." if @user.id.to_i === 104691
raise Error, errors.full_messages.join(",") unless valid?
raise Error, "密码不正确." unless @user.check_password?(@password)
exist_owner = Owner.find_by(phone: @phone)


+ 1
- 1
app/services/gitea/client_service.rb View File

@@ -82,7 +82,7 @@ class Gitea::ClientService < ApplicationService
req.headers['Content-Type'] = 'application/json'
req.response :logger # 显示日志
req.adapter Faraday.default_adapter
req.options.timeout = 1200 # open/read timeout in seconds
req.options.timeout =7200 # open/read timeout in seconds
req.options.open_timeout = 10 # connection open timeout in seconds
if token.blank?
req.basic_auth(username, secret)


+ 1
- 1
app/services/gitea/repository/commits/file_list_service.rb View File

@@ -20,7 +20,7 @@ class Gitea::Repository::Commits::FileListService < Gitea::ClientService

private
def params
{sha: args[:sha] || 'master', page: args[:page] || PAGINATE_DEFAULT_PAGE, limit: args[:limit] || PAGINATE_DEFAULT_LIMIT, token: args[:token] || "" }
{sha: args[:sha] || 'master', page: args[:page] || PAGINATE_DEFAULT_PAGE, limit: args[:limit] || PAGINATE_DEFAULT_LIMIT, token: args[:token] || "", stat: args[:page].to_i != 1 }
end

def url


+ 1
- 1
app/views/admins/organizations/index.js.erb View File

@@ -1 +1 @@
$('.organizations-list-container').html("<%= j( render partial: 'admins/organizations/shared/org_list', locals: { organizations: @orgs } ) %>");
$('.organizations-list-container').html("<%= j( render partial: 'admins/organizations/shared/org_list', locals: { organizations: @orgs } ) %>");

+ 3
- 3
app/views/api/v1/projects/contributors/stat.json.jbuilder View File

@@ -1,10 +1,10 @@
json.total_count @result_object[:total_data].to_i
result_arr = @result_object[:data]
result_arr = result_arr.sort_by!{|c| User.develop_score(c["commits"])}.reverse
result_arr = result_arr.sort_by!{|c| User.develop_score(c["commits"],c["additions"]+c["deletions"])}.reverse
json.contributors result_arr.each do |contributor|
user = $redis_cache.hgetall("v2-owner-common:#{contributor["name"]}-#{contributor["email"]}")
if user.blank?
json.score User.develop_score(contributor["commits"])
json.score User.develop_score(contributor["commits"],contributor["additions"]+contributor["deletions"] )-300
json.contributions contributor["commits"]
json.additions contributor["additions"]
json.deletions contributor["deletions"]
@@ -15,7 +15,7 @@ json.contributors result_arr.each do |contributor|
json.name contributor["name"]
json.image_url User::Avatar.get_letter_avatar_url(contributor["name"])
else
json.score User.develop_score(contributor["commits"])
json.score User.develop_score(contributor["commits"],contributor["additions"]+contributor["deletions"])-300
json.contributions contributor["commits"]
json.additions contributor["additions"]
json.deletions contributor["deletions"]


+ 1
- 2
app/views/repositories/contributors.json.jbuilder View File

@@ -1,7 +1,6 @@
total_count = @total_count
json.list @contributors.each do |contributor|
json.partial! 'contributor', locals: { contributor: contributor, project: @project }
end
json.total_count total_count
json.total_count @total_count



+ 1
- 1
app/views/repositories/detail.json.jbuilder View File

@@ -11,7 +11,7 @@ json.issues_count @project.issues.issue_issue.size - @project.issues.issue_issue
json.pull_requests_count @project.pull_requests.opening.size
json.project_identifier render_identifier(@project)
json.praises_count @project.praises_count.to_i
json.forked_count @project.forked_count.to_i
json.forked_count @project_forked_count.to_i
json.watchers_count @project.watchers_count.to_i
json.versions_count @project.versions.opening.size #里程碑数量
json.version_releases_count @project.releases_size(@user.try(:id), "all")


+ 50
- 49
config/application.rb View File

@@ -1,49 +1,50 @@
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Gitlink
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
#
#
# config.gitlink = config_for(:configuration)
# Custom directories with classes and modules you want to be autoloadable.
config.active_record.default_timezone = :utc
config.time_zone = 'Beijing'
# I18n
config.i18n.default_locale = 'zh-CN'
config.i18n.load_path += Dir[Rails.root.join('config/locales', '**', '*.yml').to_s]
# job
config.active_job.queue_adapter = :sidekiq
# disable actioncable development nend true
# config.action_cable.disable_request_forgery_protection = true
config.middleware.use OmniAuth::Builder do
provider :cas, url: 'https://urp.tfswufe.edu.cn/cas'
end
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
# location of your api
resource '/*', :headers => :any, :methods => [:get, :post, :delete, :options, :put, :patch]
end
end
end
end
require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module Gitlink
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2

# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
#
#
# config.gitlink = config_for(:configuration)

# Custom directories with classes and modules you want to be autoloadable.

config.active_record.default_timezone = :utc
config.time_zone = 'Beijing'

# I18n
config.i18n.default_locale = 'zh-CN'
config.i18n.load_path += Dir[Rails.root.join('config/locales', '**', '*.yml').to_s]

# job
config.active_job.queue_adapter = :sidekiq

# disable actioncable development nend true
# config.action_cable.disable_request_forgery_protection = true

config.middleware.use OmniAuth::Builder do
provider :cas, url: 'https://urp.tfswufe.edu.cn/cas'
end

config.middleware.insert_before 0, Rack::Cors do
allow do
# origins '*'
origins /http:\/\/localhost(:\d+)?\z/, /^(http|https):\/\/(.*(gitlink.org.cn))$/, /^(http|https):\/\/(.*(trustie.net))$/
# location of your api
resource '/*', :headers => :any, :methods => [:get, :post, :delete, :options, :put, :patch], credentials: true
end
end
end
end

+ 12
- 12
config/sidekiq.yml View File

@@ -1,12 +1,12 @@
:concurrency: <%= ENV["sidekiq_threads"] || 20 %>
:pidfile: tmp/pids/sidekiq.pid
:logfile: log/sidekiq.log
:timeout: 30
:queues:
- [default, 3]
- [searchkick, 10]
- [notify, 100]
- [mailers, 101]
- [cache, 10]
- [message, 20]
- [webhook, 20]
:concurrency: <%= ENV["sidekiq_threads"] || 40 %>
:pidfile: tmp/pids/sidekiq.pid
:logfile: log/sidekiq.log
:timeout: 30
:queues:
- [default, 3]
- [searchkick, 10]
- [notify, 100]
- [mailers, 101]
- [cache, 10]
- [message, 20]
- [webhook, 20]

+ 8
- 5
docker-compose.yml View File

@@ -13,7 +13,7 @@ services:
MYSQL_DATABASE: educoder

redis:
image: redis:3.2
image: redis:6.2.5
container_name: redis
restart: always
ports:
@@ -22,14 +22,17 @@ services:
- ./redis_data:/data

web:
image: guange/educoder:latest
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 4000 -b '0.0.0.0'"
image: gitlink-ubuntu18.04:latest
build:
context: ../
dockerfile: Dockerfile
# command: bash -c "rm -f tmp/pids/server.pid && rails s -p 4000 -b '0.0.0.0'"
stdin_open: true
tty: true
volumes:
- .:/app
- .:/home/app/gitlink
ports:
- "4000:4000"
depends_on:
- mysql
- redis
- redis

BIN
docs/figs/PR.png View File

Before After
Width: 1236  |  Height: 830  |  Size: 58 kB

BIN
docs/figs/code.png View File

Before After
Width: 1792  |  Height: 1017  |  Size: 323 kB

BIN
docs/figs/engine.png View File

Before After
Width: 1238  |  Height: 809  |  Size: 33 kB

BIN
docs/figs/gitlink.png View File

Before After
Width: 2549  |  Height: 912  |  Size: 1.2 MB

BIN
docs/figs/issue_assign.png View File

Before After
Width: 758  |  Height: 2069  |  Size: 204 kB

BIN
docs/figs/issue_assign2.png View File

Before After
Width: 266  |  Height: 779  |  Size: 70 kB

BIN
docs/figs/issue_manage.png View File

Before After
Width: 1583  |  Height: 1116  |  Size: 384 kB

BIN
docs/figs/issue_view.png View File

Before After
Width: 1320  |  Height: 938  |  Size: 210 kB

BIN
docs/figs/issues.png View File

Before After
Width: 1247  |  Height: 972  |  Size: 72 kB

BIN
docs/figs/milestone.png View File

Before After
Width: 2192  |  Height: 1006  |  Size: 228 kB

BIN
docs/figs/project_list.png View File

Before After
Width: 2560  |  Height: 1252  |  Size: 484 kB

BIN
docs/figs/repo.png View File

Before After
Width: 1237  |  Height: 832  |  Size: 84 kB

+ 61
- 0
lib/tasks/batch_add_commits.rake View File

@@ -0,0 +1,61 @@
namespace :batch_add_commits do
desc "batch_add_issues"
task gitee: :environment do
project_id = ENV['project_id']
puts "project_id=================#{project_id}"
next if project_id.blank?
project = Project.find project_id
count = 0
if ENV['count'].present?
count = ENV['count'].to_i
end

total_count = 65669
puts "total_count==========#{total_count}"
if total_count > 100
total_page = (total_count / 100) + 1
total_page.times do |i|
add_commits_to_project(project, i + 1 + count)
end
else
add_commits_to_project(project, 1)
end


end

def add_commits_to_project(project,page)
puts "page==========#{page}"
# curl -X GET --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/mindspore/mindspore/issues?access_token=5ccebd935915fb6cfcae634b161047a2&state=open&sort=created&direction=desc&page=1&per_page=10'
api_url = "https://gitee.com/api/v5/repos/mindspore/mindspore/commits?access_token=96a637aa055f15056e77e3cf11a67525&state=all&sort=created&direction=desc&page=#{page}&per_page=100"
uri = URI.parse(api_url)
response = Net::HTTP.get_response(uri)
puts "gitee api response.code ===== #{response.code}"
lists = JSON.parse(response.body)
puts "lists.size =====#{lists.size}"

data = ""
lists.each do |commit|
# puts "commit==========#{commit}"
commiter = commit['commit']['author']
commit_sha = commit['sha']
next if CommitLog.find_by(commit_id: commit_sha).present?
ref = "master"
commit_message = commit['commit']['message'].to_s.size > 200 ? "Message Data too long" : commit['commit']['message'].to_s.gsub("/n","").gsub("\"","")
user = User.find_by(mail: commiter['email'])
user_id = user&.id || project.user_id
commit_date = Time.parse(commit['commit']['author']['date'])
commit_date_str = commit_date.strftime("%Y-%m-%d %H:%M:%S")

data += "(#{user_id},#{project.id},#{project.repository&.id},'#{project.identifier}','#{project.owner.name}/#{project.identifier}','#{commit_sha}','#{ref}',\"#{commit_message}\",'#{commit_date_str}','#{commit_date_str}'),"
end
data = data[0,data.length-1]
if data.present?
sql_connection = ActiveRecord::Base.connection
sql_connection.begin_db_transaction
sql = "INSERT INTO commit_logs (`user_id`, `project_id`, `repository_id`, `name`, `full_name`, `commit_id`, `ref`, `message`, `created_at`, `updated_at`) VALUES #{data}"
sql_connection.execute(sql)
sql_connection.commit_db_transaction
end
end
end

+ 129
- 0
lib/tasks/batch_add_contributors.rake View File

@@ -0,0 +1,129 @@
namespace :batch_add_contributors do
desc "batch_add_contributors"
task done: :environment do
puts "project_id=================#{ENV['project_id']}"
return if ENV['project_id'].blank?
projects = Project.where(id: ENV['project_id'])
if ENV['project_name'] == "jittor"
projects = Project.where(id: [1403791,1404837,1404087,1403854,1403883,1403886,1403894,1404027,1404187,1404234,1404291,1404522,1404238,1404632,1404003,1403975,1404285,1404525,1404017,1403843,1403867,1403874,1403878,1403881,1403887,1403898,1403916,1403937,1403954,1403961,1403963,1403965,1403967,1403972,1403974,1403976,1403977,1403978,1404007,1404012,1404020,1404023,1404032,1404042,1404058,1404065,1404069,1404071,1404072,1404078,1404094,1404104,1404143,1404146,1404167,1404173,1404174,1404175,1404210,1404216,1404226,1404229,1404240,1404242,1404244,1404247,1404248,1404250,1404261,1404272,1404276,1404290,1404327,1404333,1404360,1404450,1404460,1404466,1404485,1404489,1404491,1404496,1404500,1404502,1404507,1404519,1404521,1404523,1404527,1404530,1404532,1404537,1404540,1404541,1404710,1404328,1404211,1404241,1404107,1403880,1404271,1404268,1404745,1404101,1404051,1404047,1404052,1406706,1403852,1403931,1404165,1404607,1404498,1404014,1404045,1404043,1403739,1403801,1403815,1403821,1403822,1403824,1403836,1403853,1403872,1403904,1403906,1403909,1403915,1403919,1403921,1403943,1403945,1403971,1403981,1404022,1404026,1404030,1404037,1404091,1404133,1404163,1404184,1404209,1404212,1404220,1404246,1404249,1404263,1404265,1404287,1404299,1404311,1404497,1404506,1404546,1404558,1404577,1404582,1404591,1404592,1404594,1404595,1404596,1404597,1404605,1404606,1404609,1404639,1404641,1404659,1404671,1404681,1404702,1404748,1404754,1404759,1404785,1404879,1404955,1405169,1405205,1405265,1405374,1407368,1407446,1407671,1407673,1404956,1404079,1404080,1403889,1404665,1404801,1404224,1404931,1404544,1403844,1404036,1404067,1404587,1404696,1404732,1404598,1405192,1404162,1403920,1403903,1405248,1403792,1403817,1403962,1403841,1404188,1404185,1405273,1404575,1404550,1404834,1405420,1404141,1405256,1404633,1405277,1404590,1404796,1405230,1405189,1404584,1405257,1405198,1403925,1404692,1405253,1403809,1405118,1404756,1404962,1404864,1405190,1405258,1405274,1404642,1404924,1404453,1404926,1404649,1404237,1404233,1404600,1404758,1405259,1404157,1404444,1404451,1404920,1404919,1404927,1403830,1404658,1405145,1405185,1403842,1403807,1403895,1404549,1404593,1404750,1404798,1404551,1404701,1405156,1404579,1404655,1405267,1404957,1404556,1404651,1404456,1405430,1403955,1404063,1404214,1403942,1404040,1404804,1428732,1403939,1404208,1404245,1405278,1404139,1403850,1404192,1404293,1404297,1404370,1404492,1404693,1404757,1404329,1404512,1404228,1404314,1404016,1404652,1405275,1404832,1404561,1404653,1404704,1404892,1404589,1404953,1405269,1404881,1404221,1404230,1404793,1403953,1404933,1404035,1404599,1403924,1404119,1404526,1404581,1404705,1404709,1404073,1403808,1403892,1404574,1403849,1404251,1404792,1403865,1404640,1404783,1404048,1406707,1404708,1404053,1404295,1404050,1404049,1404044,1404274,1404046,1404636])
end
if ENV['project_name'] == "mindspore"
projects = Project.where(identifier: ['MindSpore-first-experience', ' MindSpore-install', 'MindSpore-Application-practice', 'MindSpore-Model-Development', 'MindSpore-Data-preprocessing', 'Mindspore-Data-storage-use', 'MindSpore-Data-storage-kunpeng', 'MindSpore-LeNet-jzx3', 'MindSpore-competition'] )
end
projects.each_with_index do |project, index|
# result = Gitea::Repository::Contributors::GetService.call(project.owner, project.repository.identifier, {page: params[:page], limit: params[:limit]})
result = Gitea::Repository::Commits::ListService.call(project.owner.login,project.identifier,sha: "", page: 1, limit: 200, token: project.owner.gitea_token)
# @total_count = result[:total_count]
# @contributors = result.is_a?(Hash) ? result[:body] : []
next if result.blank? || result[:total_count].blank?
total_count = result[:total_count]
# next if total_count > 2000
puts "#{index} total_count==========#{total_count}"
if total_count > 200
total_page = (total_count / 200) + 1
total_page.times do |i|
add_data_by_page(project, i + 1)
end
else
# add_commit_to_index(project, 1)
data = ""
result[:body].each do |commit|
# puts "commit==========#{commit}"
commiter = commit['commit']['author']
# "luoyuan <luoyuan7@huawei.com>"
commit_author = "#{commiter['name']} <#{commiter['email']}>"
commit_sha = commit['sha']
# next if CommitLog.find_by(commit_id: commit_sha).present?
ref = "master"
commit_message = commit['commit']['message'].to_s.size > 200 ? "Message Data too long" : commit['commit']['message'].to_s.gsub("/n","").gsub("\"","")
# user = User.find_by(mail: commiter['email'])
# user_id = user&.id || project.user_id
commit_date = Time.parse(commit['commit']['author']['date'])
commit_date_str = commit_date.strftime("%Y-%m-%d %H:%M:%S")
site = Site.find_by_sql("select id, created_at from commit_contributors where name='#{commiter['email']}'")
sql =""
if site.present?
puts "commit_date====#{commit_date},created_at======#{site.first&.created_at}"
if commit_date.to_i < site.first&.created_at.to_i
sql = "update commit_contributors set created_at ='#{commit_date_str}' where name='#{commiter['email']}'"
end
else
sql = "INSERT INTO commit_contributors (`created_at`, `count`, `name`) VALUES ('#{commit_date_str}',1,'#{commiter['email']}')"
end
puts "sql====#{sql}"
next if sql.blank?

sql_connection = ActiveRecord::Base.connection
sql_connection.begin_db_transaction
sql_connection.execute(sql)
sql_connection.commit_db_transaction

# data += "(#{user_id},#{project.id},#{project.repository&.id},'#{project.identifier}','#{project.owner.name}/#{project.identifier}','#{commit_sha}','#{ref}',\"#{commit_message}\",'#{commit_date_str}','#{commit_date_str}'),"
end
# data = data[0,data.length-1]
# if data.present?
# sql_connection = ActiveRecord::Base.connection
# sql_connection.begin_db_transaction
# sql = "INSERT INTO commit_contributors (`created_at`, `count`, `name`) VALUES #{data}"
# sql_connection.execute(sql)
# sql_connection.commit_db_transaction
# end
end
end

# Time.now
# Wed Mar 15 14:12:09 2023 +0800
# Time.now.strftime("%a %b %d %H:%M:%S %Y")
# Time.now.strftime("%a %b %d %H:%M:%S %Y +0800")
Time.parse("2023-03-15 14:12:09").strftime("%a %b %d %H:%M:%S %Y +0800")

end

def add_data_by_page(project, page)
# Gitea::Repository::Commits::ListSliceService.call(project.owner.login,project.identifier,sha: "", page: 1, limit: 1000, token: "a9244ecac647dd33fee3b480c5898baab1d3fe7d")
result = Gitea::Repository::Commits::ListService.call(project.owner.login,project.identifier,sha: "", page: page, limit: 200, token: project.owner.gitea_token)
data = ""
result[:body].each do |commit|
# puts "commit==========#{commit}"
commiter = commit['commit']['author']
# "luoyuan <luoyuan7@huawei.com>"
commit_author = "#{commiter['name']} <#{commiter['email']}>"
commit_sha = commit['sha']
# next if CommitLog.find_by(commit_id: commit_sha).present?
ref = "master"
commit_message = commit['commit']['message'].to_s.size > 200 ? "Message Data too long" : commit['commit']['message'].to_s.gsub("/n","").gsub("\"","")
# user = User.find_by(mail: commiter['email'])
# user_id = user&.id || project.user_id
commit_date = Time.parse(commit['commit']['author']['date'])
commit_date_str = commit_date.strftime("%Y-%m-%d %H:%M:%S")
site = Site.find_by_sql("select id, created_at from commit_contributors where name='#{commiter['email']}'")
sql= ""
if site.present?
puts "commit_date====#{commit_date},created_at======#{site.first&.created_at}"
if commit_date.to_i < site.first&.created_at.to_i
sql = "update commit_contributors set created_at ='#{commit_date_str}' where name='#{commiter['email']}'"
end
else
sql = "INSERT INTO commit_contributors (`created_at`, `count`, `name`) VALUES ('#{commit_date_str}',1,'#{commiter['email']}')"
end
puts "sql====#{sql}"
next if sql.blank?

sql_connection = ActiveRecord::Base.connection
sql_connection.begin_db_transaction
sql_connection.execute(sql)
sql_connection.commit_db_transaction

# data += "(#{user_id},#{project.id},#{project.repository&.id},'#{project.identifier}','#{project.owner.name}/#{project.identifier}','#{commit_sha}','#{ref}',\"#{commit_message}\",'#{commit_date_str}','#{commit_date_str}'),"
end
# data = data[0,data.length-1]
# if data.present?
# sql_connection = ActiveRecord::Base.connection
# sql_connection.begin_db_transaction
# sql = "INSERT INTO commit_logs (`user_id`, `project_id`, `repository_id`, `name`, `full_name`, `commit_id`, `ref`, `message`, `created_at`, `updated_at`) VALUES #{data}"
# sql_connection.execute(sql)
# sql_connection.commit_db_transaction
# end
end

end

+ 130
- 0
lib/tasks/batch_add_issues.rake View File

@@ -0,0 +1,130 @@
namespace :batch_add_issues do
desc "batch_add_issues"
task gitee: :environment do
project_id = ENV['project_id']
puts "project_id=================#{project_id}"
next if project_id.blank?
project = Project.find project_id
count = 0
if ENV['count'].present?
count = ENV['count'].to_i
end

total_count = 2066 + 499 + 16675 + 451
puts "total_count==========#{total_count}"
if total_count > 100
total_page = (total_count / 100) + 1
total_page.times do |i|
add_issues_to_project(project, i + 1 + count)
end
else
add_issues_to_project(project, 1)
end


end

def add_issues_to_project(project,page)
# curl -X GET --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/mindspore/mindspore/issues?access_token=5ccebd935915fb6cfcae634b161047a2&state=open&sort=created&direction=desc&page=1&per_page=10'
api_url = "https://gitee.com/api/v5/repos/mindspore/mindspore/issues?access_token=96a637aa055f15056e77e3cf11a67525&state=all&sort=created&direction=desc&page=#{page}&per_page=100"
uri = URI.parse(api_url)
response = Net::HTTP.get_response(uri)
puts "gitee api response.code ===== #{response.code}"
lists = JSON.parse(response.body)
puts "lists.size =====#{lists.size}"

# "1" => "新增",
# "2" => "正在解决",
# "3" => "已解决",
# "5" => "关闭",
# "6" => "拒绝"
# Issue的状态: open(开启的), progressing(进行中), closed(关闭的), rejected(拒绝的)。 默认: open
lists.each do |issue|
created_issue = Issue.find_by(project_id: project.id, subject: issue['title'])
unless created_issue.present?
priority = [1, 2, 3, 4].include?(issue['priority'].to_i) ? issue['priority'].to_i : 2
issue_status = ["", "open", "progressing", "", "", "closed", "rejected"].index(issue['state'])
issue_status = 1 if issue_status.nil?
user_login = issue['user']['login']
user_login = user_login[0..20] if user_login.size > 29
issue_created_at = issue['created_at']
issue_updated_at = issue['updated_at']
user = User.find_by(login: user_login)
unless user.present?
username = user_login
email = "#{username}@gitlink.org.cn"
phone = ""
password = "a12345678"
user = User.new(nickname: user_login, login: username, mail: email, password: password, type: 'User', phone: phone)
interactor = Gitea::RegisterInteractor.call({ username: username, email: email, password: password })
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(username, password)
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
user.created_on = issue_created_at
user.updated_on = issue_created_at
user.is_test = true
user.save!
UserExtension.create!(user_id: user.id)
puts "import_user batch success: phone #{phone} email: #{email}"
end

issue_params = {
:status_id => issue_status,
:priority_id => priority,
# :milestone_id,
# :branch_name,
# :start_date,
# :due_date,
:subject => issue['title'],
:description => issue['body'],
# :blockchain_token_num,
:issue_tag_ids => [],
:assigner_ids => [],
:attachment_ids => [],
:receivers_login => []
}
created_issue = Api::V1::Issues::CreateService.call(project, issue_params, user)
created_issue.update_columns(created_on: issue_created_at, updated_on: issue_updated_at)
end

issue_number = issue['number']
comment_api_url = "https://gitee.com/api/v5/repos/mindspore/mindspore/issues/#{issue_number}/comments?access_token=96a637aa055f15056e77e3cf11a67525&page=1&per_page=100&order=asc"
comment_uri = URI.parse(comment_api_url)
comment_response = Net::HTTP.get_response(comment_uri)
comment_lists = JSON.parse(comment_response.body)

comment_lists.each do |comment|
next if Journal.find_by(journalized_id: created_issue.id, journalized_type: 'Issue', notes: comment['body']).present?
user_login = comment['user']['login']
next if user_login.size >29
comment_created_at = comment['created_at']
comment_updated_at = comment['updated_at']
comment_user = User.find_by(login: user_login)
unless comment_user.present?
username = user_login
email = "#{username}@gitlink.org.cn"
phone = ""
password = "a12345678"
comment_user = User.new(nickname: user_login, login: username, mail: email, password: password, type: 'User', phone: phone)
interactor = Gitea::RegisterInteractor.call({ username: username, email: email, password: password })
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(username, password)
comment_user.gitea_token = result['sha1']
comment_user.gitea_uid = gitea_user[:body]['id']
comment_user.created_on = comment_created_at
comment_user.updated_on = comment_created_at
comment_user.save!
UserExtension.create!(user_id: comment_user.id)
end

journal_params = {:notes => comment['body'],
:attachment_ids => [],
:receivers_login => []}

object_result = Api::V1::Issues::Journals::CreateService.call(created_issue, journal_params, comment_user)
object_result.update_columns(created_on: comment_created_at, updated_on: comment_updated_at)
end
end
end
end

+ 63
- 0
lib/tasks/batch_forked_project.rake
File diff suppressed because it is too large
View File


+ 3
- 0
lib/tasks/commit_log_to_db.rake View File

@@ -7,6 +7,9 @@ namespace :commit_log_to_db do
if ENV['project_name'] == "jittor"
projects = Project.where(id: [1403791,1404837,1404087,1403854,1403883,1403886,1403894,1404027,1404187,1404234,1404291,1404522,1404238,1404632,1404003,1403975,1404285,1404525,1404017,1403843,1403867,1403874,1403878,1403881,1403887,1403898,1403916,1403937,1403954,1403961,1403963,1403965,1403967,1403972,1403974,1403976,1403977,1403978,1404007,1404012,1404020,1404023,1404032,1404042,1404058,1404065,1404069,1404071,1404072,1404078,1404094,1404104,1404143,1404146,1404167,1404173,1404174,1404175,1404210,1404216,1404226,1404229,1404240,1404242,1404244,1404247,1404248,1404250,1404261,1404272,1404276,1404290,1404327,1404333,1404360,1404450,1404460,1404466,1404485,1404489,1404491,1404496,1404500,1404502,1404507,1404519,1404521,1404523,1404527,1404530,1404532,1404537,1404540,1404541,1404710,1404328,1404211,1404241,1404107,1403880,1404271,1404268,1404745,1404101,1404051,1404047,1404052,1406706,1403852,1403931,1404165,1404607,1404498,1404014,1404045,1404043,1403739,1403801,1403815,1403821,1403822,1403824,1403836,1403853,1403872,1403904,1403906,1403909,1403915,1403919,1403921,1403943,1403945,1403971,1403981,1404022,1404026,1404030,1404037,1404091,1404133,1404163,1404184,1404209,1404212,1404220,1404246,1404249,1404263,1404265,1404287,1404299,1404311,1404497,1404506,1404546,1404558,1404577,1404582,1404591,1404592,1404594,1404595,1404596,1404597,1404605,1404606,1404609,1404639,1404641,1404659,1404671,1404681,1404702,1404748,1404754,1404759,1404785,1404879,1404955,1405169,1405205,1405265,1405374,1407368,1407446,1407671,1407673,1404956,1404079,1404080,1403889,1404665,1404801,1404224,1404931,1404544,1403844,1404036,1404067,1404587,1404696,1404732,1404598,1405192,1404162,1403920,1403903,1405248,1403792,1403817,1403962,1403841,1404188,1404185,1405273,1404575,1404550,1404834,1405420,1404141,1405256,1404633,1405277,1404590,1404796,1405230,1405189,1404584,1405257,1405198,1403925,1404692,1405253,1403809,1405118,1404756,1404962,1404864,1405190,1405258,1405274,1404642,1404924,1404453,1404926,1404649,1404237,1404233,1404600,1404758,1405259,1404157,1404444,1404451,1404920,1404919,1404927,1403830,1404658,1405145,1405185,1403842,1403807,1403895,1404549,1404593,1404750,1404798,1404551,1404701,1405156,1404579,1404655,1405267,1404957,1404556,1404651,1404456,1405430,1403955,1404063,1404214,1403942,1404040,1404804,1428732,1403939,1404208,1404245,1405278,1404139,1403850,1404192,1404293,1404297,1404370,1404492,1404693,1404757,1404329,1404512,1404228,1404314,1404016,1404652,1405275,1404832,1404561,1404653,1404704,1404892,1404589,1404953,1405269,1404881,1404221,1404230,1404793,1403953,1404933,1404035,1404599,1403924,1404119,1404526,1404581,1404705,1404709,1404073,1403808,1403892,1404574,1403849,1404251,1404792,1403865,1404640,1404783,1404048,1406707,1404708,1404053,1404295,1404050,1404049,1404044,1404274,1404046,1404636])
end
if ENV['project_name'] == "mindspore"
projects = Project.where(identifier: ['MindSpore-first-experience', ' MindSpore-install', 'MindSpore-Application-practice', 'MindSpore-Model-Development', 'MindSpore-Data-preprocessing', 'Mindspore-Data-storage-use', 'MindSpore-Data-storage-kunpeng', 'MindSpore-LeNet-jzx3', 'MindSpore-competition'] )
end
projects.each_with_index do |project, index|
result = Gitea::Repository::Commits::ListService.call(project.owner.login,project.identifier,sha: "", page: 1, limit: 200, token: project.owner.gitea_token)
next if result.blank? || result[:total_count].blank?


+ 97
- 0
lib/tasks/import_educoder_cource_repo.rake View File

@@ -0,0 +1,97 @@
namespace :import_educoder_cource_repo do
desc "sync outer repository to gitlink"
task done: :environment do
data = ImportRepo.all
if ENV['name'].present?
data = data.where("name like '%#{ENV['name']}%'")
end
data.each_with_index do |row, index|
puts index
root_repo = Repository.find_by(mirror_url: row.git_url)
next if root_repo.blank?
root_project = root_repo.project

begin
user = User.find_by(phone: row.myshixun_user_phone) || User.find_by(mail: row.myshixun_user_mail)
unless user.present?
username = generate_user_login('p')
email = row.myshixun_user_mail.blank? ? "#{username}@gitlink.org.cn" : row.myshixun_user_mail
phone = row.myshixun_user_phone
password = "a12345678"
user = User.new(nickname: row.myshixun_user_name, login: username, mail: email, password: password, type: 'User', phone: phone)
interactor = Gitea::RegisterInteractor.call({ username: username, email: email, password: password })
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(username, password)
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
user.save!
UserExtension.create!(user_id: user.id)
puts "import_user batch success: phone #{phone} email: #{email}"
end

repo = Repository.find_by(mirror_url: row.myshixun_git_url)
next if repo.present? && repo.project.present?
mirror_params = {
user_id: user.id,
auth_username: "xxqfamous@gmail.com",
auth_password: "eHhxMTIzNDU2Nzg5NTIx",
name: root_project.name,
description: root_project.description,
repository_name: root_project.identifier,
project_category_id: root_project.project_category_id,
project_language_id: root_project.project_language_id,
clone_addr: row.myshixun_git_url
}
Projects::MigrateService.call(user, mirror_params)

puts "sync outer repository to gitlink Success repo: #{row.myshixun_git_url}"
rescue Exception => e
puts "sync outer repository to gitlink Error repo: #{row.myshixun_git_url}, error:#{e}"
end
end
end

desc "batch forked project"
task forked: :environment do
data =ImportRepo.all
if ENV['name'].present?
data = data.where("name like '%#{ENV['name']}%'")
end
puts data.to_sql
data.each_with_index do |row, index|
begin
puts index
user = User.find_by(phone: row.myshixun_user_phone) || User.find_by(mail: row.myshixun_user_mail)
next if user.blank?
root_repo = Repository.find_by(mirror_url: row.git_url)
next if root_repo.blank?
root_project = root_repo.project
repo = Repository.find_by(mirror_url: row.myshixun_git_url)
# 学员项目未导入就跳过
next if repo.blank?
# 已绑定的跳过
next if repo.project.forked_from_project_id.present?
# 绑定fork关系
ForkUser.create(project_id: root_project.id, fork_project_id: repo.project.id, user_id: repo.project.user_id)
# 处理时间防止列表刷屏
new_date = root_project.created_on > Time.now - 30.days ? Time.now - 1.years + rand(5..90).day + rand(5..60).hour : root_project.created_on
root_project.update_columns(created_on: new_date, updated_on: new_date, forked_count: (root_project.forked_count.to_i + 1))
# fork时间同样处理在创建时间之后
new_date2 = new_date + rand(5..50).day + rand(5..30).hour
repo.project.update_columns(created_on: new_date2, updated_on: new_date2, forked_from_project_id: root_project.id)
puts "forked project success username: #{user.id}:#{repo.project.id}"
rescue Exception => e
puts "forked project error username: #{username}"
end
end
end

# 生成邀请码
CODES = %W(0 1 2 3 4 5 6 7 8 9)
def generate_user_login type
code = CODES.sample(8).join
code = type + code.to_s
return generate_user_login(type) if User.where(login: code).present?
code
end
end

+ 26
- 0
lib/tasks/init_project_topic.rake View File

@@ -0,0 +1,26 @@
# 执行示例 bundle exec rake init_project_topic:project
# RAILS_ENV=production bundle exec rake init_project_topic:project

namespace :init_project_topic do
desc "Init Project Topic for Project"
task project: :environment do
Project.order(created_at: :desc).find_each do |p|
next unless p.owner.present?
next if p.project_topics.size >= 3
begin
languages = $gitea_client.get_repos_languages_by_owner_repo(p.owner.login, p.identifier)
topic_count = p.project_topics.size
languages.each do |k, _|
next if topic_count >= 3
project_topic = ProjectTopic.find_or_create_by!(name: k.downcase)
project_topic_ralate = project_topic.project_topic_ralates.find_or_create_by!(project_id: p.id)
if project_topic.present? && project_topic_ralate.present?
topic_count +=1
end
end
rescue
next
end
end
end
end

+ 44
- 0
lib/tasks/special_commit.rake View File

@@ -0,0 +1,44 @@
# 执行示例 bundle exec rake "special_commit:load[yystopf, pig]"
# RAILS_ENV=production bundle exec rake "special_commit:load[yystopf, pig]"
#
namespace :special_commit do
desc "Sync Special Commit to Cache"
task :load, [:login, :identifier] => :environment do |t, args|
owner = Owner.find_by(login: args.login)
project = Project.find_by(user_id: owner&.id, identifier: args.identifier)
if owner.nil? || project.nil?
puts "====Project is not found.===="
else
puts "====Sync Project: #{owner.real_name}/#{project.name}===="
puts "====Sync Count Project Self Commit===="
self_commit_list_result = $gitea_client.get_repos_commits_by_owner_repo(owner.login, project.identifier)
total_commits = self_commit_list_result[:total_data].to_i
puts "====Sync Count Project Submodule Commit===="
entries = $gitea_client.get_repos_contents_by_owner_repo(owner.login, project.identifier)
entries.each do |entry|
next if entry["submodule_git_url"].nil?
submodule_git_url = entry["submodule_git_url"].gsub(Rails.application.config_for(:configuration)['platform_url'], '').gsub(".git", '')
real_relative_path = File.expand_path(submodule_git_url, "#{owner.login}/#{project.identifier}").gsub("#{Rails.root}/", '')
sub_project_owner_login = real_relative_path.split("/")[0]
sub_project_identifier = real_relative_path.split("/")[1]
sub_owner = Owner.find_by(login: sub_project_owner_login)
sub_project = sub_owner.projects.find_by(identifier: sub_project_identifier)
next if sub_owner.nil? || sub_project.nil?
sub_commit_list_result = $gitea_client.get_repos_commits_by_owner_repo(sub_project_owner_login, sub_project_identifier)
total_commits += sub_commit_list_result[:total_data].to_i
puts "====Sync Count Project Submodule forkproject Commit===="
sub_project.forked_projects.each do |p|
forked_project_owner_login = p.owner&.login
forked_project_identifier = p.identifier
next if forked_project_owner_login.nil? || forked_project_owner_login.nil?
forked_commit_list_result = $gitea_client.get_repos_commits_by_owner_repo(forked_project_owner_login, forked_project_identifier)
total_commits += forked_commit_list_result[:total_data].to_i
end
end
puts "====Write total commits to cache===="
$redis_cache.set("ProjectSpecialCommit:#{project.id}", total_commits)
$redis_cache.expireat("ProjectSpecialCommit:#{project.id}", (Date.today+30.days).to_time.to_i)
end
end
end

+ 79
- 0
lib/tasks/sync_mindspore_contributors.rake View File

@@ -0,0 +1,79 @@
# 执行示例 bundle exec rake "sync_mindspore:contributor_to_user"
# RAILS_ENV=production bundle exec rake "sync_mindspore:contributor_to_user"
desc "mindspore项目贡献者数据"

# 同步mindspre贡献者数据至用户表

namespace :sync_mindspore do
desc "同步用户信息"
task contributor_to_user: :environment do
i = 1
fail_users = []
file = File.open('public/mindspore_authors', 'r')
file.each_line do |l|
itemArray = l.gsub("\r\n", "").split("|:|")
email = itemArray[0]
username = itemArray[1]
password = '12345678'
puts "=======Generate:[#{i}] Username: #{username}, Password: #{password}, Email: #{email}======="
puts "=======Create User Begin====== "

user = User.new(admin: false, login: username, mail: email, type: "User", is_test: 1)
user.password = password
user.platform = 'forge'
user.activate
unless user.valid?
puts "=======Create User Fail!====== "
fail_users << [username, email]
next
end

interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password})
if interactor.success?
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(username, password)
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
if user.save!
UserExtension.create!(user_id: user.id)
end
end

i += 1
puts "=======Create User End====== "
end
puts "=======Fail Users:#{fail_users}====== "

file.close
end
# 执行示例 bundle exec rake "sync_mindspore:init_project_blockchain[1,2]"
# RAILS_ENV=production bundle exec rake "sync_mindspore:init_project_blockchain[1,2]"
desc "初始化区块链项目"
task :init_project_blockchain, [:id, :init_id] => :environment do |t, args|
puts "=====Init Project Blockchain: #{args.id}====="
project = Project.find_by_id(args.id)
project.update_column(:use_blockchain, true)
username = project.user_id.to_s
token_name = project.id.to_s
total_supply = 10000
token_balance = [[init_id.to_s, 100]]

contributions = Project.mindspore_contributors
total_contributions = contributions.sum{|i| i["contributions"]}
contributions.each do |con|
cont_balance = Float(con["contributions"]*9900/total_contributions).round(0)
token_balance << [con["id"].to_s, cont_balance] if cont_balance > 0
end
params = {
"request-type": "create repo",
"username": username,
"token_name": token_name,
"total_supply": total_supply,
"token_balance": token_balance
}.to_json
resp_body = Blockchain::InvokeBlockchainApi.call(params)
end
end

+ 57
- 0
lib/tasks/total_commit_count.rake View File

@@ -0,0 +1,57 @@
namespace :total_commit_count do
desc "total_commit_count"
task done: :environment do
project_name = ENV['name'] || "mindspore"
puts "project_id=================#{project_name}"
projects = Project.where("name like ?", "%#{project_name}%")
if ENV['count'].present?
projects = projects.limit(ENV['count'].to_i)
end

@date_count_hash = {}
# projects = Project.where(:name => 'opensource0311')
projects.each_with_index do |project, index|
result = Gitea::Repository::Commits::ListService.call(project.owner.login,project.identifier,sha: "", page: 1, limit: 5, token: project.owner.gitea_token)
next if result.blank? || result[:total_count].blank?
total_count = result[:total_count]
next if total_count > 2000
puts "#{index} total_count==========#{total_count}"
if total_count > 50
total_page = (total_count / 50) + 1
total_page.times do |i|
add_commit_to_index(project, i + 1)
end
else
add_commit_to_index(project, 1)
end
puts "#{index} date_count_hash===========#{@date_count_hash.to_json}"

end
puts "@date_count_hash===========#{@date_count_hash.to_json}"




# Time.now
# Wed Mar 15 14:12:09 2023 +0800
# Time.now.strftime("%a %b %d %H:%M:%S %Y")
# Time.now.strftime("%a %b %d %H:%M:%S %Y +0800")
Time.parse("2023-03-15 14:12:09").strftime("%a %b %d %H:%M:%S %Y +0800")

end

def add_commit_to_index(project, page)
# Gitea::Repository::Commits::ListSliceService.call(project.owner.login,project.identifier,sha: "", page: 1, limit: 1000, token: "a9244ecac647dd33fee3b480c5898baab1d3fe7d")
result = Gitea::Repository::Commits::ListService.call(project.owner.login,project.identifier,sha: "", page: page, limit: 50, token: project.owner.gitea_token)
result[:body].each do |commit|
commit_date = Time.parse(commit['commit']['author']['date'])
commit_date_str = commit_date.strftime("%Y-%m")
if @date_count_hash[commit_date_str].present?
@date_count_hash[commit_date_str] = @date_count_hash[commit_date_str] + 1
else
@date_count_hash[commit_date_str] = 1
end
end
end

end

+ 7
- 4
lib/tasks/total_commit_to_db.rake View File

@@ -3,10 +3,13 @@ namespace :total_commit_to_db do
task done: :environment do
project_name = ENV['name'] || "mindspore"
puts "project_id=================#{project_name}"
projects = Project.where(identifier: ['MindSpore-first-experience', ' MindSpore-install', 'MindSpore-Application-practice', 'MindSpore-Model-Development', 'MindSpore-Data-preprocessing', 'Mindspore-Data-storage-use', 'MindSpore-Data-storage-kunpeng', 'MindSpore-LeNet-jzx3', 'MindSpore-competition'] )

if ENV['project_id'].present?
projects = Project.where(id: ENV['project_id'])
else
projects = Project.where(identifier: ['MindSpore-first-experience', ' MindSpore-install', 'MindSpore-Application-practice', 'MindSpore-Model-Development', 'MindSpore-Data-preprocessing', 'Mindspore-Data-storage-use', 'MindSpore-Data-storage-kunpeng', 'MindSpore-LeNet-jzx3', 'MindSpore-competition'] )
end
projects.each_with_index do |project, index|
result = Gitea::Repository::Commits::ListService.call(project.owner.login,project.identifier,sha: "", page: 1, limit: 5, token: project.owner.gitea_token)
result = Gitea::Repository::Commits::ListService.call(project.owner.login,project.identifier,sha: "", page: 1, limit: 200, token: project.owner.gitea_token)
next if result.blank? || result[:total_count].blank?
total_count = result[:total_count]
# next if total_count > 2000
@@ -62,4 +65,4 @@ namespace :total_commit_to_db do
sql_connection.execute(sql)
end

end
end

+ 1
- 1
lib/tasks/update_educoder_user.rake View File

@@ -23,7 +23,7 @@ namespace :update_educoder_user do
department_name = user_info["school"]
password = "12345678"

user.update_columns(mail: "#{email}", phone: "#{phone}")
user.update_columns(mail: "#{email}", phone: "#{phone}", lastname: real_name, nickname: real_name)

sync_params = {
email: email,


+ 0
- 1
public/assets/.sprockets-manifest-7657344e1d61e579de6a996a4498d7a2.json
File diff suppressed because it is too large
View File


+ 1
- 0
public/assets/.sprockets-manifest-fcdcb36eff7e19f6646153ed2fcfd2b4.json
File diff suppressed because it is too large
View File


+ 0
- 142257
public/assets/admin-04ff7d4c76f406e0df9e02923038d175f26ee098d43e266c2138b07163a2da9e.js
File diff suppressed because it is too large
View File


BIN
public/assets/admin-04ff7d4c76f406e0df9e02923038d175f26ee098d43e266c2138b07163a2da9e.js.gz View File


+ 0
- 26869
public/assets/admin-15ad6e029d1195111f661b61d8252ec40b1e453c44c489c661c8fa3211ff62b2.css
File diff suppressed because it is too large
View File


BIN
public/assets/admin-15ad6e029d1195111f661b61d8252ec40b1e453c44c489c661c8fa3211ff62b2.css.gz View File


+ 0
- 26215
public/assets/admin-31e7cc6208d66802217e899555cd22920bb7d043578b1b16250e09dbe76b7bc6.css
File diff suppressed because it is too large
View File


BIN
public/assets/admin-31e7cc6208d66802217e899555cd22920bb7d043578b1b16250e09dbe76b7bc6.css.gz View File


+ 0
- 26869
public/assets/admin-343a62865a99bebf4247a945a48400b472f76196fb80e86b4cce6b2cc480d306.css
File diff suppressed because it is too large
View File


BIN
public/assets/admin-343a62865a99bebf4247a945a48400b472f76196fb80e86b4cce6b2cc480d306.css.gz View File


public/assets/admin-7c523d78203d02769553abade33413cdf663eea3fe1d15ee07ab449240a10a9a.js → public/assets/admin-3e4fde7de877298349280a53b1de578b155575be742d34a72de7574db7f26219.js View File

@@ -28030,6 +28030,187 @@ $.fn.bootstrapViewer.defaults = {
src: 'src'
}
;
/*! ========================================================================
* Bootstrap Toggle: bootstrap-toggle.js v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */



+function ($) {
'use strict';

// TOGGLE PUBLIC CLASS DEFINITION
// ==============================

var Toggle = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, this.defaults(), options)
this.render()
}

Toggle.VERSION = '2.2.0'

Toggle.DEFAULTS = {
on: 'On',
off: 'Off',
onstyle: 'primary',
offstyle: 'default',
size: 'normal',
style: '',
width: null,
height: null
}

Toggle.prototype.defaults = function() {
return {
on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
style: this.$element.attr('data-style') || Toggle.DEFAULTS.style,
width: this.$element.attr('data-width') || Toggle.DEFAULTS.width,
height: this.$element.attr('data-height') || Toggle.DEFAULTS.height
}
}

Toggle.prototype.render = function () {
this._onstyle = 'btn-' + this.options.onstyle
this._offstyle = 'btn-' + this.options.offstyle
var size = this.options.size === 'large' ? 'btn-lg'
: this.options.size === 'small' ? 'btn-sm'
: this.options.size === 'mini' ? 'btn-xs'
: ''
var $toggleOn = $('<label class="btn">').html(this.options.on)
.addClass(this._onstyle + ' ' + size)
var $toggleOff = $('<label class="btn">').html(this.options.off)
.addClass(this._offstyle + ' ' + size + ' active')
var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
.addClass(size)
var $toggleGroup = $('<div class="toggle-group">')
.append($toggleOn, $toggleOff, $toggleHandle)
var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
.addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
.addClass(size).addClass(this.options.style)

this.$element.wrap($toggle)
$.extend(this, {
$toggle: this.$element.parent(),
$toggleOn: $toggleOn,
$toggleOff: $toggleOff,
$toggleGroup: $toggleGroup
})
this.$toggle.append($toggleGroup)

var width = this.options.width || Math.max($toggleOn.outerWidth(), $toggleOff.outerWidth())+($toggleHandle.outerWidth()/2)
var height = this.options.height || Math.max($toggleOn.outerHeight(), $toggleOff.outerHeight())
$toggleOn.addClass('toggle-on')
$toggleOff.addClass('toggle-off')
this.$toggle.css({ width: width, height: height })
if (this.options.height) {
$toggleOn.css('line-height', $toggleOn.height() + 'px')
$toggleOff.css('line-height', $toggleOff.height() + 'px')
}
this.update(true)
this.trigger(true)
}

Toggle.prototype.toggle = function () {
if (this.$element.prop('checked')) this.off()
else this.on()
}

Toggle.prototype.on = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
this.$element.prop('checked', true)
if (!silent) this.trigger()
}

Toggle.prototype.off = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
this.$element.prop('checked', false)
if (!silent) this.trigger()
}

Toggle.prototype.enable = function () {
this.$toggle.removeAttr('disabled')
this.$element.prop('disabled', false)
}

Toggle.prototype.disable = function () {
this.$toggle.attr('disabled', 'disabled')
this.$element.prop('disabled', true)
}

Toggle.prototype.update = function (silent) {
if (this.$element.prop('disabled')) this.disable()
else this.enable()
if (this.$element.prop('checked')) this.on(silent)
else this.off(silent)
}

Toggle.prototype.trigger = function (silent) {
this.$element.off('change.bs.toggle')
if (!silent) this.$element.change()
this.$element.on('change.bs.toggle', $.proxy(function() {
this.update()
}, this))
}

Toggle.prototype.destroy = function() {
this.$element.off('change.bs.toggle')
this.$toggleGroup.remove()
this.$element.removeData('bs.toggle')
this.$element.unwrap()
}

// TOGGLE PLUGIN DEFINITION
// ========================

function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.toggle')
var options = typeof option == 'object' && option

if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
if (typeof option == 'string' && data[option]) data[option]()
})
}

var old = $.fn.bootstrapToggle

$.fn.bootstrapToggle = Plugin
$.fn.bootstrapToggle.Constructor = Toggle

// TOGGLE NO CONFLICT
// ==================

$.fn.toggle.noConflict = function () {
$.fn.bootstrapToggle = old
return this
}

// TOGGLE DATA-API
// ===============

$(function() {
$('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
})

$(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
var $checkbox = $(this).find('input[type=checkbox]')
$checkbox.bootstrapToggle('toggle')
e.preventDefault()
})

}(jQuery);
/* Author:mingyuhisoft@163.com
* Github:https://github.com/imingyu/jquery.mloading
* Npm:npm install jquery.mloading.js
@@ -135541,8 +135722,8 @@ $(document).on('turbolinks:load', function() {
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-courses-index-page').length > 0) {
let searchContainer = $(".course-list-form");
let searchForm = $("form.search-form",searchContainer);
var searchContainer = $(".course-list-form");
var searchForm = $("form.search-form",searchContainer);

searchContainer.on('change', '.course-homepage-show', function(){
searchForm.find('input[type="submit"]').trigger('click');
@@ -135979,6 +136160,20 @@ $(document).on('turbolinks:load', function() {
});
}
});

// ------------ 上移/下移 -------------
$('.discipline-list-container').on('click', ".move-action", function () {
var $doAction = $(this);

var disciplineId = $doAction.data('id');
var opr = $doAction.data('opr');
$.ajax({
url: '/admins/disciplines/' + disciplineId + '/adjust_position',
method: 'POST',
dataType: 'script',
data: {opr: opr}
});
});
}
});
$(document).on('turbolinks:load', function() {
@@ -136082,6 +136277,9 @@ $(document).on('turbolinks:load', function() {
});
}
});
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
;
$(document).on('turbolinks:load', function() {
if($(".admins-graduation-standards-index-page").length > 0){
$(".admin-body-container").on("click", ".standard-create-modal", function () {
@@ -137754,17 +137952,149 @@ $(document).on('turbolinks:load', function() {
}
})
;
$(document).on('turbolinks:load', function () {
if ($('body.admins-projects-index-page').length > 0) {
var $form = $('.search-form');
/*
* @Description: Do not edit
* @Date: 2021-08-31 11:16:45
* @LastEditors: viletyy
* @Author: viletyy
* @LastEditTime: 2021-08-31 14:19:46
* @FilePath: /forgeplus/app/assets/javascripts/admins/system_notifications/index.js
*/

// 清空
$form.on('click', '.clear-btn', function () {
$form.find('input[name="search"]').val('');
$form.find('input[type="submit"]').trigger('click');
});
$(document).on('turbolinks:load', function(){

var showSuccessNotify = function() {
$.notify({
message: '操作成功'
},{
type: 'success'
});
}
});

// close user
$('.project-list-container').on('click', '.recommend-action', function(){
var $closeAction = $(this);
var $uncloseAction = $closeAction.siblings('.unrecommend-action');
var $editAction = $closeAction.siblings('.edit-recommend-action');

var keywordID = $closeAction.data('id');
customConfirm({
content: '确认将该项目设置为推荐项目吗?',
ok: function(){
$.ajax({
url: '/admins/projects/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
project: {
recommend: true,
recommend_index: 1
}
},
success: function() {
showSuccessNotify();
$closeAction.hide();
$uncloseAction.show();
$editAction.show();
$(".project-item-"+keywordID).children('td').eq(5).text("√")
}
});
}
});
});

// unclose user
$('.project-list-container').on('click', '.unrecommend-action', function(){
var $uncloseAction = $(this);
var $closeAction = $uncloseAction.siblings('.recommend-action');
var $editAction = $closeAction.siblings('.edit-recommend-action');

var keywordID = $uncloseAction.data('id');
customConfirm({
content: '确认取消该推荐项目吗?',
ok: function () {
$.ajax({
url: '/admins/projects/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
project: {
recommend: false,
recommend_index: 0
}
},
success: function() {
showSuccessNotify();
$closeAction.show();
$uncloseAction.hide();
$editAction.hide();
$(".project-item-"+keywordID).children('td').eq(5).text("")
}
});
}
})
});


// close user
$('.project-list-container').on('click', '.pinned-action', function(){
var $closeAction = $(this);
var $uncloseAction = $closeAction.siblings('.unpinned-action');

var keywordID = $closeAction.data('id');
customConfirm({
content: '确认将该项目设置为精选项目吗?',
ok: function(){
$.ajax({
url: '/admins/projects/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
project: {
is_pinned: true,
}
},
success: function() {
showSuccessNotify();
$closeAction.hide();
$uncloseAction.show();
$(".project-item-"+keywordID).children('td').eq(4).text("√")
}
});
}
});
});

// unclose user
$('.project-list-container').on('click', '.unpinned-action', function(){
var $uncloseAction = $(this);
var $closeAction = $uncloseAction.siblings('.pinned-action');

var keywordID = $uncloseAction.data('id');
customConfirm({
content: '确认取消该精选项目吗?',
ok: function () {
$.ajax({
url: '/admins/projects/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
project: {
is_pinned: false,
}
},
success: function() {
showSuccessNotify();
$closeAction.show();
$uncloseAction.hide();
$(".project-item-"+keywordID).children('td').eq(4).text("")
}
});
}
})
});
})
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-repertoires-index-page').length > 0) {

@@ -137830,6 +138160,84 @@ $(document).on('turbolinks:load', function() {
});
}
});
/*
* @Description: Do not edit
* @Date: 2021-08-31 11:16:45
* @LastEditors: viletyy
* @Author: viletyy
* @LastEditTime: 2021-08-31 14:19:46
* @FilePath: /forgeplus/app/assets/javascripts/admins/reversed_keywords/index.js
*/

$(document).on('turbolinks:load', function(){

var showSuccessNotify = function() {
$.notify({
message: '操作成功'
},{
type: 'success'
});
}

// close user
$('.reversed-keyword-list-container').on('click', '.close-action', function(){
var $closeAction = $(this);
var $uncloseAction = $closeAction.siblings('.unclose-action');

var keywordID = $closeAction.data('id');
customConfirm({
content: '确认关闭限制吗?',
ok: function(){
$.ajax({
url: '/admins/reversed_keywords/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
reversed_keyword: {
closed: true
}
},
success: function() {
showSuccessNotify();
$closeAction.hide();
$uncloseAction.show();
$(".reversed-keyword-item-"+keywordID).children('td').eq(3).text("")
}
});
}
});
});

// unclose user
$('.reversed-keyword-list-container').on('click', '.unclose-action', function(){
var $uncloseAction = $(this);
var $closeAction = $uncloseAction.siblings('.close-action');

var keywordID = $uncloseAction.data('id');
customConfirm({
content: '确认开启限制吗?',
ok: function () {
$.ajax({
url: '/admins/reversed_keywords/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
reversed_keyword: {
closed: false
}
},
success: function() {
showSuccessNotify();
$closeAction.show();
$uncloseAction.hide();
$(".reversed-keyword-item-"+keywordID).children('td').eq(3).text("√")
}
});
}
})
});
})
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-salesman-channels-index-page').length > 0) {

@@ -137837,13 +138245,13 @@ $(document).on('turbolinks:load', function() {
var $addMemberModal = $('.admin-add-salesman-channel-user-modal');
var $addMemberForm = $addMemberModal.find('.admin-add-salesman-channel-user-form');
var $memberSelect = $addMemberModal.find('.salesman-channel-user-select');
var $salesmanIdInput = $('.salesman-channel-list-form').find(".btn-primary");
var $form = $addMemberModal.find('form.admin-add-salesman-user-form');

$addMemberModal.on('show.bs.modal', function(event){
var $link = $(event.relatedTarget);
// var salesmanId = $link.data('salesman_id');
// $salesmanIdInput.val(salesmanId);
// 搜索
var searchscForm = $(".saleman-channel-list-form .search-form");


$addMemberModal.on('show.bs.modal', function(event){
$memberSelect.select2('val', ' ');
});

@@ -137880,28 +138288,73 @@ $(document).on('turbolinks:load', function() {
// var salesmanId = $salesmanIdInput.val();
var memberIds = $memberSelect.val();
if (memberIds && memberIds.length > 0) {
var url = $form.data('url');
$.ajax({
method: 'POST',
dataType: 'json',
url: '/admins/salesman_channels/batch_add',
data: { salesman_id: $salesmanIdInput.data("salesman-id"), school_ids: memberIds },
url: url,
data: $form.serialize(),
success: function(){
$.notify({ message: '创建成功' });
$addMemberModal.modal('hide');
searchscForm.find('input[name="keyword"]').val('');

setTimeout(function(){
window.location.reload();
submitForm();
}, 500);
},
error: function(res){
var data = res.responseJSON;
$form.find('.error').html(data.message);
$addMemberForm.find('.error').html(data.message);
}
});
} else {
$addMemberModal.modal('hide');
}
});


// 清空
searchscForm.on('click', '.clear-btn', function () {
searchscForm.find('.start_date').val('');
searchscForm.find('.end_date').val('').trigger('change');
searchscForm.find('input[name="keyword"]').val('');
});

// 时间跨度
var baseOptions = {
autoclose: true,
language: 'zh-CN',
format: 'yyyy-mm-dd',
startDate: '2017-04-01'
};

var defineDateRangeSelect = function(element){
var options = $.extend({inputs: $(element).find('.start-date, .end-date')}, baseOptions);
$(element).datepicker(options);

$(element).find('.start-date').datepicker().on('changeDate', function(e){
$(element).find('.end-date').datepicker('setStartDate', e.date);
});
};

defineDateRangeSelect('.grow-date-input-daterange');


// 区间搜索
searchscForm.on('click', ".search-btn", function(){
submitForm();
});

var submitForm = function(){
var url = searchscForm.data('search-form-url');
var form = searchscForm;
$.ajax({
url: url,
data: form.serialize(),
dataType: "script"
})
};
}
});
$(document).on('turbolinks:load', function() {
@@ -137964,7 +138417,7 @@ $(document).on('turbolinks:load', function() {
$addMemberModal.modal('hide');

setTimeout(function(){
window.location.reload();
listForm();
}, 500);
},
error: function(res){
@@ -137976,6 +138429,14 @@ $(document).on('turbolinks:load', function() {
$addMemberModal.modal('hide');
}
});


var listForm = function(){
$.ajax({
url: '/admins/salesman_customers?salesman_id='+ $salesmanIdInput.data("salesman-id"),
dataType: "script"
});
};
}
});
$(document).on('turbolinks:load', function() {
@@ -138272,22 +138733,19 @@ $(document).on('turbolinks:load', function(){
defineDateRangeSelect('.grow-date-input-daterange');
}
});
$(document).on('turbolinks:load', function () {
if ($('body.admins-shixun-modify-records-index-page').length > 0) {
var $form = $('.search-form');
/*
* @Description: Do not edit
* @Date: 2021-07-16 11:58:16
* @LastEditors: viletyy
* @Author: viletyy
* @LastEditTime: 2021-08-31 14:48:59
* @FilePath: /forgeplus/app/assets/javascripts/admins/shixun_settings/index.js
*/

// 清空
$form.on('click', '.clear-btn', function () {
$form.find('select[name="date"]').val('weekly');
$form.find('input[name="user_name"]').val('');
$form.find('input[type="submit"]').trigger('click');
});
}
});
$(document).on('turbolinks:load', function() {
if ($('body.admins-shixun-settings-index-page').length > 0) {
let searchContainer = $(".shixun-settings-list-form");
let searchForm = $("form.search-form",searchContainer);
var searchContainer = $(".shixun-settings-list-form");
var searchForm = $("form.search-form",searchContainer);

searchContainer.on('change', '.shixun-settings-select', function(){
searchForm.find('input[type="submit"]').trigger('click');
@@ -138458,6 +138916,19 @@ $(document).on('turbolinks:load', function () {
data: json
});
});
// ------------ 上移/下移 -------------
$('.sub-discipline-list-container').on('click', ".move-action", function () {
var $doAction = $(this);

var objectId = $doAction.data('id');
var opr = $doAction.data('opr');
$.ajax({
url: '/admins/sub_disciplines/' + objectId + '/adjust_position',
method: 'POST',
dataType: 'script',
data: {opr: opr}
});
});
}
});
$(document).on('turbolinks:load', function() {
@@ -138577,6 +139048,7 @@ $(document).on('turbolinks:load', function () {
}
});


$(".subject-setting-list-container").on("change", '.subject-setting-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
@@ -138716,6 +139188,84 @@ $(document).on('turbolinks:load', function () {
defineStatusChangeFunc('.cancel-excellent-action', '.excellent-action', '/cancel_excellent', excellentCallback);
}
});
/*
* @Description: Do not edit
* @Date: 2021-08-31 11:16:45
* @LastEditors: viletyy
* @Author: viletyy
* @LastEditTime: 2021-08-31 14:19:46
* @FilePath: /forgeplus/app/assets/javascripts/admins/system_notifications/index.js
*/

$(document).on('turbolinks:load', function(){

var showSuccessNotify = function() {
$.notify({
message: '操作成功'
},{
type: 'success'
});
}

// close user
$('.system-notification-list-container').on('click', '.close-action', function(){
var $closeAction = $(this);
var $uncloseAction = $closeAction.siblings('.unclose-action');

var keywordID = $closeAction.data('id');
customConfirm({
content: '确认取消置顶吗?',
ok: function(){
$.ajax({
url: '/admins/system_notifications/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
system_notification: {
is_top: false
}
},
success: function() {
showSuccessNotify();
$closeAction.hide();
$uncloseAction.show();
$(".system-notification-item-"+keywordID).children('td').eq(3).text("")
}
});
}
});
});

// unclose user
$('.system-notification-list-container').on('click', '.unclose-action', function(){
var $uncloseAction = $(this);
var $closeAction = $uncloseAction.siblings('.close-action');

var keywordID = $uncloseAction.data('id');
customConfirm({
content: '确认置顶吗?',
ok: function () {
$.ajax({
url: '/admins/system_notifications/' + keywordID,
method: 'PUT',
dataType: 'json',
data: {
system_notification: {
is_top: true
}
},
success: function() {
showSuccessNotify();
$closeAction.show();
$uncloseAction.hide();
$(".system-notification-item-"+keywordID).children('td').eq(3).text("√")
}
});
}
})
});
})
;
$(document).on('turbolinks:load', function () {
if ($('body.admins-tag-disciplines-index-page').length > 0) {

@@ -138790,6 +139340,20 @@ $(document).on('turbolinks:load', function () {
data: json
});
});

// ------------ 上移/下移 -------------
$('.tag-discipline-list-container').on('click', ".move-action", function () {
var $doAction = $(this);

var objectId = $doAction.data('id');
var opr = $doAction.data('opr');
$.ajax({
url: '/admins/tag_disciplines/' + objectId + '/adjust_position',
method: 'POST',
dataType: 'script',
data: {opr: opr}
});
});
}
});
$(document).on('turbolinks:load', function() {
@@ -139603,6 +140167,7 @@ $(document).on('turbolinks:load', function() {






$.ajaxSetup({
@@ -139675,3 +140240,39 @@ $(document).on("turbolinks:before-cache", function () {

$(function () {
});

$(document).on('turbolinks:load', function() {
$('.logo-item-left').on("change", 'input[type="file"]', function () {
var $fileInput = $(this);
var file = this.files[0];
var imageType = /image.*/;
if (file && file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function () {
var $box = $fileInput.parent();
$box.find('img').attr('src', reader.result).css('display', 'block');
$box.addClass('has-img');
};
reader.readAsDataURL(file);
} else {
}
});

$('.attachment-item-left').on("change", 'input[type="file"]', function () {
var $fileInput = $(this);
var file = this.files[0];
var imageType = /image.*/;
if (file && file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function () {
var $box = $fileInput.parent();
$box.find('img').attr('src', reader.result).css('display', 'block');
$box.addClass('has-img');
};
reader.readAsDataURL(file);
} else {
}
});
})
;

BIN
public/assets/admin-3e4fde7de877298349280a53b1de578b155575be742d34a72de7574db7f26219.js.gz View File


+ 0
- 142260
public/assets/admin-46d2460ea8c06a885f92df73240e8eb84d320402bbdf580ffe3e038d07fdda3d.js
File diff suppressed because it is too large
View File


BIN
public/assets/admin-46d2460ea8c06a885f92df73240e8eb84d320402bbdf580ffe3e038d07fdda3d.js.gz View File


public/assets/admin-5fa03af0e91aea5a8125dc7a7bb31e7a8c4d0a480e2c09ccc7b6db230063c555.css
File diff suppressed because it is too large
View File


BIN
public/assets/admin-5fa03af0e91aea5a8125dc7a7bb31e7a8c4d0a480e2c09ccc7b6db230063c555.css.gz View File


BIN
public/assets/admin-719988f975840fa3b187ef2594aecb8494218f82342377a1f3c71731f68fbf61.css.gz View File


BIN
public/assets/admin-7c523d78203d02769553abade33413cdf663eea3fe1d15ee07ab449240a10a9a.js.gz View File


+ 0
- 142309
public/assets/admin-8cb0e9724b33e253621a5f1020bdc270f828cb7d602de8434d3cc606e0b4dbc2.js
File diff suppressed because it is too large
View File


BIN
public/assets/admin-8cb0e9724b33e253621a5f1020bdc270f828cb7d602de8434d3cc606e0b4dbc2.js.gz View File


+ 0
- 142271
public/assets/admin-8d7c2001aaf2599bddad06c5bc30526b059780d9fda2f01797524c0b8a1c43c3.js
File diff suppressed because it is too large
View File


BIN
public/assets/admin-8d7c2001aaf2599bddad06c5bc30526b059780d9fda2f01797524c0b8a1c43c3.js.gz View File


+ 0
- 49
public/assets/admin-b2526c7eefd8212cde88c53131e8a7dd02f4d96e6d9e262d31dbca516addc979.js
File diff suppressed because it is too large
View File


BIN
public/assets/admin-b2526c7eefd8212cde88c53131e8a7dd02f4d96e6d9e262d31dbca516addc979.js.gz View File


+ 0
- 142301
public/assets/admin-b8f26db185886f99021da91f0e2c1a8cc4ced4d1b895794751d11b7a9f45de98.js
File diff suppressed because it is too large
View File


BIN
public/assets/admin-b8f26db185886f99021da91f0e2c1a8cc4ced4d1b895794751d11b7a9f45de98.js.gz View File


+ 40473
- 0
public/assets/application-1852bb2a261b8a9ce0d4a83dcc076d63be1105549c174f335c1e0f466fa9f8c1.js
File diff suppressed because it is too large
View File


BIN
public/assets/application-1852bb2a261b8a9ce0d4a83dcc076d63be1105549c174f335c1e0f466fa9f8c1.js.gz View File


BIN
public/assets/application-346b678500708f3f4e9cd72c46d1e9e54aaf76e0478b766519ac083bf93fbcff.css.gz View File


+ 0
- 17296
public/assets/application-47eaf72a32e7cee15e04ee7632fbbaadd5efd1129bfe0978d28d9b84ecec913e.js
File diff suppressed because it is too large
View File


BIN
public/assets/application-47eaf72a32e7cee15e04ee7632fbbaadd5efd1129bfe0978d28d9b84ecec913e.js.gz View File


+ 0
- 16
public/assets/application-860dba70259cdc6c5c72c499f8be717c050d517f1fd6a1543c0b6863af987000.js
File diff suppressed because it is too large
View File


BIN
public/assets/application-860dba70259cdc6c5c72c499f8be717c050d517f1fd6a1543c0b6863af987000.js.gz View File


+ 0
- 11520
public/assets/application-8853af8ba870ca7fc8bdae048322f1c5a5caa26f1df87dbbf0c6d04232c4ac4e.css
File diff suppressed because it is too large
View File


BIN
public/assets/application-8853af8ba870ca7fc8bdae048322f1c5a5caa26f1df87dbbf0c6d04232c4ac4e.css.gz View File


+ 0
- 11976
public/assets/application-d3da385d89dfa7edfbecc09573322b132ffc5580cbd185d5f7a74d5358881815.css
File diff suppressed because it is too large
View File


BIN
public/assets/application-d3da385d89dfa7edfbecc09573322b132ffc5580cbd185d5f7a74d5358881815.css.gz View File


+ 0
- 19833
public/assets/application-d44f4301c7dfbe07bcb2788d7c006c22c184ae6b7016c09f7911b4962aacd767.js
File diff suppressed because it is too large
View File


BIN
public/assets/application-d44f4301c7dfbe07bcb2788d7c006c22c184ae6b7016c09f7911b4962aacd767.js.gz View File


+ 0
- 11976
public/assets/application-e194b45894d0c5240d954851211a86516ee6ad871ca99bf7783ce44aeb8c0687.css
File diff suppressed because it is too large
View File


BIN
public/assets/application-e194b45894d0c5240d954851211a86516ee6ad871ca99bf7783ce44aeb8c0687.css.gz View File


+ 1
- 0
public/assets/bootstrap/bootstrap-toggle.min.js-fac504e43bc81af46909bd71548406af8a8fee086aa3e6d0ef86fe93cafbc650.map View File

@@ -0,0 +1 @@
{"version":3,"file":"bootstrap-toggle.min.js","sources":["bootstrap-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","outerHeight","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":"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"}

+ 1
- 0
public/assets/bootstrap/bootstrap2-toggle.min.js-b3598be8ca2991d3ae918a855c3b506702ddafb35ae5178f36473f2705ec4a9c.map View File

@@ -0,0 +1 @@
{"version":3,"file":"bootstrap2-toggle.min.js","sources":["bootstrap2-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":"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"}

+ 0
- 17366
public/assets/college-2065ab3f84df62eb2ca345c83198920fad15cc3b93baf22c091f3c6bfced11b4.css
File diff suppressed because it is too large
View File


BIN
public/assets/college-2065ab3f84df62eb2ca345c83198920fad15cc3b93baf22c091f3c6bfced11b4.css.gz View File


+ 0
- 115915
public/assets/college-431d908264782ef54e90202095d4cf397c586f74d2b7879684348dc8b53d2cd2.js
File diff suppressed because it is too large
View File


BIN
public/assets/college-431d908264782ef54e90202095d4cf397c586f74d2b7879684348dc8b53d2cd2.js.gz View File


+ 0
- 17366
public/assets/college-461b4e52a77522c5ff4341992359aba660dc26d7d985e394b69d8b87db954a14.css
File diff suppressed because it is too large
View File


BIN
public/assets/college-461b4e52a77522c5ff4341992359aba660dc26d7d985e394b69d8b87db954a14.css.gz View File


+ 0
- 16850
public/assets/college-893ba916d2b043f4b751cacc104de43d14e0db0b4001822f996e803bacbda169.css
File diff suppressed because it is too large
View File


BIN
public/assets/college-893ba916d2b043f4b751cacc104de43d14e0db0b4001822f996e803bacbda169.css.gz View File


+ 0
- 34
public/assets/college-bd7fb1ab1da64733a0172f89c8b9d5cfe4db736bb3ee51e0ca0701b40e2e49cc.js
File diff suppressed because it is too large
View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save