| @@ -46,7 +46,7 @@ class Api::V1::Issues::JournalsController < Api::V1::BaseController | |||
| end | |||
| def load_issue | |||
| @issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || Issue.find_by_id(params[:index]) | |||
| @issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || @project.issues.issue_issue.find_by_id(params[:index]) | |||
| if @issue.blank? | |||
| render_not_found("疑修不存在!") | |||
| end | |||
| @@ -70,7 +70,7 @@ class Api::V1::IssuesController < Api::V1::BaseController | |||
| private | |||
| def load_issue | |||
| @issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || Issue.find_by_id(params[:index]) | |||
| @issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || @project.issues.issue_issue.find_by_id(params[:index]) | |||
| if @issue.blank? | |||
| render_not_found("疑修不存在!") | |||
| end | |||
| @@ -210,6 +210,10 @@ class ApplicationController < ActionController::Base | |||
| tip_exception(401, "请登录后再操作") unless User.current.logged? | |||
| end | |||
| def require_referer | |||
| tip_exception(403, "你没有权限访问") if request.host.present? && !request.referer.to_s.include?(request.host.to_s.gsub("www.","")) | |||
| end | |||
| def require_login_or_token | |||
| if params[:token].present? | |||
| user = User.try_to_autologin(params[:token]) | |||
| @@ -30,25 +30,33 @@ class AttachmentsController < ApplicationController | |||
| def get_file | |||
| Rails.logger.info("request.host===#{request.host},request.referer===#{request.referer}") | |||
| tip_exception(403, "你没有权限访问") if request.host.present? && !request.referer.to_s.include?(request.host.to_s.gsub("www.","")) | |||
| normal_status(-1, "参数缺失") if params[:download_url].blank? | |||
| url = base_url.starts_with?("https:") ? params[:download_url].to_s.gsub("http:", "https:") : params[:download_url].to_s | |||
| md5_file = Digest::MD5.hexdigest(params[:download_url]) | |||
| FileUtils.mkdir_p("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/") unless Dir.exists?("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/") | |||
| tmp_path = "#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/#{Time.now.strftime('%Y%m%d')}-#{md5_file}" | |||
| if url.starts_with?(base_url) && !url.starts_with?("#{base_url}/repo") | |||
| domain = GiteaService.gitea_config[:domain] | |||
| api_url = GiteaService.gitea_config[:base_url] | |||
| url = ("/repos"+url.split(base_url + "/api")[1]) | |||
| filepath, ref = url.split("/")[-1].split("?") | |||
| url.gsub!(url.split("/")[-1], '') | |||
| Rails.logger.info("url===#{url}") | |||
| # Rails.logger.info("url===#{url}") | |||
| Rails.logger.info(filepath) | |||
| request_url = [domain, api_url, URI.encode(url), URI.escape(filepath), "?ref=#{URI.escape(ref.split('ref=')[1])}&access_token=#{User.where(admin: true).take&.gitea_token}"].join | |||
| ref = ref.blank? ? "" : URI.escape(ref.split('ref=')[1]) | |||
| request_url = [domain, api_url, URI.encode(url), URI.escape(filepath), "?ref=#{ref}&access_token=#{User.where(admin: true).take&.gitea_token}"].join | |||
| Rails.logger.info("request_url===#{request_url}") | |||
| response = Faraday.get(request_url) | |||
| File.delete(tmp_path) if File.exist?(tmp_path) # 删除之前的文件 | |||
| Util.download_file(request_url, tmp_path) | |||
| filename = filepath | |||
| else | |||
| response = Faraday.get(URI.encode(url)) | |||
| File.delete(tmp_path) if File.exist?(tmp_path) # 删除之前的文件 | |||
| Util.download_file(URI.encode(url), tmp_path) | |||
| filename = params[:download_url].to_s.split("/").pop() | |||
| end | |||
| send_data(response.body.force_encoding("UTF-8"), filename: filename, type: "application/octet-stream", disposition: 'attachment') | |||
| send_file(tmp_path, filename: filename, type: "application/octet-stream", disposition: 'attachment') | |||
| end | |||
| def create | |||
| @@ -25,6 +25,16 @@ class CommitLogsController < ApplicationController | |||
| commit_log.project_trends.create(user_id: user.id, project_id: project&.id, action_type: "create") if user.id !=2 | |||
| # 统计数据新增 | |||
| CacheAsyncSetJob.perform_later("project_common_service", {commits: 1}, project.id) | |||
| commit_user = User.find_by(mail: commit[:committer][:email]) rescue nil | |||
| commit_user = User.find_by(login: commit[:committer][:name]) if commit_user.blank? rescue nil | |||
| next if commit_user.blank? | |||
| # 触发变更issue状态的job | |||
| close_issue_content = message.to_s.scan(/\b(Close|Closes|Closed|Closing|close|closes|closed|closing)\s*(#\d+(,\s*#\d+)*)?\b/) | |||
| ChangeIssueStatusByMessageJob.perform_later(commit_id, project, commit_user, close_issue_content[0][1], 5) if close_issue_content[0].present? && close_issue_content[0][1].present? | |||
| solve_issue_content = message.to_s.scan(/\b(Fix|Fixes|Fixed|Fixing|fix|fixes|fixed|fixing|Resolve|Resolves|Resolved|Resolving|resolve|resolves|resolved|resolving|Implement|Implements|Implemented|Implementing|implement|implements|implemented|implementing)\s*(#\d+(,\s*#\d+)*)?\b/) | |||
| ChangeIssueStatusByMessageJob.perform_later(commit_id, project, commit_user, solve_issue_content[0][1], 3) if solve_issue_content[0].present? && solve_issue_content[0][1].present? | |||
| end | |||
| end | |||
| @@ -77,4 +77,12 @@ module GitHelper | |||
| cha_path = path.present? ? path.split(";") : [] | |||
| cha_path.reject(&:blank?)[0].try(:strip) | |||
| end | |||
| def expain_issue_commit(commit_message) | |||
| respace_arr= commit_message.to_s.scan(/#(\d+)/).map{|s|[s[0], "##{s[0]}"]}.uniq.sort_by{|s|-s[0].to_i} | |||
| respace_arr.each do |item| | |||
| issue = Issue.find_by_id(item[0].to_i) | |||
| end | |||
| end | |||
| end | |||
| @@ -50,7 +50,7 @@ class MarkFilesController < ApplicationController | |||
| end | |||
| def load_pull_request | |||
| @pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id]) | |||
| @pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || @project.pull_requests.find_by_id(params[:id]) | |||
| end | |||
| end | |||
| @@ -0,0 +1,53 @@ | |||
| class Oauth::Ci4sController < Oauth::BaseController | |||
| include RegisterHelper | |||
| def oauth_url | |||
| redirect_to Ci4s::Service.oauth_url | |||
| end | |||
| # 需要educoder那边设置回调地址 | |||
| def create | |||
| begin | |||
| code = params['code'].to_s.strip | |||
| tip_exception("code不能为空") if code.blank? | |||
| new_user = false | |||
| token = Ci4s::Service.access_token(code) | |||
| Rails.logger.info("[OAuth2] result -> #{token}") | |||
| result = Ci4s::Service.user_info(token[:access_token]) | |||
| tip_exception("请求用户信息错误") if result['code'].to_i != 200 | |||
| user_info = result['data'] | |||
| # 存在该用户 | |||
| open_user = OpenUsers::Ci4s.find_by(uid: user_info['username']) | |||
| if open_user.present? && open_user.user.present? | |||
| successful_authentication(open_user.user) | |||
| redirect_to root_path(new_user: false) | |||
| return | |||
| else | |||
| if current_user.blank? || !current_user.logged? | |||
| new_user = true | |||
| session[:unionid] = user_info['username'] | |||
| # login = User.generate_login('E') | |||
| login = user_info['username'] | |||
| email = user_info['email'] | |||
| email = "#{login}@forge.com" if email.blank? | |||
| reg_result = autologin_register(login, email, "Ec#{login}2021#", 'educoder', user_info['mobile']) | |||
| Rails.logger.info("[OAuth2] reg_result -> #{reg_result}") | |||
| if reg_result[:message].blank? | |||
| open_user = OpenUsers::Ci4s.create!(user_id: reg_result[:user][:id], uid: login, extra: user_info) | |||
| successful_authentication(open_user.user) | |||
| else | |||
| tip_exception(reg_result[:message]) | |||
| end | |||
| else | |||
| OpenUsers::Ci4s.create!(user: current_user, uid: user_info['username'], extra: user_info) | |||
| end | |||
| end | |||
| Rails.logger.info("[OAuth2] session[:unionid] -> #{session[:unionid]}") | |||
| redirect_to root_path(new_user: new_user) | |||
| rescue Exception => ex | |||
| render_error(ex.message) | |||
| end | |||
| end | |||
| end | |||
| @@ -295,11 +295,11 @@ class PullRequestsController < ApplicationController | |||
| private | |||
| def load_pull_request | |||
| @pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id]) | |||
| @pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || @project.pull_requests.find_by_id(params[:id]) | |||
| end | |||
| def find_pull_request | |||
| @pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id]) | |||
| @pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || @project.pull_requests.find_by_id(params[:id]) | |||
| @issue = @pull_request&.issue | |||
| if @pull_request.blank? | |||
| normal_status(-1, "合并请求不存在") | |||
| @@ -13,6 +13,7 @@ class RepositoriesController < ApplicationController | |||
| before_action :get_ref, only: %i[entries sub_entries top_counts files archive] | |||
| before_action :get_latest_commit, only: %i[entries sub_entries top_counts] | |||
| before_action :get_statistics, only: %i[top_counts] | |||
| before_action :require_referer, only: [:raw] | |||
| def files | |||
| result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token) | |||
| @@ -14,7 +14,7 @@ class ReviewsController < ApplicationController | |||
| end | |||
| def load_pull_request | |||
| @pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id]) | |||
| @pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || @project.pull_requests.find_by_id(params[:id]) | |||
| end | |||
| end | |||
| @@ -0,0 +1,46 @@ | |||
| class ChangeIssueStatusByMessageJob < ApplicationJob | |||
| queue_as :notify | |||
| # Close, Closes, Closed, Closing, close, closes, closed, closing | |||
| # Fix, Fixes, Fixed, Fixing, fix, fixes, fixed, fixing | |||
| # Resolve, Resolves, Resolved, Resolving, resolve, resolves, resolved, resolving | |||
| # Implement, Implements, Implemented, Implementing, implement, implements, implemented, implementing | |||
| # 以上关键词后接 issue_id 例如:Closes #234 Closes #123, #245, #992 | |||
| def get_pm_issue_data(user, org, pm_project_id, issue_id) | |||
| url = URI("#{EduSetting.get("pms_server_url")}/api/pms/#{org.login}/pmsProjectIssues/#{issue_id}?pmProjectId=#{pm_project_id}") | |||
| https = Net::HTTP.new(url.host, url.port) | |||
| https.use_ssl = true | |||
| request = Net::HTTP::Get.new(url) | |||
| request["Cookie"] = "autologin_trustie=#{Token.get_or_create_permanent_login_token(user, 'autologin')&.value}" | |||
| response = https.request(request) | |||
| puts response.read_body | |||
| return JSON.parse(response.read_body)['code'].to_i == 200 | |||
| rescue | |||
| return false | |||
| end | |||
| def perform(commitsha, project, user, tag_issue_id_content, status_id=1) | |||
| Rails.logger.info "需要操作的issue_id内容为 #{tag_issue_id_content}" | |||
| tag_issue_id_content = tag_issue_id_content.gsub(/\s+/, '') | |||
| tag_issue_id_content.to_s.split(",").each do |tag_issue| | |||
| issue_id = tag_issue.gsub('#', '') | |||
| issue = project.issues.issue_issue.where(project_issues_index: issue_id).where.not(id: issue_id).take || Issue.issue_issue.find_by_id(issue_id) | |||
| next unless issue.present? # issue不存在 跳过 | |||
| next if issue.project.present? && !issue.project.member?(user) # issue归属项目,用户没有修改issue的权限,跳过 | |||
| next if issue.pm_project_id.present? && !get_pm_issue_data(user, project.owner, issue.pm_project_id, issue.id) # issue是组织下工作项,不具备组织的访问权限,跳过 | |||
| issue_project = issue.project || Project.new(id: 0, user_id: 0, name: 'pm_mm', identifier: 'pm_mm', is_public:true) | |||
| if issue.pm_project_id.present? | |||
| Api::Pm::Issues::UpdateService.call(issue_project, issue, {status_id: status_id}, user, "Project##{project.id}@#{commitsha}") | |||
| else | |||
| Api::V1::Issues::UpdateService.call(issue_project, issue, {status_id: status_id}, user, "Project##{project.id}@#{commitsha}") | |||
| end | |||
| end | |||
| end | |||
| end | |||
| @@ -4,6 +4,7 @@ class UpdateProjectTopicJob < ApplicationJob | |||
| queue_as :message | |||
| def perform(project_id) | |||
| return unless $redis_cache.set("UpdateProjectTopicJob:#{project_id}", 1, nx: true, ex: 10.seconds) | |||
| project = Project.find_by(id: project_id) | |||
| return if project.blank? | |||
| begin | |||
| @@ -25,7 +26,9 @@ class UpdateProjectTopicJob < ApplicationJob | |||
| topic_count +=1 | |||
| end | |||
| end | |||
| $redis_cache.del("UpdateProjectTopicJob:#{project_id}") | |||
| rescue => e | |||
| $redis_cache.del("UpdateProjectTopicJob:#{project_id}") | |||
| puts "get_repos_languages: error:#{e.message}" | |||
| end | |||
| end | |||
| @@ -0,0 +1,70 @@ | |||
| require 'oauth2' | |||
| module Ci4s::Service | |||
| module_function | |||
| def client_id | |||
| config = Rails.application.config_for(:configuration) | |||
| config.dig("oauth", "ci4s", "client_id") | |||
| end | |||
| def client_secret | |||
| config = Rails.application.config_for(:configuration) | |||
| config.dig("oauth", "ci4s", "client_secret") | |||
| end | |||
| def base_url | |||
| config = Rails.application.config_for(:configuration) | |||
| config.dig("oauth", "ci4s", "base_url") | |||
| end | |||
| def redirect_uri | |||
| config = Rails.application.config_for(:configuration) | |||
| config.dig("oauth", "ci4s", "redirect_uri") | |||
| end | |||
| def oauth_url | |||
| "#{base_url}/oauth/authorize?client_id=#{client_id}&redirect_uri=#{URI.encode_www_form_component(redirect_uri)}&response_type=code&grant_type=authorization_code" | |||
| end | |||
| def request(method, url, params) | |||
| begin | |||
| Rails.logger.info("[Ci4sOauth] [#{method.to_s.upcase}] #{url} || #{params}") | |||
| client ||= begin | |||
| Faraday.new(url: base_url) do |req| | |||
| req.request :url_encoded | |||
| req.headers['Content-Type'] = 'application/json' | |||
| req.response :logger # 显示日志 | |||
| req.adapter Faraday.default_adapter | |||
| req.authorization :Bearer, params[:access_token] | |||
| req.headers['Authorization'] | |||
| end | |||
| end | |||
| response = client.public_send(method, url, params) | |||
| result = JSON.parse(response.body) | |||
| Rails.logger.info("[Ci4sOauth] [#{response.status}] #{result}") | |||
| result | |||
| rescue Exception => e | |||
| raise Gitlink::TipException.new(e.message) | |||
| end | |||
| end | |||
| def access_token(code) | |||
| begin | |||
| Rails.logger.info("[Ci4sOauth] [code] #{code} ") | |||
| Rails.logger.info("[Ci4sOauth] [redirect_uri] #{redirect_uri} ") | |||
| client = OAuth2::Client.new(client_id, client_secret, site: base_url) | |||
| result = client.auth_code.get_token(code, redirect_uri: redirect_uri).to_hash | |||
| return result | |||
| rescue Exception => e | |||
| raise Gitlink::TipException.new(e.message) | |||
| end | |||
| end | |||
| def user_info(access_token) | |||
| request(:get, '/user/info', {access_token: access_token}) | |||
| end | |||
| end | |||
| @@ -22,6 +22,7 @@ | |||
| # resolveer_id :integer | |||
| # need_respond :boolean default("0") | |||
| # updated_on :datetime | |||
| # operate_by :string(255) default("Issue") | |||
| # | |||
| # Indexes | |||
| # | |||
| @@ -82,6 +83,17 @@ class Journal < ApplicationRecord | |||
| end | |||
| end | |||
| def operate_by_content | |||
| return '' if self.operate_by == "Issue" | |||
| if self.operate_by.starts_with?("Project#") | |||
| project_id, commit_sha = self.operate_by.scan(/#(\d+).*?@(\w+)/)[0] | |||
| project =Project.find_by_id(project_id) | |||
| return "通过 #{project&.owner&.real_name}/#{project&.name} 提交 <a href=\"#{Rails.application.config_for(:configuration)['platform_url']}/#{project&.owner&.login}/#{project&.identifier}/commits/#{commit_sha}\">#{commit_sha[0...10]}</a>" | |||
| end | |||
| rescue | |||
| return '' | |||
| end | |||
| def pm_operate_category | |||
| detail = self.journal_details.take | |||
| if %w(requirement task bug).include?(detail.property) && detail.prop_key.to_s == "1" | |||
| @@ -92,7 +104,7 @@ class Journal < ApplicationRecord | |||
| end | |||
| def pm_operate_content | |||
| content = "" | |||
| content = "#{operate_by_content}" | |||
| detail = self.journal_details.take | |||
| case detail.property | |||
| when 'requirement' | |||
| @@ -153,7 +165,7 @@ class Journal < ApplicationRecord | |||
| end | |||
| return content | |||
| else | |||
| return "创建了需求" | |||
| content += "创建了需求" | |||
| end | |||
| when 'task' | |||
| case detail.prop_key | |||
| @@ -213,7 +225,7 @@ class Journal < ApplicationRecord | |||
| end | |||
| return content | |||
| else | |||
| return "创建了任务" | |||
| content += "创建了任务" | |||
| end | |||
| when 'bug' | |||
| case detail.prop_key | |||
| @@ -273,14 +285,14 @@ class Journal < ApplicationRecord | |||
| end | |||
| return content | |||
| else | |||
| return "创建了缺陷" | |||
| content += "创建了缺陷" | |||
| end | |||
| when 'attr' | |||
| case detail.prop_key | |||
| when 'subject' | |||
| return "修改了<b>标题</b>" | |||
| content += "修改了<b>标题</b>" | |||
| when 'description' | |||
| return "修改了<b>正文</b>" | |||
| content += "修改了<b>正文</b>" | |||
| when 'priority_id' | |||
| old_value = IssuePriority.find_by_id(detail.old_value)&.name | |||
| new_value = IssuePriority.find_by_id(detail.value)&.name | |||
| @@ -490,21 +502,23 @@ class Journal < ApplicationRecord | |||
| issue = self.issue | |||
| case issue.pm_issue_type | |||
| when 1 | |||
| return "创建了需求" | |||
| content += "创建了需求" | |||
| when 2 | |||
| return "创建了任务" | |||
| content += "创建了任务" | |||
| when 3 | |||
| return "创建了缺陷" | |||
| content += "创建了缺陷" | |||
| end | |||
| end | |||
| return content | |||
| end | |||
| def operate_content | |||
| content = "" | |||
| content = "#{operate_by_content}" | |||
| detail = self.journal_details.take | |||
| case detail.property | |||
| when 'issue' | |||
| return "创建了<b>疑修</b>" | |||
| content += "创建了<b>疑修</b>" | |||
| when 'attachment' | |||
| old_value = Attachment.where("BINARY id in (?) or uuid in (?)", detail.old_value.to_s.split(","), detail.old_value.to_s.split(",")).pluck(:filename).join("、") | |||
| new_value = Attachment.where("BINARY id in (?) or uuid in (?)", detail.value.to_s.split(","), detail.value.to_s.split(",")).pluck(:filename).join("、") | |||
| @@ -533,12 +547,12 @@ class Journal < ApplicationRecord | |||
| content += "将负责人由<b>#{old_value}</b>更改为<b>#{new_value}</b>" | |||
| end | |||
| when 'attr' | |||
| content = "将" | |||
| content += "将" | |||
| case detail.prop_key | |||
| when 'subject' | |||
| return "修改了<b>标题</b>" | |||
| content += "修改了<b>标题</b>" | |||
| when 'description' | |||
| return "修改了<b>描述</b>" | |||
| content += "修改了<b>描述</b>" | |||
| when 'status_id' | |||
| old_value = IssueStatus.find_by_id(detail.old_value)&.name | |||
| new_value = IssueStatus.find_by_id(detail.value)&.name | |||
| @@ -0,0 +1,27 @@ | |||
| # == Schema Information | |||
| # | |||
| # Table name: open_users | |||
| # | |||
| # id :integer not null, primary key | |||
| # user_id :integer | |||
| # type :string(255) | |||
| # uid :string(255) | |||
| # created_at :datetime not null | |||
| # updated_at :datetime not null | |||
| # extra :text(65535) | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_open_users_on_type_and_uid (type,uid) UNIQUE | |||
| # index_open_users_on_user_id (user_id) | |||
| # | |||
| class OpenUsers::Ci4s < OpenUser | |||
| def nickname | |||
| extra&.[]('username') | |||
| end | |||
| def en_type | |||
| 'ci4s' | |||
| end | |||
| end | |||
| @@ -19,4 +19,8 @@ class ProjectTopicRalate < ApplicationRecord | |||
| belongs_to :project_topic, counter_cache: :projects_count | |||
| belongs_to :project | |||
| validates :project_id, uniqueness: { scope: :project_topic_id } | |||
| end | |||
| @@ -3,7 +3,7 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| include Api::V1::Issues::Concerns::Checkable | |||
| include Api::V1::Issues::Concerns::Loadable | |||
| attr_reader :project, :issue, :current_user | |||
| attr_reader :project, :issue, :current_user, :operate_by | |||
| attr_reader :status_id, :priority_id, :milestone_id, :branch_name, :start_date, :due_date, :subject, :description, :blockchain_token_num | |||
| attr_reader :target_pm_project_id, :pm_sprint_id, :pm_issue_type, :root_id, :time_scale | |||
| attr_reader :issue_tag_ids, :assigner_ids, :attachment_ids, :receivers_login, :before_issue_tag_ids, :before_assigner_ids, :project_id | |||
| @@ -12,10 +12,11 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| validates :project, :issue, :current_user, presence: true | |||
| validates :blockchain_token_num, numericality: {greater_than: 0}, allow_blank: true | |||
| def initialize(project, issue, params, current_user = nil) | |||
| def initialize(project, issue, params, current_user = nil, operate_by='Issue') | |||
| @project = project | |||
| @issue = issue | |||
| @current_user = current_user | |||
| @operate_by = operate_by | |||
| @status_id = params[:status_id] | |||
| @priority_id = params[:priority_id] | |||
| @milestone_id = params[:milestone_id] | |||
| @@ -183,91 +184,91 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| begin | |||
| # 更改标题 | |||
| if @updated_issue.previous_changes["subject"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "subject", old_value: @updated_issue.previous_changes["subject"][0], value: @updated_issue.previous_changes["subject"][1]}) | |||
| end | |||
| # 更改描述 | |||
| if @updated_issue.previous_changes["description"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "description", old_value: @updated_issue.previous_changes["description"][0], value: @updated_issue.previous_changes["description"][1]}) | |||
| end | |||
| # 修改状态 | |||
| if @updated_issue.previous_changes["status_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: @updated_issue.pm_issue_type_string, prop_key: "status_id", old_value: @updated_issue.previous_changes["status_id"][0], value: @updated_issue.previous_changes["status_id"][1]}) | |||
| end | |||
| # 修改优先级 | |||
| if @updated_issue.previous_changes["priority_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "priority_id", old_value: @updated_issue.previous_changes["priority_id"][0], value: @updated_issue.previous_changes["priority_id"][1]}) | |||
| end | |||
| # 修改工作项类型 | |||
| if @updated_issue.previous_changes["pm_issue_type"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "pm_issue_type", old_value: @updated_issue.previous_changes["pm_issue_type"][0], value: @updated_issue.previous_changes["pm_issue_type"][1]}) | |||
| end | |||
| # 修改迭代 | |||
| if @updated_issue.previous_changes["pm_sprint_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "pm_sprint_id", old_value: @updated_issue.previous_changes["pm_sprint_id"][0], value: @updated_issue.previous_changes["pm_sprint_id"][1]}) | |||
| end | |||
| # 修改代码库 | |||
| if @updated_issue.previous_changes["project_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "project_id", old_value: @updated_issue.previous_changes["project_id"][0], value: @updated_issue.previous_changes["project_id"][1]}) | |||
| end | |||
| # 修改里程碑 | |||
| if @updated_issue.previous_changes["fixed_version_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "fixed_version_id", old_value: @updated_issue.previous_changes["fixed_version_id"][0], value: @updated_issue.previous_changes["fixed_version_id"][1]}) | |||
| end | |||
| # 更改分支 | |||
| if @updated_issue.previous_changes["branch_name"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "branch_name", old_value: @updated_issue.previous_changes["branch_name"][0], value: @updated_issue.previous_changes["branch_name"][1]}) | |||
| end | |||
| # 更改开始时间 | |||
| if @updated_issue.previous_changes["start_date"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "start_date", old_value: @updated_issue.previous_changes["start_date"][0], value: @updated_issue.previous_changes["start_date"][1]}) | |||
| end | |||
| # 更改结束时间 | |||
| if @updated_issue.previous_changes["due_date"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "due_date", old_value: @updated_issue.previous_changes["due_date"][0], value: @updated_issue.previous_changes["due_date"][1]}) | |||
| end | |||
| # 更改预估工时 | |||
| if @updated_issue.previous_changes["time_scale"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "time_scale", old_value: @updated_issue.previous_changes["time_scale"][0], value: @updated_issue.previous_changes["time_scale"][1]}) | |||
| end | |||
| # 更改父工作项 | |||
| if @updated_issue.previous_changes["root_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: @updated_issue.pm_issue_type_string, prop_key: "root_id", old_value: @updated_issue.previous_changes["root_id"][0], value: @updated_issue.previous_changes["root_id"][1]}) | |||
| # 更改子工作项 | |||
| before_parent_issue = Issue.find_by_id(@updated_issue.previous_changes["root_id"][0]) | |||
| if before_parent_issue.present? | |||
| journal = before_parent_issue.journals.create!({user_id: current_user.id}) | |||
| journal = before_parent_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: @updated_issue.pm_issue_type_string, prop_key: "tag_leaf_issue", old_value: @updated_issue.id.to_s}) | |||
| end | |||
| after_parent_issue = Issue.find_by_id(@updated_issue.previous_changes["root_id"][1]) | |||
| if after_parent_issue.present? | |||
| journal = after_parent_issue.journals.create!({user_id: current_user.id}) | |||
| journal = after_parent_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: @updated_issue.pm_issue_type_string, prop_key: "tag_leaf_issue", value: @updated_issue.id.to_s}) | |||
| end | |||
| end | |||
| @@ -283,7 +284,7 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| new_assigner_ids = [] if @assigner_ids.nil? | |||
| now_assigner_ids = @updated_issue.assigners.pluck(:id) | |||
| if !(now_assigner_ids.sort == new_assigner_ids.sort) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "assigner", prop_key: "#{new_assigner_ids.size}", old_value: now_assigner_ids.join(","), value: new_assigner_ids.join(",")}) | |||
| end | |||
| @@ -299,7 +300,7 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| new_issue_tag_ids = [] if @issue_tag_ids.nil? | |||
| now_issue_tag_ids = @updated_issue.issue_tags.pluck(:id) | |||
| if !(now_issue_tag_ids.sort == new_issue_tag_ids.sort) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "issue_tag", prop_key: "#{new_issue_tag_ids.size}", old_value: now_issue_tag_ids.join(","), value: new_issue_tag_ids.join(",")}) | |||
| end | |||
| rescue | |||
| @@ -315,7 +316,7 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| new_attachment_ids = [] if @attachment_ids.nil? | |||
| now_attachment_ids = @updated_issue.attachments.pluck(:id) | |||
| if !(now_attachment_ids.sort == new_attachment_ids.sort) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attachment", prop_key: "#{new_attachment_ids.size}", old_value: now_attachment_ids.join(","), value: new_attachment_ids.join(",")}) | |||
| end | |||
| rescue | |||
| @@ -3,7 +3,7 @@ class Api::V1::Issues::UpdateService < ApplicationService | |||
| include Api::V1::Issues::Concerns::Checkable | |||
| include Api::V1::Issues::Concerns::Loadable | |||
| attr_reader :project, :issue, :current_user | |||
| attr_reader :project, :issue, :current_user, :operate_by | |||
| attr_reader :status_id, :priority_id, :milestone_id, :branch_name, :start_date, :due_date, :subject, :description, :blockchain_token_num | |||
| attr_reader :target_pm_project_id, :pm_sprint_id, :pm_issue_type, :root_id, :time_scale | |||
| attr_reader :issue_tag_ids, :assigner_ids, :attachment_ids, :receivers_login, :before_issue_tag_ids, :before_assigner_ids, :project_id | |||
| @@ -12,10 +12,11 @@ class Api::V1::Issues::UpdateService < ApplicationService | |||
| validates :project, :issue, :current_user, presence: true | |||
| validates :blockchain_token_num, numericality: {greater_than: 0}, allow_blank: true | |||
| def initialize(project, issue, params, current_user = nil) | |||
| def initialize(project, issue, params, current_user = nil, operate_by='Issue') | |||
| @project = project | |||
| @issue = issue | |||
| @current_user = current_user | |||
| @operate_by = operate_by | |||
| @status_id = params[:status_id] | |||
| @priority_id = params[:priority_id] | |||
| @milestone_id = params[:milestone_id] | |||
| @@ -183,49 +184,49 @@ class Api::V1::Issues::UpdateService < ApplicationService | |||
| begin | |||
| # 更改标题 | |||
| if @updated_issue.previous_changes["subject"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "subject", old_value: @updated_issue.previous_changes["subject"][0], value: @updated_issue.previous_changes["subject"][1]}) | |||
| end | |||
| # 更改描述 | |||
| if @updated_issue.previous_changes["description"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "description", old_value: @updated_issue.previous_changes["description"][0], value: @updated_issue.previous_changes["description"][1]}) | |||
| end | |||
| # 修改状态 | |||
| if @updated_issue.previous_changes["status_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "status_id", old_value: @updated_issue.previous_changes["status_id"][0], value: @updated_issue.previous_changes["status_id"][1]}) | |||
| end | |||
| # 修改优先级 | |||
| if @updated_issue.previous_changes["priority_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "priority_id", old_value: @updated_issue.previous_changes["priority_id"][0], value: @updated_issue.previous_changes["priority_id"][1]}) | |||
| end | |||
| # 修改里程碑 | |||
| if @updated_issue.previous_changes["fixed_version_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "fixed_version_id", old_value: @updated_issue.previous_changes["fixed_version_id"][0], value: @updated_issue.previous_changes["fixed_version_id"][1]}) | |||
| end | |||
| # 更改分支 | |||
| if @updated_issue.previous_changes["branch_name"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "branch_name", old_value: @updated_issue.previous_changes["branch_name"][0], value: @updated_issue.previous_changes["branch_name"][1]}) | |||
| end | |||
| # 更改开始时间 | |||
| if @updated_issue.previous_changes["start_date"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "start_date", old_value: @updated_issue.previous_changes["start_date"][0], value: @updated_issue.previous_changes["start_date"][1]}) | |||
| end | |||
| # 更改结束时间 | |||
| if @updated_issue.previous_changes["due_date"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attr", prop_key: "due_date", old_value: @updated_issue.previous_changes["due_date"][0], value: @updated_issue.previous_changes["due_date"][1]}) | |||
| end | |||
| rescue | |||
| @@ -240,7 +241,7 @@ class Api::V1::Issues::UpdateService < ApplicationService | |||
| new_assigner_ids = [] if @assigner_ids.nil? | |||
| now_assigner_ids = @updated_issue.assigners.pluck(:id) | |||
| if !(now_assigner_ids & assigner_ids).empty? || !(now_assigner_ids.empty? && new_assigner_ids.empty?) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "assigner", prop_key: "#{new_assigner_ids.size}", old_value: now_assigner_ids.join(","), value: new_assigner_ids.join(",")}) | |||
| end | |||
| @@ -256,7 +257,7 @@ class Api::V1::Issues::UpdateService < ApplicationService | |||
| new_issue_tag_ids = [] if @issue_tag_ids.nil? | |||
| now_issue_tag_ids = @updated_issue.issue_tags.pluck(:id) | |||
| if !(now_issue_tag_ids & new_issue_tag_ids).empty? || !(now_issue_tag_ids.empty? && new_issue_tag_ids.empty?) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "issue_tag", prop_key: "#{new_issue_tag_ids.size}", old_value: now_issue_tag_ids.join(","), value: new_issue_tag_ids.join(",")}) | |||
| end | |||
| rescue | |||
| @@ -272,7 +273,7 @@ class Api::V1::Issues::UpdateService < ApplicationService | |||
| new_attachment_ids = [] if @attachment_ids.nil? | |||
| now_attachment_ids = @updated_issue.attachments.pluck(:id) | |||
| if !(now_attachment_ids & new_attachment_ids).empty? || !(now_attachment_ids.empty? && new_attachment_ids.empty?) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id}) | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: "attachment", prop_key: "#{new_attachment_ids.size}", old_value: now_attachment_ids.join(","), value: new_attachment_ids.join(",")}) | |||
| end | |||
| rescue | |||
| @@ -1,4 +1,4 @@ | |||
| json.username @user.full_name | |||
| json.username @user.full_name.to_s.each_char.select { |c| c.bytes.first < 240 }.join('') | |||
| json.login @user.login | |||
| json.user_id @user.id | |||
| json.image_url url_to_avatar(@user) | |||
| @@ -1375,4 +1375,78 @@ B样 | |||
| 江猪媳 | |||
| 酱猪媳 | |||
| 枪支 | |||
| 毒品 | |||
| 毒品 | |||
| 新葡京 | |||
| 皇家 | |||
| 皇家娱乐 | |||
| 官网开户 | |||
| 客服开户 | |||
| 娱乐开户 | |||
| 财务客服 | |||
| 果博 | |||
| 果博东方 | |||
| 缅甸果博 | |||
| 腾龙 | |||
| 新腾龙 | |||
| 开户会员 | |||
| 果敢老街 | |||
| 客服QV | |||
| 代理QV | |||
| Q微 | |||
| 微QV | |||
| 综合盘 | |||
| 盛世 | |||
| 玉祥 | |||
| 玉祥娱乐 | |||
| 百家龙虎 | |||
| 新锦江 | |||
| 游戏真假 | |||
| 小勐拉 | |||
| 华纳 | |||
| 腾龙官方 | |||
| 老街银河 | |||
| 福利来 | |||
| 环球娱乐 | |||
| 果博福布斯 | |||
| 欧亚公司 | |||
| 欧亚国际 | |||
| 龙虎 | |||
| 腾龍 | |||
| 麦芒国际 | |||
| 龙源国际 | |||
| 皇家国际 | |||
| 银钻国际 | |||
| 迪威国际 | |||
| 锦利国际 | |||
| 网投 | |||
| 网上赢了 | |||
| 金沙国际 | |||
| 澳门金沙 | |||
| 新胜公司 | |||
| 银河公司 | |||
| 娱乐公司 | |||
| 明珠代理 | |||
| 亚星娱乐 | |||
| 利博娱乐 | |||
| 永鑫娱乐 | |||
| 新锦江公司 | |||
| 福布斯客服 | |||
| 亚星正网 | |||
| 尊龙凯时 | |||
| 线上开户 | |||
| 百家乐 | |||
| 卡卡湾 | |||
| 新金宝 | |||
| 99贵宾 | |||
| 牌桌 | |||
| 游戏注册 | |||
| 真人实体 | |||
| 私人孕妈 | |||
| 助孕 | |||
| 捐卵 | |||
| 借腹 | |||
| 代妈 | |||
| 孕妈 | |||
| 借卵 | |||
| 试管 | |||
| 受孕 | |||
| @@ -64,4 +64,4 @@ | |||
| - ZHENGJIAN | |||
| - ZHENGJIANWANG | |||
| - ZHENSHANREN | |||
| - | |||
| - | |||
| @@ -26,6 +26,8 @@ Rails.application.routes.draw do | |||
| get 'auth/failure', to: 'oauth/base#auth_failure' | |||
| get 'auth/cas/callback', to: 'oauth/cas#create' | |||
| get 'auth/acge/callback', to: "oauth/acge#create" | |||
| get 'oauth_ci4s', to: "oauth/ci4s#oauth_url" | |||
| get 'auth/ci4s/callback', to: "oauth/ci4s#create" | |||
| get 'auth/acge/refer', to: "oauth/acge#refer" | |||
| get 'auth/:provider/callback', to: 'oauth/callbacks#create' | |||
| @@ -0,0 +1,5 @@ | |||
| class AddOperateByToJournals < ActiveRecord::Migration[5.2] | |||
| def change | |||
| add_column :journals, :operate_by, :string, default: 'Issue' | |||
| end | |||
| end | |||