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

This commit is contained in:
xxq250 2023-05-10 16:15:51 +08:00
commit 69f8b43186
122 changed files with 43316 additions and 1248001 deletions

1
.gitignore vendored
View File

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

47
Dockerfile Normal file
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'

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'

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

208
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. 克隆稳定版本
```
git clone -b standalone https://git.trustie.net/jasder/forgeplus.git
```
#### 2. 安装依赖包
### 步骤
1安装 Rails 必要的一些三方库:
- Mac OS X
```bash
cd forgeplus && bundle install
brew install imagemagick ghostscript libxml2 libxslt libiconv
```
#### 3. 配置初始化文件
进入项目根目录执行一下命令:
- 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安装 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
git clone -b master https://gitlink.org.cn/Gitlink/forgeplus.git
```
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环境**
8配置/config/database.yml文件(安装redis环境:请自行搜索各平台如何安装部署redis环境)
```yaml
default: &default
url: redis://localhost:6379
db: 1
#### 7. 安装imagemagick插件
- Mac OS X
```bash
brew install imagemagick ghostscript
production:
<<: *default
url: redis://localhost:6379
```
- Linux
```bash
sudo apt-get install -y imagemagick
```
#### 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**
12clone前端代码将前端代码克隆到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)
<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_view.png?raw=true)
- 任务指派
![](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协作开发流程】")
## License
#### 指导文档
- [API文档](https://www.gitlink.org.cn/docs/api)
- [Git常用命令](https://git-scm.com/)
## 许可证协议

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])

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

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

View File

@ -0,0 +1,6 @@
# for oauth2 application
class ImportRepo < ApplicationRecord
self.table_name = "open_shixuns"
end

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

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

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

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
{

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)

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)

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)

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

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 } ) %>");

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"]

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

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")

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

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]

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 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 KiB

BIN
docs/figs/engine.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
docs/figs/gitlink.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

BIN
docs/figs/issues.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

BIN
docs/figs/project_list.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

BIN
docs/figs/repo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

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

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

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

File diff suppressed because one or more lines are too long

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?

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

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

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

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

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

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

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,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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);
/* Authormingyuhisoft@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');
// 搜索
var searchscForm = $(".saleman-channel-list-form .search-form");
$addMemberModal.on('show.bs.modal', function(event){
var $link = $(event.relatedTarget);
// var salesmanId = $link.data('salesman_id');
// $salesmanIdInput.val(salesmanId);
$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 {
}
});
})
;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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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"}

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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"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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