Compare commits

...

53 Commits

Author SHA1 Message Date
jasder 0d7a11f3ab Merge branch 'develop' into dev_trustie_server 2021-04-19 18:41:18 +08:00
vilet.yy 2976742b29 fix: org team nickname change error 2021-04-19 18:37:30 +08:00
vilet.yy 55e081ba2b fix 2021-04-19 18:37:30 +08:00
vilet.yy a3c49b3d5f add: org valid 2021-04-19 18:37:30 +08:00
vilet.yy 5a9f29c25f fix 2021-04-19 18:37:30 +08:00
vilet.yy f75827bcf0 fix: org not need create member 2021-04-19 18:37:30 +08:00
vilet.yy f0c4d1226b fix: org not need create member 2021-04-19 18:37:30 +08:00
vilet.yy 3a47c61010 add: team nickname 2021-04-19 18:37:30 +08:00
jasder de6ae5b720 Upate models Schema Information 2021-04-19 18:36:02 +08:00
jasder 8a55e84372 FIX 调整自动生成头像中字母大小 2021-04-19 18:34:18 +08:00
jasder 21befb6486 FIX auto generate avatar bug 2021-04-19 17:28:57 +08:00
jasder b6e8a135f0 FIX url_to_avatar bug 2021-04-19 15:42:54 +08:00
jasder 9cddda7fd4 Update render user avatar url in projects api 2021-04-19 15:38:51 +08:00
jasder 002ae9f327 ADD auto generate user avatar 2021-04-19 15:06:56 +08:00
jasder 879e45e106 Merge branch 'develop' into trustie_server 2021-04-13 16:40:23 +08:00
jasder 07d11737e9 组织权限问题
组织权限问题
2021-04-13 16:39:50 +08:00
vilet.yy 1fe9ea126a fix: permission with organization 2021-04-13 11:53:06 +08:00
jasder b3b0f75e9b Merge branch 'develop' into trustie_server 2021-04-13 10:18:52 +08:00
jasder dcd4457cf5 FIX 开放平台管理员可以访问所有团队信息 2021-04-13 10:16:18 +08:00
jasder 5c8e561bd8 Merge branch 'develop' into trustie_server 2021-04-08 18:36:27 +08:00
jasder 0bd6621821 项目增加课程链接 2021-04-08 18:35:49 +08:00
vilet.yy 04a1376820 add: project's lesson_url 2021-04-08 15:20:34 +08:00
jasder 2b0c987558 Merge branch 'develop' into trustie_server 2021-04-07 11:35:09 +08:00
jasder c3a1fb78ea 组织支持中文名称 2021-04-07 11:34:37 +08:00
vilet.yy cf224bc9fe add: project menulist resources 2021-04-07 11:29:44 +08:00
vilet.yy d6c3bcfaf1 add: org add nickname 2021-04-07 11:29:44 +08:00
vilet.yy a66e5b876d fix 2021-04-07 11:29:44 +08:00
vilet.yy b11fd350da fix: project permission 2021-04-07 11:29:44 +08:00
vilet.yy c417fa7369 add: project list author type 2021-04-07 11:29:44 +08:00
jasder 6796805b21 Merge branch 'develop' into trustie_server 2021-04-02 18:58:08 +08:00
jasder e9a4370adc pull bug 2021-04-02 18:57:49 +08:00
jasder e6b8435037 FIX gug 2021-04-02 18:57:13 +08:00
jasder 5752f19b2f FIX gug 2021-04-02 18:56:44 +08:00
vilet.yy c175fa1339 fix: commit author and fork create units 2021-04-02 18:53:53 +08:00
jasder eb52f05417 集成educoder登陆 2021-04-02 18:46:15 +08:00
vilet.yy 786629dbff fix 2021-04-02 18:41:48 +08:00
vilet.yy 7a00541375 Merge branch 'develop' into hh_develop 2021-04-02 18:41:37 +08:00
jasder 6ce4b26047 FIX api bug 2021-04-02 18:40:26 +08:00
vilet.yy 1d832a1723 fix 2021-04-02 18:38:08 +08:00
vilet.yy 80ce40e492 fix 2021-04-02 18:33:31 +08:00
vilet.yy 91f6dae56a fix 2021-04-02 18:24:20 +08:00
vilet.yy 8c5a834b14 Merge branch 'develop' into hh_develop 2021-04-02 18:22:32 +08:00
jasder e022e429d4 FIX code bug 2021-04-02 18:22:21 +08:00
vilet.yy 57f420848e Merge branch 'develop' into hh_develop 2021-04-02 18:20:41 +08:00
jasder 50fb8d3983 ADD sync user info api 2021-04-02 18:18:52 +08:00
vilet.yy fba58800a7 fix 2021-04-02 18:08:36 +08:00
vilet.yy c4a43c4392 add: need edit user password 2021-04-02 16:44:36 +08:00
jasder 02d26df172 FIX query builds api bug 2021-04-02 15:53:17 +08:00
vilet.yy 1153bd5ab6 fix: set redirect_uri 2021-04-02 09:43:18 +08:00
vilet.yy f732b0374c fix: ceshi 2021-04-02 09:23:11 +08:00
jasder 254718e390 Update db/structure.sql 2021-04-01 20:33:05 +08:00
vilet.yy 0d97d7d4f0 add: educoder third party 2021-04-01 18:01:51 +08:00
jasder 0b6ebb7b36 FIX get site url bug with setting api 2021-04-01 15:04:17 +08:00
74 changed files with 918 additions and 191 deletions

4
.gitignore vendored
View File

@ -36,6 +36,7 @@ public/react/yarn.lock
/.idea/*
# Ignore react node_modules
public/system/*
public/react/*
/public/react/.cache
/public/react/node_modules/
@ -82,4 +83,5 @@ docker/
educoder.sql
redis_data/
Dockerfile
dump.rdb
dump.rdb
.tags*

View File

@ -126,3 +126,5 @@ gem 'request_store'
gem 'harmonious_dictionary', '~> 0.0.1'
gem 'parallel', '~> 1.19', '>= 1.19.1'
gem 'letter_avatar'

View File

@ -162,6 +162,7 @@ GEM
activerecord
kaminari-core (= 1.2.0)
kaminari-core (1.2.0)
letter_avatar (0.3.8)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
@ -456,6 +457,7 @@ DEPENDENCIES
jbuilder (~> 2.5)
jquery-rails
kaminari (~> 1.1, >= 1.1.1)
letter_avatar
listen (>= 3.0.5, < 3.2)
mysql2 (>= 0.4.4, < 0.6.0)
oauth2

View File

@ -329,7 +329,6 @@ class ApplicationController < ActionController::Base
User.current = user
end
end
# if !User.current.logged? && Rails.env.development?
# User.current = User.find 1
# end

View File

@ -1,13 +1,17 @@
module RegisterHelper
extend ActiveSupport::Concern
def autologin_register(username, email, password, platform= 'forge')
def autologin_register(username, email, password, platform= 'forge', need_edit_info = false)
result = {message: nil, user: nil}
user = User.new(admin: false, login: username, mail: email, type: "User")
user.password = password
user.platform = platform
user.activate
if need_edit_info
user.need_edit_info
else
user.activate
end
return unless user.valid?
@ -27,4 +31,30 @@ module RegisterHelper
result
end
def autosync_register_trustie(username, password, email)
config = Rails.application.config_for(:configuration).symbolize_keys!
api_host = config[:sync_url]
return if api_host.blank?
url = "#{api_host}/api/v1/users/common"
sync_json = {
"mail": email,
"password": password,
"login": username
}
uri = URI.parse(url)
if api_host
http = Net::HTTP.new(uri.hostname, uri.port)
if api_host.include?("https://")
http.use_ssl = true
end
http.send_request('POST', uri.path, sync_json.to_json, {'Content-Type' => 'application/json'})
end
end
end

View File

@ -47,7 +47,7 @@ class MembersController < ApplicationController
end
def member_exists?
@project.member?(params[:user_id])
@project.members.exists?(params[:user_id])
end
def operate!
@ -59,6 +59,6 @@ class MembersController < ApplicationController
end
def check_member_not_exists!
return render_result(1, "user_id为#{params[:user_id]}的用户还不是项目成员") unless member_exists?
return render_result(1, "user_id为#{params[:user_id]}的用户还不是项目成员") unless @project.member?(params[:user_id])
end
end

View File

@ -2,6 +2,7 @@ class Oauth::BaseController < ActionController::Base
include RenderHelper
include LoginHelper
include ControllerRescueHandler
include LoggerHelper
# include LaboratoryHelper
skip_before_action :verify_authenticity_token
@ -11,6 +12,18 @@ class Oauth::BaseController < ActionController::Base
end
private
def tip_exception(status = -1, message)
raise Educoder::TipException.new(status, message)
end
def tip_show_exception(status = -2, message)
raise Educoder::TipException.new(status, message)
end
def tip_show(exception)
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
render json: exception.tip_json
end
def session_user_id
# session[:user_id]
@ -48,4 +61,13 @@ class Oauth::BaseController < ActionController::Base
Rails.logger.info("[wechat] set session unionid: #{unionid}")
session[:unionid] = unionid
end
def session_edulogin
session[:edulogin]
end
def set_session_edulogin(login)
Rails.logger.info("[educoder] set sesstion edulogin: #{login}")
session[:edulogin] = login
end
end

View File

@ -1,4 +1,6 @@
class Oauth::EducoderController < Oauth::BaseController
include RegisterHelper
def bind
begin
login = params[:login]
@ -32,4 +34,41 @@ class Oauth::EducoderController < Oauth::BaseController
render_error(ex.message)
end
end
# 需要educoder那边设置回调地址
def create
begin
code = params['code'].to_s.strip
tip_exception("code不能为空") if code.blank?
new_user = false
result = EducoderOauth::Service.access_token(code)
result = EducoderOauth::Service.user_info(result[:access_token])
# 存在该用户
open_user = OpenUsers::Educoder.find_by(uid: result['login'])
if open_user.present? && open_user.user.present?
successful_authentication(open_user.user)
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
else
OpenUsers::Educoder.create!(user: current_user, uid: result['login'], extra: result)
end
end
redirect_to root_path(new_user: new_user)
rescue Exception => ex
render_error(ex.message)
end
end
end

View File

@ -21,7 +21,7 @@ class Organizations::BaseController < ApplicationController
end
def team_not_found_condition
@team.team_users.where(user_id: current_user.id).blank? && !@organization.is_owner?(current_user.id)
!current_user&.admin? && @team.team_users.where(user_id: current_user.id).blank? && !@organization.is_owner?(current_user.id)
end
def user_mark
@ -31,4 +31,4 @@ class Organizations::BaseController < ApplicationController
def project_mark
params[:repo_name] || params[:id]
end
end
end

View File

@ -25,6 +25,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
def create
ActiveRecord::Base.transaction do
Organizations::CreateForm.new(organization_params).validate!
@organization = Organizations::CreateService.call(current_user, organization_params)
Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
end
@ -36,8 +37,10 @@ class Organizations::OrganizationsController < Organizations::BaseController
def update
ActiveRecord::Base.transaction do
login = @organization.login
@organization.update!(login: organization_params[:name]) if organization_params[:name].present?
@organization.organization_extension.update_attributes!(organization_params.except(:name))
@organization.login = organization_params[:name] if organization_params[:name].present?
@organization.nickname = organization_params[:nickname] if organization_params[:nickname].present?
@organization.save!
@organization.organization_extension.update_attributes!(organization_params.except(:name, :nickname))
Gitea::Organization::UpdateService.call(@organization.gitea_token, login, @organization.reload)
Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
end
@ -82,7 +85,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
def organization_params
params.permit(:name, :description, :website, :location,
:repo_admin_change_team_access, :visibility,
:max_repo_creation)
:max_repo_creation, :nickname)
end
def password

View File

@ -33,7 +33,10 @@ class Organizations::TeamsController < Organizations::BaseController
end
def create
@team = Organizations::Teams::CreateService.call(current_user, @organization, team_params)
ActiveRecord::Base.transaction do
Organizations::CreateTeamForm.new(team_params).validate!
@team = Organizations::Teams::CreateService.call(current_user, @organization, team_params)
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
@ -60,7 +63,7 @@ class Organizations::TeamsController < Organizations::BaseController
private
def team_params
params.permit(:name, :description, :authorize, :includes_all_project, :can_create_org_project, :unit_types => [])
params.permit(:name, :nickname, :description, :authorize, :includes_all_project, :can_create_org_project, :unit_types => [])
end
def load_organization

View File

@ -16,6 +16,7 @@ class ProjectsController < ApplicationController
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls")
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("resources")) if @project.has_menu_permission("resources")
menu.append(menu_hash_by_name("activity"))
menu.append(menu_hash_by_name("setting")) if current_user.admin? || @project.manager?(current_user)
@ -182,7 +183,7 @@ class ProjectsController < ApplicationController
private
def project_params
params.permit(:user_id, :name, :description, :repository_name, :website,
params.permit(:user_id, :name, :description, :repository_name, :website, :lesson_url,
:project_category_id, :project_language_id, :license_id, :ignore_id, :private)
end

View File

@ -140,7 +140,7 @@ class PullRequestsController < ApplicationController
end
def pr_merge
return render_forbidden("你没有权限操作.") if @project.reporter?(current_user)
return render_forbidden("你没有权限操作.") unless current_user.project_manager?(@project)
if params[:do].blank?
normal_status(-1, "请选择合并方式")

View File

@ -4,7 +4,7 @@ class SettingsController < ApplicationController
get_add_menu
get_common_menu
get_personal_menu
get_third_party
end
private
@ -40,19 +40,26 @@ class SettingsController < ApplicationController
end
end
def get_third_party
@third_party = []
@third_party << {
name: 'educoder',
url: EducoderOauth.oauth_url
}
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
key.to_s === "url" ? append_http(reset_site_url(value)) : reset_site_url(value)
end
def reset_site_url(url)
return url unless url.to_s.include?("current_user")
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
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
def append_http(url)
url.to_s.start_with?("http") ? url : [request.protocol, request.host_with_port, url].join('')
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 sync_user_info]
before_action :connect_to_ci_db, only: [:get_user_info]
skip_before_action :check_sign, only: [:attachment_show]
@ -233,6 +233,26 @@ class UsersController < ApplicationController
render_ok
end
def sync_user_info
user = User.find_by_login params[:login]
return render_forbidden unless user === current_user
sync_params = {
email: params[:email],
password: params[:password]
}
Users::UpdateInfoForm.new(sync_params.merge(login: params[:login])).validate!
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params)
if interactor.success?
user.update!(password: params[:password], mail: params[:email], status: User::STATUS_ACTIVE)
render_ok
else
render_error(interactor.error)
end
end
private
def load_user
@user = User.find_by_login(params[:id]) || User.find_by(id: params[:id])

View File

@ -0,0 +1,8 @@
class Organizations::CreateForm < BaseForm
NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
attr_accessor :name, :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, :nickname
validates :name, :nickname, :visibility, presence: true
validates :name, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
end

View File

@ -0,0 +1,8 @@
class Organizations::CreateTeamForm < BaseForm
NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
attr_accessor :name, :nickname, :description, :authorize, :includes_all_project, :can_create_org_project, :unit_types
validates :name, :nickname, :authorize, presence: true
validates :name, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
end

View File

@ -0,0 +1,9 @@
class Users::UpdateInfoForm
include ActiveModel::Model
attr_accessor :email, :password, :login
validates :email, presence: true, format: { with: CustomRegexp::EMAIL }
validates :password, presence: true
validates :login, presence: true
end

View File

@ -144,17 +144,12 @@ module ApplicationHelper
if File.exist?(disk_filename(source&.class, source&.id))
ctime = File.ctime(disk_filename(source.class, source.id)).to_i
if %w(User Organization).include?(source.class.to_s)
File.join(relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
File.join("images", relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
else
File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
end
elsif source.class.to_s == 'User'
str = source.user_extension.try(:gender).to_i == 0 ? "b" : "g"
File.join(relative_path, "#{source.class}", str)
elsif source.class.to_s == 'Subject'
File.join("images","educoder", "index", "subject", "subject#{rand(17)}.jpg")
elsif source.class.to_s == 'Shixun'
File.join("images","educoder", "index", "shixun", "shixun#{rand(23)}.jpg")
source.get_letter_avatar_url
end
end

View File

@ -90,8 +90,4 @@ module ProjectsHelper
def render_educoder_avatar_url(project_educoder)
[Rails.application.config_for(:configuration)['educoder']['cdn_url'], project_educoder&.image_url].join('/')
end
def render_avatar_url(owner)
['images', url_to_avatar(owner)].join('/')
end
end

View File

@ -1,7 +1,6 @@
module RepositoriesHelper
def render_permission(user, project)
return "Admin" if user&.admin?
return "Owner" if user === project.owner
project.get_premission(user)
end

View File

@ -0,0 +1,18 @@
module EducoderOauth
class << self
attr_accessor :client_id, :client_secret, :base_url, :redirect_uri
def logger
@_logger ||= STDOUT
end
def logger=(l)
@_logger = l
end
def oauth_url
"#{base_url}/oauth2?call_url=/oauth/authorize?client_id=#{client_id}&redirect_uri=#{URI.encode_www_form_component(redirect_uri)}&response_type=code"
end
end
end

View File

@ -0,0 +1,37 @@
require 'oauth2'
module EducoderOauth::Service
module_function
def request(method, url, params)
begin
Rails.logger.info("[EducoderOauth] [#{method.to_s.upcase}] #{url} || #{params}")
client = Faraday.new(url: EducoderOauth.base_url)
response = client.public_send(method, url, params)
result = JSON.parse(response.body)
Rails.logger.info("[EducoderOauth] [#{response.status}] #{result}")
result
rescue Exception => e
raise Educoder::TipException.new(e.message)
end
end
def access_token(code)
begin
Rails.logger.info("[EducoderOauth] [code] #{code} ")
Rails.logger.info("[EducoderOauth] [redirect_uri] #{EducoderOauth.redirect_uri} ")
client = OAuth2::Client.new(EducoderOauth.client_id, EducoderOauth.client_secret, site: EducoderOauth.base_url)
result = client.auth_code.get_token(code, redirect_uri: EducoderOauth.redirect_uri).to_hash
return result
rescue Exception => e
raise Educoder::TipException.new(e.message)
end
end
def user_info(access_token)
request(:get, '/api/users/info.json', {access_token: access_token})
end
end

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)
#
@ -78,8 +80,8 @@ class Organization < Owner
scope :with_visibility, ->(visibility) { joins(:organization_extension).where(organization_extensions: {visibility: visibility}) if visibility.present? }
def self.build(name, gitea_token=nil)
self.create!(login: name, gitea_token: gitea_token)
def self.build(name, nickname, gitea_token=nil)
self.create!(login: name, nickname: nickname, gitea_token: gitea_token)
end
def can_create_project?(user_id)
@ -113,7 +115,9 @@ class Organization < Owner
end
def real_name
login
name = lastname + firstname
name = name.blank? ? (nickname.blank? ? login : nickname) : name
name.gsub(/\s+/, '').strip #6.11 -hs
end
def show_real_name

View File

@ -1,78 +1,75 @@
# == Schema Information
#
# Table name: projects
#
# id :integer not null, primary key
# name :string(255) default(""), not null
# description :text(4294967295)
# homepage :string(255) default("")
# is_public :boolean default("1"), not null
# parent_id :integer
# created_on :datetime
# updated_on :datetime
# identifier :string(255)
# status :integer default("1"), not null
# lft :integer
# rgt :integer
# inherit_members :boolean default("0"), not null
# project_type :integer default("0")
# hidden_repo :boolean default("0"), not null
# attachmenttype :integer default("1")
# user_id :integer
# dts_test :integer default("0")
# enterprise_name :string(255)
# organization_id :integer
# project_new_type :integer
# gpid :integer
# forked_from_project_id :integer
# forked_count :integer default("0")
# publish_resource :integer default("0")
# visits :integer default("0")
# hot :integer default("0")
# invite_code :string(255)
# qrcode :string(255)
# qrcode_expiretime :integer default("0")
# script :text(65535)
# training_status :integer default("0")
# 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")
# pull_requests_count :integer default("0")
# language :string(255)
# versions_count :integer default("0")
# issue_tags_count :integer default("0")
# closed_issues_count :integer default("0")
# open_devops :boolean default("0")
# gitea_webhook_id :integer
# open_devops_count :integer default("0")
# recommend :boolean default("0")
# platform :integer default("0")
# default_branch :string(255) default("master")
# website :string(255)
#
# Indexes
#
# index_projects_on_forked_from_project_id (forked_from_project_id)
# index_projects_on_identifier (identifier)
# index_projects_on_is_public (is_public)
# index_projects_on_lft (lft)
# index_projects_on_name (name)
# index_projects_on_platform (platform)
# index_projects_on_project_type (project_type)
# index_projects_on_recommend (recommend)
# index_projects_on_rgt (rgt)
# index_projects_on_status (status)
# index_projects_on_updated_on (updated_on)
#
# == Schema Information
#
# Table name: projects
#
# id :integer not null, primary key
# name :string(255) default(""), not null
# description :text(4294967295)
# homepage :string(255) default("")
# is_public :boolean default("1"), not null
# parent_id :integer
# created_on :datetime
# updated_on :datetime
# identifier :string(255)
# status :integer default("1"), not null
# lft :integer
# rgt :integer
# inherit_members :boolean default("0"), not null
# project_type :integer default("0")
# hidden_repo :boolean default("0"), not null
# attachmenttype :integer default("1")
# user_id :integer
# dts_test :integer default("0")
# enterprise_name :string(255)
# organization_id :integer
# project_new_type :integer
# gpid :integer
# forked_from_project_id :integer
# forked_count :integer default("0")
# publish_resource :integer default("0")
# visits :integer default("0")
# hot :integer default("0")
# invite_code :string(255)
# qrcode :string(255)
# qrcode_expiretime :integer default("0")
# script :text(65535)
# training_status :integer default("0")
# rep_identifier :string(255)
# project_category_id :integer
# project_language_id :integer
# praises_count :integer default("0")
# watchers_count :integer default("0")
# issues_count :integer default("0")
# pull_requests_count :integer default("0")
# language :string(255)
# versions_count :integer default("0")
# issue_tags_count :integer default("0")
# closed_issues_count :integer default("0")
# open_devops :boolean default("0")
# gitea_webhook_id :integer
# 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)
# lesson_url :string(255)
#
# Indexes
#
# index_projects_on_forked_from_project_id (forked_from_project_id)
# index_projects_on_identifier (identifier)
# index_projects_on_is_public (is_public)
# index_projects_on_lft (lft)
# index_projects_on_name (name)
# index_projects_on_platform (platform)
# index_projects_on_project_type (project_type)
# index_projects_on_recommend (recommend)
# index_projects_on_rgt (rgt)
# index_projects_on_status (status)
# index_projects_on_updated_on (updated_on)
#
class Project < ApplicationRecord
include Matchable
@ -161,6 +158,7 @@ class Project < ApplicationRecord
#创建项目管理员
def check_project_members
return if owner.is_a?(Organization)
unless members.present? && members.exists?(user_id: self.user_id)
member_params = {
user_id: self.user_id,
@ -242,10 +240,12 @@ class Project < ApplicationRecord
end
def get_premission user
permission = "Reporter"
member = members.find_by(user: user)
return "Owner" if owner?(user)
return "Manager" if manager?(user)
return "Developer" if develper?(user)
return "Reporter" if reporter?(user)
member&.roles&.last&.name || permission
return ""
end
def fork_project

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

@ -16,7 +16,7 @@
class ProjectUnit < ApplicationRecord
belongs_to :project
enum unit_type: {code: 1, issues: 2, pulls: 3, devops: 4, versions: 5}
enum unit_type: {code: 1, issues: 2, pulls: 3, devops: 4, versions: 5, resources: 6}
validates :unit_type, uniqueness: { scope: :project_id}

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

@ -14,6 +14,7 @@
# gtid :integer
# created_at :datetime not null
# updated_at :datetime not null
# nickname :string(255)
#
# Indexes
#

View File

@ -1,19 +1,19 @@
# == Schema Information
#
# Table name: tokens
#
# id :integer not null, primary key
# user_id :integer default("0"), not null
# action :string(30) default(""), not null
# value :string(40) default(""), not null
# created_on :datetime not null
#
# Indexes
#
# index_tokens_on_user_id (user_id)
# tokens_value (value) UNIQUE
#
# == Schema Information
#
# Table name: tokens
#
# id :integer not null, primary key
# user_id :integer default("0"), not null
# action :string(30) default(""), not null
# value :string(40) default(""), not null
# created_on :datetime not null
#
# Indexes
#
# index_tokens_on_user_id (user_id)
# tokens_value (value) UNIQUE
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@ -76,7 +76,7 @@ class Token < ActiveRecord::Base
# Returns the active user who owns the key for the given action
def self.find_active_user(action, key, validity_days=nil)
user = find_user(action, key, validity_days)
if user && user.active?
if user && (user.active? || user.need_edit_info?)
user
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)
#
@ -66,6 +68,7 @@ class User < Owner
include Likeable
include BaseModel
include Droneable
include User::Avatar
# include Searchable::Dependents::User
# devops step
@ -79,6 +82,7 @@ class User < Owner
STATUS_ACTIVE = 1
STATUS_REGISTERED = 2
STATUS_LOCKED = 3
STATUS_EDIT_INFO = 4
# tpi tpm权限控制
EDU_ADMIN = 1 # 超级管理员
@ -161,7 +165,7 @@ class User < Owner
has_many :organizations, through: :organization_users
# Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) }
scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
scope :like, lambda { |keywords|
where("LOWER(concat(lastname, firstname, login, mail)) LIKE ?", "%#{keywords.split(" ").join('|')}%") unless keywords.blank?
}
@ -189,6 +193,10 @@ class User < Owner
validate :validate_sensitive_string
validate :validate_password_length
def name
login
end
# 删除自动登录的token一旦退出下次会提示需要登录
def delete_autologin_token(value)
Token.where(:user_id => id, :action => 'autologin', :value => value).delete_all
@ -203,7 +211,7 @@ class User < Owner
end
def project_manager?(project)
project.managers.exists?(user: self) || self.admin?
project.manager?(self) || self.admin?
end
# 学号
@ -378,6 +386,10 @@ class User < Owner
status == STATUS_LOCKED
end
def need_edit_info?
status == STATUS_EDIT_INFO
end
def activate
self.status = STATUS_ACTIVE
end
@ -390,6 +402,10 @@ class User < Owner
self.status = STATUS_LOCKED
end
def need_edit_info
self.status = STATUS_EDIT_INFO
end
def activate!
update_attribute(:status, STATUS_ACTIVE)
end
@ -402,6 +418,10 @@ class User < Owner
update_attribute(:status, STATUS_LOCKED)
end
def need_edit_info!
update_attribute(:status, STATUS_EDIT_INFO)
end
# 课程用户身份
def course_identity(course)
if !logged?

37
app/models/user/avatar.rb Normal file
View File

@ -0,0 +1,37 @@
require 'letter_avatar/has_avatar'
require 'chinese_pinyin'
class User
module Avatar
extend ActiveSupport::Concern
include LetterAvatar::HasAvatar
def username
self.lastname.blank? ? self.login : Pinyin.t(self.lastname)
end
def get_letter_avatar_url(size = :lg)
avatar_path(size).split('public/')&.last
end
def avatar_path(size)
LetterAvatar.generate self.username, avatar_size(size)
end
# 返回头像尺寸
# xs: 22px
# sm: 32px
# md: 48px
# lg: 120px
def avatar_size(size)
case size
when :xs then 22
when :sm then 32
when :md then 48
when :lg then 120
else size
end
end
end
end

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

@ -25,7 +25,7 @@ class Ci::Builds::ListQuery < ApplicationQuery
scope
end
builds = scope.by_branch(params[:branch]) if params[:branch]
builds = builds.by_branch(params[:branch]) if params[:branch]
custom_sort(builds, params[:sort_by], params[:sort_direction])
end

View File

@ -47,7 +47,7 @@ class Organizations::CreateService < ApplicationService
end
def create_org_and_extension
@organization = Organization.build(params[:name], user.gitea_token)
@organization = Organization.build(params[:name], params[:nickname], user.gitea_token)
org_extension = OrganizationExtension.build(organization.id, description, website,
location, repo_admin_change_team_access,
visibility, max_repo_creation)

View File

@ -27,7 +27,7 @@ class Organizations::Teams::UpdateService < ApplicationService
if team.authorize == "owner"
update_params = params.slice(:description)
else
update_params = params.slice(:name, :description, :authorize, :includes_all_project, :can_create_org_project)
update_params = params.slice(:name, :nickname, :description, :authorize, :includes_all_project, :can_create_org_project)
end
update_params
end

View File

@ -24,6 +24,8 @@ class Projects::ForkService < ApplicationService
new_repository.identifier = @project.identifier
new_repository.save!
ProjectUnit.init_types(clone_project.id)
result = Gitea::Repository::ForkService.new(@project.owner, @target_owner, @project.identifier, @organization).call
@project.update_column('forked_count', @project&.forked_count.to_i + 1)

View File

@ -1,5 +1,6 @@
json.id organization.id
json.name organization.login
json.nickname organization.nickname.blank? ? organization.name : organization.nickname
json.description organization.description
json.website organization.website
json.location organization.location

View File

@ -1,5 +1,6 @@
json.id team.id
json.name team.name
json.nickname team.nickname.blank? ? team.name : team.nickname
json.description team.description
json.authorize team.authorize
json.includes_all_project team.includes_all_project

View File

@ -26,7 +26,7 @@ json.author do
json.name user.try(:show_real_name)
json.type user&.type
json.login user.login
json.image_url render_avatar_url(user)
json.image_url url_to_avatar(user)
end
end

View File

@ -25,9 +25,10 @@ json.projects @projects do |project|
json.image_url render_educoder_avatar_url(project.project_educoder)
else
user = project.owner
json.type user.type
json.name user.try(:show_real_name)
json.login user.login
json.image_url render_avatar_url(user)
json.image_url url_to_avatar(user)
end
end

View File

@ -5,4 +5,5 @@ json.description @project.description
json.project_category_id @project.project_category_id
json.project_language_id @project.project_language_id
json.is_public @project.is_public
json.website @project.website
json.website @project.website
json.lesson_url @project.lesson_url

View File

@ -1,11 +1,11 @@
json.author do
author = User.find_by(login: commit['Author']['Name'])
json.partial! 'repositories/commit_author', locals: { user: author }
json.partial! 'repositories/commit_author', locals: { user: author, name: commit['Committer']['Name'] }
end
json.committer do
author = User.find_by(login: commit['Committer']['Name'])
json.partial! 'repositories/commit_author', locals: { user: author }
json.partial! 'repositories/commit_author', locals: { user: author, name: commit['Committer']['Name'] }
end
json.timestamp render_unix_time(commit['Committer']['When'])
json.time_from_now time_from_now(commit['Committer']['When'])

View File

@ -1,5 +1,6 @@
json.content @project.content
json.website @project.website
json.lesson_url @project.lesson_url
if @result[:readme].blank?
json.readme nil
else

View File

@ -6,4 +6,5 @@ json.project_category_id @project.project_category_id
json.project_language_id @project.project_language_id
json.private !@project.is_public
json.website @project.website
json.project_units @project.project_units.pluck(:unit_type)
json.project_units @project.project_units.pluck(:unit_type)
json.lesson_url @project.lesson_url

View File

@ -56,4 +56,5 @@ json.setting do
end
json.common @common
json.third_party @third_party
end

View File

@ -8,8 +8,9 @@ json.is_teacher @user.user_extension&.teacher?
json.user_identity @user.identity
json.tidding_count 0
json.user_phone_binded @user.phone.present?
json.need_edit_info @user.need_edit_info?
# 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

@ -43,6 +43,11 @@ default: &default
cate_id: '-1'
callback_url: 'callback_url'
signature_key: 'test12345678'
educoder:
client_id: 'e9ce4d5ba1698d6f7d01d8ee2959776c7a6d743ebe94da2341e288fd2fbf60aa'
client_secret: '6ff84dd75eddd859c5bd0e7a791b58bc5ad1ba4fbb30bc9db37cb0baf9f33012'
base_url: 'https://test-data.educoder.net'
redirect_uri: 'https://testforgeplus.trustie.net/api/auth/educoder/callback'
gitea:
access_key_id: 'root'

View File

@ -0,0 +1,16 @@
oauth_config = {}
begin
config = Rails.application.config_for(:configuration)
oauth_config = config.dig('oauth', 'educoder')
raise 'oauth educoder config missing' if oauth_config.blank?
rescue => ex
raise ex if Rails.env.production?
puts %Q{\033[33m [warning] wechat oauth config or configuration.yml missing,
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
end
EducoderOauth.client_id = oauth_config['client_id']
EducoderOauth.client_secret = oauth_config['client_secret']
EducoderOauth.base_url = oauth_config['base_url']
EducoderOauth.redirect_uri = oauth_config['redirect_uri']

View File

@ -0,0 +1,9 @@
LetterAvatar.setup do |config|
config.fill_color = 'rgba(255, 255, 255, 1)' # default is 'rgba(255, 255, 255, 0.65)'
config.cache_base_path = 'public/system/lets' # default is 'public/system'
config.colors_palette = :iwanthue # default is :google
# config.weight = 500 # default is 300
config.annotate_position = '-0+10' # default is -0+5
# config.letters_count = 2 # default is 1
config.pointsize = 300
end

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
@ -218,6 +218,7 @@ Rails.application.routes.draw do
post :sync_salt
get :trustie_projects
get :trustie_related_projects
post :sync_user_info
scope '/ci', module: :ci do
scope do
@ -312,6 +313,7 @@ Rails.application.routes.draw do
get '/auth/qq/callback', to: 'oauth/qq#create'
get '/auth/wechat/callback', to: 'oauth/wechat#create'
get '/auth/educoder/callback', to: 'oauth/educoder#create'
resource :bind_user, only: [:create]
resources :hot_keywords, only: [:index]

View File

@ -0,0 +1,5 @@
class AddLessonUrlToProjects < ActiveRecord::Migration[5.2]
def change
add_column :projects, :lesson_url, :string
end
end

View File

@ -0,0 +1,5 @@
class AddNicknameToTeams < ActiveRecord::Migration[5.2]
def change
add_column :teams, :nickname, :string
end
end

View File

@ -3445,12 +3445,77 @@ INSERT INTO `roles` (`id`, `name`, `position`, `assignable`, `builtin`, `permiss
(15, 'Contestant', 13, 1, 0, '---\n- :add_project\n- :projects_attachments_download\n- :add_course\n- :course_attachments_download\n- :view_course_files\n- :select_contest_modules\n- :quote_project\n- :contest_attachments_download\n- :notificationcomment_contestnotifications\n- :add_messages\n- :edit_own_messages\n- :delete_own_messages\n- :view_calendar\n- :manage_files\n- :view_files\n- :view_gantt\n- :view_issues\n- :save_queries\n- :browse_repository\n- :view_changesets\n', 'default');
COMMIT;
-- ----------------------------
-- Records of ci_languages
-- ----------------------------
BEGIN;
INSERT INTO `ci_languages` (`id`, `name`, `content`, `usage_amount`, `created_at`, `updated_at`, `cover_id`) VALUES
(1, 'C', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGdjYwogIGNvbW1hbmRzOgogIC0gLi9jb25maWd1cmUKICAtIG1h\na2UKICAtIG1ha2UgdGVzdA==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(2, 'C++', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGdjYwogIGNvbW1hbmRzOgogIC0gLi9jb25maWd1cmUKICAtIG1h\na2UKICAtIG1ha2UgdGVzdA==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(3, 'Docker', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGRvY2tlcjpkaW5kCiAgdm9sdW1lczoKICAtIG5hbWU6IGRvY2tl\ncnNvY2sKICAgIHBhdGg6IC92YXIvcnVuL2RvY2tlci5zb2NrCiAgICBjb21t\nYW5kczoKICAgIC0gZG9ja2VyIHBzIC1hCgp2b2x1bWVzOgotIG5hbWU6IGRv\nY2tlcnNvY2sKICBob3N0OgogICAgcGF0aDogL3Zhci9ydW4vZG9ja2VyLnNv\nY2s=\n', 0, '2020-10-21 10:14:22', '2020-11-26 01:35:20', 351688),
(4, 'Java', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IG1hdmVuOjMtamRrLTEwCiAgY29tbWFuZHM6CiAgLSBtdm4gaW5z\ndGFsbCAtRHNraXBUZXN0cz10cnVlIC1EbWF2ZW4uamF2YWRvYy5za2lwPXRy\ndWUgLUIgLVYKICAtIG12biB0ZXN0IC1C\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(5, 'R', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHItYmFzZQogIGNvbW1hbmRzOgogIC0gUiAtZSAnaW5zdGFsbC5w\nYWNrYWdlcyhjKCdwYWNrYWdlMScsJ3BhY2thZ2UyJykpJwogIC0gUiBDTUQg\nYnVpbGQgLg==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(6, 'Ruby', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHJ1YnkKICBjb21tYW5kczoKICAtIGJ1bmRsZSBpbnN0YWxsIC0t\nam9icz0zIC0tcmV0cnk9MwogIC0gcmFrZQ==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(7, 'PHP', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiBpbnN0YWxs\nCiAgaW1hZ2U6IGNvbXBvc2VyCiAgY29tbWFuZHM6CiAgLSBjb21wb3NlciBp\nbnN0YWxsCgotIG5hbWU6IHRlc3QKICBpbWFnZTogcGhwOjcKICBjb21tYW5k\nczoKICAtIHZlbmRvci9iaW4vcGhwdW5pdCAtLWNvbmZpZ3VyYXRpb24gY29u\nZmlnLnhtbA==\n', 0, '2020-10-21 10:14:22', '2020-11-26 01:37:04', 351690),
(8, 'Python', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHB5dGhvbgogIGNvbW1hbmRzOgogIC0gcGlwIGluc3RhbGwgLXIg\ncmVxdWlyZW1lbnRzLnR4dAogIC0gcHl0ZXN0\n', 0, '2020-10-21 10:14:22', '2020-11-26 01:40:00', 351693),
(9, 'MySQL', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IG15c3FsCiAgY29tbWFuZHM6CiAgLSBzbGVlcCAxNQogIC0gbXlz\ncWwgLXUgcm9vdCAtaCBkYXRhYmFzZSAtLWV4ZWN1dGU9J1NFTEVDVCBWRVJT\nSU9OKCk7JwoKc2VydmljZXM6Ci0gbmFtZTogZGF0YWJhc2UKICBpbWFnZTog\nbXlzcWwKICBlbnZpcm9ubWVudDoKICAgIE1ZU1FMX0FMTE9XX0VNUFRZX1BB\nU1NXT1JEOiAneWVzJwogICAgTVlTUUxfREFUQUJBU0U6IHRlc3Q=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(10, 'MongoDB', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiBwaW5nCiAg\naW1hZ2U6IG1vbmdvOjQKICBjb21tYW5kczoKICAtIHNsZWVwIDUKICAtIG1v\nbmdvIC0taG9zdCBtb25nbyAtLWV2YWwgJ2RiLnZlcnNpb24oKScKCnNlcnZp\nY2VzOgotIG5hbWU6IG1vbmdvCiAgaW1hZ2U6IG1vbmdvOjQKICBjb21tYW5k\nOiBbIC0tc21hbGxmaWxlcyBd\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(11, 'Clojure', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGNsb2p1cmUKICBjb21tYW5kczoKICAtIGxlaW4gdGVzdA==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(12, 'CouchDB', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGNvdWNoZGI6Mi4yCiAgY29tbWFuZHM6CiAgLSBzbGVlcCAxNQog\nIC0gY3VybCBodHRwOi8vZGF0YWJhc2U6NTk4NAoKc2VydmljZXM6Ci0gbmFt\nZTogZGF0YWJhc2UKICBpbWFnZTogY291Y2hkYjoyLjI=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(13, 'Crystal', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGNyeXN0YWxsYW5nL2NyeXN0YWwKICBjb21tYW5kczoKICAtIHNo\nYXJkcyBpbnN0YWxsCiAgLSBjcnlzdGFsIHNwZWMuMg==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(14, 'D', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGRsYW5ndWFnZS9kbWQKICBjb21tYW5kczoKICAtIGR1YiB0ZXN0\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(15, 'Dart', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGdvb2dsZS9kYXJ0CiAgY29tbWFuZHM6CiAgLSBwdWIgZ2V0CiAg\nLSBwdWIgcnVuIHRlc3Q=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(16, 'Docker (dind)', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGRvY2tlcjpkaW5kCiAgdm9sdW1lczoKICAtIG5hbWU6IGRvY2tl\ncnNvY2sKICAgIHBhdGg6IC92YXIvcnVuCiAgICBjb21tYW5kczoKICAgIC0g\nc2xlZXAgNSAjIGdpdmUgZG9ja2VyIGVub3VnaCB0aW1lIHRvIHN0YXJ0CiAg\nICAtIGRvY2tlciBwcyAtYQoKc2VydmljZXM6Ci0gbmFtZTogZG9ja2VyCiAg\naW1hZ2U6IGRvY2tlcjpkaW5kCiAgcHJpdmlsZWdlZDogdHJ1ZQogIHZvbHVt\nZXM6CiAgLSBuYW1lOiBkb2NrZXJzb2NrCiAgICBwYXRoOiAvdmFyL3J1bgoK\ndm9sdW1lczoKLSBuYW1lOiBkb2NrZXJzb2NrCiAgdGVtcDoge30=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(17, 'Elasticsearch', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGFscGluZTozLjgKICBjb21tYW5kczoKICAtIGFwayBhZGQgY3Vy\nbAogIC0gc2xlZXAgNDUKICAtIGN1cmwgaHR0cDovL2RhdGFiYXNlOjkyMDAK\nCnNlcnZpY2VzOgotIG5hbWU6IGRhdGFiYXNlCiAgaW1hZ2U6IGVsYXN0aWNz\nZWFyY2g6NS1hbHBpbmU=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(18, 'Elixir', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGVsaXhpcjoxLjUKICBjb21tYW5kczoKICAtIG1peCBsb2NhbC5y\nZWJhciAtLWZvcmNlCiAgLSBtaXggbG9jYWwuaGV4IC0tZm9yY2UKICAtIG1p\neCBkZXBzLmdldAogIC0gbWl4IHRlc3Q=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(19, 'Erlang', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGVybGFuZzoyMQogIGNvbW1hbmRzOgogIC0gcmViYXIgZ2V0LWRl\ncHMKICAtIHJlYmFyIGNvbXBpbGUKICAtIHJlYmFyIHNraXBfZGVwcz10cnVl\nIGV1bml0\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(20, '20.Go (with Gopath)', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0Cgp3b3Jrc3BhY2U6CiAgYmFzZTogL2dv\nCiAgcGF0aDogc3JjL2hlbGxvLXdvcmxkCgpzdGVwczoKLSBuYW1lOiB0ZXN0\nCiAgaW1hZ2U6IGdvbGFuZwogIGNvbW1hbmRzOgogIC0gZ28gZ2V0CiAgLSBn\nbyB0ZXN0\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(21, '21.Go (with Modules)', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGdvbGFuZwogIGNvbW1hbmRzOgogIC0gZ28gdGVzdAogIC0gZ28g\nYnVpbGQ=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(22, 'Gradle', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGdyYWRsZTpqZGsxMAogIGNvbW1hbmRzOgogIC0gZ3JhZGxlIGFz\nc2VtYmxlCiAgLSBncmFkbGUgY2hlY2s=\n', 0, '2020-10-21 10:14:22', '2020-11-26 01:36:17', 351689),
(23, 'Groovy', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGdyYWRsZToyLjUtamRrOAogIGNvbW1hbmRzOgogIC0gLi9ncmFk\nbGV3IGFzc2VtYmxlCiAgLSAuL2dyYWRsZXcgY2hlY2s=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(24, 'Haskell', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGhhc2tlbGwKICBjb21tYW5kczoKICAtIGNhYmFsIGluc3RhbGwg\nLS1vbmx5LWRlcGVuZGVuY2llcyAtLWVuYWJsZS10ZXN0cwogIC0gY2FiYWwg\nY29uZmlndXJlIC0tZW5hYmxlLXRlc3RzCiAgLSBjYWJhbCBidWlsZAogIC0g\nY2FiYWwgdGVzdA==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(25, 'Haxe', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IGhheGUKICBjb21tYW5kczoKICAtIGhheGVsaWIgaW5zdGFsbCBi\ndWlsZC5oeG1sCiAgLSBoYXhlIGJ1aWxkLmh4bWw=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(26, 'MariaDB', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IG1hcmlhZGIKICBjb21tYW5kczoKICAtIHNsZWVwIDE1CiAgLSBt\neXNxbCAtdSByb290IC1oIGRhdGFiYXNlIC0tZXhlY3V0ZT0nU0VMRUNUIFZF\nUlNJT04oKTsnCgpzZXJ2aWNlczoKLSBuYW1lOiBkYXRhYmFzZQogIGltYWdl\nOiBtYXJpYWRiCiAgZW52aXJvbm1lbnQ6CiAgICBNWVNRTF9BTExPV19FTVBU\nWV9QQVNTV09SRDogJ3llcycKICAgIE1ZU1FMX0RBVEFCQVNFOiB0ZXN0\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(27, 'Maven', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IG1hdmVuOjMtamRrLTEwCiAgY29tbWFuZHM6CiAgLSBtdm4gaW5z\ndGFsbCAtRHNraXBUZXN0cz10cnVlIC1EbWF2ZW4uamF2YWRvYy5za2lwPXRy\ndWUgLUIgLVYKICAtIG12biB0ZXN0IC1C\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(28, 'Memcached', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHVidW50dQogIGNvbW1hbmRzOgogIC0gYXB0LWdldCB1cGRhdGUg\nLXFxCiAgLSBhcHQtZ2V0IGluc3RhbGwgLXkgLXFxIHRlbG5ldCA+IC9kZXYv\nbnVsbAogIC0gKHNsZWVwIDE7IGVjaG8gJ3N0YXRzJzsgc2xlZXAgMjsgZWNo\nbyAncXVpdCc7KSB8IHRlbG5ldCBjYWNoZSAxMTIxMSB8fCB0cnVlCgpzZXJ2\naWNlczoKLSBuYW1lOiBjYWNoZQogIGltYWdlOiBtZW1jYWNoZWQ6YWxwaW5l\nCiAgY29tbWFuZDogWyAtdnYgXQ==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(29, 'Nats', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHJ1Ynk6MgogIGNvbW1hbmRzOgogIC0gZ2VtIGluc3RhbGwgbmF0\ncwogIC0gbmF0cy1wdWIgLXMgdGNwOi8vbmF0czo0MjIyIGdyZWV0aW5nICdo\nZWxsbycKICAtIG5hdHMtcHViIC1zIHRjcDovL25hdHM6NDIyMiBncmVldGlu\nZyAnd29ybGQnCgpzZXJ2aWNlczoKLSBuYW1lOiBuYXRzCiAgaW1hZ2U6IG5h\ndHM6MS4zLjA=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(30, 'Node', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IG5vZGUKICBjb21tYW5kczoKICAtIG5wbSBpbnN0YWxsCiAgLSBu\ncG0gdGVzdA==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(31, 'Perl', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHBlcmwKICBjb21tYW5kczoKICAtIGNwYW5tIC0tcXVpZXQgLS1p\nbnN0YWxsZGVwcyAtLW5vdGVzdCAuCiAgLSBwZXJsIEJ1aWxkLlBMCiAgLSAu\nL0J1aWxkIHRlc3Q=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(32, 'Postgres', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHBvc3RncmVzOjktYWxwaW5lCiAgY29tbWFuZHM6CiAgLSBwc3Fs\nIC1VIHBvc3RncmVzIC1kIHRlc3QgLWggZGF0YWJhc2UKCnNlcnZpY2VzOgot\nIG5hbWU6IGRhdGFiYXNlCiAgaW1hZ2U6IHBvc3RncmVzOjktYWxwaW5lCiAg\nZW52aXJvbm1lbnQ6CiAgICBQT1NUR1JFU19VU0VSOiBwb3N0Z3JlcwogICAg\nUE9TVEdSRVNfREI6IHRlc3Q=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(33, 'Redis', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHJlZGlzCiAgY29tbWFuZHM6CiAgLSBzbGVlcCA1CiAgLSByZWRp\ncy1jbGkgLWggcmVkaXMgcGluZwogIC0gcmVkaXMtY2xpIC1oIHJlZGlzIHNl\ndCBGT08gYmFyCiAgLSByZWRpcy1jbGkgLWggcmVkaXMgZ2V0IEZPTwoKc2Vy\ndmljZXM6Ci0gbmFtZTogcmVkaXMKICBpbWFnZTogcmVkaXM=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(34, 'RethinkDB', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IG5vZGU6OQogIGNvbW1hbmRzOgogIC0gbnBtIGluc3RhbGwgLXMg\nLWcgcmVjbGkKICAtIHJlY2xpIC1oIGRhdGFiYXNlIC1qICdyLmRiKCdyZXRo\naW5rZGInKS50YWJsZSgnc3RhdHMnKScKCnNlcnZpY2VzOgotIG5hbWU6IGRh\ndGFiYXNlCiAgaW1hZ2U6IHJldGhpbmtkYjoyCiAgY29tbWFuZDogWyByZXRo\naW5rZGIsIC0tYmluZCwgYWxsIF0=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(35, 'Rust', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHJ1c3Q6MS4zMAogIGNvbW1hbmRzOgogIC0gY2FyZ28gYnVpbGQg\nLS12ZXJib3NlIC0tYWxsCiAgLSBjYXJnbyB0ZXN0IC0tdmVyYm9zZSAtLWFs\nbA==\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(36, 'Swift', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHN3aWZ0OjQKICBjb21tYW5kczoKICAtIHN3aWZ0IGJ1aWxkCiAg\nLSBzd2lmdCB0ZXN0\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL),
(37, 'Vault', 'CmtpbmQ6IHBpcGVsaW5lCm5hbWU6IGRlZmF1bHQKCnBsYXRmb3JtOgogIG9z\nOiBsaW51eAogIGFyY2g6IGFybTY0CgpzdGVwczoKLSBuYW1lOiB0ZXN0CiAg\naW1hZ2U6IHZhdWx0OjEuMC4wLWJldGEyCiAgZW52aXJvbm1lbnQ6CiAgICBW\nQVVMVF9BRERSOiBodHRwOi8vdmF1bHQ6ODIwMAogICAgVkFVTFRfVE9LRU46\nIGR1bW15CiBjb21tYW5kczoKIC0gc2xlZXAgNQogLSB2YXVsdCBrdiBwdXQg\nc2VjcmV0L215LXNlY3JldCBteS12YWx1ZT1zM2NyM3QKIC0gdmF1bHQga3Yg\nZ2V0IHNlY3JldC9teS1zZWNyZXQKCnNlcnZpY2VzOgotIG5hbWU6IHZhdWx0\nCiAgaW1hZ2U6IHZhdWx0OjEuMC4wLWJldGEyCiAgZW52aXJvbm1lbnQ6CiAg\nICBWQVVMVF9ERVZfUk9PVF9UT0tFTl9JRDogZHVtbXk=\n', 0, '2020-10-21 10:14:22', '2020-10-21 10:14:22', NULL);
COMMIT;
-- ----------------------------
-- Records of ci_templates
-- ----------------------------
BEGIN;
INSERT INTO `ci_templates` VALUES (2,'linux/amd64','init','初始化','kind: pipeline\r\ntype: docker\r\nname: default\r\nplatform:\r\n os: linux\r\n arch: amd64','2021-01-12 02:44:23','2021-01-12 02:44:23',NULL),(3,'linux/arm64','init','初始化','kind: pipeline\r\ntype: docker\r\nname: default\r\nplatform:\r\n os: linux\r\n arch: arm64','2021-01-12 02:45:17','2021-01-12 02:45:17',NULL),(4,'maven','build','Java','- name: maven\r\n image: maven:3-jdk-10\r\n commands:\r\n - mvn install -DskipTests=true','2021-01-12 02:53:29','2021-01-12 02:53:29','编译构建'),(5,'maven单元测试','customize','Java','- name: maven\r\n image: maven:3-jdk-10\r\n commands:\r\n - mvn test','2021-01-12 02:53:29','2021-01-12 02:53:29','单元测试'),(6,'golang单元测试','customize','Golang','- name: golang单元测试\r\n image: golang\r\n commands:\r\n - go test','2021-01-12 03:03:35','2021-01-12 03:03:35','单元测试'),(9,'gradle单元测试','customize','Java','- name: gradle\r\n image: gradle:jdk10\r\n commands:\r\n - gradle test','2021-01-12 03:05:33','2021-01-12 03:05:33','单元测试'),(7,'golang编译','build','Golang','- name: golang编译\r\n image: golang\r\n commands:\r\n - go build','2021-01-12 03:03:35','2021-01-12 03:03:35','编译构建'),(8,'gradle','build','Java','- name: gradle\r\n image: gradle:jdk10\r\n commands:\r\n - gradle build -x test','2021-01-12 03:05:33','2021-01-12 03:05:33','编译构建'),(10,'远程主机部署','deploy','部署','# 根据实际情况修改主机ip、账号、密码\r\n# 需要将软件包与部署脚本提前上传到远程主机(见文件上传模板)\r\n\r\n- name: 远程主机部署\r\n image: appleboy/drone-ssh\r\n settings:\r\n host: 192.168.1.1\r\n username: username\r\n password: \'pasword\'\r\n port: 22\r\n commands:\r\n - chmod +x /home/deploy.sh\r\n - ./home/deploy.sh','2021-01-12 03:32:46','2021-01-12 03:32:46','部署'),(11,'远程命令','customize','工具','- name: 远程命令\r\n image: appleboy/drone-ssh\r\n settings:\r\n host: 192.168.0.1\r\n username: username\r\n password: \'pwd\'\r\n port: 22\r\n script:\r\n - echo \'hello world!\'','2021-01-12 03:40:38','2021-01-12 03:40:38','其他'),(12,'上传文件','customize','工具','# 修改目标服务器的ip、账号密码以及上传路径\r\n# 本模板示例为上传软件包和部署脚本到home目录\r\n\r\n- name: 上传文件\r\n image: appleboy/drone-scp\r\n settings:\r\n host: 192.168.1.1\r\n username: username\r\n password: \'password\'\r\n port: 22\r\n target: /home\r\n source: \r\n - target/*.jar\r\n - deploy.sh','2021-01-12 03:40:55','2021-01-12 03:40:55','其他'),(17,'make-c','build','C语言','- name: 编译\r\n image: gcc\r\n commands:\r\n - ./configure\r\n - make','2021-01-15 01:19:38','2021-01-15 01:19:38','编译构建'),(19,'make-c++','build','C++','- name: 编译构建\r\n image: gcc\r\n commands:\r\n - ./configure\r\n - make','2021-01-15 01:21:05','2021-01-15 01:21:05','编译构建'),(20,'python','build','Python','- name: 编译构建\r\n image: python\r\n commands:\r\n - pip install -r requirements.txt','2021-01-15 01:22:36','2021-01-15 01:22:36','编译构建'),(21,'Docker镜像构建','build','Docker镜像构建','# 构建Docker镜像并推送到仓库\r\n# 定义镜像Hub路径以及账号密码\r\n- name: Docker镜像构建\r\n image: plugins/docker\r\n settings:\r\n username: username\r\n password: pwd\r\n repo: repoUrl\r\n tags: latest','2021-01-15 01:23:16','2021-01-15 01:23:16','编译构建'),(22,'空白模板','customize','customize','','2021-01-15 02:53:02','2021-01-15 02:53:02','其他'),(23,'空白模板','build','自定义','','2021-01-15 03:27:33','2021-01-15 03:27:33','编译构建');
INSERT INTO `ci_templates` (`id`, `template_name`, `stage_type`, `category`, `content`, `created_at`, `updated_at`, `parent_category`, `login`) VALUES
(2, 'linux/amd64', 'init', '初始化', 'kind: pipeline\r\ntype: docker\r\nname: {name}\r\nplatform:\r\n os: linux\r\n arch: amd64', '2021-01-12 02:44:23', '2021-02-02 10:51:36', '初始化', 'admin'),
(3, 'linux/arm64', 'init', '初始化', 'kind: pipeline\r\ntype: docker\r\nname: {name}\r\nplatform:\r\n os: linux\r\n arch: arm64', '2021-01-12 02:45:17', '2021-02-02 10:51:47', '初始化', 'admin'),
(4, 'maven', 'build', 'Java', '- name: maven\r\n image: maven:3-jdk-10\r\n commands:\r\n - mvn install -DskipTests=true', '2021-01-12 02:53:29', '2021-01-12 02:53:29', '编译构建', 'admin'),
(5, 'maven单元测试', 'customize', 'Java', '- name: maven\r\n image: maven:3-jdk-10\r\n commands:\r\n - mvn test', '2021-01-12 02:53:29', '2021-01-12 02:53:29', '单元测试', 'admin'),
(6, 'golang单元测试', 'customize', 'Golang', '- name: golang单元测试\r\n image: golang\r\n commands:\r\n - go test', '2021-01-12 03:03:35', '2021-01-12 03:03:35', '单元测试', 'admin'),
(8, 'gradle', 'build', 'Java', '- name: gradle\r\n image: gradle:jdk10\r\n commands:\r\n - gradle build -x test', '2021-01-12 03:05:33', '2021-01-12 03:05:33', '编译构建', 'admin'),
(9, 'gradle单元测试', 'customize', 'Java', '- name: gradle\r\n image: gradle:jdk10\r\n commands:\r\n - gradle test', '2021-01-12 03:05:33', '2021-01-12 03:05:33', '单元测试', 'admin'),
(10, '远程主机部署', 'deploy', '部署', '# 需要将软件包与部署脚本提前上传到远程主机(见文件上传模板)\r\n# host、username、password可在参数管理中配置\r\n- name: 远程主机部署\r\n image: appleboy/drone-ssh\r\n settings:\r\n host: \r\n from_secret: ip\r\n username: \r\n from_secret: name\r\n password: \r\n from_secret: pwd\r\n port: 22\r\n script:\r\n - chmod +x /home/deploy.sh\r\n - ./home/deploy.sh', '2021-01-12 03:32:46', '2021-03-05 06:22:02', '部署', 'admin'),
(11, '远程命令', 'customize', '其他', '# host、username、password可在参数管理中配置\r\n- name: 远程命令\r\n image: appleboy/drone-ssh\r\n settings:\r\n host: \r\n from_secret: ip\r\n username: \r\n from_secret: name\r\n password: \r\n from_secret: pwd\r\n port: 22\r\n script:\r\n - echo ''hello world!''', '2021-01-12 03:40:38', '2021-03-05 06:19:44', '其他', 'admin'),
(12, '上传文件', 'customize', '其他', '# 本模板示例为上传软件包和部署脚本到home目录\r\n# host、username、password可在参数管理中配置\r\n- name: 上传文件\r\n image: appleboy/drone-scp\r\n settings:\r\n host: \r\n from_secret: ip\r\n username: \r\n from_secret: name\r\n password: \r\n from_secret: pwd\r\n port: 22\r\n target: /home\r\n source: \r\n - target/*.jar\r\n - deploy.sh', '2021-01-12 03:40:55', '2021-03-05 06:22:22', '其他', 'admin'),
(17, 'make-c', 'build', 'C', '- name: 编译\r\n image: gcc\r\n commands:\r\n - ./configure\r\n - make', '2021-01-15 01:19:38', '2021-02-02 10:52:15', '编译构建', 'admin'),
(19, 'make-c++', 'build', 'C++', '- name: 编译构建\r\n image: gcc\r\n commands:\r\n - ./configure\r\n - make', '2021-01-15 01:21:05', '2021-01-15 01:21:05', '编译构建', 'admin'),
(20, 'python', 'build', 'Python', '- name: 编译构建\r\n image: python\r\n commands:\r\n - pip install -r requirements.txt', '2021-01-15 01:22:36', '2021-01-15 01:22:36', '编译构建', 'admin'),
(21, 'Docker', 'build', 'Docker', '# 构建Docker镜像并推送到仓库\r\n# 定义镜像Hub路径以及账号密码\r\n- name: Docker镜像构建\r\n image: plugins/docker\r\n settings:\r\n username: username\r\n password: pwd\r\n repo: repoUrl\r\n tags: latest', '2021-01-15 01:23:16', '2021-02-03 03:40:49', '编译构建', 'admin'),
(22, '空白模板', 'customize', 'customize', '', '2021-01-15 02:53:02', '2021-01-15 02:53:02', '其他', 'admin'),
(25, 'Go (with Gopath)', 'build', 'Go', '- name: golang\r\n image: golang\r\n commands:\r\n - go get\r\n - go test', '2021-02-03 00:57:32', '2021-02-03 03:36:15', '编译构建', 'admin'),
(26, 'PHP', 'build', 'PHP', '- name: install\r\n image: composer\r\n commands:\r\n - composer install', '2021-02-03 00:59:15', '2021-02-03 00:59:15', '编译构建', 'admin'),
(27, 'Ruby', 'build', 'Ruby', '- name: ruby\r\n image: ruby\r\n commands:\r\n - bundle install --jobs=3 --retry=3\r\n - rake', '2021-02-03 00:59:52', '2021-02-03 00:59:52', '编译构建', 'admin'),
(29, 'Go (with Modules)', 'build', 'Go', '- name: test\r\n image: golang\r\n commands:\r\n - go test\r\n - go build', '2021-02-03 03:35:45', '2021-02-03 03:35:45', '编译构建', 'admin'),
(30, 'Node', 'build', 'Node', '- name: Node编译\r\n image: node\r\n commands:\r\n - npm install\r\n - npm test', '2021-02-03 03:37:31', '2021-02-03 03:37:31', '编译构建', 'admin'),
(31, 'Perl ', 'build', 'Perl', '- name: perl\r\n image: perl\r\n commands:\r\n - cpanm --quiet --installdeps --notest .\r\n - perl Build.PL\r\n - ./Build test', '2021-02-03 03:38:06', '2021-02-03 03:38:06', '编译构建', 'admin'),
(32, 'Rust ', 'build', 'Rust', '- name: rust\r\n image: rust:1.30\r\n commands:\r\n - cargo build --verbose --all\r\n - cargo test --verbose --all', '2021-02-03 03:38:37', '2021-02-03 03:38:37', '编译构建', 'admin'),
(33, 'test', 'init', '初始化', 'qqqq', '2021-02-04 09:02:42', '2021-02-04 09:02:42', '初始化', 'admin');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;