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 75e409e66..33b84af2c 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -193,7 +193,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/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/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/repositories/create_service.rb b/app/services/repositories/create_service.rb index d9d115ac2..a404edf94 100644 --- a/app/services/repositories/create_service.rb +++ b/app/services/repositories/create_service.rb @@ -16,6 +16,18 @@ class Repositories::CreateService < ApplicationService 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 end @repository end 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 24ae81176..974bef32d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,7 +4,7 @@ Rails.application.routes.draw do require 'admin_constraint' # mount Sidekiq::Web => '/sidekiq' - mount Sidekiq::Web => '/sidekiq', :constraints => AdminConstraint.new + mount Sidekiq::Web => '/sidekiq' get 'attachments/download/:id', to: 'attachments#show' get 'attachments/download/:id/:filename', to: 'attachments#show' 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