| @@ -141,4 +141,4 @@ gem 'doorkeeper' | |||
| gem 'doorkeeper-jwt' | |||
| gem 'gitea-client', '~> 1.4.2' | |||
| gem 'gitea-client', '~> 1.4.3' | |||
| @@ -201,12 +201,12 @@ class AccountsController < ApplicationController | |||
| return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked? | |||
| login_control = LimitForbidControl::UserLogin.new(@user) | |||
| return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid? | |||
| return normal_status(-2, "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid? | |||
| password_ok = @user.check_password?(params[:password].to_s) | |||
| unless password_ok | |||
| if login_control.remain_times-1 == 0 | |||
| normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") | |||
| normal_status(-2, "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") | |||
| else | |||
| normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会") | |||
| end | |||
| @@ -222,6 +222,7 @@ class AccountsController < ApplicationController | |||
| end | |||
| def change_password | |||
| return render_error("两次输入的密码不一致") if params[:password].to_s != params[:new_password_repeat].to_s | |||
| @user = User.find_by(login: params[:login]) | |||
| return render_error("此用户禁止修改密码!") if @user.id.to_i === 104691 | |||
| return render_error("未找到相关用户!") if @user.blank? | |||
| @@ -7,4 +7,12 @@ class Api::V1::Issues::IssuePrioritiesController < Api::V1::BaseController | |||
| @priorities = @priorities.ransack(name_cont: params[:keyword]).result if params[:keyword] | |||
| @priorities = kaminary_select_paginate(@priorities) | |||
| end | |||
| def pm_index | |||
| @priorities = IssuePriority.order(position: :asc) | |||
| @priorities = @priorities.ransack(name_cont: params[:keyword]).result if params[:keyword] | |||
| @priorities = kaminary_select_paginate(@priorities) | |||
| render "index" | |||
| end | |||
| end | |||
| @@ -1,5 +1,5 @@ | |||
| class Api::V1::Issues::IssueTagsController < Api::V1::BaseController | |||
| before_action :require_login, except: [:index] | |||
| before_action :require_login, except: [:index, :pm_index] | |||
| before_action :require_public_and_member_above, only: [:index] | |||
| before_action :require_operate_above, only: [:create, :update, :destroy] | |||
| @@ -7,12 +7,17 @@ class Api::V1::Issues::IssueTagsController < Api::V1::BaseController | |||
| @issue_tags = @project.issue_tags.reorder("#{sort_by} #{sort_direction}") | |||
| @issue_tags = @issue_tags.ransack(name_cont: params[:keyword]).result if params[:keyword].present? | |||
| if params[:only_name] | |||
| @issue_tags = kaminary_select_paginate(@issue_tags.select(:id, :name, :color)) | |||
| @issue_tags = kaminary_select_paginate(@issue_tags.select(:id, :name, :color)) | |||
| else | |||
| @issue_tags = kaminari_paginate(@issue_tags.includes(:project, :user, :issue_issues, :pull_request_issues)) | |||
| end | |||
| end | |||
| def pm_index | |||
| @issue_tags = IssueTag.init_mp_issues_tags | |||
| render_ok(@issue_tags) | |||
| end | |||
| def create | |||
| @issue_tag = @project.issue_tags.new(issue_tag_params) | |||
| if @issue_tag.save! | |||
| @@ -8,4 +8,11 @@ class Api::V1::Issues::StatuesController < Api::V1::BaseController | |||
| @statues = @statues.ransack(name_cont: params[:keyword]).result if params[:keyword].present? | |||
| @statues = kaminary_select_paginate(@statues) | |||
| end | |||
| def pm_index | |||
| @statues = IssueStatus.order("position asc") | |||
| @statues = @statues.ransack(name_cont: params[:keyword]).result if params[:keyword].present? | |||
| @statues = kaminary_select_paginate(@statues) | |||
| render "index" | |||
| end | |||
| end | |||
| @@ -1,6 +1,6 @@ | |||
| class Api::V1::IssuesController < Api::V1::BaseController | |||
| before_action :require_login, except: [:index, :show] | |||
| before_action :require_public_and_member_above, only: [:index, :show, :create, :update, :destroy] | |||
| before_action :require_login, except: [:index, :show, :show_by_id] | |||
| before_action :require_public_and_member_above, only: [:index, :show, :show_by_id, :create, :update, :destroy] | |||
| before_action :require_operate_above, only: [:batch_update, :batch_destroy] | |||
| def index | |||
| @@ -22,6 +22,12 @@ class Api::V1::IssuesController < Api::V1::BaseController | |||
| before_action :load_issue, only: [:show, :update, :destroy] | |||
| before_action :check_issue_operate_permission, only: [:update, :destroy] | |||
| before_action :load_issue_by_id, only: [:show_by_id] | |||
| def show_by_id | |||
| @issue.associate_attachment_container | |||
| @user_permission = current_user.present? && current_user.logged? && (@project.member?(current_user) || current_user.admin? || @issue.user == current_user) | |||
| end | |||
| def show | |||
| @issue.associate_attachment_container | |||
| @@ -70,6 +76,13 @@ class Api::V1::IssuesController < Api::V1::BaseController | |||
| end | |||
| end | |||
| def load_issue_by_id | |||
| @issue = Issue.find_by_id(params[:index]) | |||
| if @issue.blank? | |||
| render_not_found("疑修不存在!") | |||
| end | |||
| end | |||
| def load_issues | |||
| return render_error("请输入正确的ID数组!") unless params[:ids].is_a?(Array) | |||
| params[:ids].each do |id| | |||
| @@ -1,10 +1,13 @@ | |||
| class Api::V1::Projects::TagsController < Api::V1::BaseController | |||
| before_action :require_public_and_member_above, only: [:index] | |||
| before_action :require_public_and_member_above, only: [:index, :show] | |||
| def index | |||
| @release_tags = @repository.version_releases.pluck(:tag_name) | |||
| @result_object = Api::V1::Projects::Tags::ListService.call(@project, {page: page, limit: limit}, current_user&.gitea_token) | |||
| puts @result_object | |||
| end | |||
| def show | |||
| @result_object = Api::V1::Projects::Tags::GetService.call(@project, params[:name], current_user&.gitea_token) | |||
| end | |||
| before_action :require_operate_above, only: [:destroy] | |||
| @@ -94,6 +94,7 @@ class AttachmentsController < ApplicationController | |||
| @attachment.author_id = current_user.id | |||
| @attachment.disk_directory = month_folder | |||
| @attachment.cloud_url = remote_path | |||
| @attachment.uuid = SecureRandom.uuid | |||
| @attachment.save! | |||
| else | |||
| logger.info "文件已存在,id = #{@attachment.id}, filename = #{@attachment.filename}" | |||
| @@ -143,12 +144,14 @@ class AttachmentsController < ApplicationController | |||
| private | |||
| def find_file | |||
| tip_exception(404, "您访问的页面不存在或已被删除") if params[:id].blank? | |||
| @file = | |||
| if params[:type] == 'history' | |||
| AttachmentHistory.find params[:id] | |||
| else | |||
| Attachment.find params[:id] | |||
| Attachment.where_id_or_uuid(params[:id]).first | |||
| end | |||
| tip_exception(404, "您访问的页面不存在或已被删除") if @file.blank? | |||
| end | |||
| def delete_file(file_path) | |||
| @@ -218,7 +221,7 @@ class AttachmentsController < ApplicationController | |||
| def attachment_candown | |||
| unless current_user.admin? || current_user.business? | |||
| candown = true | |||
| if @file.container | |||
| if @file.container && @file.uuid.nil? | |||
| if @file.container.is_a?(Issue) | |||
| project = @file.container.project | |||
| candown = project.is_public || (current_user.logged? && project.member?(current_user)) | |||
| @@ -139,7 +139,7 @@ class IssuesController < ApplicationController | |||
| SendTemplateMessageJob.perform_later('ProjectIssue', current_user.id, @issue&.id) if Site.has_notice_menu? | |||
| if params[:attachment_ids].present? | |||
| params[:attachment_ids].each do |id| | |||
| attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) | |||
| attachment = Attachment.where_id_or_uuid(id).select(:id, :container_id, :container_type)&.first | |||
| unless attachment.blank? | |||
| attachment.container = @issue | |||
| attachment.author_id = current_user.id | |||
| @@ -232,7 +232,7 @@ class IssuesController < ApplicationController | |||
| if issue_files.present? | |||
| change_files = true | |||
| issue_files.each do |id| | |||
| attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) | |||
| attachment = Attachment.where_id_or_uuid(id).select(:id, :container_id, :container_type)&.first | |||
| unless attachment.blank? | |||
| attachment.container = @issue | |||
| attachment.author_id = current_user.id | |||
| @@ -35,7 +35,7 @@ class JournalsController < ApplicationController | |||
| if journal.save | |||
| if params[:attachment_ids].present? | |||
| params[:attachment_ids].each do |id| | |||
| attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) | |||
| attachment = Attachment.where_id_or_uuid(id).select(:id, :container_id, :container_type)&.first | |||
| unless attachment.blank? | |||
| attachment.container = journal | |||
| attachment.author_id = current_user.id | |||
| @@ -20,12 +20,12 @@ class Oauth2Controller < ActionController::Base | |||
| return @error = {msg: '违反平台使用规范,账号已被锁定', id: 'login'} if @user.locked? | |||
| login_control = LimitForbidControl::UserLogin.new(@user) | |||
| return @error = {msg: "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码", id: 'account'} if login_control.forbid? | |||
| return @error = {msg: "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码", id: 'account'} if login_control.forbid? | |||
| password_ok = @user.check_password?(params[:password].to_s) | |||
| unless password_ok | |||
| if login_control.remain_times-1 == 0 | |||
| @error = {msg: "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码", id: 'account'} | |||
| @error = {msg: "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码", id: 'account'} | |||
| else | |||
| @error = {msg: "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会", id: 'account'} | |||
| end | |||
| @@ -4,9 +4,9 @@ class ProjectsController < ApplicationController | |||
| include ProjectsHelper | |||
| include Acceleratorable | |||
| before_action :require_login, except: %i[index branches branches_slice group_type_list simple show fork_users praise_users watch_users recommend banner_recommend about menu_list verify_auth_token] | |||
| before_action :require_login, except: %i[index branches branches_slice group_type_list simple show mp_show fork_users praise_users watch_users recommend banner_recommend about menu_list verify_auth_token] | |||
| before_action :require_profile_completed, only: [:create, :migrate,:page_migrate,:verify_auth_token] | |||
| before_action :load_repository, except: %i[index group_type_list migrate page_migrate create recommend banner_recommend verify_auth_token] | |||
| before_action :load_repository, except: %i[index mp_show group_type_list migrate page_migrate create recommend banner_recommend verify_auth_token] | |||
| before_action :authorizate_user_can_edit_project!, only: %i[update] | |||
| before_action :project_public?, only: %i[fork_users praise_users watch_users] | |||
| before_action :request_limit, only: %i[index] | |||
| @@ -232,6 +232,15 @@ class ProjectsController < ApplicationController | |||
| def show | |||
| end | |||
| def mp_show | |||
| @project = Project.joins(:owner).find params[:project_id] | |||
| data={ | |||
| owner:@project.owner.try(:login), | |||
| identifier:@project.identifier | |||
| } | |||
| render_ok(data:data) | |||
| end | |||
| def destroy | |||
| if current_user.admin? || @project.manager?(current_user) | |||
| ActiveRecord::Base.transaction do | |||
| @@ -152,11 +152,12 @@ class VersionReleasesController < ApplicationController | |||
| def create_attachments(attachment_ids, target) | |||
| attachment_ids.each do |id| | |||
| attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) | |||
| attachment = Attachment.where_id_or_uuid(id).select(:id, :container_id, :container_type)&.first | |||
| unless attachment.blank? | |||
| attachment.container = target | |||
| attachment.author_id = current_user.id | |||
| attachment.description = "" | |||
| attachment.uuid = SecureRandom.uuid | |||
| attachment.save | |||
| end | |||
| end | |||
| @@ -299,7 +299,7 @@ module ApplicationHelper | |||
| end | |||
| def download_url attachment,options={} | |||
| attachment_path(attachment,options) | |||
| attachment&.uuid.present? ? attachment_path(attachment.uuid,options) : attachment_path(attachment,options) | |||
| end | |||
| # 耗时:天、小时、分、秒 | |||
| @@ -1,44 +1,45 @@ | |||
| # == Schema Information | |||
| # | |||
| # Table name: attachments | |||
| # | |||
| # id :integer not null, primary key | |||
| # container_id :integer | |||
| # container_type :string(30) | |||
| # filename :string(255) default(""), not null | |||
| # disk_filename :string(255) default(""), not null | |||
| # filesize :integer default("0"), not null | |||
| # content_type :string(255) default("") | |||
| # digest :string(60) default(""), not null | |||
| # downloads :integer default("0"), not null | |||
| # author_id :integer default("0"), not null | |||
| # created_on :datetime | |||
| # description :text(65535) | |||
| # disk_directory :string(255) | |||
| # attachtype :integer default("1") | |||
| # is_public :integer default("1") | |||
| # copy_from :integer | |||
| # quotes :integer default("0") | |||
| # is_publish :integer default("1") | |||
| # publish_time :datetime | |||
| # resource_bank_id :integer | |||
| # unified_setting :boolean default("1") | |||
| # cloud_url :string(255) default("") | |||
| # course_second_category_id :integer default("0") | |||
| # delay_publish :boolean default("0") | |||
| # memo_image :boolean default("0") | |||
| # extra_type :integer default("0") | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_attachments_on_author_id (author_id) | |||
| # index_attachments_on_container_id_and_container_type (container_id,container_type) | |||
| # index_attachments_on_course_second_category_id (course_second_category_id) | |||
| # index_attachments_on_created_on (created_on) | |||
| # index_attachments_on_is_public (is_public) | |||
| # index_attachments_on_quotes (quotes) | |||
| # | |||
| # == Schema Information | |||
| # | |||
| # Table name: attachments | |||
| # | |||
| # id :integer not null, primary key | |||
| # container_id :integer | |||
| # container_type :string(30) | |||
| # filename :string(255) default(""), not null | |||
| # disk_filename :string(255) default(""), not null | |||
| # filesize :integer default("0"), not null | |||
| # content_type :string(255) default("") | |||
| # digest :string(60) default(""), not null | |||
| # downloads :integer default("0"), not null | |||
| # author_id :integer default("0"), not null | |||
| # created_on :datetime | |||
| # description :text(65535) | |||
| # disk_directory :string(255) | |||
| # attachtype :integer default("1") | |||
| # is_public :integer default("1") | |||
| # copy_from :integer | |||
| # quotes :integer default("0") | |||
| # is_publish :integer default("1") | |||
| # publish_time :datetime | |||
| # resource_bank_id :integer | |||
| # unified_setting :boolean default("1") | |||
| # cloud_url :string(255) default("") | |||
| # course_second_category_id :integer default("0") | |||
| # delay_publish :boolean default("0") | |||
| # memo_image :boolean default("0") | |||
| # extra_type :integer default("0") | |||
| # uuid :string(255) | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_attachments_on_author_id (author_id) | |||
| # index_attachments_on_container_id_and_container_type (container_id,container_type) | |||
| # index_attachments_on_course_second_category_id (course_second_category_id) | |||
| # index_attachments_on_created_on (created_on) | |||
| # index_attachments_on_is_public (is_public) | |||
| # index_attachments_on_quotes (quotes) | |||
| # | |||
| @@ -68,6 +69,7 @@ class Attachment < ApplicationRecord | |||
| scope :simple_columns, -> { select(:id, :filename, :filesize, :created_on, :cloud_url, :author_id, :content_type, :container_type, :container_id) } | |||
| scope :search_by_container, -> (ids) {where(container_id: ids)} | |||
| scope :unified_setting, -> {where("unified_setting = ? ", 1)} | |||
| scope :where_id_or_uuid, -> (id) { (Float(id) rescue nil).present? ? where(id: id) : where(uuid: id) } | |||
| validates_length_of :description, maximum: 100, message: "不能超过100个字符" | |||
| @@ -97,6 +99,11 @@ class Attachment < ApplicationRecord | |||
| downloads | |||
| end | |||
| def generate_uuid | |||
| self.uuid = uuid || SecureRandom.uuid | |||
| save! | |||
| end | |||
| def quotes_count | |||
| quotes.nil? ? 0 : quotes | |||
| end | |||
| @@ -6,10 +6,10 @@ | |||
| # user_id :integer not null | |||
| # number :string(255) not null | |||
| # name :string(255) not null | |||
| # card_front :integer | |||
| # card_back :integer | |||
| # hold_card_front :integer | |||
| # hold_card_back :integer | |||
| # card_front :string(255) | |||
| # card_back :string(255) | |||
| # hold_card_front :string(255) | |||
| # hold_card_back :string(255) | |||
| # state :integer default("0") | |||
| # description :string(255) | |||
| # created_at :datetime not null | |||
| @@ -24,9 +24,9 @@ class IdentityVerification < ApplicationRecord | |||
| belongs_to :user | |||
| enum state: { "待审核": 0, "已通过": 1, "已拒绝": 2} | |||
| after_create do | |||
| Attachment.where(id:[card_front,card_back,hold_card_front,hold_card_back]).update_all(is_public:0) | |||
| Attachment.where(uuid:[card_front,card_back,hold_card_front,hold_card_back]).update_all(is_public:0) | |||
| end | |||
| after_save do | |||
| if state == "已通过" | |||
| user.update(id_card_verify: true, website_permission: true) | |||
| @@ -34,18 +34,18 @@ class IdentityVerification < ApplicationRecord | |||
| end | |||
| def card_front_attachment | |||
| Attachment.find_by_id card_front | |||
| Attachment.where_id_or_uuid(card_front).first | |||
| end | |||
| def card_back_attachment | |||
| Attachment.find_by_id card_back | |||
| Attachment.where_id_or_uuid(card_back).first | |||
| end | |||
| def hold_card_front_attachment | |||
| Attachment.find_by_id hold_card_front | |||
| Attachment.where_id_or_uuid(hold_card_front).first | |||
| end | |||
| def hold_card_back_attachment | |||
| Attachment.find_by_id hold_card_back | |||
| Attachment.where_id_or_uuid(hold_card_back).first | |||
| end | |||
| end | |||
| @@ -34,6 +34,8 @@ | |||
| # ref_name :string(255) | |||
| # branch_name :string(255) | |||
| # blockchain_token_num :integer | |||
| # pm_project_id :integer | |||
| # pm_sprint_id :integer | |||
| # | |||
| # Indexes | |||
| # | |||
| @@ -222,13 +224,23 @@ class Issue < ApplicationRecord | |||
| # 关附件到功能 | |||
| def associate_attachment_container | |||
| return if self.project_id == 0 | |||
| att_ids = [] | |||
| # 附件的格式为(/api/attachments/ + 附件id)的形式,提取出id进行附件属性关联,做附件访问权限控制 | |||
| att_ids += self.description.to_s.scan(/\(\/api\/attachments\/.+\)/).map{|s|s.match(/\d+/)[0]} | |||
| att_ids += self.description.to_s.scan(/\/api\/attachments\/.+\"/).map{|s|s.match(/\d+/)[0]} | |||
| att_ids += self.description.to_s.scan(/\/api\/attachments\/\d+/).map{|s|s.match(/\d+/)[0]} | |||
| if att_ids.present? | |||
| Attachment.where(id: att_ids).where("container_type IS NULL OR container_type = 'Issue'").update_all(container_id: self.project_id, container_type: "Project") | |||
| Attachment.where(id: att_ids).where("container_type IS NULL OR container_type = 'Issue'").update_all(container_id: self.project_id, container_type: 'Project') | |||
| end | |||
| att_ids2 = [] | |||
| # uuid_regex= /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/ | |||
| # 附件的格式为(/api/attachments/ + uuid)的形式,提取出id进行附件属性关联,做附件访问权限控制 | |||
| att_ids2 += self.description.to_s.scan(/\(\/api\/attachments\/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\)/).map{|s|s.match(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/)[0]} | |||
| att_ids2 += self.description.to_s.scan(/\/api\/attachments\/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/).map{|s|s.match(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/)[0]} | |||
| if att_ids2.present? | |||
| Attachment.where(uuid: att_ids2).where("container_type IS NULL OR container_type = 'Issue'").update_all(container_id: self.project_id, container_type: 'Project') | |||
| end | |||
| end | |||
| @@ -32,7 +32,22 @@ class IssueTag < ApplicationRecord | |||
| validates :name, uniqueness: {scope: :project_id, message: "已存在" } | |||
| def self.init_data(project_id) | |||
| data = [ | |||
| data = init_issue_tag_data | |||
| data.each do |item| | |||
| next if IssueTag.exists?(project_id: project_id, name: item[0]) | |||
| IssueTag.create!(project_id: project_id, name: item[0], description: item[1], color: item[2]) | |||
| end | |||
| $redis_cache.hset("project_init_issue_tags", project_id, 1) | |||
| end | |||
| def reset_counter_field | |||
| self.update_column(:issues_count, issue_issues.size) | |||
| self.update_column(:pull_requests_count, pull_request_issues.size) | |||
| end | |||
| def self.init_issue_tag_data | |||
| [ | |||
| ["缺陷", "表示存在意外问题或错误", "#d92d4c"], | |||
| ["功能", "表示新功能申请", "#ee955a"], | |||
| ["疑问", "表示存在疑惑", "#2d6ddc"], | |||
| @@ -44,16 +59,18 @@ class IssueTag < ApplicationRecord | |||
| ["测试", "表示需要测试的需求", "#2897b9"], | |||
| ["重复", "表示已存在类似的疑修", "#bb5332"] | |||
| ] | |||
| data.each do |item| | |||
| next if IssueTag.exists?(project_id: project_id, name: item[0]) | |||
| IssueTag.create!(project_id: project_id, name: item[0], description: item[1], color: item[2]) | |||
| end | |||
| $redis_cache.hset("project_init_issue_tags", project_id, 1) | |||
| end | |||
| def reset_counter_field | |||
| self.update_column(:issues_count, issue_issues.size) | |||
| self.update_column(:pull_requests_count, pull_request_issues.size) | |||
| def self.init_mp_issues_tags | |||
| data = {"total_count": 10,} | |||
| data["issue_tags"] = init_issue_tag_data.map{|item| | |||
| { | |||
| "name": item[0], | |||
| "description": item[1], | |||
| "color": item[2], | |||
| } | |||
| } | |||
| data | |||
| end | |||
| @@ -61,6 +61,7 @@ class Journal < ApplicationRecord | |||
| # 关附件到功能 | |||
| def associate_attachment_container | |||
| return if self.issue&.project_id.to_i == 0 | |||
| att_ids = [] | |||
| # 附件的格式为(/api/attachments/ + 附件id)的形式,提取出id进行附件属性关联,做附件访问权限控制 | |||
| att_ids += self.notes.to_s.scan(/\(\/api\/attachments\/.+\)/).map{|s|s.match(/\d+/)[0]} | |||
| @@ -69,6 +70,15 @@ class Journal < ApplicationRecord | |||
| if att_ids.present? | |||
| Attachment.where(id: att_ids).where("container_type IS NULL OR container_type = 'Journal'").update_all(container_id: self.issue.project_id, container_type: "Project") | |||
| end | |||
| att_ids2 = [] | |||
| # uuid_regex= /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/ | |||
| # 附件的格式为(/api/attachments/ + uuid)的形式,提取出id进行附件属性关联,做附件访问权限控制 | |||
| att_ids2 += self.notes.to_s.scan(/\(\/api\/attachments\/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\)/).map{|s|s.match(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/)[0]} | |||
| att_ids2 += self.notes.to_s.scan(/\/api\/attachments\/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/).map{|s|s.match(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/)[0]} | |||
| if att_ids2.present? | |||
| Attachment.where(uuid: att_ids).where("container_type IS NULL OR container_type = 'Journal'").update_all(container_id: self.issue.project_id, container_type: "Project") | |||
| end | |||
| end | |||
| def operate_content | |||
| @@ -78,9 +88,9 @@ class Journal < ApplicationRecord | |||
| when 'issue' | |||
| return "创建了<b>疑修</b>" | |||
| when 'attachment' | |||
| old_value = Attachment.where(id: detail.old_value.split(",")).pluck(:filename).join("、") | |||
| new_value = Attachment.where(id: detail.value.split(",")).pluck(:filename).join("、") | |||
| if old_value.nil? || old_value.blank? | |||
| old_value = Attachment.where("id in (?) or uuid in (?)", detail.old_value.to_s.split(","), detail.old_value.to_s.split(",")).pluck(:filename).join("、") | |||
| new_value = Attachment.where("id in (?) or uuid in (?)", detail.value.to_s.split(","), detail.value.to_s.split(",")).pluck(:filename).join("、") | |||
| if old_value.nil? || old_value.blank? | |||
| content += "添加了<b>#{new_value}</b>附件" | |||
| else | |||
| new_value = "无" if new_value.blank? | |||
| @@ -43,8 +43,9 @@ class TraceUser < ApplicationRecord | |||
| def build_token | |||
| return if username.blank? || password.blank? || unit.blank? || email.blank? || name.blank? | |||
| response = Trace::AddUserService.call(username, password, unit, telnumber, email, name) | |||
| self.token = response[1]['token'] | |||
| response1 = Trace::AddUserService.call(username, password, unit, telnumber, email, name) | |||
| response2 = Trace::LoginService.call(username, password) | |||
| self.token = response2[1]['token'] | |||
| self.expired_at = Time.now + 1.hours | |||
| end | |||
| @@ -31,8 +31,8 @@ module Api::V1::Issues::Concerns::Checkable | |||
| def check_attachments (attachment_ids) | |||
| raise ApplicationService::Error, "请输入正确的附件ID数组!" unless attachment_ids.is_a?(Array) | |||
| attachment_ids.each do |aid| | |||
| raise ApplicationService::Error, "请输入正确的附件ID!" unless Attachment.exists?(id: aid) | |||
| end | |||
| raise ApplicationService::Error, "请输入正确的附件ID!" unless Attachment.where_id_or_uuid(aid).exists? | |||
| end | |||
| end | |||
| def check_atme_receivers(receivers_login) | |||
| @@ -9,7 +9,7 @@ module Api::V1::Issues::Concerns::Loadable | |||
| end | |||
| def load_attachments(attachment_ids) | |||
| @attachments = Attachment.where(id: attachment_ids) | |||
| @attachments = Attachment.where("id in (?) or uuid in (?)", attachment_ids, attachment_ids) | |||
| end | |||
| def load_atme_receivers(receivers_login) | |||
| @@ -0,0 +1,48 @@ | |||
| class Api::V1::Projects::Tags::GetService < ApplicationService | |||
| include ActiveModel::Model | |||
| attr_reader :project, :token, :owner, :repo, :tag_name | |||
| attr_accessor :gitea_data | |||
| validates :tag_name, presence: true | |||
| def initialize(project, tag_name, token=nil) | |||
| @project = project | |||
| @owner = project&.owner&.login | |||
| @repo = project&.identifier | |||
| @tag_name = tag_name.to_s | |||
| @token = token | |||
| end | |||
| def call | |||
| raise Error, errors.full_messages.join(",") unless valid? | |||
| check_tag_exist | |||
| load_gitea_data | |||
| gitea_data | |||
| end | |||
| private | |||
| def request_params | |||
| params = { | |||
| access_token: token | |||
| } | |||
| params | |||
| end | |||
| def load_gitea_data | |||
| @gitea_data = $gitea_hat_client.get_repos_tags_by_owner_repo_tag(owner, repo, URI.escape(tag_name), {query: request_params}) rescue nil | |||
| raise Error, '获取标签失败!' unless @gitea_data.is_a?(Hash) | |||
| end | |||
| def check_tag_exist | |||
| result = $gitea_hat_client.get_repos_tag_name_set_by_owner_repo(owner, repo, {query: request_params}) rescue nil | |||
| raise Error, '查询标签名称失败!' unless result.is_a?(Array) | |||
| raise Error, '标签不存在!' if !result.include?(@tag_name) | |||
| end | |||
| end | |||
| @@ -59,7 +59,11 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService | |||
| if @body[:new_branch].present? && (@body[:new_branch].include?('/') || @body[:new_branch].include?('\'') || @body[:new_branch].include?('^') || @body[:new_branch].include?('*')) | |||
| error("不合法的分支名称!") | |||
| else | |||
| error("#{filepath}文件已存在,不能重复创建!") | |||
| if json_parse!(body)["message"].present? && json_parse!(body)["message"].starts_with?("branch already exists") | |||
| error("#{@body[:new_branch]}分支已存在!") | |||
| else | |||
| error("#{filepath}文件已存在,不能重复创建!") | |||
| end | |||
| end | |||
| else | |||
| Rails.logger.error("Gitea api url==#{url},status:#{status},body=#{body}") | |||
| @@ -0,0 +1,2 @@ | |||
| json.partial! "api/v1/issues/detail", locals: {issue: @issue} | |||
| json.user_permission @user_permission | |||
| @@ -4,7 +4,11 @@ if tag.present? && tag.is_a?(Hash) | |||
| json.zipball_url render_zip_url(@owner, @repository, tag['name']) | |||
| json.tarball_url render_tar_url(@owner, @repository, tag['name']) | |||
| json.tagger do | |||
| json.partial! 'api/v1/users/commit_user', user: render_cache_commit_author(tag['tagger']), name: tag['tagger']['name'] | |||
| if tag['tagger'].present? | |||
| json.partial! 'api/v1/users/commit_user', user: render_cache_commit_author(tag['tagger']), name: tag['tagger']['name'] | |||
| else | |||
| json.nil! | |||
| end | |||
| end | |||
| json.time_ago time_from_now(tag['tagger']['date'].to_time) | |||
| json.created_at_unix tag['tagger']['date'].to_time.to_i | |||
| @@ -0,0 +1 @@ | |||
| json.partial! "api/v1/projects/tags/simple_gitea_index_detail", tag: @result_object | |||
| @@ -1,2 +1,7 @@ | |||
| json.id @attachment.id | |||
| json.filesize @attachment.filesize | |||
| json.id @attachment.uuid | |||
| json.title @attachment.title | |||
| json.filesize number_to_human_size(@attachment.filesize) | |||
| json.is_pdf @attachment.is_pdf? | |||
| json.url Rails.application.config_for(:configuration)['platform_url'] + (@attachment.is_pdf? ? download_url(@attachment,disposition:"inline") : download_url(@attachment)).to_s | |||
| json.created_on @attachment.created_on.strftime("%Y-%m-%d %H:%M") | |||
| json.content_type @attachment.content_type | |||
| @@ -127,6 +127,7 @@ Rails.application.routes.draw do | |||
| # blockchain related routes | |||
| get 'users/blockchain/balance', to: 'users#blockchain_balance' | |||
| get 'projects/mp_show', to: 'projects#mp_show' | |||
| post 'users/blockchain/balance_project', to: 'users#blockchain_balance_one_project' | |||
| post 'users/blockchain/transfer', to: 'users#blockchain_transfer' | |||
| post 'users/blockchain/exchange', to: 'users#blockchain_exchange' | |||
| @@ -47,6 +47,7 @@ defaults format: :json do | |||
| end | |||
| member do | |||
| get :show_by_id | |||
| resources :journals, module: :issues, only: [:index, :create, :update, :destroy] do | |||
| member do | |||
| get :children_journals | |||
| @@ -55,12 +56,24 @@ defaults format: :json do | |||
| end | |||
| end | |||
| scope module: :issues do | |||
| resources :issue_tags, except: [:new, :edit] | |||
| resources :issue_tags, except: [:new, :edit] do | |||
| collection do | |||
| get :pm_index | |||
| end | |||
| end | |||
| resources :milestones, except: [:new, :edit] | |||
| resources :issue_statues, only: [:index], controller: '/api/v1/issues/statues' | |||
| resources :issue_statues, only: [:index], controller: '/api/v1/issues/statues' do | |||
| collection do | |||
| get :pm_index | |||
| end | |||
| end | |||
| resources :issue_authors, only: [:index], controller: '/api/v1/issues/authors' | |||
| resources :issue_assigners, only: [:index], controller: '/api/v1/issues/assigners' | |||
| resources :issue_priorities, only: [:index] | |||
| resources :issue_priorities, only: [:index] do | |||
| collection do | |||
| get :pm_index | |||
| end | |||
| end | |||
| end | |||
| # projects文件夹下的 | |||
| @@ -90,8 +103,9 @@ defaults format: :json do | |||
| end | |||
| match 'branches/*name', to: "branches#destroy", via: :all | |||
| resources :tags, param: :name, only: [:index, :destroy] | |||
| match 'tags/*name', to: "tags#destroy", via: :all | |||
| resources :tags, param: :name, only: [:index, :show, :destroy] | |||
| delete 'tags/*name', to: "tags#destroy", via: :all | |||
| get 'tags/*name', to: "tags#show", via: :all | |||
| resources :commits, only: [:index] | |||
| resources :code_stats, only: [:index] | |||
| @@ -0,0 +1,6 @@ | |||
| class AddPmProjectIdAndPmSprintIdToIssues < ActiveRecord::Migration[5.2] | |||
| def change | |||
| add_column :issues, :pm_project_id , :integer | |||
| add_column :issues, :pm_sprint_id , :integer | |||
| end | |||
| end | |||
| @@ -0,0 +1,5 @@ | |||
| class AddUuidToAttachments < ActiveRecord::Migration[5.2] | |||
| def change | |||
| add_column :attachments, :uuid, :string, index: true | |||
| end | |||
| end | |||
| @@ -0,0 +1,8 @@ | |||
| class ChangeIdentityVerification < ActiveRecord::Migration[5.2] | |||
| def change | |||
| change_column :identity_verifications, :card_front, :string | |||
| change_column :identity_verifications, :card_back, :string | |||
| change_column :identity_verifications, :hold_card_front, :string | |||
| change_column :identity_verifications, :hold_card_back, :string | |||
| end | |||
| end | |||