Compare commits

..

55 Commits

Author SHA1 Message Date
jasder 7520fa03c2 Merge branch 'develop' into dev_educoder 2021-03-28 20:05:52 +08:00
jasder f282d971e3 FIX get branches api bug and project menu list bug 2021-03-28 19:56:11 +08:00
jasder 56f01801ae Merge branch 'dev_educoder' into educoder_server 2021-03-28 19:45:24 +08:00
jasder 45e70367d5 Merge branch 'develop' into dev_educoder 2021-03-28 19:45:07 +08:00
jasder a0b376e70a Merge branch 'dev_educoder' into educoder_server 2021-03-27 23:55:11 +08:00
jasder d62d757c42 Merge branch 'develop' into dev_educoder 2021-03-27 23:54:55 +08:00
jasder 033c2607e2 Merge branch 'dev_educoder' into educoder_server 2021-03-25 21:30:46 +08:00
vilet.yy 0d6abdf7d0 fix: setting common arr 2021-03-25 20:59:24 +08:00
jasder 22c68f4c70 FIX bug 2021-03-25 20:29:36 +08:00
jasder fcd86fb01b Merge branch 'dev_educoder' into educoder_server 2021-03-25 19:58:28 +08:00
jasder faecb99136 Merge branch 'develop' into dev_educoder 2021-03-25 19:58:03 +08:00
jasder 15a002f601 Update defalut laboratory setting url 2021-03-23 16:36:35 +08:00
jasder 206d7bc159 Merge branch 'trustie_server' into dev_educoder 2021-03-23 15:58:47 +08:00
jasder 5e0006a830 Merge branch 'trustie_server' into dev_educoder 2021-03-23 15:47:13 +08:00
jasder 3abf993463 Merge branch 'trustie_server' into dev_educoder 2021-03-23 15:43:08 +08:00
jasder efbf6d627d FIX merge 2021-03-23 11:43:24 +08:00
jasder 6836907146 FIX code bug 2021-03-23 10:26:20 +08:00
jasder 6c4058cde5 Merge branch 'educoder_server' into dev_educoder 2021-03-23 10:22:12 +08:00
jasder 5a2e17abe2 FIX project and project_info aasion 2021-03-23 09:34:20 +08:00
jasder 9a8b89bcd8 FIX 解决实训作业关联项目的问题 2021-03-23 09:28:40 +08:00
jasder 4856da1607 Merge branch 'dev_educoder' into educoder_server 2021-03-22 21:02:56 +08:00
jasder 883a5f7e38 Merge branch 'develop' into dev_educoder 2021-03-22 21:02:35 +08:00
jasder 1658c1b923 Merge branch 'dev_educoder' of https://git.trustie.net/jasder/forgeplus into dev_educoder 2021-03-22 17:58:29 +08:00
jasder 74f6a54d29 FIX update setting api for nav bar url 2021-03-22 17:58:15 +08:00
vilet.yy adb315521e fix 2021-03-22 14:20:03 +08:00
vilet.yy 01cad866b8 fix: laboratory 500
fix

fix
2021-03-22 14:17:03 +08:00
jasder 3447b17cdf FIX change password bug 2021-03-22 14:13:25 +08:00
jasder 0079255e98 Merge branch 'develop' into dev_educoder 2021-03-21 11:25:57 +08:00
vilet.yy 490bff5ded fix: form error 2021-03-19 16:18:09 +08:00
vilet.yy 008b8ac709 Merge branch 'develop' into dev_educoder 2021-03-19 15:07:34 +08:00
vilet.yy d0532a8f70 Merge branch 'dev_educoder' of https://git.trustie.net/jasder/forgeplus into dev_educoder 2021-03-19 11:54:10 +08:00
vilet.yy a8c4cde350 add: user info sync_pwd 2021-03-19 11:50:35 +08:00
jasder 5de5974102 FIX remove email for gitea_register api 2021-03-19 10:54:56 +08:00
jasder 3d3e778078 Merge branch 'dev_educoder' of https://git.trustie.net/jasder/forgeplus into dev_educoder 2021-03-19 10:31:12 +08:00
jasder f5ea8dc4a2 FIX change password api 2021-03-19 10:31:06 +08:00
vilet.yy c4b942a5f2 fix 2021-03-18 18:22:07 +08:00
jasder 13391b189a FIX conflict 2021-03-18 18:17:41 +08:00
jasder b116a72ce7 Merge branch 'dev_educoder' of https://git.trustie.net/jasder/forgeplus into dev_educoder 2021-03-18 18:15:22 +08:00
jasder f01aec94d6 FIX 2021-03-18 18:15:08 +08:00
jasder cc97f85a1e ADD has_ansenty 2021-03-18 18:11:06 +08:00
vilet.yy 133995080a add: user info email 2021-03-18 18:11:06 +08:00
vilet.yy 27304c35dc add: user info mark 2021-03-18 18:11:06 +08:00
vilet.yy d6bf85ef73 add: user gitea register 2021-03-18 18:11:06 +08:00
jasder be9c01bf1d ADD educoder api 2021-03-18 18:11:06 +08:00
jasder edeaaa5db7 FIX sync user for educoder 2021-03-18 18:11:06 +08:00
jasder 0e41b6cc9b FIX 整理表结构 2021-03-18 18:11:03 +08:00
jasder 5f3946f187 ADD has_ansenty 2021-03-18 18:07:56 +08:00
jasder b7be00f3ec Merge branch 'dev_educoder' of https://git.trustie.net/jasder/forgeplus into dev_educoder 2021-03-18 17:28:20 +08:00
jasder 9b21e29426 ADD educoder api 2021-03-18 17:27:18 +08:00
vilet.yy f37fccfdb3 add: user info email 2021-03-18 17:22:59 +08:00
vilet.yy 810d2dbac6 add: user info mark 2021-03-18 16:00:05 +08:00
vilet.yy 6af97d865f Merge branch 'dev_educoder' of https://git.trustie.net/jasder/forgeplus into dev_educoder 2021-03-18 15:28:09 +08:00
vilet.yy efba4b2b4f add: user gitea register 2021-03-18 15:28:03 +08:00
jasder aaf1f43cc2 FIX sync user for educoder 2021-03-18 13:46:19 +08:00
jasder 823c99bd71 FIX 整理表结构 2021-03-15 16:02:59 +08:00
86 changed files with 825 additions and 584 deletions

View File

@ -1,17 +1,6 @@
# Changelog
## [v3.0.1](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-03-19
* BUGFIXES
* Fix pull reqeust模块中用户头像显示问题
* Fix 解决issue模块中指派用户的问题
* Fix 解决合并请求失败的后显示message信息不正确
* Fix 代码目录页面readme文件提供单独的api
* ENHANCEMENTS
* 重构项目详情页面
## [v3.0.0](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2020-12-29
## [v3.0.0](https://github.com/go-gitea/gitea/releases/tag/v1.13.1) - 2020-12-29
* BUGFIXES
* Fix pull reqeust的访问权限问题 (#14156) (#14171)

View File

@ -11,32 +11,13 @@ Trustie (确实)是一个以大众化协同开发、开放式资源共享、
## 部署
### Depends Versions
* Ruby 2.4.5
* Rails ~> 5.2
* MySql ~> 5.6
* Redis 5+
* NodeJS > 13.0.0
### Steps
#### 1. 克隆稳定版本
```
git clone -b standalone https://git.trustie.net/jasder/forgeplus.git
```
#### 2. 安装依赖包
### 1. 安装依赖包
```bash
cd forgeplus && bundle install
bundle install
```
#### 3. 配置初始化文件
### 2. 配置初始化文件
进入项目根目录执行一下命令:
```bash
@ -46,24 +27,10 @@ touch config/redis.yml
touch config/elasticsearch.yml
```
#### 4. 配置数据库
数据库配置信息请查看/config/database.yml文件
项目默认采用mysql数据库, 如需更改,请自行修改配置信息,
默认配置如下:
```bash
default: &default
adapter: mysql2
host: 127.0.0.1
encoding: utf8
username: root
password: 123456
```
#### 5. 配置gitea服务(可选)
### 3. 配置gitea服务(可选)
**如需要部署自己的gitea平台请参考gitea官方平台https://docs.gitea.io/zh-cn/install-from-binary/**
**因目前gitea平台api受限暂时推荐从forge平台获取gitea部署文件进行部署https://forgeplus.trustie.net/projects/Trustie/gitea-binary**
**因目前gitea平台api受限暂时推荐从forge平台获取gitea部署文件进行部署https://forgeplus.trustie.net/projects/jasder/gitea-binary
#### 配置gitea服务步骤
1. 部署gitea服务并注册root账户
@ -77,89 +44,75 @@ gitea:
base_url: '/api/v1'
```
#### 6. 安装redis环境
### 4. 安装redis环境
**请自行搜索各平台如何安装部署redis环境**
#### 7. 创建数据库
**开发环境为development 生成环境为production**
### 5. 创建数据库
```bash
rails db:create RAILS_ENV=development
rails db:create
```
#### 8. 导入数据表结构
### 6. 导入数据表结构
```bash
bundle exec rake sync_table_structure:import_csv
```
#### 9. 执行migrate迁移文件
### 7. 执行migrate迁移文件
**开发环境为development 生成环境为production**
```bash
rails db:migrate RAILS_ENV=development
```
#### 10. clone前端代码
**将前端代码克隆到public/react目录下目录结构应该是: public/react/build**
```bash
git clone -b standalone https://git.trustie.net/jasder/build.git
```
#### 11. 启动redis(此处已mac系统为例)
### 8. 启动redis(此处已mac系统为例)
```bash
redis-server&
```
#### 12. 启动sidekiq
### 9. 启动sidekiq
**开发环境为development 生成环境为production**
```bash
bundle exec sidekiq -C config/sidekiq.yml -e production -d
```
#### 13. 启动rails服务
### 10. 启动rails服务
```bash
rails s
```
#### 14. 浏览器访问
### 11. 浏览器访问
在浏览器中输入如下地址访问:
```bash
http://localhost:3000/
```
#### 15. 浏览器访问
在浏览器中输入如下地址访问:
```bash
http://localhost:3000/
```
#### 15. 其他说明
通过页面注册都第一个用户为平台管理员用户
## 页面展示
- 代码库
![](docs/figs/code.png?raw=true)
![](docs/figs/code.png)
- 任务管理
![](docs/figs/issue_manage.png?raw=true)
![](docs/figs/issue_manage.png)
- 任务查看
![](docs/figs/issue_view.png?raw=true)
![](docs/figs/issue_view.png)
- 任务指派
![](docs/figs/issue_assign2.png?raw=true)
![](docs/figs/issue_assign2.png)
- 里程碑
![](docs/figs/milestone.png?raw=true)
![](docs/figs/milestone.png)
### API
- [API文档](https://forgeplus.trustie.net/docs/api)
- [API](api_document.md)
- [API](showdoc.com.cn)
账号forgeplus@admin.com 密码forge123

View File

@ -6,6 +6,27 @@ class AccountsController < ApplicationController
render json: session
end
# 为了同步平台上未注册gitea的用户
def gitea_register
Users::SyncGiteaForm.new(sync_gitea_params).validate!
user = User.find_by(login: sync_gitea_params[:login])
return render_error("该用户已同步协作平台") if user.gitea_token.present? && user.gitea_uid.present?
interactor = Gitea::RegisterInteractor.call({username: sync_gitea_params[:login], email: sync_gitea_params[:email], password: sync_gitea_params[:password]})
if interactor.success?
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(sync_gitea_params[:login], sync_gitea_params[:password])
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
user.save!
render_ok
else
render_error(interactor.error)
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
# 其他平台同步注册的用户
def remote_register
username = params[:username]&.gsub(/\s+/, "")
@ -341,6 +362,10 @@ class AccountsController < ApplicationController
{ login: pre + code, email: email, phone: phone }
end
def sync_gitea_params
params.permit(:login, :email, :password)
end
def user_params
params.require(:user).permit(:login, :email, :phone)
end

View File

@ -35,15 +35,15 @@ module LaboratoryHelper
# my_projects: "/users/#{current_user.try(:login)}/projects",
# my_projects: "https://www.trustie.net/users/#{current_user.try(:login)}/user_projectlist",
{
new_syllabuses: "https://www.trustie.net/syllabuses/new",
new_course: "https://www.trustie.net/courses/new",
edit_account: "https://www.trustie.net/my/account",
my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist",
new_syllabuses: "https://forge.educoder.net/syllabuses/new",
new_course: "https://forge.educoder.net/courses/new",
edit_account: "https://forge.educoder.net/my/account",
my_courses: "https://forge.educoder.net/users/#{current_user.try(:login)}/user_courselist",
my_projects: "/users/#{current_user.try(:login)}/projects",
my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations",
default_url: "https://www.trustie.net/",
tiding_url: "https://www.trustie.net/users/#{current_user.try(:login)}/user_messages",
register_url: "https://www.trustie.net/login?login=false"
my_organ: "https://forge.educoder.net/users/#{current_user.try(:login)}/user_organizations",
default_url: "https://www.educoder.net/",
tiding_url: "https://www.educoder.net/users/#{current_user.try(:login)}/user_tidings",
register_url: "https://www.educoder.net/user/register"
}
end
end

View File

@ -5,6 +5,14 @@ class ForksController < ApplicationController
def create
@new_project = Projects::ForkService.new(current_user, @project, params[:organization]).call
# TODO: fix Educoder shixun
if @new_project.persisted?
ProjectScore.create(:project_id => @new_project.id, :score => 0) if @new_project.project_score.nil?
project_info = ProjectInfo.new(:user_id => current_user.id, :project_id => @new_project.id)
@project.project_infos << project_info
end
end
private

View File

@ -4,7 +4,7 @@ class Projects::ProjectUnitsController < Projects::BaseController
end
def create
if current_user.admin? || @project.manager?(current_user)
if current_user.admin? || @project.owner?(current_user)
ActiveRecord::Base.transaction do
ProjectUnit.update_by_unit_types!(@project, unit_types)
render_ok

View File

@ -17,7 +17,7 @@ class ProjectsController < ApplicationController
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops")
menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions")
menu.append(menu_hash_by_name("activity"))
menu.append(menu_hash_by_name("setting")) if current_user.admin? || @project.manager?(current_user)
menu.append(menu_hash_by_name("setting")) if current_user.admin? || @project.owner?(current_user)
render json: menu
end
@ -44,6 +44,13 @@ class ProjectsController < ApplicationController
Projects::CreateForm.new(project_params).validate!
@project = Projects::CreateService.new(current_user, project_params).call
# TODO: fix Educoder shixun
if @project.persisted?
ProjectScore.create(:project_id => @project.id, :score => 0) if @project.project_score.nil?
project_info = ProjectInfo.new(:user_id => current_user.id, :project_id => @project.id)
@project.project_infos << project_info
end
end
rescue Exception => e
uid_logger_error(e.message)
@ -111,7 +118,7 @@ class ProjectsController < ApplicationController
end
def destroy
if current_user.admin? || @project.manager?(current_user)
if current_user.admin? || @project.owner?(current_user)
ActiveRecord::Base.transaction do
Gitea::Repository::DeleteService.new(@project.owner, @project.identifier).call
@project.destroy!

View File

@ -1,58 +1,28 @@
class SettingsController < ApplicationController
def show
@old_projects_url = nil
get_add_menu
get_common_menu
get_personal_menu
@old_projects_url = "https://www.trustie.net/users/#{current_user.try(:login)}/projects" if User.current.logged?
end
private
def get_add_menu
@add = []
Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|
@add = Site.add.select(:id, :name, :url, :key)
@personal = []
if User.current.logged?
Site.personal.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|
hash = {}
site.each {|k, v|
hash.merge!("#{k}": get_site_url(k, v))
hash.merge!("#{k}": v.to_s.include?("current_user") ? v.split('current_user').join(current_user&.login) : v)
}
@add << hash
@personal << hash
end
end
def get_common_menu
@common = {}
Site.common.select(:url, :key).each do |site|
next if site["url"].to_s.include?("current_user") && !User.current.logged?
@common.merge!("#{site["key"]}": append_http(reset_site_url(site["url"])))
end
@common = []
Site.common.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|
next if site["url"].to_s.include?("current_user") && !User.current.logged?
hash = {}
site.each {|k, v|
hash.merge!("#{k}": v.to_s.include?("current_user") ? v.split('current_user').join(current_user&.login) : v)
}
@common << hash
end
def get_personal_menu
@personal = []
if User.current.logged?
Site.personal.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|
hash = {}
site.each {|k, v|
hash.merge!("#{k}": get_site_url(k, v))
}
@personal << hash
end
end
end
def get_site_url(key, value)
url = reset_site_url(value)
key.to_s === "url" && !value.to_s.start_with?("http") ? [request.protocol, request.host_with_port, value].join('') : url
end
def reset_site_url(url)
return url unless url.to_s.include?("current_user")
split_arr = url.split('current_user')
split_arr.length > 1 ? split_arr.join(current_user&.login) : (split_arr << current_user&.login).join('')
end
def append_http(url)
url.to_s.start_with?("http") ? url : [request.protocol, request.host_with_port, url].join('')
end
end
end

View File

@ -4,7 +4,7 @@ class UsersController < ApplicationController
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users]
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users]
before_action :require_login, only: %i[me list]
before_action :require_login, only: %i[me list change_password change_email]
before_action :connect_to_ci_db, only: [:get_user_info]
skip_before_action :check_sign, only: [:attachment_show]
@ -233,6 +233,63 @@ class UsersController < ApplicationController
render_ok
end
# TODO: For Educoder
def change_password
user = User.find_by_login params[:login]
return render_error("用户 #{params[:login]} 不存在.") unless user === current_user
form_params= {
login: params[:login],
email: user&.mail,
password: params[:password],
user: user
}
Gitea::User::ChangePasswordForm.new(form_params).validate!
sync_params = {
email: user&.mail,
password: params[:password]
}
if sync_params.present?
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params)
if interactor.success?
user.update!(password: params[:password], is_sync_pwd: true)
render_ok
else
render_error(interactor.error)
end
end
end
# TODO: For Educoder
def change_email
user = User.find_by_login params[:login]
return render_error("用户 #{rq_params[:login]} 不存在.") unless user === current_user
form_params= {
login: params[:login],
email: user&.mail,
user: user
}
Gitea::User::ChangeEmailForm.new(form_params).validate!
sync_params = {
email: params[:email]
}
if sync_params.present?
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params)
if interactor.success?
user.update!(mail: params[:email])
render_ok
else
render_error(interactor.error)
end
end
end
private
def load_user
@user = User.find_by_login(params[:id]) || User.find_by(id: params[:id])

View File

@ -0,0 +1,9 @@
class Gitea::User::ChangeEmailForm
include ActiveModel::Model
attr_accessor :user
attr_accessor :email, :login
validates :email, presence: true, format: { with: CustomRegexp::EMAIL }
validates :login, presence: true
end

View File

@ -0,0 +1,22 @@
class Gitea::User::ChangePasswordForm
include ActiveModel::Model
attr_accessor :user
attr_accessor :email, :login, :password
validates :email, presence: true, format: { with: CustomRegexp::EMAIL }
validates :login, presence: true
validates :password, presence: true
# validate :check_old_password
def check_old_password
return if user.check_password?(old_password.to_s)
errors.add(:old_password, :password_error)
end
# def check_user!
# user === current_user
# end
end

View File

@ -0,0 +1,18 @@
class Users::SyncGiteaForm
include ActiveModel::Model
attr_accessor :login, :password, :email, :user
validates :login, :password, :email, presence: true
validate :check_user, :check_password
def check_user
@user = User.find_by(login: login)
raise '用户不存在.' unless user.present?
end
def check_password
raise '用户密码错误.' unless user.check_password?(password)
end
end

View File

@ -28,7 +28,7 @@ module RepositoriesHelper
def render_commit_author(author_json)
return nil if author_json.blank?
find_user_by_login author_json['name']
find_user_by_login author_json['login']
end
def readme_render_decode64_content(str, path)

View File

@ -17,7 +17,7 @@
# disk_directory :string(255)
# attachtype :integer default("1")
# is_public :integer default("1")
# copy_from :integer
# copy_from :string(255)
# quotes :integer default("0")
# is_publish :integer default("1")
# publish_time :datetime
@ -26,15 +26,15 @@
# cloud_url :string(255) default("")
# course_second_category_id :integer default("0")
# delay_publish :boolean default("0")
# link :string(255)
# clone_id :integer
#
# Indexes
#
# index_attachments_on_author_id (author_id)
# index_attachments_on_clone_id (clone_id)
# index_attachments_on_container_id_and_container_type (container_id,container_type)
# index_attachments_on_course_second_category_id (course_second_category_id)
# index_attachments_on_created_on (created_on)
# index_attachments_on_is_public (is_public)
# index_attachments_on_quotes (quotes)
#
class Attachment < ApplicationRecord

View File

@ -1,3 +1,21 @@
# == Schema Information
#
# Table name: chart_rules
#
# id :integer not null, primary key
# rule_type :string(255)
# content :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
# competition_id :integer
# competition_stage_id :integer
#
# Indexes
#
# index_chart_rules_on_competition_id (competition_id)
# index_chart_rules_on_competition_stage_id (competition_stage_id)
#
class ChartRule < ApplicationRecord
validates :content, length: { maximum: 1000, too_long: "不能超过1000个字符" }

View File

@ -1,3 +1,22 @@
# == Schema Information
#
# Table name: stages
#
# id :integer not null
# subject_id :integer
# name :string(255)
# description :text(65535)
# user_id :integer
# position :integer
# created_at :datetime not null
# updated_at :datetime not null
# shixuns_count :integer default("0")
#
# Indexes
#
# index_stages_on_subject_id (subject_id)
#
class Ci::Stage < Ci::RemoteBase
self.primary_key = 'stage_id'

View File

@ -39,13 +39,14 @@
# business :boolean default("0")
# profile_completed :boolean default("0")
# laboratory_id :integer
# platform :string(255) default("0")
# gitea_token :string(255)
# gitea_uid :integer
# is_shixun_marker :boolean default("0")
# admin_visitable :boolean default("0")
# collaborator :boolean default("0")
# gitea_uid :integer
# is_sync_pwd :boolean default("1")
# watchers_count :integer default("0")
# devops_step :integer default("0")
# gitea_token :string(255)
#
# Indexes
#
@ -53,8 +54,9 @@
# index_users_on_homepage_engineer (homepage_engineer)
# index_users_on_homepage_teacher (homepage_teacher)
# index_users_on_laboratory_id (laboratory_id)
# index_users_on_login (login)
# index_users_on_mail (mail)
# index_users_on_login (login) UNIQUE
# index_users_on_mail (mail) UNIQUE
# index_users_on_phone (phone) UNIQUE
# index_users_on_type (type)
#

View File

@ -1,3 +1,38 @@
# == Schema Information
#
# Table name: discusses
#
# id :integer not null, primary key
# user_id :integer
# dis_type :string(255)
# dis_id :integer
# content :text(65535)
# parent_id :integer
# root_id :integer
# praise_count :integer
# created_at :datetime not null
# updated_at :datetime not null
# challenge_id :integer
# reward :integer
# hidden :boolean default("0")
# last_reply_id :integer
# position :integer
# praises_count :integer default("0")
# sticky :boolean default("0")
# course_sticky :boolean default("0")
# course_hidden :boolean default("0")
# copy_message_id :integer
#
# Indexes
#
# index_discusses_on_challenge_id (challenge_id)
# index_discusses_on_copy_message_id (copy_message_id)
# index_discusses_on_course_hidden (course_hidden)
# index_discusses_on_course_sticky (course_sticky)
# index_discusses_on_dis_id_and_dis_type (dis_id,dis_type)
# index_discusses_on_user_id (user_id)
#
class Discuss < ApplicationRecord
default_scope { order(created_at: :desc) }

View File

@ -1,5 +1,24 @@
# == Schema Information
#
# Table name: forge_activities
#
# id :integer not null, primary key
# user_id :integer
# project_id :integer
# forge_act_id :integer
# forge_act_type :string(255)
# org_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# forge_act_index (project_id,forge_act_id,created_at,forge_act_type)
# index_forge_activities_on_forge_act_id (forge_act_id)
#
class ForgeActivity < ApplicationRecord
belongs_to :user
belongs_to :project
belongs_to :forge_act, polymorphic: true
end
end

View File

@ -1,3 +1,17 @@
# == Schema Information
#
# Table name: helps
#
# id :integer not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
# about_us :text(65535)
# agreement :text(65535)
# status :text(65535)
# help_center :text(65535)
# join_us :text(65535)
#
class Help < ApplicationRecord
end
end

View File

@ -10,6 +10,12 @@
# sync_course :boolean default("0")
# sync_subject :boolean default("0")
# sync_shixun :boolean default("0")
# is_local :boolean default("0")
#
# Indexes
#
# index_laboratories_on_identifier (identifier) UNIQUE
# index_laboratories_on_school_id (school_id)
#
class Laboratory < ApplicationRecord

View File

@ -6,6 +6,10 @@
# laboratory_id :integer
# config :text(65535)
#
# Indexes
#
# index_laboratory_settings_on_laboratory_id (laboratory_id)
#
class LaboratorySetting < ApplicationRecord
belongs_to :laboratory

View File

@ -7,7 +7,6 @@
# content :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
# is_secret :boolean default("0")
#
class License < ApplicationRecord

View File

@ -1,3 +1,27 @@
# == Schema Information
#
# Table name: live_links
#
# id :integer not null, primary key
# course_id :integer
# user_id :integer
# url :string(255)
# description :text(65535)
# on_status :boolean default("0")
# created_at :datetime not null
# updated_at :datetime not null
# course_name :string(255)
# platform :string(255)
# live_time :datetime
# duration :integer
# position :integer
#
# Indexes
#
# index_live_links_on_course_id (course_id)
# index_live_links_on_user_id (user_id)
#
class LiveLink < ApplicationRecord
# belongs_to :course
belongs_to :user

View File

@ -11,7 +11,6 @@
# course_group_id :integer default("0")
# is_collect :integer default("1")
# graduation_group_id :integer default("0")
# is_apply_signature :boolean default("0")
#
# Indexes
#

View File

@ -1,3 +1,18 @@
# == Schema Information
#
# Table name: message_details
#
# id :integer not null, primary key
# content :text(4294967295)
# message_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_message_details_on_message_id (message_id)
#
class MessageDetail < ApplicationRecord
# belongs_to :message, :touch => true
validates :content, length: { maximum: 10000, too_long: "内容不能超过10000个字符" }

View File

@ -39,13 +39,14 @@
# business :boolean default("0")
# profile_completed :boolean default("0")
# laboratory_id :integer
# platform :string(255) default("0")
# gitea_token :string(255)
# gitea_uid :integer
# is_shixun_marker :boolean default("0")
# admin_visitable :boolean default("0")
# collaborator :boolean default("0")
# gitea_uid :integer
# is_sync_pwd :boolean default("1")
# watchers_count :integer default("0")
# devops_step :integer default("0")
# gitea_token :string(255)
#
# Indexes
#
@ -53,8 +54,9 @@
# index_users_on_homepage_engineer (homepage_engineer)
# index_users_on_homepage_teacher (homepage_teacher)
# index_users_on_laboratory_id (laboratory_id)
# index_users_on_login (login)
# index_users_on_mail (mail)
# index_users_on_login (login) UNIQUE
# index_users_on_mail (mail) UNIQUE
# index_users_on_phone (phone) UNIQUE
# index_users_on_type (type)
#

View File

@ -37,8 +37,6 @@
# rep_identifier :string(255)
# project_category_id :integer
# project_language_id :integer
# license_id :integer
# ignore_id :integer
# praises_count :integer default("0")
# watchers_count :integer default("0")
# issues_count :integer default("0")
@ -52,6 +50,8 @@
# open_devops_count :integer default("0")
# recommend :boolean default("0")
# platform :integer default("0")
# license_id :integer
# ignore_id :integer
# default_branch :string(255) default("master")
# website :string(255)
#
@ -71,9 +71,6 @@
#
class Project < ApplicationRecord
include Matchable
include Publicable
@ -102,6 +99,7 @@ class Project < ApplicationRecord
has_one :project_educoder, dependent: :destroy
has_one :project_score, dependent: :destroy
has_many :project_infos, :dependent => :destroy
has_one :repository, dependent: :destroy
has_many :pull_requests, dependent: :destroy
has_many :issue_tags, -> { order("issue_tags.created_at DESC") }, dependent: :destroy

View File

@ -8,11 +8,6 @@
# projects_count :integer default("0")
# created_at :datetime not null
# updated_at :datetime not null
# ancestry :string(255)
#
# Indexes
#
# index_project_categories_on_ancestry (ancestry)
#
class ProjectCategory < ApplicationRecord

View File

@ -0,0 +1,8 @@
class ProjectInfo < ActiveRecord::Base
belongs_to :project
belongs_to :user
validates_presence_of :project_id, :user_id
validates_uniqueness_of :project_id, :scope => :user_id
end

View File

@ -25,7 +25,6 @@
#
# Indexes
#
# index_repositories_on_identifier (identifier)
# index_repositories_on_project_id (project_id)
# index_repositories_on_user_id (user_id)
#

View File

@ -1,3 +1,39 @@
# == Schema Information
#
# Table name: schools
#
# id :integer not null, primary key
# name :string(255)
# province :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# logo_link :string(255)
# pinyin :string(255)
# school_type :integer default("0")
# city :string(255)
# address :string(255)
# auto_users_trial :boolean default("0")
# shool_code :string(255)
# authorization_time :datetime
# ec_auth :integer default("0")
# identifier :string(255)
# is_online :boolean default("0")
# video_name :string(255)
# video_desc :string(255)
# course_link :string(255)
# course_name :string(255)
# partner_id :integer
# customer_id :integer
# school_property_id :integer
#
# Indexes
#
# index_schools_on_customer_id (customer_id)
# index_schools_on_identifier (identifier)
# index_schools_on_partner_id (partner_id)
# index_schools_on_school_property_id (school_property_id)
#
class School < ApplicationRecord
has_many :departments, dependent: :destroy

View File

@ -17,56 +17,7 @@ class Site < ApplicationRecord
# common: 普通链接
enum site_type: { add: 0, personal: 1, common: 2 }
def self.set_default_menu
set_add_menu!
set_personal_menu!
set_common_menu!
def self.set_default
end
private
def self.set_add_menu!
adds= [
{name: '新建镜像项目', key: 'add_mirror_project', url: '/projects/mirror/new'},
{name: '新建托管项目', key: 'add_common', url: '/projects/deposit/new'},
{name: '新建组织', key: 'add_r', url: '/organize/new'}]
adds.each { |ele|
Site.find_or_create_by(key: ele[:key]) do |site|
site.name = ele[:name]
site.url = ele[:url]
site.site_type = Site.site_types[:add]
end
}
end
def self.set_personal_menu!
personals = [
{name: '个人中心', key: 'my_page', url: '/users/current_user'},
{name: '我的组织', key: 'my_organizes', url: '/users/current_user/organizes'}
]
personals.each { |ele|
Site.find_or_create_by(key: ele[:key]) do |site|
site.name = ele[:name]
site.url = ele[:url]
site.site_type = Site.site_types[:personal]
end
}
end
def self.set_common_menu!
commons = [
{name: '通知', key: 'notice', url: '/users/current_user/user_messages'},
{name: '找回密码', key: 'lost_password', url: '/account/lost_password'},
{name: '注册', key: 'register', url: '/login?login=false'}
]
commons.each { |ele|
Site.find_or_create_by(key: ele[:key]) do |site|
site.name = ele[:name]
site.url = ele[:url]
site.site_type = Site.site_types[:common]
end
}
end
end

View File

@ -1,4 +1,87 @@
# == Schema Information
#
# Table name: courses
#
# id :integer not null, primary key
# tea_id :integer
# name :string(255)
# state :integer
# code :string(255)
# time :integer
# extra :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# location :string(255)
# term :string(255)
# string :string(255)
# password :string(255)
# setup_time :string(255)
# endup_time :string(255)
# class_period :integer default("0")
# school_id :integer
# description :text(65535)
# status :integer default("1")
# attachmenttype :integer default("2")
# lft :integer
# rgt :integer
# is_public :integer default("1")
# inherit_members :integer default("1")
# open_student :integer default("0")
# outline :integer default("0")
# publish_resource :integer default("0")
# is_delete :integer default("0")
# end_time :integer
# end_term :string(255)
# is_excellent :integer default("0")
# excellent_option :integer default("0")
# is_copy :integer default("0")
# visits :integer default("0")
# syllabus_id :integer
# invite_code :string(255)
# qrcode :string(255)
# qrcode_expiretime :integer default("0")
# invite_code_halt :integer default("0")
# os_allow :integer default("0")
# credit :float(24)
# is_end :boolean default("0")
# end_date :date
# choose_group_allow :boolean default("0")
# homepage_show :boolean default("0")
# course_list_id :integer
# members_count :integer default("0")
# homework_commons_count :integer default("0")
# show_unit :boolean default("0")
# teacher_list :string(255) default("老师")
# student_list :string(255) default("学生")
# is_hidden :boolean default("0")
# course_members_count :integer default("0")
# course_groups_count :integer default("0")
# authentication :boolean default("0")
# professional_certification :boolean default("0")
# graduation_topics_count :integer default("0")
# graduation_tasks_count :integer default("0")
# polls_count :integer default("0")
# exercises_count :integer default("0")
# start_date :date
# subject_id :integer default("0")
# excellent :boolean default("0")
# email_notify :boolean default("0")
# sticky :boolean default("0")
# sticky_time :datetime
# laboratory_id :integer
# mooc_course_id :integer
#
# Indexes
#
# index_courses_on_invite_code (invite_code) UNIQUE
# index_courses_on_laboratory_id (laboratory_id)
# index_courses_on_mooc_course_id (mooc_course_id)
# index_courses_on_school_id_and_is_delete (school_id,is_delete)
# index_courses_on_subject_id (subject_id)
# index_courses_on_tea_id (tea_id)
#
class Trustie::Course < Trustie::Database
has_many :course_groups, class_name: "Trustie::CourseGroup"
has_many :homework_commons, class_name: "Trustie::HomeworkCommon"
end
end

View File

@ -1,3 +1,25 @@
# == Schema Information
#
# Table name: course_groups
#
# id :integer not null, primary key
# name :string(255)
# course_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# members_count :integer
# invite_code :string(255)
# position :integer default("0")
# course_members_count :integer default("0")
# invite_code_halt :boolean default("0")
# invite_code_set :integer default("0")
#
# Indexes
#
# index_course_groups_on_course_id (course_id)
# index_course_groups_on_invite_code (invite_code) UNIQUE
#
class Trustie::CourseGroup < Trustie::Database
belongs_to :course, class_name: "Trustie::Course"
end
end

View File

@ -1,3 +1,54 @@
# == Schema Information
#
# Table name: homework_commons
#
# id :integer not null, primary key
# name :string(255)
# user_id :integer
# description :text(65535)
# publish_time :datetime
# end_time :datetime
# homework_type :integer default("1")
# late_penalty :string(255) default("0")
# course_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# teacher_priority :integer default("1")
# anonymous_comment :boolean default("0")
# quotes :integer default("0")
# is_open :integer default("0")
# simi_time :datetime
# score_open :boolean default("0")
# anonymous_appeal :boolean default("0")
# homework_bank_id :integer
# is_update :boolean default("0")
# is_public :boolean default("0")
# reference_answer :text(65535)
# answer_public :boolean default("0")
# archive_time :datetime
# allow_late :boolean default("0")
# late_time :datetime
# work_public :boolean default("0")
# explanation :text(65535)
# unified_setting :boolean default("1")
# comment_public :boolean default("1")
# course_homework_category_id :integer
# work_efficiency :boolean default("0")
# eff_score :float(24) default("0")
# max_efficiency :float(24) default("0")
# course_second_category_id :integer default("0")
# calculation_time :datetime
# position :integer default("0")
# total_score :float(24) default("100")
# category_position :integer default("0")
#
# Indexes
#
# index_homework_commons_on_course_id_and_id (course_id,id)
# index_homework_commons_on_course_second_category_id (course_second_category_id)
# index_homework_commons_on_homework_bank_id (homework_bank_id)
#
class Trustie::HomeworkCommon < Trustie::Database
belongs_to :course, class_name: "Trustie::Course"
end
end

View File

@ -39,13 +39,14 @@
# business :boolean default("0")
# profile_completed :boolean default("0")
# laboratory_id :integer
# platform :string(255) default("0")
# gitea_token :string(255)
# gitea_uid :integer
# is_shixun_marker :boolean default("0")
# admin_visitable :boolean default("0")
# collaborator :boolean default("0")
# gitea_uid :integer
# is_sync_pwd :boolean default("1")
# watchers_count :integer default("0")
# devops_step :integer default("0")
# gitea_token :string(255)
#
# Indexes
#
@ -53,8 +54,9 @@
# index_users_on_homepage_engineer (homepage_engineer)
# index_users_on_homepage_teacher (homepage_teacher)
# index_users_on_laboratory_id (laboratory_id)
# index_users_on_login (login)
# index_users_on_mail (mail)
# index_users_on_login (login) UNIQUE
# index_users_on_mail (mail) UNIQUE
# index_users_on_phone (phone) UNIQUE
# index_users_on_type (type)
#

View File

@ -12,7 +12,9 @@
#
# Indexes
#
# index_user_actions_on_ip (ip)
# index_user_actions_on_ip (ip)
# index_user_actions_on_user_id (user_id)
# index_user_actions_on_user_id_and_action_type (user_id,action_type)
#
class UserAction < ApplicationRecord

View File

@ -10,10 +10,13 @@
# updated_at :datetime not null
# register_status :integer default("0")
# action_status :integer default("0")
# is_delete :boolean default("0")
# user_id :integer
#
# Indexes
#
# index_user_agents_on_ip (ip) UNIQUE
# index_user_agents_on_ip (ip)
# index_user_agents_on_user_id (user_id)
#
class UserAgent < ApplicationRecord

View File

@ -22,6 +22,9 @@
# school_id :integer
# description :string(255) default("")
# department_id :integer
# honor :text(65535)
# edu_background :integer
# edu_entry_year :integer
#
# Indexes
#

View File

@ -24,7 +24,7 @@
#
class Version < ApplicationRecord
belongs_to :project, counter_cache: true
belongs_to :project, counter_cache: true, optional: true
has_many :issues, class_name: "Issue", foreign_key: "fixed_version_id"
belongs_to :user, optional: true

View File

@ -1,13 +1,12 @@
# Get a list of all commits from a repository
class Gitea::Versions::ListService < Gitea::ClientService
attr_reader :token, :user_name, :repo, :args
attr_reader :token, :user_name, :repo
# sha: SHA or branch to start listing commits from (usually 'master')
def initialize(token, user_name, repo, args={})
def initialize(token, user_name, repo)
@token = token
@user_name = user_name
@repo = repo
@args = args
end
def call
@ -17,7 +16,7 @@ class Gitea::Versions::ListService < Gitea::ClientService
private
def params
args.merge(token: token)
Hash.new.merge(token: token)
end
def url

View File

@ -37,7 +37,7 @@ class Repositories::DetailService < ApplicationService
end
def release_suitable
releases = Gitea::Versions::ListService.call(@owner.gitea_token, @owner.try(:login), @repo.try(:identifier), {page: 1, limit: 1})
releases = Gitea::Versions::ListService.call(@owner.gitea_token, @owner.try(:login), @repo.try(:identifier))
releases.is_a?(Hash) && releases[:status] == -1 ? [] : releases
end

View File

@ -9,11 +9,11 @@
<% end %>
</td>
<td>
<% if school && school.identifier.present? %>
<%= link_to school.identifier.to_s, statistics_college_path(school.identifier), target: '_blank' %>
<% else %>
<%# if school && school.identifier.present? %>
<%#= link_to school.identifier.to_s, statistics_college_path(school.identifier), target: '_blank' %>
<%# else %>
--
<% end %>
<%# end %>
</td>
<td class="member-container">
<div class="laboratory-user">

View File

@ -1,6 +1,5 @@
json.author do
if @project.forge?
json.id user.id
json.login user.login
json.type user&.type
json.name user.real_name

View File

@ -26,9 +26,9 @@ if @project.forge?
end
json.author do
json.partial! 'commit_author', user: render_commit_author(commit['commit']['author']), name: commit['commit']['author']['name']
json.partial! 'commit_author', user: render_commit_author(commit['author'])
end
json.committer do
json.partial! 'commit_author', user: render_commit_author(commit['commit']['committer']), name: commit['commit']['committer']['name']
json.partial! 'commit_author', user: render_commit_author(commit['committer'])
end
end

View File

@ -4,8 +4,5 @@ if user
json.name user.real_name
json.image_url url_to_avatar(user)
else
json.id nil
json.login name
json.name name
json.image_url File.join("avatars/User","b")
json.nil!
end

View File

@ -5,7 +5,6 @@ else
json.total_count @hash_commit[:total_count]
json.commits do
json.array! @hash_commit[:body] do |commit|
json.commit1 commit
commiter = commit['committer']
if commiter.present?
commit_user_id = commiter['id']
@ -18,13 +17,7 @@ else
if forge_user
json.partial! 'author', user: forge_user
else
json.author do
json.id nil
json.login commit['commit']['author']['name']
json.type nil
json.name commit['commit']['author']['name']
json.image_url File.join("avatars/User","b")
end
json.author nil
end
end
end

View File

@ -61,7 +61,7 @@ json.release_versions do
json.tag_name release["tag_name"]
json.created_at format_time(release["created_at"].to_time)
end
json.total_count @repository&.version_releases.size
json.total_count @result[:release].size
end
json.branches do
json.list @result[:branch].each do |branch|
@ -93,5 +93,3 @@ json.contributors do
json.total_count total_count
end
json.languages @result[:language]
json.partial! 'author', locals: { user: @project.owner }

View File

@ -45,15 +45,18 @@ json.setting do
json.main_site current_laboratory.main_site?
json.new_course default_course_links
json.old_projects_url @old_projects_url
json.add do
json.array! @add
json.array! @add, :name, :url, :key
end
json.personal do
json.array! @personal
end
json.common @common
json.common do
json.array! @common
end
end

View File

@ -5,11 +5,13 @@ json.user_id @user.id
json.image_url url_to_avatar(@user)
json.admin @user.admin?
json.is_teacher @user.user_extension&.teacher?
json.has_gitea_user @user.gitea_token.present? && @user.gitea_uid.present?
json.is_sync_pwd @user.is_sync_pwd
json.user_identity @user.identity
json.tidding_count 0
json.user_phone_binded @user.phone.present?
# json.phone @user.phone
# json.email @user.mail
json.email @user.mail
json.profile_completed @user.profile_completed?
json.professional_certification @user.professional_certification
json.devops_step @user.devops_step

View File

@ -11,7 +11,6 @@
#
default: &default
adapter: mysql2
host: 127.0.0.1
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
@ -52,3 +51,5 @@ test:
production:
<<: *default
database: forge_production
username: educoderplus
password: <%= ENV['EDUCODERPLUS_DATABASE_PASSWORD'] %>

View File

@ -0,0 +1,17 @@
'zh-CN':
activemodel:
attributes:
gitea/user/change_password_form:
user: ''
email: 邮箱
login: 用户名
old_password: 旧密码
password: 新密码
errors:
models:
gitea/user/change_password_form:
attributes:
old_password:
password_error: 错误
user:
not_exist: 不存在

View File

@ -72,12 +72,12 @@ Rails.application.routes.draw do
end
resources :statistic, only: [:index] do
collection do
collection do
get :platform_profile
get :platform_code
get :active_project_rank
get :active_developer_rank
end
end
end
resources :sync_forge, only: [:create] do
collection do
@ -185,6 +185,7 @@ Rails.application.routes.draw do
get :logout
get :get_verification_code
get :valid_email_and_phone
post :gitea_register
post :remote_register
post :remote_update
post :remote_login
@ -218,6 +219,8 @@ Rails.application.routes.draw do
post :sync_salt
get :trustie_projects
get :trustie_related_projects
post :change_password
post :change_email
scope '/ci', module: :ci do
scope do

View File

@ -1,5 +1,5 @@
class AddPlatformToUsers < ActiveRecord::Migration[5.2]
def change
# add_column :users, :platform, :string, default: 0
add_column :users, :platform, :string, default: 0
end
end

View File

@ -1,5 +1,5 @@
class AddGiteaTokenToUsers < ActiveRecord::Migration[5.2]
def change
# add_column :users, :gitea_token, :string
add_column :users, :gitea_token, :string
end
end

View File

@ -1,6 +1,6 @@
class AddProjectCategoryIdAndProjectLanguageIdToProjects < ActiveRecord::Migration[5.2]
def change
# add_column :projects, :project_category_id, :integer
# add_column :projects, :project_language_id, :integer
add_column :projects, :project_category_id, :integer
add_column :projects, :project_language_id, :integer
end
end

View File

@ -1,7 +1,7 @@
class AddUserRefToRepository < ActiveRecord::Migration[5.2]
def change
# add_column :repositories, :user_id, :integer
# add_index :repositories, :user_id
add_column :repositories, :user_id, :integer
add_index :repositories, :user_id
Project.joins(:repository).find_each do |project|
project&.repository&.update_column(:user_id, project&.user_id) unless project&.repository.blank?

View File

@ -1,5 +1,5 @@
class AddGiteaUidToUsers < ActiveRecord::Migration[5.2]
def change
# add_column :users, :gitea_uid, :integer
add_column :users, :gitea_uid, :integer
end
end

View File

@ -1,5 +1,5 @@
class AddMirrorUrlToRepositories < ActiveRecord::Migration[5.2]
def change
# add_column :repositories, :mirror_url, :string
add_column :repositories, :mirror_url, :string
end
end

View File

@ -1,14 +1,14 @@
class CreateIssueTags < ActiveRecord::Migration[5.2]
def change
# create_table :issue_tags do |t|
# t.string :title
# t.string :description
# t.string :color
# t.integer :user_id
# t.integer :project_id
# t.integer :issues_count,default: 0
# t.timestamps
# end
# add_index :issue_tags, [:user_id, :title,:project_id]
create_table :issue_tags do |t|
t.string :title
t.string :description
t.string :color
t.integer :user_id
t.integer :project_id
t.integer :issues_count,default: 0
t.timestamps
end
add_index :issue_tags, [:user_id, :title,:project_id]
end
end

View File

@ -1,5 +1,5 @@
class AddPraisesCountToProjects < ActiveRecord::Migration[5.2]
def change
# add_column :projects, :praises_count, :integer, :default => 0
add_column :projects, :praises_count, :integer, :default => 0
end
end

View File

@ -1,8 +1,8 @@
class AddIssuesTypeAndToken < ActiveRecord::Migration[5.2]
def change
# add_column :issues, :issue_type, :string
# add_column :issues, :token, :string
# add_column :issues, :issue_tag_ids, :string
add_column :issues, :issue_type, :string
add_column :issues, :token, :string
add_column :issues, :issue_tag_ids, :string
end
end

View File

@ -1,5 +1,5 @@
class RenameIssueTagTitle < ActiveRecord::Migration[5.2]
def change
# rename_column :issue_tags, :title, :name
rename_column :issue_tags, :title, :name
end
end

View File

@ -1,10 +1,10 @@
class CreateIssueTagsRelates < ActiveRecord::Migration[5.2]
def change
# create_table :issue_tags_relates do |t|
# t.integer :issue_id
# t.integer :issue_tag_id
# t.timestamps
# end
# add_index :issue_tags_relates, [:issue_id, :issue_tag_id]
create_table :issue_tags_relates do |t|
t.integer :issue_id
t.integer :issue_tag_id
t.timestamps
end
add_index :issue_tags_relates, [:issue_id, :issue_tag_id]
end
end

View File

@ -1,5 +1,5 @@
class RenameIssuesIssueTagIds < ActiveRecord::Migration[5.2]
def change
# rename_column :issues, :issue_tag_ids, :issue_tags_value
rename_column :issues, :issue_tag_ids, :issue_tags_value
end
end

View File

@ -1,13 +1,13 @@
class CreateIssueTimes < ActiveRecord::Migration[5.2]
def change
# create_table :issue_times do |t|
# t.integer :issue_id
# t.integer :user_id
# t.datetime :start_time
# t.datetime :end_time
# t.string :cost_time
# t.timestamps
# end
# add_index :issue_times, [:issue_id, :user_id]
create_table :issue_times do |t|
t.integer :issue_id
t.integer :user_id
t.datetime :start_time
t.datetime :end_time
t.string :cost_time
t.timestamps
end
add_index :issue_times, [:issue_id, :user_id]
end
end

View File

@ -1,5 +1,5 @@
class AddIsLockToIssue < ActiveRecord::Migration[5.2]
def change
# add_column :issues, :is_lock, :boolean, default: false
add_column :issues, :is_lock, :boolean, default: false
end
end

View File

@ -1,5 +1,5 @@
class AddWatchersCountToProjects < ActiveRecord::Migration[5.2]
def change
# add_column :projects, :watchers_count, :integer, :default => 0
add_column :projects, :watchers_count, :integer, :default => 0
end
end

View File

@ -1,18 +1,18 @@
class CreateVersionReleases < ActiveRecord::Migration[5.2]
def change
# create_table :version_releases do |t|
# t.integer :user_id
# t.string :name
# t.text :body
# t.string :tag_name
# t.string :target_commitish
# t.boolean :draft, default: false
# t.boolean :prerelease, default: false
# t.string :tarball_url
# t.string :zipball_url
# t.string :url
# t.string :version_gid
# t.timestamps
# end
create_table :version_releases do |t|
t.integer :user_id
t.string :name
t.text :body
t.string :tag_name
t.string :target_commitish
t.boolean :draft, default: false
t.boolean :prerelease, default: false
t.string :tarball_url
t.string :zipball_url
t.string :url
t.string :version_gid
t.timestamps
end
end
end

View File

@ -1,6 +1,6 @@
class AddProjectIdToVersionRelease < ActiveRecord::Migration[5.2]
def change
# add_column :version_releases, :repository_id, :integer
# add_index :version_releases, [:repository_id]
add_column :version_releases, :repository_id, :integer
add_index :version_releases, [:repository_id]
end
end

View File

@ -1,6 +1,6 @@
class AddColumnToIssueTags < ActiveRecord::Migration[5.2]
def change
# add_column :issue_tags, :gid, :integer
# add_column :issue_tags, :gitea_url, :string
add_column :issue_tags, :gid, :integer
add_column :issue_tags, :gitea_url, :string
end
end

View File

@ -1,8 +1,8 @@
class AddColumnToPullRequests < ActiveRecord::Migration[5.2]
def change
# add_column :pull_requests, :version_id, :integer
# add_column :pull_requests, :body, :text
# add_column :pull_requests, :from_ref, :string
# add_column :pull_requests, :to_ref, :string
add_column :pull_requests, :version_id, :integer
add_column :pull_requests, :body, :text
add_column :pull_requests, :from_ref, :string
add_column :pull_requests, :to_ref, :string
end
end

View File

@ -4,10 +4,10 @@ class ChangePullRequestsColumns < ActiveRecord::Migration[5.2]
# add_column :pull_request_assigns, :user_login, :string
#
# add_index :pull_request_assigns, [:user_login]
#
# rename_column :pull_requests, :version_id, :milestone
# rename_column :pull_requests, :from_ref, :head
# rename_column :pull_requests, :to_ref, :base
rename_column :pull_requests, :version_id, :milestone
rename_column :pull_requests, :from_ref, :head
rename_column :pull_requests, :to_ref, :base
end

View File

@ -1,6 +1,6 @@
class AddColumnsToPullRequests < ActiveRecord::Migration[5.2]
def change
# add_column :pull_requests, :issue_id, :integer
# add_column :issues, :issue_classify, :string
add_column :pull_requests, :issue_id, :integer
add_column :issues, :issue_classify, :string
end
end

View File

@ -1,6 +1,6 @@
class AddIssuesRefNameAndBranchName < ActiveRecord::Migration[5.2]
def change
# add_column :issues, :ref_name, :string
# add_column :issues, :branch_name, :string
add_column :issues, :ref_name, :string
add_column :issues, :branch_name, :string
end
end

View File

@ -1,9 +1,9 @@
class MigrateTidingStatus < ActiveRecord::Migration[5.2]
def change
Tiding.where(container_type: "JoinCourse", status: 0).each do |tiding|
unless CourseMessage.where(course_message_id: tiding.trigger_user_id, course_id: tiding.container_id, course_message_type: "JoinCourseRequest", status: 0).exists?
tiding.update!(status: 1)
end
end
# Tiding.where(container_type: "JoinCourse", status: 0).each do |tiding|
# unless CourseMessage.where(course_message_id: tiding.trigger_user_id, course_id: tiding.container_id, course_message_type: "JoinCourseRequest", status: 0).exists?
# tiding.update!(status: 1)
# end
# end
end
end

View File

@ -1,6 +1,6 @@
class AddIssuesCountAndPullRequestsCountToProjects < ActiveRecord::Migration[5.2]
def change
# add_column :projects, :issues_count, :integer, :default => 0
# add_column :projects, :pull_requests_count, :integer, :default => 0
add_column :projects, :issues_count, :integer, :default => 0
add_column :projects, :pull_requests_count, :integer, :default => 0
end
end

View File

@ -1,11 +1,11 @@
class MigrateUserLocation < ActiveRecord::Migration[5.2]
def change
UserExtension.where("location like '%省'").each do |ue|
ue.update_column("location", ue.location.chop)
end
UserExtension.where("location_city like '%市'").each do |ue|
ue.update_column("location_city", ue.location_city.chop)
end
# UserExtension.where("location like '%省'").each do |ue|
# ue.update_column("location", ue.location.chop)
# end
#
# UserExtension.where("location_city like '%市'").each do |ue|
# ue.update_column("location_city", ue.location_city.chop)
# end
end
end

View File

@ -1,7 +1,7 @@
class AddIssuesCountToVersions < ActiveRecord::Migration[5.2]
def change
# add_column :versions, :issues_count, :integer, :default => 0
# add_column :versions, :closed_issues_count, :integer, :default => 0
# add_column :versions, :percent, :float, default: 0.0
add_column :versions, :issues_count, :integer, :default => 0
add_column :versions, :closed_issues_count, :integer, :default => 0
add_column :versions, :percent, :float, default: 0.0
end
end

View File

@ -1,69 +1,69 @@
class ChangeQuillToMd < ActiveRecord::Migration[5.2]
#迁移quill编辑器的内容为md
def change
migrate_time = Time.current - 20.days
migrate_time = Time.current - 20.days
all_issues = Issue.where("updated_on > ?", migrate_time)
pros = PullRequest.where("updated_at > ?", migrate_time)
journals = Journal.where("created_on > ?", migrate_time)
Issue.transaction do
if all_issues.size > 0
all_issues.each do |i|
description = i.description
if description.present? && description.include?("insert")
new_content = change_content(description)
i.update_attribute(:description, new_content)
end
puts "__update_issue_content_____id:#{i.id}__"
end
end
end
# Issue.transaction do
# if all_issues.size > 0
# all_issues.each do |i|
# description = i.description
# if description.present? && description.include?("insert")
# new_content = change_content(description)
# i.update_attribute(:description, new_content)
# end
# puts "__update_issue_content_____id:#{i.id}__"
# end
# end
# end
Journal.transaction do
if journals.size > 0
journals.each do |j|
description = j.notes
if description.present? && description.include?("insert")
new_content = change_content(description)
j.update_attribute(:notes, new_content)
end
puts "__update_journal_content_____id:#{j.id}__"
end
end
end
# Journal.transaction do
# if journals.size > 0
# journals.each do |j|
# description = j.notes
# if description.present? && description.include?("insert")
# new_content = change_content(description)
# j.update_attribute(:notes, new_content)
# end
# puts "__update_journal_content_____id:#{j.id}__"
# end
# end
#
# end
PullRequest.transaction do
if pros.size > 0
pros.each do |p|
description = p.body
if description.present? && description.include?("insert")
new_content = change_content(description)
p.update_attribute(:body, new_content)
end
puts "__update_pull_request_content_____id:#{p.id}__"
end
end
end
# PullRequest.transaction do
# if pros.size > 0
# pros.each do |p|
# description = p.body
# if description.present? && description.include?("insert")
# new_content = change_content(description)
# p.update_attribute(:body, new_content)
# end
# puts "__update_pull_request_content_____id:#{p.id}__"
# end
# end
# end
end
def change_content(content)
puts "####________content_____######{content}"
new_content = ""
return "" if content.blank?
desc = JSON.parse(content)["ops"]
if desc.length > 0
desc.each do |d|
image = d["insert"]["image"]
if image.present?
new_content += "![#{image['alt']}](#{image['url']})"
else
new_content += d["insert"].gsub("\n", "")
end
end
end
new_content
end
# def change_content(content)
# puts "####________content_____######{content}"
# new_content = ""
# return "" if content.blank?
# desc = JSON.parse(content)["ops"]
# if desc.length > 0
# desc.each do |d|
# image = d["insert"]["image"]
# if image.present?
# new_content += "![#{image['alt']}](#{image['url']})"
# else
# new_content += d["insert"].gsub("\n", "")
# end
# end
# end
# new_content
# end
end

View File

@ -0,0 +1,6 @@
class AddColumnsToProjects < ActiveRecord::Migration[5.2]
def change
add_column :projects, :license_id, :integer
add_column :projects, :ignore_id, :integer
end
end

View File

@ -8,7 +8,5 @@ class CreateSites < ActiveRecord::Migration[5.2]
t.timestamps
end
Site.set_default_menu
end
end

View File

@ -16,18 +16,13 @@
## Steps
### 1. 克隆稳定版本仓库
```
git clone -b standalone https://git.trustie.net/jasder/forgeplus.git
```
### 2. 安装依赖包
### 1. 安装依赖包
```bash
bundle install
```
### 3. 配置初始化文件
### 2. 配置初始化文件
进入项目根目录执行一下命令:
```bash
@ -37,24 +32,10 @@ touch config/redis.yml
touch config/elasticsearch.yml
```
### 4. 配置数据库
数据库配置信息请查看/config/database.yml文件
项目默认采用mysql数据库, 如需更改,请自行修改配置信息,
默认配置如下:
```bash
default: &default
adapter: mysql2
host: 127.0.0.1
encoding: utf8
username: root
password: 123456
```
### 4. 配置gitea服务(可选)
### 3. 配置gitea服务(可选)
**如需要部署自己的gitea平台请参考gitea官方平台https://docs.gitea.io/zh-cn/install-from-binary/**
**因目前gitea平台api受限暂时推荐从forge平台获取gitea部署文件进行部署https://forgeplus.trustie.net/projects/Trustie/gitea-binary**
**因目前gitea平台api受限暂时推荐从forge平台获取gitea部署文件进行部署https://forgeplus.trustie.net/projects/jasder/gitea-binary**
#### 配置gitea服务步骤
1. 部署gitea服务并注册root账户
@ -68,51 +49,51 @@ gitea:
base_url: '/api/v1'
```
### 5. 安装redis环境
### 4. 安装redis环境
**请自行搜索各平台如何安装部署redis环境**
### 6. 创建数据库
### 5. 创建数据库
```bash
rails db:create
```
### 7. 导入数据表结构
### 6. 导入数据表结构
```bash
bundle exec rake sync_table_structure:import_csv
```
### 8. 执行migrate迁移文件
### 7. 执行migrate迁移文件
**开发环境为development 生成环境为production**
```bash
rails db:migrate RAILS_ENV=development
```
### 9. clone前端代码
### 8. clone前端代码
**将前端代码克隆到public/react目录下目录结构应该是: public/react/build**
```bash
git clone -b standalone https://git.trustie.net/jasder/build.git
git clone -b dev_trustie https://git.trustie.net/jasder/build.git
```
### 10. 启动redis(此处已mac系统为例)
### 9. 启动redis(此处已mac系统为例)
```bash
redis-server&
```
### 11. 启动sidekiq
### 10. 启动sidekiq
**开发环境为development 生成环境为production**
```bash
bundle exec sidekiq -C config/sidekiq.yml -e production -d
```
### 12. 启动rails服务
### 1`. 启动rails服务
```bash
rails s
```
### 13. 浏览器访问
### 12. 浏览器访问
在浏览器中输入如下地址访问:
```bash
http://localhost:3000/

135
dir.md
View File

@ -1,135 +0,0 @@
forgeplus
├── app(应用目录)
│   ├── assets(应用静态资源目录)
│   ├── channels(actioncable的频道目录)
│   │   └── application_cable(父类)
│   ├── constraint
│   ├── controllers(应用控制器目录)
│   │   ├── admins(后台管理控制器)
│   │   ├── callbacks
│   │   ├── ci(工作流相关控制器)
│   │   ├── concerns(可反复使用的抽象方法)
│   │   │   ├── admins(对应后台管理模块)
│   │   │   ├── base(父类)
│   │   │   ├── ci(对应工作流模块)
│   │   │   └── repository(对应仓库模块)
│   │   ├── oauth(oauth验证控制器)
│   │   ├── organizations(组织模块控制器)
│   │   ├── projects(项目模块控制器)
│   │   └── users(用户模块控制器)
│   ├── decorators
│   ├── docs(api文档插件)
│   ├── forms(表单验证)
│   │   ├── ci(工作流模块)
│   │   ├── contents(仓库文件模块)
│   │   ├── gitea(gitea模块)
│   │   │   └── user(gitea用户模块)
│   │   ├── project_packages(竞标模块)
│   │   ├── projects(项目模块)
│   │   ├── protected_branches(保护分支模块)
│   │   ├── repositories(仓库模块)
│   │   ├── users(用户模块)
│   │   └── validate(公共模块)
│   ├── helpers(一些控制器帮助方法)
│   ├── imports(导入文件处理)
│   ├── interactors(流程处理器,和service类似比如注册创建项目)
│   ├── jobs(异步任务)
│   ├── libs(应用扩展目录)
│   │   ├── ci(工作流模块)
│   │   │   └── drone
│   │   ├── gitea
│   │   ├── limit_forbid_control
│   │   ├── omniauth
│   │   │   └── strategies
│   │   ├── trustie
│   │   ├── util
│   │   ├── wechat
│   │   └── wechat_oauth
│   ├── mailers(用来存放实现发送邮件功能的文件)
│   ├── models(模型目录)
│   ├── queries(模型查询的封装)
│   │   ├── admins(后台管理模块)
│   │   ├── ci(工作流模块)
│   │   ├── projects(项目模块)
│   │   ├── statistic(统计模块)
│   │   └── users(用户模块)
│   ├── services(业务逻辑的封装)
│   │   ├── admins(后台管理模块)
│   │   ├── branches(仓库分支模块)
│   │   ├── concerns(可反复使用的抽象方法)
│   │   ├── educoder(educoder仓库模块)
│   │   │   └── repository(仓库)
│   │   │   ├── commits(提交)
│   │   │   └── entries(文件)
│   │   ├── gitea(gitea接口封装)
│   │   │   ├── activity(项目统计模块)
│   │   │   ├── chain
│   │   │   ├── hooks(webhook模块)
│   │   │   ├── labels
│   │   │   ├── oauth2
│   │   │   ├── organization(组织模块)
│   │   │   │   ├── organization_user(组织成员)
│   │   │   │   ├── repository(组织仓库)
│   │   │   │   ├── team(组织团队)
│   │   │   │   ├── team_project(组织团队项目)
│   │   │   │   └── team_user(组织团队成员)
│   │   │   ├── pull_request(合并请求模块)
│   │   │   ├── repository(仓库模块)
│   │   │   │   ├── branches(分支)
│   │   │   │   ├── commits(提交)
│   │   │   │   ├── contributors(贡献数)
│   │   │   │   ├── entries(文件)
│   │   │   │   ├── files(所有文件)
│   │   │   │   ├── languages(语言)
│   │   │   │   ├── members(仓库成员)
│   │   │   │   ├── protected_branches(分支保护)
│   │   │   │   ├── readme
│   │   │   │   └── tags(标签)
│   │   │   ├── user(用户)
│   │   │   └── versions(发行版)
│   │   ├── issues(易修)
│   │   ├── libraries
│   │   ├── oauth
│   │   ├── organizations(组织)
│   │   │   └── teams(组织团队)
│   │   ├── private_messages
│   │   ├── project_packages(项目竞标)
│   │   ├── projects(项目)
│   │   ├── protected_branches(分支保护)
│   │   ├── pull_requests(合并请求)
│   │   ├── repositories仓库)
│   │   └── users用户)
│   ├── tasks(可执行任务目录)
│   └── views(控制器对应视图文件目录)
├── bin(存放运行程序的 rails 脚本,以及其他用来部署或运行程序的脚本)
├── cable(actioncable配置目录)
├── config(配置的文件目录)
│   ├── admins(后台管理配置)
│   ├── environments(rails程序的不同运行环境的配置)
│   ├── harmonious_dictionary
│   ├── initializers(加载完gem后会自动加载此目录)
│   └── locales(i18n语言设置目录)
├── db(存放当前数据库的模式,以及数据库迁移文件)
│   └── migrate(用来存放数据库的迁移文件)
├── lib(程序的扩展模块)
│   ├── assets(通常是放置我们使用的插件中用到的assets)
│   ├── educoder
│   └── tasks(可执行任务目录)
├── log(日志目录)
├── public(唯一对外开放的文件夹,其他人可以直接访问这个目录中的东西)
│   ├── assets(编译好的静态资源目录)
│   ├── docs(api文档生成目录)
│   ├── echart(图表目录)
│   ├── editormd(富文本编辑器静态资源目录)
│   ├── fonts(字体目录)
│   ├── images(图片目录)
│   ├── javascripts(脚本目录)
│   ├── options(仓库许可证、gitignore、readme文件目录)
│   ├── react
│   │   └── build(前端编译好的文件目录)
│   └── stylesheets(层叠样式表目录)
├── spec(spec测试目录)
├── test(用于存放单元测试、功能测试及整合测试文件等测试文件)
├── tmp(临时文件例如缓存PID会话文件)
├── vendor(存放第三方代码。经常用来放第三方 gem)
├──   └── assets(通常是放置一些我们从别的地方借用的assets)

View File

@ -15,15 +15,27 @@ namespace :sync_data_to_gitea do
next unless regx.match user.mail
tmp_password = set_password
user_params = {
username: user.login,
email: user.mail,
password: tmp_password
}
gitea_user = Gitea::User::RegisterService.new(user_params).call
result = Gitea::User::GenerateTokenService.new(user.login, tmp_password).call
user.update_columns(gitea_token: result['sha1'], gitea_uid: gitea_user['id'])
# TODO: Educoder sync
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: tmp_password})
if interactor.success?
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(user.login, tmp_password)
user.update_columns(gitea_token: result['sha1'], gitea_uid: gitea_user[:body]['id'])
else
puts "#################【Gitea: 用户同步失败: #{interactor.error} #################"
end
# TODO: Trustie sync
# user_params = {
# username: user.login,
# email: user.mail,
# password: tmp_password
# }
#
# gitea_user = Gitea::User::RegisterService.new(user_params).call
# result = Gitea::User::GenerateTokenService.new(user.login, tmp_password).call
# user.update_columns(gitea_token: result['sha1'], gitea_uid: gitea_user['id'])
rescue Exception => e
Rails.logger.error e
next