| @@ -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}" | |||
| @@ -147,8 +148,9 @@ class AttachmentsController < ApplicationController | |||
| if params[:type] == 'history' | |||
| AttachmentHistory.find params[:id] | |||
| else | |||
| Attachment.find params[:id] | |||
| Attachment.find_by(id: params[:id]) || Attachment.find_by(uuid: params[:id]) | |||
| end | |||
| tip_exception(404, "您访问的页面不存在或已被删除") if @file.blank? | |||
| end | |||
| def delete_file(file_path) | |||
| @@ -218,7 +220,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)) | |||
| @@ -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) | |||
| # | |||
| @@ -97,6 +98,11 @@ class Attachment < ApplicationRecord | |||
| downloads | |||
| end | |||
| def generate_uuid | |||
| self.uuid = uuid || SecureRandom.uuid | |||
| save! | |||
| end | |||
| def quotes_count | |||
| quotes.nil? ? 0 : quotes | |||
| end | |||
| @@ -224,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 | |||
| @@ -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 | |||
| @@ -31,7 +31,7 @@ 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) | |||
| raise ApplicationService::Error, "请输入正确的附件ID!" unless Attachment.exists?(id: aid) || Attachment.exists?(uuid: aid) | |||
| end | |||
| end | |||
| @@ -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: attachment_ids).or(Attachment.where(uuid: attachment_ids)) | |||
| end | |||
| def load_atme_receivers(receivers_login) | |||
| @@ -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 | |||