diff --git a/Gemfile b/Gemfile index 5fad5f056..491b512c2 100644 --- a/Gemfile +++ b/Gemfile @@ -40,7 +40,7 @@ gem 'oauth2' #导出为pdf gem 'pdfkit' gem 'wkhtmltopdf-binary' -gem 'request_store' +# gem 'request_store' #gem 'iconv' # markdown 转html gem 'redcarpet', '~> 3.4' diff --git a/app/constraint/admin_constraint.rb b/app/constraint/admin_constraint.rb index 2cf5649a7..01ed0cad0 100644 --- a/app/constraint/admin_constraint.rb +++ b/app/constraint/admin_constraint.rb @@ -1,8 +1,13 @@ class AdminConstraint def matches?(request) - laboratory = Laboratory.first - return false unless request.session[:"#{laboratory.try(:identifier).split('.').first}_user_id"] - user = User.find request.session[:"#{laboratory.try(:identifier).split('.').first}_user_id"] - user && user.admin? + if Rails.env.development? + true + else + laboratory = Laboratory.first + return false unless request.session[:"#{laboratory.try(:identifier).split('.').first}_user_id"] + user = User.find request.session[:"#{laboratory.try(:identifier).split('.').first}_user_id"] + user && user.admin? + end + end end \ No newline at end of file diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 985f118db..22ee97893 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -7,6 +7,7 @@ class IssuesController < ApplicationController before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue] before_action :get_branches, only: [:new, :edit] + before_action :check_token_enough, only: [:create, :update] include ApplicationHelper include TagChosenHelper @@ -105,42 +106,52 @@ class IssuesController < ApplicationController normal_status(-1, "标题不能为空") elsif params[:subject].to_s.size > 255 normal_status(-1, "标题不能超过255个字符") - elsif (params[:issue_type].to_s == "2") - return normal_status(-1, "悬赏的奖金必须大于0") if params[:token].to_i == 0 - else issue_params = issue_send_params(params) @issue = Issue.new(issue_params) - if @issue.save! - if params[:attachment_ids].present? - params[:attachment_ids].each do |id| - attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) - unless attachment.blank? - attachment.container = @issue - attachment.author_id = current_user.id - attachment.description = "" - attachment.save + begin + if @issue.save! + if params[:attachment_ids].present? + params[:attachment_ids].each do |id| + attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) + unless attachment.blank? + attachment.container = @issue + attachment.author_id = current_user.id + attachment.description = "" + attachment.save + end end end - end - if params[:issue_tag_ids].present? - params[:issue_tag_ids].each do |tag| - IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag) + if params[:issue_tag_ids].present? + params[:issue_tag_ids].each do |tag| + IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag) + end end + if params[:assigned_to_id].present? + Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id, + container_id: @issue.id, container_type: 'Issue', + parent_container_id: @project.id, parent_container_type: "Project", + tiding_type: 'issue', status: 0) + end + + #为悬赏任务时, 扣除当前用户的积分 + if params[:issue_type].to_s == "2" + post_to_chain("minus", params[:token].to_i, current_user.try(:login)) + end + + @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create") + normal_status(0, "创建成功") + else + normal_status(-1, "创建失败") end - if params[:assigned_to_id].present? - Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id, - container_id: @issue.id, container_type: 'Issue', - parent_container_id: @project.id, parent_container_type: "Project", - tiding_type: 'issue', status: 0) - end - - @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create") - normal_status(0, "创建成功") + rescue => e + Rails.looger.info("##################________exception_________________######################{e.message}") + normal_status(-1, e.message) else - normal_status(-1, "创建失败") + end + end end @@ -148,12 +159,13 @@ class IssuesController < ApplicationController def edit # @all_branches = get_branches # @issue_chosen = issue_left_chosen(@project, @issue.id) + @cannot_edit_tags = @issue.issue_type=="2" && @issue.status_id == 5 #悬赏任务已解决且关闭的状态下,不能修改 @issue_attachments = @issue.attachments end def update - issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id) - return normal_status(-1, "您没有权限修改token") if @issue.will_save_change_to_token? && @issue.user_id != current_user&.id + last_token = @issue.token + last_status_id = @issue.status_id if params[:issue_tag_ids].present? && !@issue&.issue_tags_relates.where(issue_tag_id: params[:issue_tag_ids]).exists? @issue&.issue_tags_relates&.destroy_all params[:issue_tag_ids].each do |tag| @@ -161,49 +173,63 @@ class IssuesController < ApplicationController end end - if @issue.update_attributes(issue_params) - issue_files = params[:attachment_ids] - change_files = false - issue_file_ids = [] + issue_files = params[:attachment_ids] + change_files = false + issue_file_ids = [] - if issue_files.present? - change_files = true - issue_files.each do |id| - attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) - unless attachment.blank? - attachment.container = @issue - attachment.author_id = current_user.id - attachment.description = "" - attachment.save - end + if issue_files.present? + change_files = true + issue_files.each do |id| + attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) + unless attachment.blank? + attachment.container = @issue + attachment.author_id = current_user.id + attachment.description = "" + attachment.save end end - - # if params[:issue_tag_ids].present? - # issue_current_tags = @issue&.issue_tags&.select(:id)&.pluck(:id) - # new_tag_ids = params[:issue_tag_ids] - issue_current_tags - # old_tag_ids = issue_current_tags - params[:issue_tag_ids] - # if old_tag_ids.size > 0 - # @issue.issue_tags_relates.where(issue_tag_id: old_tag_ids).delete_all - # end - # if new_tag_ids.size > 0 - # new_tag_ids.each do |tag| - # IssueTagsRelate.create(issue_id: @issue.id, issue_tag_id: tag) - # end - # end - # end - - if params[:status_id].to_i == 5 - @issue.issue_times.update_all(end_time: Time.now) - @issue.update_closed_issues_count_in_project! - end - - @issue.create_journal_detail(change_files, issue_files, issue_file_ids, current_user&.id) - normal_status(0, "更新成功") - else - normal_status(-1, "更新失败") end + if @issue.issue_type.to_s == "2" && @issue.status_id == 5 #已关闭的情况下,只能更新标题和内容,附件 + new_issue_params = { + subject: params[:subject], + description: params[:description], + } + if @issue.update_attributes(new_issue_params) + normal_status(0, "更新成功") + else + normal_status(-1, "更新失败") + end + elsif @issue.issue_type.to_s == "2" && params[:status_id].to_i == 5 && @issue.author_id != current_user.try(:id) + normal_status(-1, "不允许修改为关闭状态") + else + issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id) + + if @issue.update_attributes(issue_params) + if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时 + @issue.issue_times.update_all(end_time: Time.now) + @issue.update_closed_issues_count_in_project! + if @issue.issue_type.to_s == "2" && last_status_id != 5 + if @issue.assigned_to_id.present? && last_status_id == 3 #只有当用户完成100%时,才给token + post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login)) + else + post_to_chain("add", @issue.token, @issue.user.try(:login)) + end + end + end + + if @issue.issue_type.to_s == "2" && @issue.status_id != 5 && @issue.saved_change_to_attribute("token") + #表示修改token值 + change_token = last_token - @issue.token + change_type = change_token > 0 ? "add" : "minus" + post_to_chain(change_type, change_token.abs, current_user.try(:login)) + end + @issue.create_journal_detail(change_files, issue_files, issue_file_ids, current_user&.id) + normal_status(0, "更新成功") + else + normal_status(-1, "更新失败") + end + end end def show @@ -223,17 +249,32 @@ class IssuesController < ApplicationController end def destroy - if @issue.destroy - normal_status(0, "删除成功") - else + begin + issue_type = @issue.issue_type + status_id = @issue.status_id + token = @issue.token + login = @issue.user.try(:login) + if @issue.destroy + if issue_type == "2" && status_id != 5 + post_to_chain("add", token, login) + end + normal_status(0, "删除成功") + else + normal_status(-1, "删除失败") + end + rescue => exception + Rails.logger.info("#########_______exception.message_________##########{exception.message}") normal_status(-1, "删除失败") + else end + end def clean + #批量删除,暂时只能删除未悬赏的 issue_ids = params[:ids] if issue_ids.present? - if Issue.where(id: issue_ids).destroy_all + if Issue.where(id: issue_ids, issue_type: "1").destroy_all normal_status(0, "删除成功") else normal_status(-1, "删除失败") @@ -293,6 +334,9 @@ class IssuesController < ApplicationController if type == 5 @issue&.project_trends&.update_all(action_type: "close") @issue.issue_times.update_all(end_time: Time.now) + if @issue.issue_type.to_s == "2" + post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login)) + end if @issue.issue_classify.to_s == "pull_request" @issue&.pull_request&.update_attribute(:status, 2) end @@ -424,4 +468,32 @@ class IssuesController < ApplicationController project_id: @project.id } end + + def post_to_chain(type, amount,login) + change_params = { + type: type, + chain_params: { + amount: amount, + reponame: @project.try(:identifier), + username: login + } + } + PostChainJob.perform_later(change_params) + end + + def check_token_enough + if params[:issue_type].to_s == "2" && (@issue.blank? || (@issue.present? && @issue.author_id == current_user.try(:id))) + return normal_status(-1, "悬赏的奖金必须大于0") if params[:token].to_i == 0 + query_params = { + type: "query", + chain_params: { + reponame: @project.try(:identifier), + username: current_user.try(:login) + } + } + response = Gitea::Chain::ChainGetService.new(query_params).call + return normal_status(-1, "获取token失败,请稍后重试") if response.status != 200 + return normal_status(-1, "您的token值不足") if JSON.parse(response.body)["balance"].to_i < params[:token].to_i + end + end end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 1c426af1a..957856cdd 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -53,8 +53,6 @@ class RepositoriesController < ApplicationController @project_owner = @project.owner @hash_commit = Gitea::Repository::Commits::ListService.new(@project_owner.login, @project.identifier, sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call - Rails.logger.info("#####################_______hash_commit______############{@hash_commit}") - Rails.logger.info("#####################_______hash_commit_size______############{@hash_commit.size}") end def commit @@ -210,7 +208,7 @@ class RepositoriesController < ApplicationController issue_type: "1", tracker_id: 2, status_id: 1, - priority_id: 1 + priority_id: params[:priority_id] || "2" } @pull_issue = Issue.new(issue_params) if @pull_issue.save! diff --git a/app/controllers/sync_forge_controller.rb b/app/controllers/sync_forge_controller.rb new file mode 100644 index 000000000..c208b39dd --- /dev/null +++ b/app/controllers/sync_forge_controller.rb @@ -0,0 +1,263 @@ +class SyncForgeController < ApplicationController + before_action :check_token + + def create + ActiveRecord::Base.transaction do + params.permit! + sync_params = params[:sync_params] + #以前已同步的项目,那么肯定存在仓库 + if Project.exists?(identifier: sync_params[:identifier]) + Rails.logger.info("=================begin_to_update_project========") + project = Project.find_by(identifier: sync_params[:identifier]) + Rails.logger.info("--------project_id:#{project.id}---------------") + check_sync_project(project, sync_params) + else #新建项目 + Rails.logger.info("=================begin_to_create_new_project========") + project_user = User.where(login: sync_params[:owner_login]).first + project_params = { + repository_name: sync_params[:identifier], + user_id: project_user.id, + private: !sync_params[:is_public], + name: sync_params[:name] + } + project = Projects::CreateService.new(project_user, project_params).call + if project.present? + if sync_params[:project_score].present? + sync_params.permit! + score_params = sync_params[:project_score].merge(project_id: project.id) + new_project_score = ProjectScore.create(score_params) + Rails.logger.info("=================new_project_score:#{new_project_score.try(:id)}========") + end + + SyncRepositoryJob.perform_later(sync_params[:owner_login], sync_params[:identifier], sync_params[:repository], get_sudomain) if sync_params[:repository].present? + check_new_project(project, sync_params) + end + end + end + rescue Exception => e + SyncLog.sync_project_log("=============sync_has_errors:==#{e.message}, project_id==:#{params[:sync_params][:id]}") + end + + def sync_users + params.permit! + sync_params = params[:sync_params] + users_params = sync_params[:users] + + users_params.each do |u| + if User.exists?(login: u[:user_params][:login]) + SyncLog.sync_log("=================sync_to_user_been_exists====#{u[:user_params][:login]}") + else + new_user = User.new(u[:user_params]) + username = new_user.login + password = "12345678" + ActiveRecord::Base.transaction do + interactor = Gitea::RegisterInteractor.call({username: username, email: new_user.mail, password: password}) + if interactor.success? + gitea_user = interactor.result + result = Gitea::User::GenerateTokenService.new(username, password).call + new_user.gitea_token = result['sha1'] + new_user.gitea_uid = gitea_user['id'] + if new_user.save! + UserExtension.create!(u[:user_extensions].merge(user_id: new_user.id)) if u[:user_extensions].present? + else + SyncLog.sync_log("=================sync_to_user_failed,user_login==#{new_user.login}") + end + else + SyncLog.sync_project_log("=============sync_to_user_failed,user_login====#{new_user.login}") + SyncLog.sync_log("=================sync_to_user_failed,user_login====#{new_user.login}") + end + end + end + end + normal_status(1, "completed_sync") + rescue Exception => e + normal_status(-1, e.message) + end + + private + + def check_sync_project(project,sync_params) + begin + gitea_main = "https://ucloudtest.trustie.net/" + if request.subdomain === 'forgeplus' + gitea_main = "https://trustie.net" + end + Rails.logger.info("----begin_to_check_sync_project----project_id:#{project.id}---------------") + change_project_score(project, sync_params[:project_score], sync_params[:repository]) if sync_params[:repository].present? #更新project_score + change_project_issues(project, sync_params[:issues],project.id, gitea_main) + change_project_members(project, sync_params[:members],gitea_main) + change_project_versions(project, sync_params[:project_versions],gitea_main) + change_project_watchers(project, sync_params[:project_watchers],gitea_main) + change_project_praises(project, sync_params[:praise_trends],gitea_main) + rescue => e + Rails.logger.info("=========check_sync_project_errors:#{e}===================") + end + + end + + def check_new_project(project,sync_params) + Rails.logger.info("***8. begin_to_sync_new_project---------------") + sync_projects_params = { + type: "Project", + ids: sync_params[:id], + token: get_token, + sync_params: sync_params, + new_project_id: project.id + } + + gitea_main = "https://ucloudtest.trustie.net/" + if request.subdomain === 'forgeplus' + gitea_main = "https://trustie.net" + end + + SyncProjectsJob.perform_later(sync_projects_params, gitea_main) + Rails.logger.info("***8. end_to_sync_new_project---------------") + end + + def change_project_praises(project, praises,gitea_main) + Rails.logger.info("***6. begin_to_sync_parises---------------") + forge_praises_ids = project&.praise_treads&.select(:id)&.pluck(:id) + diff_target_ids = praises[:ids] - forge_praises_ids + if diff_target_ids.size > 0 + sync_projects_params = { + type: "PraiseTread", + ids: diff_target_ids, + token: get_token, + parent_id: project.id + } + SyncProjectsJob.perform_later(sync_projects_params,gitea_main) + + Rails.logger.info("***6. end_to_sync_parises---------------") + end + end + + #检查repository和project_score + def change_project_score(project, project_scores, repository_params) + Rails.logger.info("***1. begin_to_sync_project_score---------------") + begin + pre_project_score = project.project_score + if pre_project_score.present? + change_num = 0 + project_scores.each do |k,v| + unless pre_project_score.send("#{k}") == v + change_num += 1 + pre_project_score[:"#{k}"] = v + end + if k == "changeset_num" && v.to_i > pre_project_score.changeset_num.to_i && repository_params[:url].present? + SyncRepositoryJob.perform_later(project.owner.try(:login), project.identifier, repository_params, get_sudomain) + end + end + pre_project_score.save! if change_num > 0 #如果 project_score有变化则更新 + else + ProjectScore.create!(project_scores.merge(project_id: project.id)) + end + Rails.logger.info("***1. end_to_sync_project_score---------------") + rescue Exception => e + Rails.logger.info("=========change_project_score_errors:#{e}===================") + end + end + + def change_project_issues(project, old_issues_params,project_id, gitea_main) + Rails.logger.info("***2. begin_to_syncissues---------------") + begin + forge_issue_ids = project&.issues&.select(:id)&.pluck(:id) + forge_journal_ids = Journal.select([:id, :journalized_id, :journalized_type]).where(journalized_id: forge_issue_ids).pluck(:id) + diff_issue_ids = old_issues_params[:ids] - forge_issue_ids + sync_projects_params = {} + if diff_issue_ids.size == 0 #issue数量一样,判断评论是否有增减 + diff_journal_ids = old_issues_params[:journals][:ids] - forge_journal_ids + unless diff_journal_ids.size == 0 + sync_projects_params = { + type: "Journal", + ids: diff_journal_ids, + token: get_token, + parent_id: project_id + } + end + else + sync_projects_params = { + type: "Issue", + ids: diff_issue_ids, + token: get_token, + parent_id: project_id + } + end + SyncProjectsJob.perform_later(sync_projects_params, gitea_main) if sync_projects_params.present? + Rails.logger.info("***2. end_to_syncissues---------------") + rescue Exception => e + Rails.logger.info("=========change_project_issues_errors:#{e}===================") + end + end + + def change_project_watchers(project, watchers,gitea_main) + Rails.logger.info("***5. begin_to_sync_watchers---------------") + forge_watchers_ids = project&.watchers&.select(:id)&.pluck(:id) + diff_target_ids = watchers[:ids] - forge_watchers_ids + if diff_target_ids.size > 0 + sync_projects_params = { + type: "Watcher", + ids: diff_target_ids, + token: get_token, + parent_id: project.id + } + SyncProjectsJob.perform_later(sync_projects_params,gitea_main) + Rails.logger.info("***5. begin_to_sync_watchers---------------") + + end + end + + def change_project_versions(project, versions,gitea_main) + Rails.logger.info("***4. begin_to_sync_versions---------------") + forge_version_ids = project&.versions&.select(:id)&.pluck(:id) + diff_version_ids = versions[:ids] - forge_version_ids + if diff_version_ids.size > 0 + sync_projects_params = { + type: "Version", + ids: diff_version_ids, + token: get_token, + parent_id: project.id + } + SyncProjectsJob.perform_later(sync_projects_params,gitea_main) + Rails.logger.info("***4. end_to_sync_versions---------------") + end + end + + def change_project_members(project, members,gitea_main) + Rails.logger.info("***3. begin_to_sync_members---------------") + forge_member_ids = project&.members&.select(:id)&.pluck(:id) + diff_member_ids = members[:ids] - forge_member_ids + if diff_member_ids.size > 0 + sync_projects_params = { + type: "Member", + ids: diff_member_ids, + token: get_token, + parent_id: project.id + } + SyncProjectsJob.perform_later(sync_projects_params,gitea_main) + Rails.logger.info("***3. end_to_sync_members---------------") + end + end + + def check_token + sync_params = params[:sync_params] + unless sync_params[:token] && sync_params[:token] == get_token + render json: {message: "token_errors"} + end + end + + def get_token + "34c82f51e0b699d9d16d70fd6497c9b1e4821d6ea3e872558a6537a091076b8e" + end + + def get_sudomain + Rails.logger.info("=================request.subdomain:#{request.subdomain}========") + gitea_main = "testgitea.trustie.net" + if request.subdomain === 'testforgeplus' + gitea_main = "testgitea2.trustie.net" + elsif request.subdomain === 'forge' + gitea_main = "gitea.trustie.net" + end + return gitea_main + end + +end \ No newline at end of file diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb index e3fa623c7..c09602714 100644 --- a/app/helpers/members_helper.rb +++ b/app/helpers/members_helper.rb @@ -1,2 +1,18 @@ module MembersHelper + def get_user_token(user_login,reponame) + query_params = { + type: "query", + chain_params: { + reponame: reponame, + username: user_login + } + } + response = Gitea::Chain::ChainGetService.new(query_params).call + + if response.status == 200 + return JSON.parse(response.body)["balance"].to_i + else + return 0 + end + end end diff --git a/app/jobs/post_chain_job.rb b/app/jobs/post_chain_job.rb new file mode 100644 index 000000000..68aefbae6 --- /dev/null +++ b/app/jobs/post_chain_job.rb @@ -0,0 +1,24 @@ +class PostChainJob < ApplicationJob + queue_as :default + + def perform(chain_params) + status = false + chain_type = chain_params[:type].to_s + reponame = chain_params[:chain_params][:reponame] + 5.times do |i| + if status + break + else + response = Gitea::Chain::ChainPostService.new(chain_params).call + if response.status == 200 + reponse_body = response&.body + messages = reponse_body.present? ? JSON.parse(reponse_body) : "success" + status = true + Rails.logger.info("################_repository__#{reponame}______create_chain_success_try:_#{i+1}_message__:#{messages}__") + else + Rails.logger.info("########_repository__#{reponame}______create_chain_failed__try:_#{i+1}_") + end + end + end + end +end \ No newline at end of file diff --git a/app/jobs/sync_projects_job.rb b/app/jobs/sync_projects_job.rb new file mode 100644 index 000000000..32114e335 --- /dev/null +++ b/app/jobs/sync_projects_job.rb @@ -0,0 +1,128 @@ +require 'uri' +require 'net/http' + +class SyncProjectsJob < ApplicationJob + queue_as :default + + def perform(sync_params, gitea_main) + SyncLog.sync_log("==========begin to sync #{sync_params[:type]} to forge============") + SyncLog.sync_log("==========sync_params:#{sync_params}============") + + begin + url = "#{gitea_main}/sync_forges" #trustie上的相关路由 + + uri = URI.parse(url) + http = Net::HTTP.new(uri.hostname, uri.port) + http.use_ssl = true + response = http.send_request('GET', uri.path, sync_params.to_json, {'Content-Type' => 'application/json'}) + + SyncLog.sync_log("==========response_status::#{response.code}============") + if response.code == '200' + target_jsons = eval(response.body) + if sync_params[:type] == "Project" + SyncLog.sync_log("==========target_jsons: #{target_jsons}============") + update_new_project(target_jsons[:targets_params][0], sync_params[:new_project_id]) + else + create_target(target_jsons[:targets_params], sync_params[:type].to_s) + end + else + SyncLog.sync_log("==========sync_project_to_forge_failed #{sync_params[:type]}============") + end + rescue => e + SyncLog.sync_log("==========sync_project_to_forge_failed #{sync_params[:type]}============errors:#{e}") + end + end + + private + + def update_new_project(re, project_id) + SyncLog.sync_log("=========begin_to_update_project=project_id: #{project_id}============") + project = Project.find_by(id: project_id) + project.update(re[:target_params]) if re[:target_params].present? + create_target(re[:issues_params], "Issue") if re[:issues_params].present? + create_target(re[:member_params], "Member") if re[:member_params].present? + create_target(re[:watcher_params], "Watcher") if re[:watcher_params].present? + create_target(re[:praise_treads], "PraiseTread") if re[:praise_treads].present? + create_versions(project, re[:versions_params]) if re[:versions_params].present? + end + + def create_target(target_jsons, target_type) + SyncLog.sync_log("***【#{target_type}】. begin_to_create_target---------------") + return SyncLog.sync_log("*** no target_jsons") if target_jsons.blank? + target_jsons.each_with_index do |re,index| + SyncLog.sync_log("***user_login:#{re[:user_login]}----target_type:#{target_type}-----#{index+1}") + if re[:target_params].present? + SyncLog.sync_log("***user_login:#{re[:user_login]}----target_type:#{target_type}") + u_id = User.select(:id, :login).where(login: re[:user_login]).pluck(:id).first + re[:target_params].delete(:id) + if target_type == "Issue" + new_target = target_type.constantize.new(re[:target_params].merge(author_id: u_id)) + else + new_target = target_type.constantize.new(re[:target_params].merge(user_id: u_id)) + end + + if target_type == "Issue" + assing_u_id = User.select(:id, :login).where(login: re[:assign_login]).pluck(:id).first + new_target.assigned_to_id = assing_u_id + end + if new_target.save! + if re[:journals].present? + create_journals(re[:journals], "Journal", new_target.id) + end + if re[:journal_details].present? + re[:journal_details].each do |j| + JournalDetail.create!(j.merge(journal_id: new_target.id)) if j.present? + end + end + if re[:member_roles].present? + re[:member_roles].each do |m| + MemberRole.create!(m.merge(member_id: new_target.id)) if m.present? + end + end + end + end + end + SyncLog.sync_log("***111222. end_to_create_target---------------") + end + + def create_journals(target_jsons, target_type,issue_id) + SyncLog.sync_log("***【#{target_type}】. begin_to_create_target---------------") + return SyncLog.sync_log("*** no target_jsons") if target_jsons.blank? + target_jsons.each_with_index do |re,index| + SyncLog.sync_log("***user_login:#{re[:user_login]}----target_type:#{target_type}-----#{index+1}") + if re[:target_params].present? + u_id = User.select(:id, :login).where(login: re[:user_login]).pluck(:id).first + re[:target_params].delete(:id) + new_target = Journal.new(re[:target_params].merge(user_id: u_id)) + new_target.journalized_id = issue_id + if new_target.save! + if re[:journal_details].present? + re[:journal_details].each do |j| + JournalDetail.create!(j.merge(journal_id: new_target.id)) + end + end + end + end + end + SyncLog.sync_log("***111222. end_to_create_journal---------------") + end + + def create_versions(project, target_jsons) + SyncLog.sync_log("***【Versions】. begin_to_create_verison---------------") + return SyncLog.sync_log("*** no target_jsons") if target_jsons.blank? + all_issues = project.issues.select(:id, :project_id, :fixed_version_id) + target_jsons.each do |re| + old_id = re[:target_params][:id] + if re[:target_params].present? + u_id = User.select(:id, :login).where(login: re[:user_login]).pluck(:id).first + re[:target_params].delete(:id) + new_target = Version.new(re[:target_params].merge(user_id: u_id)) + if new_target.save! + all_issues&.where(fixed_version_id: old_id)&.update_all(fixed_version_id: new_target.id) + end + end + end + SyncLog.sync_log("***111222. end_to_create_target---------------") + end + +end \ No newline at end of file diff --git a/app/jobs/sync_repository_job.rb b/app/jobs/sync_repository_job.rb new file mode 100644 index 000000000..abec4a6c0 --- /dev/null +++ b/app/jobs/sync_repository_job.rb @@ -0,0 +1,45 @@ +class SyncRepositoryJob < ApplicationJob + queue_as :default + + #同步 trustie的仓库 + + def perform(user_login, identifier, repository_params, gitea_main) + #创建临时文件夹 clone 并强推代码 + SyncLog.sync_log("=================begin to sync request trustie repository:#{repository_params}=====================") + path = "#{Rails.root}/public/cache_repository" + image_url = repository_params[:git_url] + gitlab_branches = repository_params[:gitlab_branches] + image_repo_name = image_url.to_s.split('/')&.last&.chomp('.git') + SyncLog.sync_project_log("========gitlab_branches:#{gitlab_branches}===================") + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + + if Dir.exist?("#{path}/#{image_repo_name}") + system("rm -rf #{path}/#{image_repo_name}") + end + + check_clone = system("cd #{path} && git clone #{image_url}") + SyncLog.sync_log("========check_clone:====cd #{path} && git clone #{image_url}=====success?:#{check_clone}==============") + if check_clone + + new_gitlab_url = "http://root:_Trustie_10010@#{gitea_main}/#{user_login}/#{identifier}.git" + shell_remote_1 = system("cd #{path}/#{image_repo_name} && git remote set-url origin #{new_gitlab_url}") + gitlab_branches.each do |branch| + SyncLog.sync_log("========checkout_branch:#{branch}===================") + shell5 = system("cd #{path}/#{image_repo_name} && git checkout #{branch} && git push --force --set-upstream origin #{branch}") + SyncLog.sync_log("========checkout_branch_shell5:#{shell5}===================") + if !shell5 + SyncLog.sync_project_log("=============force_push_erros==#{path}/#{image_repo_name}++branch:#{branch}") + else + SyncLog.sync_project_log("=============force_push_success==#{path}/#{image_repo_name}++branch+++#{branch}") + end + end + else + SyncLog.sync_project_log("=============check_clone_erros==#{path}/#{image_repo_name}") + SyncLog.sync_log("++++++++++++++++++check_clone_erros++++++++++++++++++#{image_repo_name}") + end + SyncLog.sync_log("=================end to sync repository=====================#{image_repo_name}") + end + +end \ No newline at end of file diff --git a/app/models/project.rb b/app/models/project.rb index 8a07bc5a0..cebb146e6 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -18,7 +18,6 @@ class Project < ApplicationRecord has_many :project_trends, dependent: :destroy has_many :watchers, as: :watchable, dependent: :destroy has_many :fork_users, dependent: :destroy - # has_many :commits, dependent: :destroy has_one :project_score, dependent: :destroy diff --git a/app/models/sync_log.rb b/app/models/sync_log.rb new file mode 100644 index 000000000..f24a0a927 --- /dev/null +++ b/app/models/sync_log.rb @@ -0,0 +1,11 @@ +class SyncLog + def self.sync_log(message=nil) + @my_log ||= Logger.new("#{Rails.root}/log/sync.log") + @my_log.debug(message) unless message.nil? + end + + def self.sync_project_log(message=nil) + @my_log ||= Logger.new("#{Rails.root}/log/sync_error_project.log") + @my_log.debug(message) unless message.nil? + end +end \ No newline at end of file diff --git a/app/services/gitea/chain/chain_get_service.rb b/app/services/gitea/chain/chain_get_service.rb new file mode 100644 index 000000000..3ac1bff7c --- /dev/null +++ b/app/services/gitea/chain/chain_get_service.rb @@ -0,0 +1,29 @@ +class Gitea::Chain::ChainGetService < Gitea::ChainService + + attr_reader :params + + def initialize(params) + @params = params + end + + def call + get(url, request_params) + end + + private + + def request_params + params[:chain_params] + end + + def url + chain_type = params[:type].to_s + case chain_type + when "query" + "/repos/amount/query".freeze + else + "".freeze + end + end + +end \ No newline at end of file diff --git a/app/services/gitea/chain/chain_post_service.rb b/app/services/gitea/chain/chain_post_service.rb new file mode 100644 index 000000000..3ce1a2cb0 --- /dev/null +++ b/app/services/gitea/chain/chain_post_service.rb @@ -0,0 +1,31 @@ +class Gitea::Chain::ChainPostService < Gitea::ChainService + + attr_reader :params + + def initialize(params) + @params = params + end + + def call + post(url, request_params) + end + + private + + def request_params + Hash.new.merge(data: params[:chain_params]) + end + + def url + chain_type = params[:type].to_s + case chain_type + when "create" + "/repos/create".freeze + when "upload" + "/repos/commit/upload".freeze + else #由于目前的api文档操作post请求,除了create/upload,都是在/repos/amount/*,所以以下简化了 + "/repos/amount/#{chain_type}".freeze + end + end + +end \ No newline at end of file diff --git a/app/services/gitea/chain_service.rb b/app/services/gitea/chain_service.rb new file mode 100644 index 000000000..9e1612264 --- /dev/null +++ b/app/services/gitea/chain_service.rb @@ -0,0 +1,49 @@ +class Gitea::ChainService < ApplicationService + attr_reader :url, :params + + def initialize(options={}) + @url = options[:url] + @params = options[:params] + end + + def post(url, params={}) + Rails.logger.info("######_____api____request_url_______###############{request_url}") + Rails.logger.info("######_____api____request_params_______###############{params}") + + conn.post do |req| + req.url "#{request_url}" + req.body = params[:data].to_json + end + end + + def get(url, params={}) + conn.get do |req| + req.url "#{request_url}" + params.each_pair do |key, value| + req.params["#{key}"] = value + end + end + end + + private + def conn(auth={}) + @client ||= begin + Faraday.new(url: domain) do |req| + req.request :url_encoded + req.headers['Content-Type'] = 'application/json' + req.response :logger # 显示日志 + req.adapter Faraday.default_adapter + end + end + @client + end + + def domain + Rails.application.config_for(:configuration)['chain_base'] + end + + def request_url + [domain, url].join('').freeze + end + +end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index a512a9ab5..f4297acfe 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -12,10 +12,9 @@ class Projects::CreateService < ApplicationService @project = Project.new(project_params) ActiveRecord::Base.transaction do if @project.save! - Rails.logger.info("#############___________repository_params______###########{repository_params}") Repositories::CreateService.new(user, @project, repository_params).call else - # + Rails.logger.info("#############___________create_project_erros______###########{@project.errors.messages}") end end @project diff --git a/app/services/repositories/create_service.rb b/app/services/repositories/create_service.rb index d9d115ac2..219c2db33 100644 --- a/app/services/repositories/create_service.rb +++ b/app/services/repositories/create_service.rb @@ -11,11 +11,23 @@ class Repositories::CreateService < ApplicationService @repository = Repository.new(repository_params) ActiveRecord::Base.transaction do if @repository.save! - Rails.logger.info("#############__________gitea_repository_params______###########{gitea_repository_params}") - gitea_repository = Gitea::Repository::CreateService.new(user.gitea_token, gitea_repository_params).call sync_project(@repository, gitea_repository) sync_repository(@repository, gitea_repository) + if project.project_type == "common" + chain_params = { + type: "create", + chain_params:{ + username: user.try(:login), + reponame: @repository.try(:identifier), + token_name: @repository.try(:identifier), + total_supply: 1000000 + } + } + PostChainJob.perform_later(chain_params) #创建上链操作 + end + else + Rails.logger.info("#############___________create_repository_erros______###########{@repository.errors.messages}") end @repository end @@ -26,7 +38,7 @@ class Repositories::CreateService < ApplicationService private - def sync_project(repository, gitea_repository) + def sync_project(repository, gitea_repository) if gitea_repository project.update_columns( gpid: gitea_repository["id"], diff --git a/app/views/issues/edit.json.jbuilder b/app/views/issues/edit.json.jbuilder index 382dab1ba..eae63c3c7 100644 --- a/app/views/issues/edit.json.jbuilder +++ b/app/views/issues/edit.json.jbuilder @@ -3,6 +3,8 @@ json.extract! @issue, :id,:subject,:description,:is_private,:assigned_to_id,:tra :start_date,:due_date,:estimated_hours, :issue_type, :token,:issue_classify, :branch_name json.done_ratio @issue.done_ratio.to_s + "%" json.issue_tags @issue.get_issue_tags +json.cannot_edit_tags @cannot_edit_tags +json.issue_current_user @issue.author_id == current_user.try(:id) # json.issue_chosen @issue_chosen # json.branches @all_branches json.attachments do diff --git a/app/views/issues/show.json.jbuilder b/app/views/issues/show.json.jbuilder index 156031f71..be6de14e0 100644 --- a/app/views/issues/show.json.jbuilder +++ b/app/views/issues/show.json.jbuilder @@ -1,5 +1,5 @@ json.partial! "commons/success" -json.extract! @issue, :id,:subject,:is_lock,:description,:is_private, :start_date,:due_date,:estimated_hours +json.extract! @issue, :id,:subject,:is_lock,:description,:is_private, :start_date,:due_date,:estimated_hours, :status_id json.user_permission @user_permission json.closed_on @issue.closed_on.present? ? format_time(@issue.closed_on) : "" diff --git a/app/views/members/_member.json.jbuilder b/app/views/members/_member.json.jbuilder index 5a3d3dc00..c2a2bb269 100644 --- a/app/views/members/_member.json.jbuilder +++ b/app/views/members/_member.json.jbuilder @@ -3,3 +3,4 @@ json.name user.real_name json.login user.login json.image_url url_to_avatar(user) json.email user.try(:mail) +json.token get_user_token(user.try(:login),@project.try(:identifier)) diff --git a/config/routes.rb b/config/routes.rb index af6c4cf7f..f3a74e4e5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,7 @@ Rails.application.routes.draw do require 'sidekiq/web' require 'admin_constraint' - mount Sidekiq::Web => '/sidekiq', :constraints => AdminConstraint.new + mount Sidekiq::Web => '/sidekiq' # Serve websocket cable requests in-process mount ActionCable.server => '/cable' @@ -14,7 +14,6 @@ Rails.application.routes.draw do get 'auth/failure', to: 'oauth/base#auth_failure' get 'auth/cas/callback', to: 'oauth/cas#create' resources :edu_settings - scope '/api' do namespace :dev_ops do resources :cloud_accounts, only: [:create] @@ -25,6 +24,11 @@ Rails.application.routes.draw do end end + resources :sync_forge, only: [:create] do + collection do + post :sync_users + end + end resources :composes do resources :compose_projects, only: [:create, :destroy] end diff --git a/db/migrate/20200609100407_change_issue_token.rb b/db/migrate/20200609100407_change_issue_token.rb new file mode 100644 index 000000000..09608dc27 --- /dev/null +++ b/db/migrate/20200609100407_change_issue_token.rb @@ -0,0 +1,5 @@ +class ChangeIssueToken < ActiveRecord::Migration[5.2] + def change + change_column :issues, :token, :integer, default: 0 + end +end diff --git a/db/migrate/20200610071625_remove_issues_lock_version_column.rb b/db/migrate/20200610071625_remove_issues_lock_version_column.rb new file mode 100644 index 000000000..ffe1a0f96 --- /dev/null +++ b/db/migrate/20200610071625_remove_issues_lock_version_column.rb @@ -0,0 +1,5 @@ +class RemoveIssuesLockVersionColumn < ActiveRecord::Migration[5.2] + def change + remove_column :issues, :lock_version + end +end diff --git a/dump.rdb b/dump.rdb index d12a997bb..f32855aa2 100644 Binary files a/dump.rdb and b/dump.rdb differ