1159 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			1159 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Ruby
		
	
	
	
require 'oauth2'
 | 
						||
# require 'openssl'
 | 
						||
# require 'jwt'
 | 
						||
 | 
						||
class ApplicationController < ActionController::Base
 | 
						||
	include CodeExample
 | 
						||
	include RenderExpand
 | 
						||
	include RenderHelper
 | 
						||
	include ControllerRescueHandler
 | 
						||
	include LaboratoryHelper
 | 
						||
	include GitHelper
 | 
						||
	include LoggerHelper
 | 
						||
	include LoginHelper
 | 
						||
	include RegisterHelper
 | 
						||
 | 
						||
	protect_from_forgery prepend: true, unless: -> { request.format.json? }
 | 
						||
 | 
						||
	before_action :check_sign
 | 
						||
	before_action :user_setup
 | 
						||
	#before_action :check_account
 | 
						||
 | 
						||
	# TODO
 | 
						||
	# check sql query time
 | 
						||
	before_action do
 | 
						||
    # if request.subdomain === 'testforgeplus' || request.subdomain === "profiler"
 | 
						||
    #   Rack::MiniProfiler.authorize_request
 | 
						||
    # end
 | 
						||
  end
 | 
						||
 | 
						||
	DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
 | 
						||
	OPENKEY = Rails.application.config_for(:configuration)['sign_key'] || "79e33abd4b6588941ab7622aed1e67e8"
 | 
						||
 | 
						||
 | 
						||
	helper_method :current_user, :base_url
 | 
						||
 | 
						||
	# 所有请求必须合法签名
 | 
						||
	def check_sign
 | 
						||
		# if !Rails.env.development?
 | 
						||
		# 	Rails.logger.info("66666  #{params}")
 | 
						||
		# 	# suffix = request.url.split(".").last.split("?").first
 | 
						||
		# 	# suffix_arr = ["xls", "xlsx", "pdf", "zip"] # excel文件先注释
 | 
						||
		# 	# unless suffix_arr.include?(suffix)
 | 
						||
		# 		if params[:client_key].present?
 | 
						||
		# 			randomcode = params[:randomcode]
 | 
						||
		# 			# tip_exception(501, "请求不合理") unless (Time.now.to_i - randomcode.to_i).between?(0,5)
 | 
						||
		#
 | 
						||
		# 			sign = Digest::MD5.hexdigest("#{OPENKEY}#{randomcode}")
 | 
						||
		# 			Rails.logger.info("2222  #{sign}")
 | 
						||
		# 			tip_exception(501, "请求不合理") if sign != params[:client_key]
 | 
						||
		# 		else
 | 
						||
		# 			tip_exception(501, "请求不合理")
 | 
						||
		# 		end
 | 
						||
		# 	# end
 | 
						||
		# end
 | 
						||
	end
 | 
						||
 | 
						||
	# 全局配置参数
 | 
						||
	# 返回name对应的value
 | 
						||
	def edu_setting(name)
 | 
						||
		EduSetting.get(name)
 | 
						||
	end
 | 
						||
 | 
						||
	# 平台身份权限判断(学生用户无权限)
 | 
						||
	def identity_auth
 | 
						||
		ue = current_user.user_extension
 | 
						||
		tip_exception(403, "..") unless current_user.admin_or_business? || ue.teacher? || ue.professional?
 | 
						||
	end
 | 
						||
 | 
						||
	# 平台已认证身份判断(已认证的老师和专业人士)
 | 
						||
	def certi_identity_auth
 | 
						||
		ue = current_user.user_extension
 | 
						||
		tip_exception(403, "..") unless current_user.admin_or_business? ||
 | 
						||
																									(current_user.professional_certification && (ue.teacher? || ue.professional?))
 | 
						||
	end
 | 
						||
 | 
						||
 | 
						||
	def admin_or_business?
 | 
						||
		User.current.admin? || User.current.business?
 | 
						||
	end
 | 
						||
 | 
						||
	# 判断用户的邮箱或者手机是否可用
 | 
						||
	# params[:type] 1: 注册;2:忘记密码;3:绑定
 | 
						||
	def  check_mail_and_phone_valid login, type
 | 
						||
		unless login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/ || login =~ /^1\d{10}$/
 | 
						||
			tip_exception(-2, "请输入正确的手机号或邮箱")
 | 
						||
		end
 | 
						||
	
 | 
						||
		user_exist = Owner.exists?(phone: login) || Owner.exists?(mail: login)
 | 
						||
		if user_exist && type.to_i == 1
 | 
						||
			tip_exception(-2, "该手机号码或邮箱已被注册")
 | 
						||
		elsif type.to_i == 2 && !user_exist
 | 
						||
			tip_exception(-2, "该手机号码或邮箱未注册")
 | 
						||
		elsif type.to_i == 3 && user_exist
 | 
						||
			tip_exception(-2, "该手机号码或邮箱已绑定")
 | 
						||
		end
 | 
						||
		render_ok
 | 
						||
	end
 | 
						||
 | 
						||
	# 发送及记录激活码
 | 
						||
	# 发送验证码:type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱
 | 
						||
	# 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9:验证手机号有效
 | 
						||
	def check_verification_code(code, send_type, value)
 | 
						||
		case send_type
 | 
						||
		when 1, 2, 4, 9
 | 
						||
			# 手机类型的发送
 | 
						||
			sigle_para = {phone: value}
 | 
						||
			# status = Gitlink::Sms.send(mobile: value, code: code)
 | 
						||
			# tip_exception(-2, code_msg(status)) if status != 0
 | 
						||
			status = Sms::UcloudService.call(value, code, send_type)
 | 
						||
			tip_exception(-2, ucloud_code_msg(status)) if status != 0
 | 
						||
		when 8, 3, 5
 | 
						||
			# 邮箱类型的发送
 | 
						||
			sigle_para = {email: value}
 | 
						||
			# 60s内不能重复发送
 | 
						||
			send_email_limit_cache_key = "send_email_60_second_limit:#{value}"
 | 
						||
			tip_exception(-1, '请勿频繁操作') if Rails.cache.exist?(send_email_limit_cache_key)
 | 
						||
 | 
						||
			# 短时间内不能大量发送
 | 
						||
			send_email_control = LimitForbidControl::SendEmailCode.new(value)
 | 
						||
			tip_exception(-1, '邮件发送太频繁,请稍后再试') if send_email_control.forbid?
 | 
						||
			begin
 | 
						||
				if send_type == 3
 | 
						||
					UserMailer.find_password(value, code).deliver_now
 | 
						||
				elsif send_type == 5
 | 
						||
					UserMailer.bind_email(value, code).deliver_now
 | 
						||
				else
 | 
						||
					UserMailer.register_email(value, code).deliver_now
 | 
						||
				end
 | 
						||
				Rails.cache.write(send_email_limit_cache_key, 1, expires_in: 1.minute)
 | 
						||
				send_email_control.increment!
 | 
						||
				# Mailer.run.email_register(code, value)
 | 
						||
			rescue Exception => e
 | 
						||
				logger_error(e)
 | 
						||
				tip_exception(-2,"邮件发送失败,请稍后重试")
 | 
						||
			end
 | 
						||
		end
 | 
						||
		ver_params = {code_type: send_type, code: code}.merge(sigle_para)
 | 
						||
		VerificationCode.create!(ver_params)
 | 
						||
	end
 | 
						||
 | 
						||
	def code_msg status
 | 
						||
		case status
 | 
						||
		when 0
 | 
						||
			"验证码已经发送到您的手机,请注意查收"
 | 
						||
		when 8
 | 
						||
			"同一手机号30秒内重复提交相同的内容"
 | 
						||
		when 9
 | 
						||
			"同一手机号5分钟内重复提交相同的内容超过3次"
 | 
						||
		when 22
 | 
						||
			"1小时内同一手机号发送次数超过限制"
 | 
						||
		when 33
 | 
						||
			"验证码发送次数超过频率"
 | 
						||
		when 43
 | 
						||
			"一天内同一手机号发送次数超过限制"
 | 
						||
		when 53
 | 
						||
			"手机号接收超过频率限制"
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
	def ucloud_code_msg status
 | 
						||
		case status
 | 
						||
		when 0
 | 
						||
			"验证码已经发送到您的手机,请注意查收"
 | 
						||
		when 171
 | 
						||
			"API签名错误"
 | 
						||
		when 18014
 | 
						||
			"无效手机号码"
 | 
						||
		when 18017
 | 
						||
			"无效模板"
 | 
						||
		when 18018
 | 
						||
			"短信模板参数与短信模板不匹配"
 | 
						||
		when 18023
 | 
						||
			"短信内容中含有运营商拦截的关键词"
 | 
						||
		when 18033
 | 
						||
			"变量内容不符合规范"
 | 
						||
		else
 | 
						||
			"错误码#{status}"
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
	def validate_type(object_type)
 | 
						||
		normal_status(2, "参数") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
 | 
						||
	end
 | 
						||
 | 
						||
	def set_pagination
 | 
						||
		@page  		 = params[:page] || 1
 | 
						||
		@page_size = params[:page_size] || 15
 | 
						||
	end
 | 
						||
 | 
						||
	def require_admin
 | 
						||
		normal_status(403, "") unless User.current.admin?
 | 
						||
	end
 | 
						||
 | 
						||
	def require_business
 | 
						||
		normal_status(403, "") unless admin_or_business?
 | 
						||
	end
 | 
						||
 | 
						||
	# 前端会捕捉401,弹登录弹框
 | 
						||
	# 未授权的捕捉407,弹试用申请弹框
 | 
						||
	def require_login
 | 
						||
		#6.13 -hs
 | 
						||
		tip_exception(401, "请登录后再操作") unless User.current.logged?
 | 
						||
	end
 | 
						||
 | 
						||
	def require_login_or_token
 | 
						||
		if params[:token].present?
 | 
						||
			user = User.try_to_autologin(params[:token])
 | 
						||
			User.current = user
 | 
						||
		end
 | 
						||
		tip_exception(401, "请登录后再操作") unless User.current.logged?
 | 
						||
	end
 | 
						||
 | 
						||
	def require_login_cloud_ide_saas
 | 
						||
		if params[:sign].present? && params[:email].present?
 | 
						||
			sign = Digest::MD5.hexdigest("#{OPENKEY}#{params[:email]}")
 | 
						||
			if params[:sign].to_s == sign
 | 
						||
				user = User.find_by(mail: params[:email])
 | 
						||
				User.current = user
 | 
						||
			end
 | 
						||
		end
 | 
						||
		tip_exception(401, "请登录后再操作") unless User.current.logged?
 | 
						||
	end
 | 
						||
 | 
						||
	def require_profile_completed
 | 
						||
		tip_exception(411, "请完善资料后再操作") unless User.current.profile_is_completed?
 | 
						||
	end
 | 
						||
 | 
						||
	def require_user_profile_completed(user)
 | 
						||
		tip_exception(412, "请用户完善资料后再操作") unless user.profile_is_completed?
 | 
						||
	end
 | 
						||
 | 
						||
	# 异常提醒
 | 
						||
	def tip_exception(status = -1, message)
 | 
						||
		raise Gitlink::TipException.new(status, message)
 | 
						||
	end
 | 
						||
 | 
						||
	def missing_template
 | 
						||
		tip_exception(404, "...")
 | 
						||
	end
 | 
						||
 | 
						||
	# 弹框提醒
 | 
						||
	def tip_show_exception(status = -2, message)
 | 
						||
		raise Gitlink::TipException.new(status, message)
 | 
						||
	end
 | 
						||
 | 
						||
	def normal_status(status = 0, message)
 | 
						||
		case status
 | 
						||
		when 403
 | 
						||
			message = "您没有权限进行该操作"
 | 
						||
		when 404
 | 
						||
			message = "您访问的页面不存在或已被删除"
 | 
						||
		end
 | 
						||
		render :json => { status: status, message: message }
 | 
						||
	end
 | 
						||
 | 
						||
	# 资料是否完善
 | 
						||
	def check_account
 | 
						||
		if !current_user. profile_is_completed?
 | 
						||
			#info_url = '/account/profile'
 | 
						||
			tip_exception(402, nil)
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
	# 系统全局认证(暂时隐藏试用申请的判断)
 | 
						||
	def check_auth
 | 
						||
		# day_cer = UserDayCertification.find_by(user_id: current_user.id)
 | 
						||
		# # 如果注册超过24小时则需要完善资料及授权
 | 
						||
		# if (Time.now.to_i - day_cer.try(:created_at).to_i) > 86400
 | 
						||
		# 	if !current_user.profile_completed?
 | 
						||
		# 		info_url = '/account/profile'
 | 
						||
		# 		tip_exception(402, info_url)
 | 
						||
		# 	elsif current_user.certification != 1
 | 
						||
		# 		if current_user.apply_actions.exists?(container_type: 'TrialAuthorization', status: 0)
 | 
						||
		# 			tip_exception(408, "您的试用申请正在审核中,请耐心等待")
 | 
						||
		# 		end
 | 
						||
		# 		tip_exception(407, "系统未授权")
 | 
						||
		# 	end
 | 
						||
		# end
 | 
						||
 | 
						||
 | 
						||
		# if current_user.certification != 1 && current_user.apply_actions.exists?(container_type: 'TrialAuthorization', status: 0)
 | 
						||
		# 	tip_exception(408, "您的试用申请正在审核中,请耐心等待")
 | 
						||
		# elsif (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400
 | 
						||
		# 	if !current_user.profile_completed?
 | 
						||
		# 		info_url = '/account/profile'
 | 
						||
		# 		tip_exception(402, info_url)
 | 
						||
		# 	elsif current_user.certification != 1
 | 
						||
		# 		day_cer = UserDayCertification.find_by(user_id: current_user.id)
 | 
						||
		# 		tip_exception(407, "系统未授权") unless (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400
 | 
						||
		# 	end
 | 
						||
		# end
 | 
						||
	end
 | 
						||
 | 
						||
	def user_setup
 | 
						||
		# # reacct静态资源加载不需要走这一步
 | 
						||
		#return if params[:controller] == "main"
 | 
						||
		# Find the current user
 | 
						||
		#Rails.logger.info("current_laboratory is #{current_laboratory} domain is #{request.subdomain}")
 | 
						||
		if request.headers["Authorization"].present? && request.headers["Authorization"].start_with?('Bearer')
 | 
						||
			if !valid_doorkeeper_token?
 | 
						||
				header = request.authorization
 | 
						||
				pattern = /^Bearer /i
 | 
						||
				token = header.gsub(pattern, "")
 | 
						||
				User.current, message = Bot.decode_jwt_token(token)
 | 
						||
				tip_exception(401, message) if message.present?
 | 
						||
			else
 | 
						||
				if @doorkeeper_token.present?
 | 
						||
					# client方法对接,需要一直带着用户标识uid
 | 
						||
					if @doorkeeper_token.resource_owner_id.blank?
 | 
						||
						tip_exception(-1, "缺少用户标识!") if params[:uid].nil?
 | 
						||
						User.current = User.find(params[:uid])
 | 
						||
					else
 | 
						||
						User.current = User.find_by(id: @doorkeeper_token.resource_owner_id)
 | 
						||
					end
 | 
						||
				end
 | 
						||
			end
 | 
						||
		else
 | 
						||
			User.current = find_current_user
 | 
						||
			uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
 | 
						||
 | 
						||
			# 开放课程通过链接访问的用户
 | 
						||
			if !User.current.logged? && !params[:chinaoocTimestamp].blank? && !params[:websiteName].blank? && !params[:chinaoocKey].blank?
 | 
						||
				content = "#{OPENKEY}#{params[:websiteName]}#{params[:chinaoocTimestamp]}"
 | 
						||
 | 
						||
				if Digest::MD5.hexdigest(content) == params[:chinaoocKey]
 | 
						||
					user = open_class_user
 | 
						||
					if user
 | 
						||
						start_user_session(user)
 | 
						||
						set_autologin_cookie(user)
 | 
						||
					end
 | 
						||
					User.current = user
 | 
						||
				end
 | 
						||
			end
 | 
						||
 | 
						||
			if !User.current.logged? && Rails.env.development?
 | 
						||
				user = User.find 1
 | 
						||
				User.current = user
 | 
						||
				start_user_session(user)
 | 
						||
			end
 | 
						||
 | 
						||
 | 
						||
			# 测试版前端需求
 | 
						||
			logger.info("subdomain:#{request.subdomain}")
 | 
						||
			if request.subdomain != "www"
 | 
						||
				if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
 | 
						||
					User.current = User.find 81403
 | 
						||
				elsif params[:debug] == 'student'
 | 
						||
					User.current = User.find 8686
 | 
						||
				elsif params[:debug] == 'admin'
 | 
						||
					logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
 | 
						||
					user =  User.find 36480
 | 
						||
					User.current = user
 | 
						||
					cookies.signed[:user_id] = user.id
 | 
						||
				end
 | 
						||
			end
 | 
						||
		end
 | 
						||
		# User.current = User.find 81403
 | 
						||
	end
 | 
						||
 | 
						||
	# Returns the current user or nil if no user is logged in
 | 
						||
	# and starts a session if needed
 | 
						||
	def find_current_user
 | 
						||
		uid_logger("user setup start: session[:user_id] is #{session[:user_id]}")
 | 
						||
		uid_logger("0000000000000user setup start: default_yun_session is #{default_yun_session}, session[:current_user_id] is #{session[:"#{default_yun_session}"]}")
 | 
						||
		current_domain_session = session[:"#{default_yun_session}"]
 | 
						||
		if current_domain_session
 | 
						||
			# existing session
 | 
						||
			User.current = (User.active.find(current_domain_session) rescue nil)
 | 
						||
		elsif autologin_user = try_to_autologin
 | 
						||
			autologin_user
 | 
						||
		elsif params[:format] == 'atom' && params[:key] && request.get? && accept_rss_auth?
 | 
						||
			# RSS key authentication does not start a session
 | 
						||
			User.find_by_rss_key(params[:key])
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
	def try_to_autologin
 | 
						||
		if cookies[autologin_cookie_name]
 | 
						||
			# auto-login feature starts a new session
 | 
						||
			user = nil
 | 
						||
			Rails.logger.info("111111111111111111#{default_yun_session}, session is #{session[:"#{default_yun_session}"]} ")
 | 
						||
			user = User.try_to_autologin(cookies[autologin_cookie_name])
 | 
						||
			# start_user_session(user) if user # TODO 解决sso退出不同步的问题
 | 
						||
			user
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
	def api_request?
 | 
						||
		%w(xml json).include? params[:format]
 | 
						||
	end
 | 
						||
 | 
						||
	def current_user
 | 
						||
		User.current
 | 
						||
	end
 | 
						||
 | 
						||
	## 默认输出json
 | 
						||
	def render_json
 | 
						||
		respond_to do |format|
 | 
						||
      format.json
 | 
						||
    end
 | 
						||
	end
 | 
						||
 | 
						||
	## 输出错误信息
 | 
						||
	def error_status(message = nil)
 | 
						||
		@status = -1
 | 
						||
		@message = message
 | 
						||
	end
 | 
						||
 | 
						||
	def repo_url(repo_path)
 | 
						||
		"#{edu_setting('git_address_domain')}/#{repo_path}"
 | 
						||
	end
 | 
						||
 | 
						||
	# 通关后,把最后一次成功的代码存到数据库
 | 
						||
	# type 0 创始内容, 1 最新内容
 | 
						||
	# def game_passed_code(path, myshixun, game_id)
 | 
						||
	# 	# 如果代码窗口是隐藏的,则不用保存代码
 | 
						||
	# 	return if myshixun.shixun.hide_code || myshixun.shixun.vnc
 | 
						||
	# 	file_content = git_fle_content myshixun.repo_path, path
 | 
						||
	# 	#unless file_content.present?
 | 
						||
	# 	#	raise("获取文件代码异常")
 | 
						||
	# 	#end
 | 
						||
	# 	logger.info("#######game_id:#{game_id}, file_content:#{file_content}")
 | 
						||
	# 	game_code = GameCode.where(:game_id => game_id, :path => path).first
 | 
						||
	# 	if game_code.nil?
 | 
						||
	# 		GameCode.create!(:game_id => game_id, :new_code => file_content, :path => path)
 | 
						||
	# 	else
 | 
						||
	# 		game_code.update_attributes!(:new_code => file_content)
 | 
						||
	# 	end
 | 
						||
  # end
 | 
						||
 | 
						||
	# Post请求
 | 
						||
	def uri_post(uri, params)
 | 
						||
		begin
 | 
						||
			uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
 | 
						||
			uri = URI.parse(URI.encode(uri.strip))
 | 
						||
			res = Net::HTTP.post_form(uri, params).body
 | 
						||
			uid_logger_dubug("--uri_exec: .....res is #{res}")
 | 
						||
			JSON.parse(res)
 | 
						||
		rescue Exception => e
 | 
						||
			uid_logger_error("--uri_exec: exception #{e.message}")
 | 
						||
			raise Gitlink::TipException.new("实训平台繁忙(繁忙等级:84)")
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
	# 处理返回非0就报错的请求
 | 
						||
	def interface_post(uri, params, status, message)
 | 
						||
		begin
 | 
						||
			uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
 | 
						||
			uri = URI.parse(URI.encode(uri.strip))
 | 
						||
			res = Net::HTTP.post_form(uri, params).body
 | 
						||
			uid_logger_dubug("--uri_exec: .....res is #{res}")
 | 
						||
			res = JSON.parse(res)
 | 
						||
			if (res && res['code'] != 0)
 | 
						||
				tip_exception(status, message)
 | 
						||
			else
 | 
						||
				res
 | 
						||
			end
 | 
						||
		rescue Exception => e
 | 
						||
			uid_logger("--uri_exec: exception #{e.message}")
 | 
						||
			raise Gitlink::TipException.new(message)
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
	# json格式请求
 | 
						||
	def interface_json_post(uri, params, status, message)
 | 
						||
		begin
 | 
						||
			uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
 | 
						||
			uri = URI.parse(URI.encode(uri.strip))
 | 
						||
			res = Net::HTTP.start(uri.host, uri.port) do |http|
 | 
						||
				req = Net::HTTP::Post.new(uri)
 | 
						||
				req['Content-Type'] = 'application/json'
 | 
						||
				req.body = params.to_json
 | 
						||
				http.request(req)
 | 
						||
			end
 | 
						||
			uid_logger_dubug("--uri_exec: .....res is #{res.body}")
 | 
						||
			res = JSON.parse(res.body)
 | 
						||
			if (res && res['code'] != 0)
 | 
						||
				tip_exception(status, message)
 | 
						||
			else
 | 
						||
				res
 | 
						||
			end
 | 
						||
		rescue Exception => e
 | 
						||
			uid_logger("--uri_exec: exception #{e.message}")
 | 
						||
			raise Gitlink::TipException.new("服务器繁忙")
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
 | 
						||
	# 适用与已经用url_safe编码后,回调字符串形式
 | 
						||
	def tran_base64_decode64(str)
 | 
						||
		s_size = str.size % 4
 | 
						||
		if s_size != 0
 | 
						||
			str += "=" * (4 - s_size)
 | 
						||
		end
 | 
						||
		if str.blank?
 | 
						||
			str
 | 
						||
		else
 | 
						||
			Base64.decode64(str.tr("-_", "+/")).force_encoding("utf-8")
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
	def sucess_status(message = 'success')
 | 
						||
		render :json => { status: 1, message: message }
 | 
						||
	end
 | 
						||
 | 
						||
	# 随机生成字符
 | 
						||
	def generate_identifier(container, num, pre='')
 | 
						||
		code = DCODES.sample(num).join
 | 
						||
		if container == User
 | 
						||
			while container.exists?(login: pre+code) do
 | 
						||
				code = DCODES.sample(num).join
 | 
						||
			end
 | 
						||
		else
 | 
						||
			while container.exists?(identifier: code) do
 | 
						||
				code = DCODES.sample(num).join
 | 
						||
			end
 | 
						||
		end
 | 
						||
		code
 | 
						||
	end
 | 
						||
 | 
						||
 | 
						||
	# 实训主类别列表,自带描述
 | 
						||
	def shixun_main_type
 | 
						||
		list = []
 | 
						||
		mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_main_mirror
 | 
						||
		mirrors.try(:each) do |mirror|
 | 
						||
			list << {id: mirror.id, type_name: mirror.type_name, description: mirror.try(:description), mirror_name: mirror.name}
 | 
						||
		end
 | 
						||
		list
 | 
						||
	end
 | 
						||
 | 
						||
	# 小类别列表
 | 
						||
	def shixun_small_type
 | 
						||
		list = []
 | 
						||
		mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_small_mirror
 | 
						||
		mirrors.try(:each) do |mirror|
 | 
						||
			list << {id: mirror.id, type_name: mirror.type_name, description: mirror.description, mirror_name: mirror.name}
 | 
						||
		end
 | 
						||
		list
 | 
						||
	end
 | 
						||
 | 
						||
	def container_limit(mirror_repositories)
 | 
						||
		container = []
 | 
						||
		mirror_repositories.each do |mr|
 | 
						||
			if mr.name.present?
 | 
						||
				container << {:image => mr.name, :cpuLimit => mr.cpu_limit, :memoryLimit =>  "#{mr.memory_limit}M", :type => mr.try(:main_type) == "1" ? "main" : "sub"}
 | 
						||
			end
 | 
						||
		end
 | 
						||
		container.to_json
 | 
						||
	end
 | 
						||
 | 
						||
	# 实训中间层pod配置
 | 
						||
	def shixun_container_limit shixun
 | 
						||
		container = []
 | 
						||
		shixun.shixun_service_configs.each do |config|
 | 
						||
			mirror = config.mirror_repository
 | 
						||
			if mirror.name.present?
 | 
						||
				# 资源限制没有就传默认值。
 | 
						||
				cpu_limit = config.cpu_limit.presence || 1
 | 
						||
				cpu_request = config.lower_cpu_limit.presence || 0.1
 | 
						||
				memory_limit = config.memory_limit.presence || 1024
 | 
						||
				request_limit = config.request_limit.presence || 10
 | 
						||
				resource_limit = config.resource_limit.presence || 10000
 | 
						||
				container << {:image => mirror.name,
 | 
						||
											:cpuLimit => cpu_limit,
 | 
						||
											:cpuRequest => cpu_request,
 | 
						||
											:memoryLimit => "#{memory_limit}M",
 | 
						||
											:memoryRequest => "#{request_limit}M",
 | 
						||
											:resourceLimit => "#{resource_limit}K",
 | 
						||
											:type => mirror.try(:main_type) == "1" ? "main" : "sub"}
 | 
						||
			end
 | 
						||
		end
 | 
						||
		container.to_json
 | 
						||
	end
 | 
						||
 | 
						||
	# 毕设任务列表的赛选
 | 
						||
	def course_work(task, **option)
 | 
						||
		logger.info("#############{option}")
 | 
						||
		course = task.course
 | 
						||
		work_list = task.graduation_works.includes(user: [:user_extension])
 | 
						||
		# 教师评阅搜索 0: 未评, 1 已评
 | 
						||
		if option[:teacher_comment]
 | 
						||
			graduation_work_ids = GraduationWorkScore.where(graduation_work_id: work_list.map(&:id)).pluck(:graduation_work_id)
 | 
						||
			if option[:teacher_comment].zero?
 | 
						||
				work_list  = work_list.where.not(id: graduation_work_ids)
 | 
						||
			elsif option[:teacher_comment] == 1
 | 
						||
				work_list = work_list.where(id: graduation_work_ids).where.not(work_status: 0)
 | 
						||
			end
 | 
						||
		end
 | 
						||
 | 
						||
		# 作品状态 0: 未提交, 1 按时提交, 2 延迟提交
 | 
						||
		if option[:task_status]
 | 
						||
			work_list = work_list.where(work_status: option[:task_status])
 | 
						||
		end
 | 
						||
 | 
						||
		# 分班情况
 | 
						||
		if option[:course_group]
 | 
						||
			group_user_ids = course.course_members.where(course_group_id: option[:course_group]).pluck(:user_id)
 | 
						||
			# 有分组只可能是老师身份查看列表
 | 
						||
			work_list = work_list.where(user_id: group_user_ids)
 | 
						||
		end
 | 
						||
 | 
						||
		# 只看我的交叉评阅
 | 
						||
		if option[:cross_comment]
 | 
						||
			graduation_work_id = task.graduation_work_comment_assignations.where(:user_id => current_user.id)
 | 
						||
															 .pluck(:graduation_work_id).uniq if task.graduation_work_comment_assignations
 | 
						||
			work_list = work_list.where(id: graduation_work_id)
 | 
						||
		end
 | 
						||
 | 
						||
		# 输入姓名和学号搜索
 | 
						||
		# TODO user_extension 如果修改 请调整
 | 
						||
		if option[:search]
 | 
						||
			work_list = work_list.joins(user: :user_extension).where("concat(lastname, firstname) like ?
 | 
						||
                         or student_id like ?", "%#{option[:search]}%", "%#{option[:search]}%")
 | 
						||
		end
 | 
						||
 | 
						||
		# 排序
 | 
						||
		rorder = UserExtension.column_names.include?(option[:order]) ? option[:order] : "updated_at"
 | 
						||
		b_order = %w(desc asc).include?(option[:b_order]) ? option[:b_order] : "desc"
 | 
						||
		if rorder == "created_at" || rorder == "work_score"
 | 
						||
			work_list = work_list.order("graduation_works.#{rorder} #{b_order}")
 | 
						||
		elsif rorder == "student_id"
 | 
						||
			work_list = work_list.joins(user: :user_extension).order("user_extensions.#{rorder} #{b_order}")
 | 
						||
		end
 | 
						||
		work_list
 | 
						||
	end
 | 
						||
 | 
						||
	def strip_html(text, len=0, endss="...")
 | 
						||
		ss = ""
 | 
						||
		if !text.nil? && text.length>0
 | 
						||
			ss=text.gsub(/<\/?.*?>/, '').strip
 | 
						||
			ss = ss.gsub(/ */, '')
 | 
						||
			ss = ss.gsub(/\r\n/,'')  #新增
 | 
						||
			ss = ss.gsub(/\n/,'')  #新增
 | 
						||
			if len > 0 && ss.length > len
 | 
						||
				ss = ss[0, len] + endss
 | 
						||
			elsif len > 0 && ss.length <= len
 | 
						||
				ss = ss
 | 
						||
				#ss = truncate(ss, :length => len)
 | 
						||
			end
 | 
						||
		end
 | 
						||
		ss
 | 
						||
	end
 | 
						||
 | 
						||
	# Returns a string that can be used as filename value in Content-Disposition header
 | 
						||
	def filename_for_content_disposition(name)
 | 
						||
		request.env['HTTP_USER_AGENT'] =~ %r{MSIE|Trident|Edge} ? ERB::Util.url_encode(name) : name
 | 
						||
	end
 | 
						||
 | 
						||
	def format_time(time)
 | 
						||
		time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M")
 | 
						||
	end
 | 
						||
 | 
						||
	# 获取Oauth Client
 | 
						||
	def get_client(site)
 | 
						||
		client_id = Rails.configuration.Gitlink['client_id']
 | 
						||
		client_secret = Rails.configuration.Gitlink['client_secret']
 | 
						||
 | 
						||
		OAuth2::Client.new(client_id, client_secret, site: site)
 | 
						||
	end
 | 
						||
 | 
						||
	def paginate(relation)
 | 
						||
		limit = params[:limit] || params[:per_page]
 | 
						||
		limit  = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
 | 
						||
		page   = params[:page].to_i.zero? ? 1 : params[:page].to_i
 | 
						||
		offset = (page - 1) * limit
 | 
						||
 | 
						||
		if relation.is_a?(Array)
 | 
						||
			relation[offset, limit]
 | 
						||
		else
 | 
						||
			relation.limit(limit).offset(offset)
 | 
						||
		end
 | 
						||
	end
 | 
						||
 | 
						||
	def kaminari_paginate(relation)
 | 
						||
		limit = params[:limit] || params[:per_page]
 | 
						||
		limit = (limit.to_i.zero? || limit.to_i > 50) ? 50 : limit.to_i
 | 
						||
		page  = params[:page].to_i.zero? ? 1 : params[:page].to_i
 | 
						||
 | 
						||
		relation.page(page).per(limit)
 | 
						||
	end
 | 
						||
 | 
						||
	def kaminari_array_paginate(relation)
 | 
						||
		limit = params[:limit] || params[:per_page]
 | 
						||
		limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
 | 
						||
		page  = params[:page].to_i.zero? ? 1 : params[:page].to_i
 | 
						||
 | 
						||
		Kaminari.paginate_array(relation).page(page).per(limit)
 | 
						||
	end
 | 
						||
 | 
						||
	def strf_time(time)
 | 
						||
		time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M:%S")
 | 
						||
	end
 | 
						||
 | 
						||
	def strf_date(date)
 | 
						||
		date.blank? ? '' : date.to_date.strftime("%Y-%m-%d")
 | 
						||
	end
 | 
						||
 | 
						||
	def logger_error(error)
 | 
						||
		Rails.logger.error(error.message)
 | 
						||
		error.backtrace.each { |msg| Rails.logger.error(msg) }
 | 
						||
	end
 | 
						||
 | 
						||
	def find_user
 | 
						||
		@user = User.find_by_login params[:login]
 | 
						||
    render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
 | 
						||
	end
 | 
						||
 | 
						||
	def find_user_with_id
 | 
						||
		@user = User.find_by_id params[:user_id]
 | 
						||
    # render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
 | 
						||
		render_error("未找到相关的用户") unless @user
 | 
						||
	end
 | 
						||
 | 
						||
	def find_repository
 | 
						||
		@repo = @user.repositories.find_by_identifier params[:repo_identifier]
 | 
						||
    render_not_found("未找到’#{params[:repo_identifier]}’相关的项目") unless @repo
 | 
						||
	end
 | 
						||
 | 
						||
	def find_repository_by_id
 | 
						||
		@repo = Repository.find params[:id]
 | 
						||
	end
 | 
						||
 | 
						||
	def find_project
 | 
						||
		project_id = params[:project_id] ? params[:project_id] : params[:id]
 | 
						||
		project = Project.where(identifier: project_id)
 | 
						||
		if project.exists?
 | 
						||
			@project = project.first
 | 
						||
		else
 | 
						||
			@project = Project.find project_id
 | 
						||
		end
 | 
						||
 | 
						||
		render_not_found("未找到’#{project}’相关的项目") unless @project
 | 
						||
	end
 | 
						||
 | 
						||
	def find_project_with_id
 | 
						||
		@project = Project.find(params[:project_id] || params[:id])
 | 
						||
	rescue Exception => e
 | 
						||
		logger_error(e.message)
 | 
						||
		tip_exception(e.message)
 | 
						||
	end
 | 
						||
 | 
						||
	def render_response(interactor)
 | 
						||
		interactor.success? ? render_ok : render_error(interactor.error)
 | 
						||
	end
 | 
						||
 | 
						||
	# projects
 | 
						||
	def load_project
 | 
						||
    namespace = params[:owner]
 | 
						||
    id = params[:repo] || params[:id]
 | 
						||
 | 
						||
    @project, @owner = Project.find_with_namespace(namespace, id)
 | 
						||
 | 
						||
    if @project and (current_user.can_read_project?(@project) || controller_path == "projects/project_invite_links")
 | 
						||
			logger.info "###########: has project and can read project"
 | 
						||
			@project
 | 
						||
    # elsif @project && current_user.is_a?(AnonymousUser)
 | 
						||
		# 	logger.info "###########:This is AnonymousUser"
 | 
						||
		# 	@project = nil if !@project.is_public?
 | 
						||
		# 	render_forbidden and return
 | 
						||
    else
 | 
						||
			if @project.present? 
 | 
						||
				logger.info "###########: has project and but can't read project"
 | 
						||
				@project = nil
 | 
						||
				render_forbidden and return
 | 
						||
			else 
 | 
						||
				logger.info "###########:project not found"
 | 
						||
				@project = nil
 | 
						||
				render_not_found and return
 | 
						||
			end
 | 
						||
    end
 | 
						||
    @project
 | 
						||
	end
 | 
						||
 | 
						||
	def load_repository
 | 
						||
		@repository ||= load_project&.repository
 | 
						||
	end
 | 
						||
 | 
						||
	def base_url
 | 
						||
		Rails.application.config_for(:configuration)['platform_url'] || request.base_url
 | 
						||
	end
 | 
						||
 | 
						||
	def image_type?(str)
 | 
						||
    default_type = %w(png jpg gif tif psd svg bmp webp jpeg ico psd)
 | 
						||
    default_type.include?(str&.downcase)
 | 
						||
  end
 | 
						||
 | 
						||
	def convert_image!
 | 
						||
		@image = params[:image] 
 | 
						||
		@image = @image.nil? && params[:user].present? ? params[:user][:image] : @image
 | 
						||
    return unless @image.present?
 | 
						||
    max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M
 | 
						||
    if @image.class == ActionDispatch::Http::UploadedFile
 | 
						||
      return render_error('请上传文件') if @image.size.zero?
 | 
						||
      return render_error('文件大小超过限制') if @image.size > max_size.to_i
 | 
						||
			return render_error('头像格式不正确!') unless image_type?(File.extname(@image.original_filename.to_s)[1..-1])
 | 
						||
    else
 | 
						||
      image = @image.to_s.strip
 | 
						||
      return render_error('请上传正确的图片') if image.blank?
 | 
						||
      @image = Util.convert_base64_image(image, max_size: max_size.to_i)
 | 
						||
    end
 | 
						||
  rescue Base64ImageConverter::Error => ex
 | 
						||
    render_error(ex.message)
 | 
						||
	end
 | 
						||
	
 | 
						||
  def avatar_path(object)
 | 
						||
    ApplicationController.helpers.disk_filename(object.class, object.id)
 | 
						||
  end
 | 
						||
 | 
						||
  private
 | 
						||
	def object_not_found
 | 
						||
		uid_logger("Missing template or cant't find record, responding with 404")
 | 
						||
		render json: {message: "您访问的页面不存在或已被删除", status: 404}
 | 
						||
		false
 | 
						||
	end
 | 
						||
 | 
						||
	def tip_show(exception)
 | 
						||
		uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
 | 
						||
		render json: exception.tip_json
 | 
						||
	end
 | 
						||
 | 
						||
	def set_export_cookies
 | 
						||
		cookies[:fileDownload] = true
 | 
						||
	end
 | 
						||
 | 
						||
	# 记录热门搜索关键字
 | 
						||
	def record_search_keyword
 | 
						||
		keyword = params[:keyword].to_s.strip
 | 
						||
		return if keyword.blank? || keyword.size <= 1
 | 
						||
		return unless HotSearchKeyword.available?
 | 
						||
 | 
						||
		HotSearchKeyword.add(keyword)
 | 
						||
	end
 | 
						||
 | 
						||
	# author: zxh
 | 
						||
	# blockchain相关项目活动调用函数
 | 
						||
	# return true: 表示上链操作成功; return false: 表示上链操作失败
 | 
						||
		def push_activity_2_blockchain(activity_type, model)
 | 
						||
		if activity_type == "issue_create"
 | 
						||
 | 
						||
			project_id = model['project_id']
 | 
						||
			project = Project.find(project_id)
 | 
						||
			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
 | 
						||
				# 无需执行上链操作
 | 
						||
				return true
 | 
						||
			end
 | 
						||
 | 
						||
			id = model['id']
 | 
						||
 | 
						||
			owner_id = project['user_id']
 | 
						||
			owner = User.find(owner_id)
 | 
						||
			ownername = owner['login']
 | 
						||
			identifier = project['identifier']
 | 
						||
 | 
						||
			author_id = project['user_id']
 | 
						||
			author = User.find(author_id)
 | 
						||
			username = author['login']
 | 
						||
 | 
						||
			action = 'opened'
 | 
						||
 | 
						||
			title = model['subject']
 | 
						||
			content = model['description']
 | 
						||
			created_at = model['created_on']
 | 
						||
			updated_at = model['updated_on']
 | 
						||
 | 
						||
			# 调用区块链接口
 | 
						||
			params = {
 | 
						||
				"request-type": "upload issue info",
 | 
						||
				"issue_id": "gitlink-" + id.to_s,
 | 
						||
				"repo_id": "gitlink-" + project_id.to_s,
 | 
						||
				"issue_number": 0, # 暂时不需要改字段
 | 
						||
				"reponame": identifier,
 | 
						||
				"ownername": ownername,
 | 
						||
				"username": username,
 | 
						||
				"action": action,
 | 
						||
				"title": title,
 | 
						||
				"content": content,
 | 
						||
				"created_at": created_at,
 | 
						||
				"updated_at": updated_at
 | 
						||
			}.to_json
 | 
						||
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
 | 
						||
			if resp_body['status'] == 10
 | 
						||
				raise ApplicationService::Error, resp_body['message']
 | 
						||
			elsif resp_body['status'] != 0
 | 
						||
				raise ApplicationService::Error, "区块链接口请求失败."
 | 
						||
			end
 | 
						||
 | 
						||
		elsif activity_type == "issue_comment_create"
 | 
						||
			issue_comment_id = model['id']
 | 
						||
			issue_id = model['journalized_id']
 | 
						||
			parent_id = model['parent_id'].nil? ? "" : model['parent_id']
 | 
						||
 | 
						||
			issue = Issue.find(issue_id)
 | 
						||
			issue_classify = issue['issue_classify'] # issue或pull_request
 | 
						||
			project_id = issue['project_id']
 | 
						||
			project = Project.find(project_id)
 | 
						||
 | 
						||
			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
 | 
						||
				# 无需执行上链操作
 | 
						||
				return
 | 
						||
			end
 | 
						||
 | 
						||
			identifier = project['identifier']
 | 
						||
			owner_id = project['user_id']
 | 
						||
			owner = User.find(owner_id)
 | 
						||
			ownername = owner['login']
 | 
						||
 | 
						||
			author_id = model['user_id']
 | 
						||
			author = User.find(author_id)
 | 
						||
			username = author['login']
 | 
						||
 | 
						||
			action = 'created'
 | 
						||
 | 
						||
			content = model['notes']
 | 
						||
			created_at = model['created_on']
 | 
						||
 | 
						||
			if issue_classify == "issue"
 | 
						||
				params = {
 | 
						||
					"request-type": "upload issue comment info",
 | 
						||
					"issue_comment_id": "gitlink-" + issue_comment_id.to_s,
 | 
						||
					"issue_comment_number": 0, # 暂时不需要
 | 
						||
					"issue_number": 0, # 暂时不需要
 | 
						||
					"issue_id": "gitlink-" + issue_id.to_s,
 | 
						||
					"repo_id": "gitlink-" + project.id.to_s,
 | 
						||
					"parent_id": parent_id.to_s,
 | 
						||
					"reponame": identifier,
 | 
						||
					"ownername": ownername,
 | 
						||
					"username": username,
 | 
						||
					"action": action,
 | 
						||
					"content": content,
 | 
						||
					"created_at": created_at,
 | 
						||
				}.to_json
 | 
						||
			elsif issue_classify == "pull_request"
 | 
						||
				params = {
 | 
						||
					"request-type": "upload pull request comment info",
 | 
						||
					"pull_request_comment_id": "gitlink-" + issue_comment_id.to_s,
 | 
						||
					"pull_request_comment_number": 0, # 不考虑该字段
 | 
						||
					"pull_request_number": 0, # 不考虑该字段
 | 
						||
					"pull_request_id": "gitlink-" + issue_id.to_s,
 | 
						||
					"parent_id": parent_id.to_s,
 | 
						||
					"repo_id": "gitlink-" + project.id.to_s,
 | 
						||
					"reponame": identifier,
 | 
						||
					"ownername": ownername,
 | 
						||
					"username": username,
 | 
						||
					"action": action,
 | 
						||
					"content": content,
 | 
						||
					"created_at": created_at,
 | 
						||
				}.to_json
 | 
						||
			end
 | 
						||
 | 
						||
			# 调用区块链接口
 | 
						||
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
 | 
						||
			if resp_body['status'] == 10
 | 
						||
				raise ApplicationService::Error, resp_body['message']
 | 
						||
			elsif resp_body['status'] != 0
 | 
						||
				raise ApplicationService::Error, "区块链接口请求失败."
 | 
						||
			end
 | 
						||
		elsif activity_type == "pull_request_create"
 | 
						||
			# 调用区块链接口
 | 
						||
			project_id = model['project_id']
 | 
						||
			project = Project.find(project_id)
 | 
						||
			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
 | 
						||
				# 无需执行上链操作
 | 
						||
				return
 | 
						||
			end
 | 
						||
 | 
						||
			pull_request_id = model['id']
 | 
						||
			identifier = project['identifier']
 | 
						||
			owner_id = project['user_id']
 | 
						||
			owner = User.find(owner_id)
 | 
						||
			ownername = owner['login']
 | 
						||
 | 
						||
			action = 'opened'
 | 
						||
 | 
						||
			title = model['title']
 | 
						||
			content = model['body']
 | 
						||
 | 
						||
			source_branch = model['head']
 | 
						||
			source_repo_id = model['fork_project_id'].nil? ? project_id : model['fork_project_id']
 | 
						||
 | 
						||
			target_branch = model['base']
 | 
						||
			target_repo_id = project_id
 | 
						||
 | 
						||
			author_id = model['user_id']
 | 
						||
			author = User.find(author_id)
 | 
						||
			username = author['login']
 | 
						||
 | 
						||
			created_at = model['created_at']
 | 
						||
			updated_at = model['updated_at']
 | 
						||
 | 
						||
			# 查询pull request对应的commit信息
 | 
						||
			commits = Gitea::PullRequest::CommitsService.call(ownername, identifier, model['gitea_number'], current_user&.gitea_token)
 | 
						||
			if commits.nil?
 | 
						||
				raise ApplicationService::Error, "区块链接口请求失败" # 获取pr中变更的commit信息失败
 | 
						||
			end
 | 
						||
			commit_shas = []
 | 
						||
			commits.each do |c|
 | 
						||
				commit_shas << c["Sha"]
 | 
						||
			end
 | 
						||
			params = {
 | 
						||
				"request-type": "upload pull request info",
 | 
						||
				"pull_request_id": "gitlink-" + pull_request_id.to_s,
 | 
						||
				"pull_request_number": 0, # trustie没有该字段
 | 
						||
				"repo_id": "gitlink-" + project_id.to_s,
 | 
						||
				"ownername": ownername,
 | 
						||
				"reponame": identifier,
 | 
						||
				"username": username,
 | 
						||
				"action": action,
 | 
						||
				"title": title,
 | 
						||
				"content": content,
 | 
						||
				"source_branch": source_branch,
 | 
						||
				"target_branch": target_branch,
 | 
						||
				"reviewers": [], # trustie没有该字段
 | 
						||
				"commit_shas": commit_shas,
 | 
						||
				"merge_user": "", # trustie没有该字段
 | 
						||
				"created_at": created_at,
 | 
						||
				"updated_at": updated_at
 | 
						||
			}.to_json
 | 
						||
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
 | 
						||
			if resp_body['status'] == 9
 | 
						||
				raise ApplicationService::Error, resp_body['message']
 | 
						||
			elsif resp_body['status'] != 0
 | 
						||
				raise ApplicationService::Error, "区块链接口请求失败."
 | 
						||
			end
 | 
						||
		elsif activity_type == "pull_request_merge"
 | 
						||
			# 调用区块链接口
 | 
						||
			project_id = model['project_id']
 | 
						||
			project = Project.find(project_id)
 | 
						||
			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
 | 
						||
				# 无需执行上链操作
 | 
						||
				return
 | 
						||
			end
 | 
						||
 | 
						||
			pull_request_id = model['id']
 | 
						||
			identifier = project['identifier']
 | 
						||
			owner_id = project['user_id']
 | 
						||
			owner = User.find(owner_id)
 | 
						||
			ownername = owner['login']
 | 
						||
 | 
						||
			action = 'merged'
 | 
						||
 | 
						||
			created_at = model['created_at']
 | 
						||
			updated_at = model['updated_at']
 | 
						||
 | 
						||
			# 查询pull request对应的commit信息
 | 
						||
			commits = Gitea::PullRequest::CommitsService.call(ownername, identifier, model['gitea_number'], current_user&.gitea_token)
 | 
						||
			if commits.nil?
 | 
						||
				raise ApplicationService::Error, "区块链接口请求失败" # 获取pr中变更的commit信息失败
 | 
						||
			end
 | 
						||
			commit_shas = []
 | 
						||
			commits.each do |c|
 | 
						||
				commit_shas << c["Sha"]
 | 
						||
			end
 | 
						||
 | 
						||
			# 将pull request相关信息写入链上
 | 
						||
			params = {
 | 
						||
				"request-type": "upload pull request info",
 | 
						||
				"pull_request_id": "gitlink-" + pull_request_id.to_s,
 | 
						||
				"pull_request_number": 0, # trustie没有该字段
 | 
						||
				"repo_id": "gitlink-" + project_id.to_s,
 | 
						||
				"ownername": ownername,
 | 
						||
				"reponame": identifier,
 | 
						||
				"username": username,
 | 
						||
				"action": action,
 | 
						||
				"title": title,
 | 
						||
				"content": content,
 | 
						||
				"source_branch": source_branch,
 | 
						||
				"target_branch": target_branch,
 | 
						||
				"reviewers": [], # trustie没有该字段
 | 
						||
				"commit_shas": commit_shas,
 | 
						||
				"merge_user": "", # trustie没有该字段
 | 
						||
				"created_at": created_at,
 | 
						||
				"updated_at": updated_at
 | 
						||
			}.to_json
 | 
						||
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
 | 
						||
			if resp_body['status'] == 9
 | 
						||
				raise ApplicationService::Error, resp_body['message']
 | 
						||
			elsif resp_body['status'] != 0
 | 
						||
				raise ApplicationService::Error, "区块链接口请求失败."
 | 
						||
			end
 | 
						||
 | 
						||
 | 
						||
			# 将commit相关信息写入链上
 | 
						||
			commit_shas.each do |commit_sha|
 | 
						||
				commit_diff = Gitea::Commit::DiffService.call(ownername, identifier, commit_sha, owner['gitea_token'])
 | 
						||
				commit = Gitea::Commit::InfoService.call(ownername, identifier, commit_sha, owner['gitea_token'])
 | 
						||
				params = {
 | 
						||
					"request-type": "upload commit info",
 | 
						||
					"commit_hash": commit_sha,
 | 
						||
					"repo_id": "gitlink-" + project_id.to_s,
 | 
						||
					"author": commit['commit']['author']['name'],
 | 
						||
					"author_email": commit['commit']['author']['email'],
 | 
						||
					"committer": commit['commit']['committer']['name'],
 | 
						||
					"committer_email": commit['commit']['committer']['email'],
 | 
						||
					"author_time": commit['commit']['author']['date'],
 | 
						||
					"committer_time": commit['commit']['committer']['date'],
 | 
						||
					"content": commit['commit']['message'],
 | 
						||
					"commit_diff": commit_diff['Files'].to_s
 | 
						||
				}.to_json
 | 
						||
				resp_body = Blockchain::InvokeBlockchainApi.call(params)
 | 
						||
				if resp_body['status'] == 7
 | 
						||
					raise ApplicationService::Error, resp_body['message']
 | 
						||
				elsif resp_body['status'] != 0
 | 
						||
					raise ApplicationService::Error, "区块链接口请求失败."
 | 
						||
				end
 | 
						||
			end
 | 
						||
 | 
						||
		elsif activity_type == "pull_request_refuse"
 | 
						||
 | 
						||
			# 调用区块链接口
 | 
						||
			project_id = model['project_id']
 | 
						||
			project = Project.find(project_id)
 | 
						||
			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
 | 
						||
				# 无需执行上链操作
 | 
						||
				return true
 | 
						||
			end
 | 
						||
 | 
						||
			pull_request_id = model['id']
 | 
						||
			identifier = project['identifier']
 | 
						||
			owner_id = project['user_id']
 | 
						||
			owner = User.find(owner_id)
 | 
						||
			ownername = owner['login']
 | 
						||
 | 
						||
			action = 'refused'
 | 
						||
 | 
						||
			# 将pull request相关信息写入链上
 | 
						||
			params = {
 | 
						||
				"request-type": "upload pull request info",
 | 
						||
				"pull_request_id": "gitlink-" + pull_request_id.to_s,
 | 
						||
				"pull_request_number": 0, # trustie没有该字段
 | 
						||
				"repo_id": "gitlink-" + project_id.to_s,
 | 
						||
				"ownername": ownername,
 | 
						||
				"reponame": identifier,
 | 
						||
				"username": username,
 | 
						||
				"action": action,
 | 
						||
				"title": title,
 | 
						||
				"content": content,
 | 
						||
				"source_branch": source_branch,
 | 
						||
				"target_branch": target_branch,
 | 
						||
				"reviewers": [], # trustie没有该字段
 | 
						||
				"commit_shas": commit_shas,
 | 
						||
				"merge_user": "", # trustie没有该字段
 | 
						||
				"created_at": created_at,
 | 
						||
				"updated_at": updated_at
 | 
						||
			}.to_json
 | 
						||
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
 | 
						||
			if resp_body['status'] == 9
 | 
						||
				raise ApplicationService::Error, resp_body['message']
 | 
						||
			elsif resp_body['status'] != 0
 | 
						||
				raise ApplicationService::Error, "区块链接口请求失败."
 | 
						||
			end
 | 
						||
		end
 | 
						||
	end
 | 
						||
  def find_atme_receivers
 | 
						||
    @atme_receivers = User.where(login: params[:receivers_login])
 | 
						||
  end
 | 
						||
 | 
						||
end
 |