You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pgfqe6ch8/app/helpers/application_helper.rb

7469 lines
294 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# encoding: utf-8
#
# Redmine - project management software
# Copyright (C) 2006-2013 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'forwardable'
require 'cgi'
require 'iconv'
module ApplicationHelper
include Redmine::WikiFormatting::Macros::Definitions
include Redmine::I18n
include GravatarHelper::PublicMethods
include Redmine::Pagination::Helper
include AvatarHelper
## added by william
include PraiseTreadHelper
include CoursesHelper
extend Forwardable
def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
# 课堂相关controller
def course_controller
["courses", "homework_common", "student_work", "exercise", "poll", "boards", "messages", "graduation_topics", "graduation_tasks",
"graduation_works", "files"]
end
# 实训课程相关controller
def subjects_controller
["subjects", "stages"]
end
# 实训路径相关controller
def shixuns_controller
["shixuns", "challenges", "myshixuns", "games"]
end
# 工程认证相关controller
def ecs_controller
["ecs", "ec_courses", "ec_course_evaluations", "ec_course_supports", "ec_course_targets", "ec_graduation_requirements",
"ec_major_schools", "ec_majors", "ec_years"]
end
def exercise_bank_json_data exercises
exercises.map do |exercise|
exercise_path = exercise_bank_path(exercise)
course_list = exercise.course_list.name
user_name = exercise.user.show_real_name
user_path = user_path(exercise.user)
exercise.attributes.dup.except("description", "is_public", "quotes", "container_id", "container_type", "created_at", "updated_at").merge({
user_name: user_name,
user_path: user_path,
course_list: course_list,
exercise_path: exercise_path
})
end
end
def ac_pass?(standard_value, real_value)
standard_value && real_value && real_value >= standard_value ? "达成" : "未达成"
end
def ec_pass?(standard_value, real_value)
standard_value && real_value && real_value >= standard_value ? 1 : 0
end
# 工程认证删除关联课堂
def delete_course_correlation_ec_course_evaluations ec_course
ec_course_evaluations = ec_course.ec_course_evaluations.where(:is_course_type => true)
ec_course_evaluations.destroy_all if ec_course_evaluations
end
def sync_ec_year_student_score ec_subitem, ce, year_students, students, works, position=1
year_students.each do |year_student|
if students.map(&:id).include?(year_student.id)
work = works.where(:user_id => students.select{|s| s.id == year_student.id}[0].try(:user_id)).first
score = work.respond_to?(:work_score) ? work.try(:work_score) : work.try(:score)
else
score = 0
end
ec_subitem.ec_student_achievements << EcStudentAchievement.new(:ec_year_student_id => year_student.id, :student_number => year_student.student_id,
:student_name => year_student.name, :score => score.to_f,
:position => position, :ec_course_evaluation_id => ce.id)
Rails.logger.info("############work_score:#{score}")
end
end
# 同步在线课堂的考核标准和考核分项
# ec_course: 工程认证的课程
# course 关联的在线课堂
def sync_course_correlation_ec_course_evaluations ec_course, course
# 先删除之前的关联数据
delete_course_correlation_ec_course_evaluations ec_course
students = EcYearStudent.find_by_sql("SELECT eys.id, eys.student_id, eys.name, uxe.user_id FROM ec_year_students eys JOIN
(SELECT ue.student_id, ue.user_id FROM user_extensions ue JOIN students_for_courses sfc ON ue.`user_id` = sfc.`student_id`
WHERE sfc.`course_id` = #{course.id})uxe ON eys.student_id = uxe.student_id WHERE eys.ec_year_id = #{ec_course.ec_year_id}")
year_students = ec_course.ec_year.ec_year_students
# 实训作业模块
shixun_models = course.homework_commons.where("homework_type = 4 and publish_time < '#{Time.now}'")
unless shixun_models.blank?
ce = EcCourseEvaluation.create(:name => "实训作业", :evluation_count => 1, :status => 2, :ec_course_id => ec_course.id, :is_course_type => true)
shixun_models.each do |shixun|
ec_subitem = EcCourseEvaluationSubitem.create(:name => shixun.name, :ec_course_evaluation_id => ce.id)
sync_ec_year_student_score ec_subitem, ce, year_students, students, shixun.student_works
end
end
# 普通作业模块
common_models = course.homework_commons.where("homework_type = 1 and publish_time < '#{Time.now}'")
unless common_models.blank?
ce = EcCourseEvaluation.create(:name => "普通作业", :evluation_count => 1, :status => 2, :ec_course_id => ec_course.id, :is_course_type => true)
common_models.each do |common|
ec_subitem = EcCourseEvaluationSubitem.create(:name => common.name, :ec_course_evaluation_id => ce.id)
sync_ec_year_student_score ec_subitem, ce, year_students, students, common.student_works
end
end
# 分组作业模块
group_models = course.homework_commons.where("homework_type = 3 and publish_time < '#{Time.now}'")
unless group_models.blank?
ce = EcCourseEvaluation.create(:name => "分组作业", :evluation_count => 1, :status => 2, :ec_course_id => ec_course.id, :is_course_type => true)
group_models.each do |group|
ec_subitem = EcCourseEvaluationSubitem.create(:name => group.name, :ec_course_evaluation_id => ce.id)
sync_ec_year_student_score ec_subitem, ce, year_students, students, group.student_works
end
end
# 试卷模块
exercise_models = course.exercises.where("exercise_status > 1")
unless exercise_models.blank?
ce = EcCourseEvaluation.create(:name => "试卷", :evluation_count => 1, :status => 2, :ec_course_id => ec_course.id, :is_course_type => true)
exercise_models.each do |exercise|
ec_subitem = EcCourseEvaluationSubitem.create(:name => exercise.exercise_name, :ec_course_evaluation_id => ce.id)
sync_ec_year_student_score ec_subitem, ce, year_students, students, exercise.exercise_users
end
end
# 毕设任务模块
task_models = course.graduation_tasks.where("publish_time < '#{Time.now}'")
unless task_models.blank?
ce = EcCourseEvaluation.create(:name => "毕设任务", :evluation_count => task_models.size, :status => 1, :ec_course_id => ec_course.id, :is_course_type => true)
task_models.each_with_index do |task, index|
ec_subitem = EcCourseEvaluationSubitem.create(:name => task.name, :ec_course_evaluation_id => ce.id)
sync_ec_year_student_score ec_subitem, ce, year_students, students, task.graduation_works, index + 1
end
end
end
# 选用实训的学校情况
def school_user_detail shixun
user_ids = shixun.myshixuns.pluck(:user_id)
schools = School.where(:id => UserExtensions.where(:user_id => user_ids).pluck(:school_id))
school_size = schools.size
str = school_size > 0 ? "#{schools.limit(2).map(&:name).join("")}#{school_size}" : "0所"
end
def shixun_json_data shixuns
shixuns.map do |shixun|
school_detail = school_user_detail shixun
preference = shixun.shixun_preference
shixun_path = shixun_path(shixun)
shixun.attributes.dup.merge({
school_detail: school_detail,
preference: preference,
shixun_path: shixun_path
})
end
end
# 分班
def member_group_name members, user_id
member = members.find_by_user_id(user_id)
group_name = member.try(:course_group_id).to_i == 0 ? '未分班' : member.course_group.name
end
# 分班
def new_member_group_name course_id, user_id
group_id = Member.where(:course_id => course_id, :user_id => user_id).pluck(:course_group_id).first
group_id == 0 ? '未分班' : CourseGroup.where(:id => group_id).pluck(:name).first
end
# 分班id
def member_group_id members, user_id
member = members.where(:user_id => user_id).first
group_id = member.try(:course_group_id).to_i
end
# 推荐实训
def recommend_shixun shixun
shixun_id = ShixunTagRepertoire.where("tag_repertoire_id = #{shixun.tag_repertoires.first.present? ? shixun.tag_repertoires.first.try(:id) : 0} and shixun_id != #{shixun.id}").map(&:shixun_id)
shixuns = Shixun.select([:id, :name, :user_id, :status, :myshixuns_count, :trainee, :identifier]).where(:id => shixun_id, :status => 2, :hidden => 0).order("myshixuns_count desc").limit(3)
if shixuns.size < 3
ids = shixuns.size == 0 ? "(-1)" : "(" + shixuns.map(&:id).join(',') + ")"
hot_shixuns = Shixun.select([:id, :name, :user_id, :status, :myshixuns_count, :trainee, :identifier]).where("status = 2 and hidden = 0 and id not in #{ids}").order("myshixuns_count desc").limit(3-shixuns.size)
return shixuns + hot_shixuns
else
return shixuns
end
end
# 用户获取的技能标签
def user_get_tags challenge_ids, user=User.current
tags = ChallengeTag.where(:challenge_id => user.games.where(:challenge_id => challenge_ids, :status => 2).pluck(:challenge_id)).pluck(:name).uniq
return tags
end
# 所属路径
def belongto_path shixun
Subject.where(:id => shixun.stage_shixuns.map(&:subject_id), :hidden => 0).limit(2)
end
# 已授权老师加入示例课堂
def join_ex_course user
course = Course.where(:id => 1309).first
if course
if course.members.where(:user_id => user.id).empty?
member = Member.new(:role_ids => [9], :user_id => user.id)
course.members << member
Tiding.create(:user_id => user.id, :trigger_user_id => 1, :container_id => course.id, :container_type => 'TeacherJoinCourse', :belong_container_id => course.id, :belong_container_type => "Course", :tiding_type => "System", :extra => "9")
end
end
end
# 成员身份
def member_zh_role member
role = ""
if member.roles.first
case member.roles.first.id
when 3
role = "管理人员"
when 4
role = "开发人员"
when 5
role = "报告人员"
end
end
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
return container.to_json
end
def shixun_container_limit shixun
container = []
shixun.shixun_service_configs.each do |config|
mirror = config.mirror_repository
if mirror.name.present?
container << {:image => mirror.name,
:cpuLimit => config.cpu_limit,
:cpuRequest => config.lower_cpu_limit,
:memoryLimit => "#{config.memory_limit}M",
:memoryRequest => "#{config.request_limit}",
:resourceLimit => "#{config.resource_limit}K",
:type => mirror.try(:main_type) == "1" ? "main" : "sub"}
end
end
Rails.logger.info("#########container: #{container.to_json}")
return container.to_json
end
# 实训作品列表的提交状态
def list_work_status work, homework, course_group_id
if work.work_status == 0
str = "未提交"
else
if work.compelete_status == 0
setting_time = homework_group_setting homework, course_group_id
end_time = setting_time.end_time.present? ? setting_time.end_time : homework.end_time
if end_time > Time.now || (homework.allow_late && !homework.course.is_end)
str = "正在提交"
else
str = "延时提交"
end
else
if work.work_status == 1
str = "按时提交"
else
str = "延时提交"
end
end
end
str
end
# 试卷、问卷提交状态
def ex_poll_work_status status
str = ""
case status
when 0
str = "未提交"
when 1
str = "<span class='color-green'>按时提交</span>"
when 2
str = "<span class='color-red'>延时提交</span>"
end
str
end
#传入分数,获取对应颜色
def score_color score
if score
color = score >= 90 ? "color-red" : "color-green"
else
color = "color-grey"
end
color
end
# 获取两断时间的日期差
def time_between_days t1, t2
Date.parse(t1.to_s) - Date.parse(t2.to_s) if t1.present? && t2.present?
end
def update_valuate_time game_id, column
record = EvaluateRecord.where(:game_id => game_id).first
if record
consume_time = format("%.2f", (Time.now.to_f - record.created_at.to_f)).to_f
if column == "file_update"
record.update_attributes!(:file_update => consume_time)
elsif column == "pull"
record.update_attributes!(:consume_time => consume_time)
elsif column == "create_pod"
record.update_attributes!(:create_pod => consume_time)
elsif column == "pod_execute"
record.update_attributes!(:pod_execute => consume_time)
end
end
end
# TPM查看权限
# result一般为页面权限
def shixun_view_allow shixun, result = nil
if User.current.manager_of_shixun?(shixun)
result ? false : true
else
if shixun.status == 0 || (shixun.use_scope == 1 && !shixun.schools.map(&:name).include?(User.current.school_name))
result ? true : (render_403)
end
end
end
# 判断TPM的代码是否被修改了
# 判断依据是看tpm的最新提交记录和tpi数据库中存储的commit_id是否一致
def repository_is_modified myshixun, shixun_gpid
g = Gitlab.client
myshixun_commit_id = myshixun.commit_id
if myshixun_commit_id.blank?
myshixun_commit_id = g.commits(myshixun.gpid).last.try(:id)
myshixun.update_column(:commit_id, myshixun_commit_id)
end
shixun_commit_id = g.commits(shixun_gpid).first.try(:id)
Rails.logger.warn("###############shixun_commit_id is #{shixun_commit_id}")
Rails.logger.warn("###############myshixun_commit_id is #{myshixun.commit_id}")
result = myshixun_commit_id != shixun_commit_id ? true :false
return result
end
# 定义当前关卡是否有权开启下一关
# :实训若发布了,必须通过当前关卡才能查看下一关
# :未发布的实训,除了最后一关,其它的关卡都可以进入下一关
def show_next_stage?(game, shixun_status)
if game.is_final_game? || ([2,3].include?(shixun_status.to_i) && game.try(:status) != 2)
false
else
true
end
end
# 适用与已经用url_safe编码后回调字符串形式
def tran_base64_decode64 str
if str.blank?
str
else
s_size = str.size % 4
if s_size != 0
str += "=" * (4 - s_size)
end
Base64.decode64(str.tr("-_", "+/")).force_encoding("utf-8")
end
end
def challenge_path path
cha_path = path.present? ? path.split("") : []
cha_path = cha_path.reject(&:blank?)[0].try(:strip)
cha_path
end
def open_webssh
# 如果我webssh类型, 开启webssh
jenkins_shixuns = Redmine::Configuration['jenkins_shixuns']
uri = URI("#{jenkins_shixuns}/jenkins-exec/webssh/getConnectInfo")
user_id = User.current.id
params = {userID:user_id}
res = uri_exec uri, params
return [host, port, username, password]
end
# 中间层启动那种语言容器的类型
# language 语言 exec_path 需要编译的文件路径
def post_tomcat_language language, exec_path
if language == "Html" && !exec_path.blank?
case exec_path.split(".")[1].downcase
when "c"
"C"
when "cpp"
'C++'
when "py"
'Python2.7'
else
"Java"
end
elsif exec_path.blank?
"Java"
else
language
end
end
def only_publish_game shixun, type
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
gameInfo = shixun.gameInfo
uri ="#{shixun_tomcat}/bridge/game/publishGame"
params = {:gameInfo => "#{gameInfo}"}
logger.info("%%%%%%%%%%%%params is #{params}")
res = uri_exec uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级90")
end
end
def publish_game_and_tpimodify myshixun, type
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
git_myshixun_url = gitlab_url myshixun
git_myshixun_url = Base64.urlsafe_encode64(git_myshixun_url)
params = {tpiID: "#{myshixun.try(:id)}", :tpiGitURL => "#{git_myshixun_url}", :tpmID => "#{myshixun.shixun.try(:id)}"}
uri ="#{shixun_tomcat}/bridge/game/resetTpiScript"
params = {:gameInfo => "#{gameInfo}"}
logger.info("%%%%%%%%%%%%params is #{params}")
res = uri_exec uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级98")
end
end
## 若实训关卡位置,关卡数等信息发生变化则需要修改脚本内容
def modify_shixun_script shixun, script
if script.present?
source_class_name = []
challenge_program_name = []
shixun.challenges.map(&:exec_path).each do |exec_path|
challenge_program_name << "\"#{exec_path}\""
if shixun.mirror_name.try(:first) == "Java"
if exec_path.nil? || exec_path.split("src/")[1].nil?
source = "\"\""
else
source = "\"#{exec_path.split("src/")[1].split(".java")[0]}\""
end
source_class_name << source.gsub("/", ".") if source.present?
elsif shixun.mirror_name.try(:first) == "C#"
if exec_path.nil? || exec_path.split(".")[1].nil?
source = "\"\""
else
source = "\"#{exec_path.split(".")[0]}.exe\""
end
source_class_name << source if source.present?
end
end
script = if script.include?("sourceClassName") && script.include?("challengeProgramName")
script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{source_class_name.reject(&:blank?).join(" ")}\)")
else
script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)")
end
end
return script
#shixun.update_column(:evaluate_script, script)
end
# 若实训有更改,则修改已发不实训的标记为已更改
# shixun_modifies表中1表示已更改进入myshixun需要强制重置0表示没有修改
# type 0:表示已经是最新的了1表示已经有修改
# res返回结果0表示正确-1表示有异常
def add_shixun_modify_status shixun, type
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
gameInfo = shixun.gameInfo
uri ="#{shixun_tomcat}/bridge/game/publishGame"
params = {:gameInfo => "#{gameInfo}"}
logger.info("%%%%%%%%%%%%params is #{params}")
res = uri_exec uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级90")
end
end
# 判断实训的路径、language是否更改如果修改在TPI中需要重置脚本
# 目前为止container为challenge和game类型
# 改工作必须在challenge或者game保存后执行
# type 1表示既需要提示又需要更新脚本的0表示仅仅需要提示
def should_modify_myshixun_script shixun, type
if type == 1
shixun.update_column(:reset_time, shixun.try(:updated_at))
else
shixun.update_column(:modify_time, shixun.try(:updated_at))
end
end
def shixun_modify_status_publish shixun, type
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
# 更新测试集
gameInfo = shixun.gameInfo
uri ="#{shixun_tomcat}/bridge/game/publishGame"
# 更新脚本
tpiList =[]
myshixuns = shixun.myshixuns
if myshixuns.present?
myshixuns.each do |myshixun|
logger.info("tpiID is #{myshixun.id}")
tpiID = myshixun.id
instanceGitURL = gitlab_url myshixun
logger.info("instanceGitURL is #{instanceGitURL}")
tpiList << {:tpiID => tpiID, :instanceGitURL => instanceGitURL}
logger.info("###############{tpiList.to_json unless tpiList.blank?}")
end
end
tpiList = Base64.urlsafe_encode64(tpiList.to_json) unless tpiList.blank?
params = {:gameInfo => "#{gameInfo}", :tpiList => "#{tpiList}" }
logger.info("%%%%%%%%%%%%params is #{params}")
# end
res = uri_exec uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级90")
end
end
# 仅仅产生记录用于已执行publish的方法
# ShixunModify中status 1表示有更改开启实训的时候需要重置0表示不需要重置或已重置完成
def shixun_modify_status_without_publish shixun, type
myshixuns = shixun.myshixuns
unless myshixuns.blank?
myshixuns.each do |myshixun|
shixun_modify = ShixunModify.where(:shixun_id => shixun.id, :myshixun_id => myshixun.id).first
if shixun_modify.nil?
ShixunModify.create!(:shixun_id => shixun.id, :myshixun_id => myshixun.id, :status => type)
else
shixun_modify.update_attributes!(:status => type)
end
end
end
end
# 通关后,把最后一次成功的代码存到数据库
# type 0 创始内容, 1 最新内容
def game_passed_code game_id, path, myshixun_gpid, type
g = Gitlab.client
rev = rev.nil? ? "master" : rev
path = path.strip if path.present?
file_content = g.files(myshixun_gpid, path, rev).content
if file_content.blank?
# gitlab缺陷forked完成短暂时间内取不了内容的所以做一个小轮询间隔0.1秒
# 超过2秒则失败需通过页面刷新
for i in 0..30 do
sleep(0.1)
file_content = g.files(myshixun_gpid, path, rev).content
unless file_content.blank?
break
end
end
end
unless file_content.present?
raise("获取文件代码异常")
end
file_content = tran_base64_decode64(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
def game_code_init game_id, path
game_code = GameCode.where(:game_id => game_id, :path => path).first
GameCode.create(:game_id => game_id, :path => path) if game_code.blank?
end
# 判断用户是否认证
def check_authentication
# return true
# if params[:action] == "on_search" || params[:action] == "apply_trail" # 之所以这样处理是为了避开account页面ajax加载
# return true
# end
Rails.logger.info("check_authentication start")
unless User.current.logged?
url = request.original_url
redirect_to signin_path(:back_url => url)
return
end
=begin
if User.current.created_on.strftime('%Y-%m-%d %H:%M:%S') > "2018-01-01 00:00:00" && User.current.phone.blank?
redirect_to change_or_bind_path(:type => "phone")
return
end
=end
user_e = UserExtensions.where(:user_id => User.current.id).first
if User.current.lastname.blank? || user_e.school_id.blank? || user_e.identity.blank? || User.current.mail.blank?
redirect_to my_account_path
Rails.logger.info("check_authentication end")
elsif User.current.certification != 1 # 系统没有授权
day_cer = UserDayCertification.where(:user_id => User.current.id).last
unless (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400
redirect_to my_account_path
Rails.logger.info("check_authentication end")
return
end
end
end
def match_specific_symbol(str)
str.gsub(" ", "<span class=\"empty\" style = \"background:#8d8787;\"></span>").gsub(/\r\n$/, "<i class=\"fa fa-level-down font-16\" style = \"color:#8d8787;\" aria-hidden=\"true\"></i>").gsub("\r\n", "<br>").gsub(/\t/, "<span class=\"tab-key\" style = \"background:#8d8787;\"><i class=\"fa fa-long-arrow-right color-grey3\" aria-hidden=\"true\"></i></span>").html_safe
end
# textarea 以/r/n开头时回车效果会被替换因此先把\r转换成\r 再添加一个\r直接添加\r不行
def match_specific_symbol1(str)
str.gsub(/\A\r/, "\r\r")
end
# 积分表中建立记录行为,有过奖励则不重复奖励
def reward_grade(user, container_id, container_type, score)
grade = Grade.where(:user_id => user.id, :container_id => container_id, :container_type => container_type).first
if grade.nil?
Grade.create!(:user_id => user.id, :container_id => container_id, :container_type => container_type, :score => score)
user.update_column(:grade, (score.to_i + user.grade.to_i))
end
end
def reward_experience(user, container_id, container_type, score)
experience = Experience.where(:user_id => user.id, :container_id => container_id, :container_type => container_type).first
if experience.nil?
Experience.create!(:user_id => user.id, :container_id => container_id, :container_type => container_type, :score => score)
user.update_column(:experience, (score.to_i + user.experience.to_i))
end
end
def shixun_name game_id
game = Game.where(:id => game_id).first
game.nil? ? "---" : game.challenge.shixun.name
end
def grade_shixun_name shixun_id
shixun = Shixun.where(:id => shixun_id).first
shixun.nil? ? "---" : shixun.name
end
def game_position game_id
game = Game.where(:id => game_id).first
game.nil? ? "---" : game.challenge.position
end
def managements_navigation_bar_show menu_type, sub_type, grandchild_type={}
case menu_type
when 1
case sub_type
when 1 then "统计总表"
when 2 then "数据变化报表"
end
when 2
sub_type == 1 ? "课程列表" : (sub_type == 2? "课堂列表" : (sub_type == 3? "实训作业" : "项目列表"))
when 3
case sub_type
when 1
"实训列表"
when 2
"实训配置列表"
when 3
"已发布的实训"
when 4
"已关闭的实训"
when 5
"镜像管理"
when 6
"学员实训列表"
when 7
"镜像类别图片"
when 8
"TPI实训列表"
when 9
"TPI性能测试结果"
end
when 4
case sub_type
when 1
"实训课程列表"
when 2
"实训课程配置"
when 3
"已发布实训课程"
end
when 5
case sub_type
when 1
"竞赛列表"
end
when 6
if sub_type == 1
link_to('单位列表', departments_part_managements_path()) + "#{grandchild_type[:next_type] == 1 ? " > #{grandchild_type[:school].name}" : ""}"
elsif sub_type == 3
"合作伙伴"
else
"单位部门列表"
end
when 7
sub_type == 1 ? "用户列表" : (sub_type == 2 ? "试用授权列表" : "自动授权列表")
when 8
sub_type == 1 ? "作业回复" :
(sub_type == 2 ? "实训反馈" :
(sub_type == 3 ? "讨论区" : "课堂讨论区")
)
when 9
sub_type == 1 ? "实训留言列表" : ""
when 10
sub_type == 1 ? "实名认证" :
(sub_type == 2 ? "试用授权" :
(sub_type == 3 ? "部门审批" :
(sub_type == 4 ? "单位审批" :
(sub_type == 5 ? "实训发布" :
(sub_type == 6 ? "实训课程发布" : "职业认证")
)
)
)
)
when 11
"工程认证+"
when 12
sub_type == 1 ? "过关任务模板" :
(sub_type == 2 ? "实训简介模板" :
(sub_type == 3 ? "背景知识模板" :
(sub_type == 4 ? "通用评测模板" :
(sub_type == 5 ? "新课导语模板" :
(sub_type == 6 ? "实训评分设置" :
(sub_type == 7 ? "技术体系" : "升级通知")
)
)
)
)
)
end
end
# codeMirror语言转换
def language_switch language
case language
when "Java"
"text/x-java"
when "C"
"text/x-csrc"
when "C++"
"text/x-c++src"
when "Python"
"text/x-python"
when "Ruby"
"text/x-ruby"
end
end
# 实训语言的种类
def shixun_language
["Java", "C", "C++", "Python2.7", "Python3.6", "MySQL/Java", "Html", "JFinal", "Docker", "Ethereum", "Dynamips", "MachineLearning",
"Verilog","Spark","MySQL/Python3.6","PHP","PHP/Web","Hadoop", "Golang","Android","Matlab","Shell", "Git", 'Perl6', 'Kotlin', 'Elixir', 'JavaScript', 'Ruby']
end
# 实训试用专业
def shixun_major_option
content = []
content << ["选择实训适用的专业", 0]
content << ["计算机科学与技术", 635]
content << ["软件工程", 636]
content << ["网络工程", 637]
content << ["信息安全", 638]
content << ["物联网工程", 639]
content << ["信息工程", 622]
content << ["通信工程", 619]
end
# 实训面向学员
def shixun_trainee
content = []
content << ["初级学员", 1]
content << ["中级学员", 2]
content << ["高级学员", 3]
content << ["顶级学员", 4]
end
# 班级设置排序中文
def switch_to_chinese word
case word
when "boards"
result = "讨论区"
when "news"
result = "通知"
when "homework"
result = "作业"
when "exercises"
result = "试卷"
when "poll"
result = "问卷"
when "statistics"
result = "统计"
when "attachment"
result ="资源"
end
return result
end
def allow_to_view_challenge challenge, shixun
# 判断对应关卡的game是否开启如果开启则允许查看
game_count = Game.where(:challenge_id => challenge, :user_id => User.current, :status => [0,1,2]).count
if game_count > 0
return true
else
return false
end
end
# 已通过的关卡数
def had_passed_changllenge_count shixun, user
myshixun = Myshixun.where(:shixun_id => shixun.id, :user_id => user.id).first
if myshixun.nil?
0
elsif myshixun.games.select{|game| game.status == 2}.count == 0
-1
elsif myshixun.games.select{|game| game.status == 0}.count > 0
[myshixun.games.select{|game| game.status == 2}.count + 1]
else
myshixun.games.select{|game| game.status == 2}.count
end
end
# 判断TPM已通过的管卡数
def had_passed_games_count shixun_id, user_id
#Game.find_by_sql("select count(*) as unpass_count from games where games.status=2 and user_id=#{user_id} and games.challenge_id in (select id from challenges where shixun_id=#{shixun_id})").first.try(:unpass_count)
Game.find_by_sql("SELECT count(*) cnt FROM `games` g join myshixuns m on m.id = g.myshixun_id where m.user_id = #{user_id} and m.shixun_id = #{shixun_id} and g.status = 2;").first.try(:cnt)
end
# 用户实训评测状态
def user_evaluate_status shixun, user
myshixun = shixun.myshixuns.where(:user_id => user.id).first
if myshixun.blank?
"--"
else
game_id = myshixun.games.map(&:id)
output = Output.where(:game_id => game_id).reorder("updated_at desc").first
if output.blank?
"--"
else
if output.try(:code) == -1
time_from_now(output.updated_at).to_s + "评测失败"
else
time_from_now(output.updated_at).to_s + "评测成功"
end
end
end
end
def student_work_performance score
case score
when (90..100)
'优秀'
when (70...90)
'良好'
when (60...70)
'及格'
when (0...60)
'不及格'
end
end
# 已通过的关卡数 返回int类型(包含查看参考答案的)
def had_passed_changllenge_num myshixun
if myshixun.nil?
0
else
myshixun.games.select{|game| game.status == 2}.count
end
end
# 已通过的关卡数 返回int类型(未查看参考答案)
def had_passed_no_ans_changllenge_num myshixun
if myshixun.nil?
0
else
myshixun.games.select{|game| game.status == 2 && game.final_score > 0}.count
end
end
# TPI状态 :已通关、未通关、未开启
def my_shixun_status shixun, user
status = ""
myshixun = Myshixun.where(:shixun_id => shixun.id, :user_id => user.id).first
if myshixun.nil?
status = "未开启"
else
status = myshixun.is_complete? ? "已通关" : "未通关"
end
status
end
# 定义实训相关方法
def sum_final_score
Game.find_by_sql("SELECT sum(final_score) as total_score FROM `games` where user_id=#{User.current.id}").first.try(:total_score)
end
# 获取某个myshixun的得分
def sum_myshixun_score myshixun_id
Game.find_by_sql("SELECT sum(final_score) as total_score FROM `games` where myshixun_id=#{myshixun_id}").first.try(:total_score)
end
# myshixun 最高分
def top_score shixun, position
Game.find_by_sql("SELECT max(final_score) as top_score FROM `games` g, `challenges` c where g.challenge_id = c.id and c.position=#{position} and g.myshixun_id in (SELECT id FROM `myshixuns` ms where ms.shixun_id=#{shixun.id})").first.try(:top_score)
end
# 实训平均分
def shixun_avg_score shixun, position
Game.find_by_sql("SELECT avg(g.final_score) as avg_score FROM `games` g, `challenges` c where g.challenge_id=c.id and c.position=#{position} and g.myshixun_id in (SELECT id FROM `myshixuns` ms where ms.shixun_id=#{shixun.id})").first.try(:avg_score)
end
# 正在进行中任务
def shixun_running shixun, position
Shixun.find_by_sql("SELECT count(*) as count FROM `myshixuns` ms, `games` g, `challenges` c where g.myshixun_id = ms.id and ms.shixun_id =#{shixun.id} and g.challenge_id=c.id and c.position=#{position} and g.status in ('0','1');").first.try(:count)
end
# 已完成任务
def shixun_done shixun, position
Shixun.find_by_sql("SELECT count(*) as count FROM `myshixuns` ms, `games` g, `challenges` c where g.myshixun_id = ms.id and ms.shixun_id =#{shixun.id} and g.challenge_id=c.id and c.position=#{position} and g.status=2;").first.try(:count)
end
# 测评次数
def shixun_exec_total_count shixun, position
Game.find_by_sql("SELECT * FROM `outputs` op, `games` g, `myshixuns` m where op.game_id = g.id and g.stage='#{position}' and m.parent_id = '#{shixun.id}';")
end
# 平均耗时
def game_avg_day created_at, updated_at
time = (updated_at - created_at).to_i
day = time / 86400
end
# 平均耗时
def game_avg_hour created_at, updated_at
time = (updated_at - created_at).to_i
hour = time % (24*60*60) / (60*60)
end
# 平均耗时
def game_avg_min created_at, updated_at
time = (updated_at - created_at).to_i
min = time % (24*60*60) % (60*60) / 60
end
# 耗时:天、小时、分、秒
# 小于1分钟则不显示
def game_spend_time time
day = time / 86400
hour = time % (24*60*60) / (60*60)
min = time % (24*60*60) % (60*60) / 60
sec = time % (24*60*60) % (60*60) % 60
if day < 1
if hour < 1
if min < 1
if sec < 1
time = "--"
else
time = "#{sec}"
end
else
time = "#{min}分钟 #{sec}"
end
else
time = "#{hour}小时 #{min}分钟 #{sec}"
end
else
time = "#{day}#{hour}小时 #{min}分钟 #{sec}"
end
return time
end
# 耗时:天、小时、分
# 小于1分钟则不显示
def work_spend_time time
if time == 0
time = "0小时"
else
day = time / 86400
hour = time % (24*60*60) / (60*60)
min = (time % (24*60*60) % (60*60) / 60.0).ceil
if day < 1
if hour < 1
if min < 1
time = "1分"
else
time = "#{min}"
end
else
time = "#{hour}小时#{min}"
end
else
time = "#{day}#{hour}小时#{min}"
end
end
return time
end
# 耗时:小时、分、秒 00:00:00
# 小于1秒钟则不显示
def com_spend_time time
hour = time / (60*60)
min = time % (60*60) / 60
sec = time % (60*60) % 60
hour_str = "00"
min_str = "00"
sec_str = "00"
if hour >= 1 && hour < 10
hour_str = "0#{hour}"
elsif hour >= 10
hour_str = "#{hour}"
end
if min >= 1 && min < 10
min_str = "0#{min}"
elsif min >= 10
min_str = "#{min}"
end
if sec >= 1 && sec < 10
sec_str = "0#{sec}"
elsif sec >= 10
sec_str = "#{sec}"
end
time = "#{hour_str} : #{min_str} : #{sec_str}"
return time
end
def consume_time time
time.strftime('%Y/%m/%d %H:%M:%S')
end
def avg_spend_time shixun_id, position
Game.find_by_sql("SELECT avg(g.end_time - g.open_time) as avg_time FROM `games` g, `challenges` c where c.id=g.challenge_id and g.status =2 and c.position = #{position} and g.myshixun_id in (SELECT id FROM `myshixuns` where shixun_id= #{shixun_id});").first.try(:avg_time).to_i
end
# 已闯关
def had_pass shixun_id, position
Game.find_by_sql("SELECT count(*) as count FROM `games` g, `challenges` c where c.id=g.challenge_id and g.status =2 and c.position =#{position} and g.myshixun_id in (SELECT id FROM `myshixuns` where shixun_id=#{shixun_id});").first.try(:count)
end
# 单个game测评次数
def avg_my_pass game
Output.where(:game_id => game).count
end
def shixun_final_score myshixun
Game.find_by_sql("SELECT sum(final_score) as final_score FROM `games` where myshixun_id='#{myshixun.id}';").first.try(:final_score)
end
# def user_blogs_path(resource,parameters={})
# super
# end
# 复制一个任务
def publish_games challenge, myshixun_id, index
game = Game.new
game.attributes = challenge.attributes.dup.except("id","shixun_id","user_id","visits")
game.myshixun_id = myshixun_id
game.user_id = User.current.id
game.stage = challenge.position
index == 0 ? game.status = 0 : game.status = 3
challenge_samples = challenge.challenge_samples
test_sets = challenge.test_sets
if game.save
unless challenge_samples.blank?
challenge_samples.each do |cs|
ChallengeSample.create(:game_id => game.id, :input => cs.input, :output => cs.output, :challenge_id => -1)
end
end
unless test_sets.blank?
test_sets.each do |ts|
TestSet.create(:game_id => game.id, :input => ts.input, :output => ts.output, :challenge_id => -1)
end
end
end
end
def git_repository_url project, type
if type == "Shixun"
rep_identify = Repository.where(:shixun_id => project.id, :type => "Repository::Gitlab").first.try(:identifier)
elsif type == "Myshixun"
rep_identify = Repository.where(:myshixun_id => project.id, :type => "Repository::Gitlab").first.try(:identifier)
else
rep_identify = Repository.where(:project_id => project.id, :type => "Repository::Gitlab").first.try(:identifier)
end
gitlab_address = Redmine::Configuration['gitlab_address']
gitUrl = gitlab_address.to_s+"/"+project.owner.to_s+"/"+ rep_identify + "."+"git"
end
def gitlab_url container
g = Gitlab.client
url = "#{Redmine::Configuration['gitlab_address_ip']}/#{g.project(container.try(:gpid)).try(:path_with_namespace)}.git"
end
def gitlab_address_url container
g = Gitlab.client
url = "#{Redmine::Configuration['gitlab_address']}/#{g.project(container.try(:gpid)).try(:path_with_namespace)}.git"
end
# paranet_gpid 为fork的源头
# u_gid 为当前用户在gitlab中对应的用户id
def sync_gitlab_rep container, parent_gpid, u_gid
Rails.logger.info("# sync_gitlab_rep # parent_gpid is #{parent_gpid}, u_gid is #{u_gid}")
if container.class == Myshixun
gshixun = Gitlab.client.fork(parent_gpid, u_gid)
container.update_attribute(:gpid, gshixun.id)
end
return gshixun.try(:id)
end
# def git_shixun_url shixun, login
# rep_identify = Repository.where(:shixun_id => shixun.id, :type => "Repository::Gitlab").first.try(:identifier)
# gitlab_address = Redmine::Configuration['gitlab_address']
# gitUrl = gitlab_address.to_s+"/"+login+"/"+ rep_identify + "."+"git"
# end
# def git_shixun_url_ip shixun, login
# rep_identify = Repository.where(:shixun_id => shixun.id, :type => "Repository::Gitlab").first.try(:identifier)
# gitlab_address = Redmine::Configuration['gitlab_address_ip']
# gitUrl = gitlab_address.to_s+"/"+login+"/"+ rep_identify + "."+"git"
# end
# def git_myshixun_url_ip myshixun, user_id
# g = Gitlab.client
# login = User.where(:id => user_id).first.try(:login)
# rep_identify = g.project(myshixun.gpid).try(:name)
# gitlab_address = Redmine::Configuration['gitlab_address_ip']
# gitUrl = gitlab_address.to_s+"/"+login+"/"+ rep_identify + "."+"git"
# end
# myshixun git url by domain
# def git_myshixun_url myshixun, user_id
# g = Gitlab.client
# login = User.where(:id => user_id).first.try(:login)
# rep_identify = g.project(myshixun.gpid).try(:name)
# gitlab_address = Redmine::Configuration['gitlab_address']
# gitUrl = gitlab_address.to_s+"/"+login+"/"+ rep_identify + "."+"git"
# end
def uri_exec uri, params
begin
Rails.logger.info("@parmas is #{params}, url is #{uri}")
uri = URI.parse(URI.encode(uri.strip))
res = Net::HTTP.post_form(uri, params).body
res = JSON.parse(res)
rescue => e
Rails.logger.error("failed to post data to brige! #{e}")
raise("实训云平台繁忙繁忙等级84")
end
end
# type 为繁忙等级
# status-> 501check检查版本库是否有代码异常
# status-> 502实训评测异常503实训版本库check异常
def interface_post uri, params, status
begin
uri = URI.parse(URI.encode(uri.strip))
res = Net::HTTP.post_form(uri, params).body
res = JSON.parse(res)
if (res && res['code'] != 0)
raise(status)
end
res
rescue Exception => e
Rails.logger.error("post failed! #{e.message}")
# 增加错误栈信息
e.backtrace.each { |msg| Rails.logger.error("post_backtrace: #{msg}") }
raise("实训云平台繁忙(繁忙等级:#{status}")
end
end
def get_url_exec uri, options={}
begin
uri = URI.parse(URI.encode(uri.strip))
res = Net::HTTP.get_response(uri).body
res = JSON.parse(res)
rescue => e
logger.error("get response failed ! #{e.message}")
raise("实训云平台繁忙繁忙等级84")
end
end
def uri_json_exec uri, params
Net::HTTP.start(uri.hostname, uri.port) {|http|
http.post(uri.path, params.to_json)
}
http = Net::HTTP.new(uri.host, uri.port)
res = Net::HTTP.post(uri, params.to_json).body
res = JSON.parse(res)
end
def last_reply_time container_id
message = Message.where(:root_id => container_id).order("created_on desc").first
time = message.created_on
return time
end
def judge_Chinese_num str
cn_reg = /[\u4e00-\u9fa5]{1}/
cn_number = str.scan(cn_reg).size
en_number = str.size - cn_number
size = 1.9* cn_number + en_number
end
# homework_common状态
# 0挂起1提交中2匿评中3评阅中
def new_homework_common_status status
case status
when 0
"未发布"
when 1
"提交中"
when 2
"补交中"
when 3
"匿评中"
when 4
"申诉中"
when 5
"评阅中"
when 6
"已结束"
end
end
# 作业不同状态的不同样式
def homework_status_color status
style = ""
case status
when '未发布'
style = 'edu-filter-btn-no-late'
when '提交中', '评阅中', '匿评中', '交叉评阅中'
style = 'edu-filter-btn-orange'
when '已开启补交'
style = 'edu-filter-btn-green'
when '已截止', '未开启补交'
style = 'edu-filter-btn-red'
when '已结束'
style = 'edu-filter-btn-end'
when '申诉中'
style = 'edu-filter-btn-appeal'
end
end
# 有分班权限的课堂 学生提交作品时发送的消息对象
def tiding_teachers course, member
if course.teacher_course_groups.count > 0
member_ids = course.teacher_course_groups.where(:course_group_id => member.try(:course_group_id)).pluck(:member_id)
teachers = course.teachers.where("members.id not in (#{course.teacher_course_groups.pluck(:member_id).size > 0 ? course.teacher_course_groups.pluck(:member_id).join(',') : -1}) or
members.id in (#{member_ids.size > 0 ? member_ids.join(',') : -1})")
else
teachers = course.teachers
end
teachers
end
# 分班管理的老师所看到的成员数
def group_student_count course
member = @course.members.where(:user_id => User.current.id).first
if User.current.allowed_to?(:as_teacher, course) && member.present? && member.teacher_course_groups.count > 0
student_count = course.members.where(:course_group_id => member.teacher_course_groups.pluck(:course_group_id)).select{|member| member.roles.to_s.include?("Student")}.count
else
student_count = course.student.count
end
student_count
end
# 已提交作品
def late_commit_work_status work, homework
if homework.allow_late
link_to "补交附件", student_work_path(work, :is_focus => 1), :class => 'edu-filter-btn edu-activity-orange ml15 fl mt5', :title => "可追加作品修订附件"
else
"<span class='edu-filter-btn edu-filter-btn-red ml15 fl mt5'>未开启补交</span>".html_safe
end
end
# 未提交作品
def un_commit_work_status project, homework
if homework.allow_late
if homework.homework_type == 3 && project.nil? && homework.homework_detail_group.base_on_project == 1
link_to "补交作品", "javascript:void(0)", :class => 'edu-filter-btn edu-activity-orange ml15 fl mt5', :style => "cursor:not-allowed", :title => '请先关联项目再补交作品'
else
link_to "补交作品", new_student_work_url_without_domain(homework.id), :class => 'edu-filter-btn edu-activity-orange ml15 fl mt5'
end
else
"<span class='edu-filter-btn edu-filter-btn-red ml15 fl mt5'>未开启补交</span>".html_safe
end
end
# 判断作业有多少人提交了
#
def had_commit_studentwork_count homework_common
member = homework_common.course.members.where(:user_id => User.current.id).first
student_works = homework_common.student_works
if member.present? && member.teacher_course_groups.size > 0
group_students = homework_common.course.members.where(:course_group_id => member.teacher_course_groups.pluck(:course_group_id)).map(&:user_id)
student_works = student_works.where(:user_id => group_students)
end
student_works.where("work_status !=?", 0).size
end
# 实训作业的有效作品数
def effective_shixun_work_count homework_common
count = 0
shixun = homework_common.shixuns
if shixun
homework_common.student_works.where("work_status !=?", 0).each do |work|
myshixun = work.myshixun
count = count + (myshixun && myshixun.games.select{|game| game.status == 2}.size > 0 ? 1 : 0)
end
end
count
end
# 实训作业的通关作品数
def tongguan_shixun_work_count homework_common
count = 0
shixun = homework_common.shixuns.first
if shixun
challenge_count = shixun.challenges.count
homework_common.student_works.where("work_status !=?", 0).each do |work|
myshixun = work.myshixun
if myshixun && myshixun.games.select{|game| game.status == 2}.size == challenge_count
count = count + 1
end
end
end
count
end
# 未提交作品数统计
def had_uncommit_studentwork_count homework_common
member = homework_common.course.members.where(:user_id => User.current.id).first
student_works = homework_common.student_works
if member.present? && member.teacher_course_groups.size > 0
group_students = homework_common.course.members.where(:course_group_id => member.teacher_course_groups.pluck(:course_group_id)).map(&:user_id)
student_works = student_works.where(:user_id => group_students)
end
student_works.where("work_status =?", 0).size
end
# 未评阅
def had_unevaluate_count homework_common
#count = StudentWorksScore.find_by_sql("SELECT count(distinct student_work_id) as count FROM student_works_scores sws, student_works sw, homework_commons hc where hc.id =#{homework_common.id} and sw.homework_common_id=hc.id and sw.is_delete = 0 and sws.student_work_id = sw.id and sws.user_id=#{User.current.id};").first.try(:count).to_i
member = homework_common.course.members.where(:user_id => User.current.id).first
student_works = homework_common.student_works
if member.present? && member.teacher_course_groups.size > 0
group_students = homework_common.course.members.where(:course_group_id => member.teacher_course_groups.pluck(:course_group_id)).map(&:user_id)
student_works = student_works.where(:user_id => group_students)
end
has_comment = StudentWorksScore.where(:student_work_id => student_works.map(&:id), :reviewer_role => [1, 2]).group_by(&:student_work_id).size
student_count = student_works.size
return student_count - has_comment
end
# 该阶段还有多长时间结束/距下一阶段还有多长时间
def homework_curr_time homework_common
result = {}
status = ""
time = ""
if homework_common.course.try(:is_end)
status = "已结束"
time = format_date homework_common.course.end_date
else
ho_detail_manual = homework_common.homework_detail_manual
if ho_detail_manual
case ho_detail_manual.comment_status
when 0
status = "未发布"
when 1
if homework_common.end_time && homework_common.end_time >= Time.now
status = "提交中"
time = how_much_time(homework_common.end_time)
end
when 3
if ho_detail_manual.evaluation_end && ho_detail_manual.evaluation_end > Time.now
status = "匿评中"
time = how_much_time(ho_detail_manual.evaluation_end)
end
when 4
if ho_detail_manual.appeal_time && ho_detail_manual.appeal_time > Time.now
status = "申诉中"
time = how_much_time(ho_detail_manual.appeal_time)
end
when 5
status = "评阅中"
when 6
status = "评阅中"
end
end
end
result[:status] = status
result[:time] = time
result
end
# 试卷:该阶段还有多长时间结束/距下一阶段还有多长时间
def exercise_curr_time exercise
result = {}
status = ""
time = ""
case exercise.exercise_status
when 1
status = "未发布"
when 2
if exercise.end_time && exercise.end_time >= Time.now
status = "提交中"
time = how_much_time(exercise.end_time)
end
when 3
status = "已截止"
time = format_time exercise.end_time
end
result[:status] = status
result[:time] = time
result
end
# 问卷:该阶段还有多长时间结束/距下一阶段还有多长时间
def poll_curr_time poll
result = {}
status = ""
time = ""
case poll.polls_status
when 1
status = "未发布"
when 2
if poll.end_time && poll.end_time >= Time.now
status = "提交中"
time = how_much_time(poll.end_time)
end
when 3
status = "已截止"
time = format_time poll.end_time
end
result[:status] = status
result[:time] = time
result
end
# 公共分页
def paginator_list objs, objs_count, limit, is_remote
@is_remote = is_remote
@objs_count = objs.count
@obj_pages = Paginator.new @objs_count, limit, params['page'] || 1
@offset ||= @obj_pages.offset
@objs = paginateHelper @attachments,25
end
# 判断当前用户能否对消息进行操作
def allow_to_show applied_message
(User.current.id == applied_message.user_id && applied_message.status == 0) ? true : false
end
# 获取竞赛的管理人员
def contest_managers contest
contest.contest_members.select{|cm| cm.roles.to_s.include?("ContestManager")}
end
# 获取竞赛的评委人员
def contest_judges contest
contest.contest_members.select{|cm| cm.roles.to_s.include?("Judge")}
end
# 获取竞赛的参赛人员
def contest_contestants contest
contest.contest_members.select{|cm| cm.roles.to_s.include?("Contestant")}
end
# 字符串加密
def aes_encrypt(key, encrypted_string)
aes = OpenSSL::Cipher::Cipher.new("AES-128-ECB")
aes.encrypt
aes.key = key
txt = aes.update(encrypted_string) << aes.final
txt.unpack('H*')[0].upcase
end
# 字符串解密
def aes_dicrypt(key, dicrypted_string)
aes = OpenSSL::Cipher::Cipher.new("AES-128-ECB")
aes.decrypt
aes.key = key
aes.update([dicrypted_string].pack('H*')) << aes.final
end
# 获取多种类型的user用户名
def user_message_username user
user.try(:show_name)
end
# 超出1w后用k+形式显示
def switch_integer_into_k number
number > 10000 ? (number.to_f / 1000).round.to_s + "k" : number
end
# 判断某个课程是否包含仅对自己可见的作业
def course_has_score_open_common_homework course
course.homework_commons.select{|hc| hc.score_open == 0}.count > 0 ? true : false
end
def welcome_course_message_count course_id
board_id = Board.where(:course_id => course_id).first.try(:id)
message_count = Message.where(:board_id => board_id).count
return message_count
end
# 可以查看到资源库的资源
def welcome_course_file_count course
course.attachments.count
end
# 超级管理员实训评分设置的横轴
def shixun_quality_show quality
lower = quality.lower_limit
upper = quality.upper_limit
result = "#{quality.name}"
if lower.present? && upper.present?
result = if(lower > lower.round)
"#{result}(#{lower.round},"
else
"#{result}[#{lower.round},"
end
result = if(upper >= upper.round)
"#{result}#{upper.round}]"
else
"#{result}#{upper.round})"
end
end
return result
end
# 管理员实训评分中 "指标"与"标准"的对应
def description_of_quality indicator, position
indicator.score_quality_descriptions.where(:position => position).first.try(:name) if indicator.present?
end
# 获取目录下所有文件,返回一个文件名的数组 type是查看文件的类型image表示图片
# type [[1, "图片"], [2, "apk/exe"], [3, "txt"], [4, "html"]]
def get_dir_filename path, type, game_id
answer_picture = []
image = ["png", "jpg", "gif", "jpeg", "bmp", "pic"]
if File.directory? path
Dir.foreach(path) do |file|
if file !="." and file !=".."
extension = file.split(".")[1].try(:downcase)
if image.include?(extension) && type == 1
answer_picture << file
@type = "image"
elsif extension == "html" && type == 4
answer_picture << file
@type = "html"
elsif extension == "txt" && type == 3
answer_picture << file
@contents = ""
f = File.open("#{path}/#{file}", "r")
# ... process the file
f.each_line do |line|
if line.include?("Your score")
game = Game.find(game_id)
max_query_index = game.query_index - 1
a = line[11, line.length-1].try(:strip)
outputs = game.outputs.where(:query_index => max_query_index)
outputs.update_all(:text_scor => a) if outputs.present?
end
@contents += "#{line}"
end
f.close
@type = "txt"
end
end
end
end
return answer_picture
end
# 隐藏项目以外的信息
# return: true 显示false 不显示
def hidden_unproject_infos
hidden_info = Setting.find_by_name("hidden_non_project")
(hidden_info && hidden_info.value == "1") ? true : false
end
# 获取当前用户的fork数量
def get_fork_from_project forked_from_project_id
Project.find(forked_from_project_id)
end
# 判断当前用户是否已经fork过当前项目
# project: current_project
def has_forked_cur_project project
cur_user_projects = Project.where(:user_id => User.current.id)
if cur_user_projects.count == 0
false
else
has_forked = cur_user_projects.select{|cur_user_project| cur_user_project.forked_from_project_id == project.id}
has_forked.length > 0 ? true : false
end
end
# 判断当前用户是否已经实训过当前项目
# project: current_project
def has_exec_cur_shixun shixun
Myshixun.where(:user_id => User.current.id, :shixun_id => shixun.id).count > 0 ? true : false
end
# 用户必须登录;必须创建了关卡;有实践任务的必须提交了版本库代码
def allow_shixun_exec shixun
g = Gitlab.client
result = User.current.logged? && shixun.challenges.count > 0
if shixun.challenges.where(:st => 0).count > 0
result = result && g.trees(shixun.gpid).count.to_i > 0
end
result
end
# 判断当前用户是否可以开始实战
def link_to_shixun_exec myshixun, shixun, str
is_modify = ShixunModify.where(:myshixun_id => myshixun.try(:id), :shixun_id => shixun.try(:id), :status => 1).first.blank?
if User.current.mail.blank?
link_to str, "javascript:void(0);", :onclick => "notice_box_redirect('#{security_settings_path}', '开启实训,请先绑定邮箱')", :class => "fr shixun-task-btn task-btn-orange mr15", :target => "_blank"
else
if is_modify || myshixun.blank?
link_to str, shixun_exec_shixun_path(shixun), :class => "fr shixun-task-btn task-btn-orange mr15", :target => "_blank"
else
link_to str, "javascript:void(0);", :onclick => "sure_box_redirect('#{myshixun_reset_myshixun_path(myshixun)}', '实训已经更新啦,系统正在为您重置')", :class => "fr shixun-task-btn task-btn-orange mr15"
end
end
end
# 通过系统外部邮箱查找用户,如果用户不存在则用邮箱替换
def get_user_by_mail mail
user = User.find_by_mail(mail)
user.nil? ? User.find(2) : user
end
# 通过登录名查找用户,能查到返回用户姓名,否则返回登录名
def link_to_user_login login, css_class
user = User.find_by_login(login)
user = user.nil? ? login : user
if user.is_a?(User)
name = user.show_name
link_to name, {:controller=> 'users', :action => 'show', id: user.id}, :class => css_class, :target => "_blank"
else
"<a class='#{css_class}'>#{h(user.to_s)}</a>".html_safe
end
end
def link_to_user_mail(mail, css_class)
user = User.find_by_mail(mail)
user = user.nil? ? mail : user
if user.is_a?(User)
name = user.show_name
link_to name, {:controller=> 'users', :action => 'show', id: user.id}, :class => css_class, :target => "_blank"
else
"<a class='#{css_class}' data-tip-down='#{user.to_s}'>#{h(user.to_s)}</a>".html_safe
end
end
# 通过系统外部用户名查找用户,如果用户不存在则用邮箱替换
def get_user_by_login_and login
user = User.find_by_login(login)
(user.nil? || login == "root") ? User.find(2) : user
end
# 登录名来自外部系统
# 通过登录名查找用户,如果用户存在则显示用户姓名,否则显示登录名
def get_user_by_login login
user = User.find_by_login(login)
user.nil? ? login : user.show_name
end
# 重置user_path目的是将id转换成用户名
def user_path(resource, parameters = {})
if Fixnum === resource
resource = User.find(resource)
end
super
end
# 重置user_path目的是将id转换成用户名
# def shixun_path(resource, parameters = {})
# if Fixnum === resource
# resource = Shixun.find(resource)
# end
# super
# end
# 历史数据(老版本库数据)处理完则可以修改该放放
def get_rep_identifier_by_project project
identifier = Repository.where(:project_id => project.id, :type => "Repository::Gitlab").first.try(:identifier)
result = identifier.nil? ? Repository.where(:project_id => project.id).first.try(:identifier) : identifier
result
end
# 项目版本库导出Excel功能
def export_rep_xls(gpid, options = {})
g = Gitlab.client
cycle = params[:cycle]
rev = params[:rev]
if cycle == "week"
statics = g.rep_stats_week(gpid, :rev => rev)
elsif cycle == "month"
statics = g.rep_stats_month(gpid, :rev => rev)
end
xls_report = StringIO.new
book = Spreadsheet::Workbook.new
sheet1 = book.create_worksheet :name => l(:project_module_repository)
blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10
sheet1.row(0).default_format = blue
sheet1.row(0).concat([l(:rep_branch),l(:rep_author),l(:rep_changeset),l(:rep_code_add),l(:rep_code_delete),l(:rep_code_modified),l(:rep_sode_time),l(:rep_sode_cycle),l(:rep_author_mail)])
count_row = 1
statics.each do |static|
user = User.where(:mail => static.email).first
sheet1[count_row,0] = rev
sheet1[count_row,1] = user.nil? ? static.uname : user.show_name
sheet1[count_row,2] = static.commits_num
sheet1[count_row,3] = static.add
sheet1[count_row,4] = static.del
sheet1[count_row,5] = static.changes
sheet1[count_row,6] = Time.now.strftime('%Y-%m-%d %H:%M:%S')
sheet1[count_row,7] = cycle == "week" ? "最近1周" : "最近一月"
sheet1[count_row,8] = static.email
count_row += 1
end
book.write xls_report
xls_report.string
end
# 项目issue列表导出Excel功能
def issue_list_xls issues
xls_report = StringIO.new
book = Spreadsheet::Workbook.new
sheet1 = book.create_worksheet :name => "issues"
blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10
sheet1.row(0).default_format = blue
sheet1.row(0).concat([l(:issue_xls_id),l(:issue_xls_tracker_id),l(:issue_xls_title),l(:issue_xls_description),l(:issue_xls_status),l(:issue_xls_assign),l(:issue_xls_priority),l(:issue_xls_author),l(:issue_xls_created_at),l(:milestone),l(:issue_xls_start),l(:issue_xls_due),l(:issue_xls_ratio)])
count_row = 1
issues.each do |issue|
sheet1[count_row,0] = issue.id
sheet1[count_row,1] = issue_tracker_change(issue.tracker_id)
sheet1[count_row,2] = issue.subject
sheet1[count_row,3] = (issue.description.gsub(/<\/?.*?>/,"")).html_safe
sheet1[count_row,4] = issue_status_change(issue.status_id)
sheet1[count_row,5] = issue.assigned_to.try(:show_name)
sheet1[count_row,6] = issue_priority_change(issue.priority_id)
sheet1[count_row,7] = issue.author.show_name
sheet1[count_row,8] = issue.created_on.nil? ? issue.created_on : issue.created_on.strftime('%Y-%m-%d %H:%M:%S')
sheet1[count_row,9] = issue.fixed_version.try(:name)
sheet1[count_row,10] = issue.start_date.nil? ? issue.start_date : issue.start_date.strftime('%Y-%m-%d')
sheet1[count_row,11] = issue.due_date.nil? ? issue.due_date : issue.due_date.strftime('%Y-%m-%d')
sheet1[count_row,12] = issue_ratio_change(issue.done_ratio, issue.status_id)
count_row += 1
end
book.write xls_report
xls_report.string
end
# 用户资料是否完善
def user_data_complete user
user_extension = UserExtensions.where(:user_id => user.id).first
data = true
if user_extension.gender.nil? || user_extension.school_id.nil? || user.lastname.blank? || (user_extension.identity == 3 && user_extension.school_id.nil?)
data = false
end
return data
end
# 获取用户单位
# 优先获取高校信息如果改信息不存在则获取occupation
def get_occupation_from_user user
School.where("id=?",user.user_extensions.school_id).first.try(:name).nil? ? user.user_extensions.try(:occupation) : School.where("id=?",user.user_extensions.school_id).first.try(:name)
end
def update_visiti_count container
container.update_column(:visits, container.visits + 1)
end
def if_hidden_subdomain field
domains = field.sub_domains.select{|domain| domain.hide.to_i == 0}
result = domains.length > 0 ? true : false
return result
end
# 判断某个资源是否可以申请
def attach_show_allow attach_id
attachment = Attachment.find(attach_id)
case attachment.container_type
when "Project"
User.current.member_of?(attachment.container) ? true : false
when "Course"
User.current.member_of_course?(attachment.container) ? true : false
when "OrgSubfield"
User.current.member_of_org?(attachment.container.organization) ? true : false
when "Principal"
User.current.id == attachment.author_id ? true : false
end
end
# 判断某个私有资源是否可以发送下载权限
# 结果为true不能下载false可以下载
def private_attachment_allow attachment_id
attach = Attachment.find(attachment_id)
# 条件取否result结果为true则不能下载
result = attach.is_public == 0 && attach.author != User.current && !attach.get_apply_resource_status(attach.id, User.current.id) && !attach_show_allow(attach)
end
# Time 2015-03-24 15:27:29
# Author lizanle
# Description 从硬盘上删除对应的资源文件
def delete_kindeditor_assets_from_disk owner_id,owner_type
assets = Kindeditor::Asset.where(["owner_id = ? and owner_type = ?",owner_id,owner_type])
if !assets.nil? && !assets.blank?
assets.all.each do |asset|
next if asset.nil?
filepath = File.join(Rails.root,"public","files","uploads",
asset[:created_at].to_s.gsub("+0800","").to_datetime.strftime("%Y%m").to_s,
asset[:asset].to_s)
File.delete(filepath) if File.exist?filepath
end
end
end
def link_to_user_version(version, options = {})
return '' unless version && version.is_a?(Version)
link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, :class => "linkBlue"
end
# 判断课程是否为精品课程
def is_excellent_course course
(course.is_excellent? or course.excellent_option?) ? true : false
end
# 判断课程对成员是否可见
def visible_course?(course)
(course.is_delete? or (!course.is_public? && !User.current.member_of_course?(course))) ? false : true
end
# 获取项目/课程总分
# 发布缺陷 4分 回复缺陷 1分 提交一次 4分 讨论帖子 2分 回复帖子 1分 发布新闻 1分
def static_project_score obj
score = obj.issue_num * 4 + obj.issue_journal_num + (obj.changeset_num||0) * 4 + obj.board_num * 2 + obj.board_message_num + obj.attach_num * 5
end
# 获取组织成员中文名字
def get_org_member_role_name member
unless member.roles[0].nil?
case member.roles[0].name
when 'orgManager'
'管理人员'
when 'orgMember'
'组织成员'
end
end
end
# 判断组织左侧展开或者隐藏
def is_hide_org_left obj
if obj.nil?
return true
else
if obj.hide == 0
return true
else
return false
end
end
end
# Time 2015-03-24 16:38:05
# Author lizanle
# Description after save后需要进行资源记录的更新
# owner_type = 1 对应的是 memo
# owner_type = 2 对应的是forum
# owner_type = 3 对应的是message
# owner_type = 4 对应的是news
# owner_type = 5 对应的是comment
def update_kindeditor_assets_owner ids,owner_id,owner_type
ids.each do |id|
asset = Kindeditor::Asset.find(id.to_i)
asset.owner_id = owner_id
asset.owner_type = owner_type
asset.save
end
end
# 更新课程活跃度得分
def course_member_score(course_id,user_id,type)
course_contributor_score = CourseContributorScore.where("course_id =? and user_id =?", course_id, user_id).first
case type
when "HomeworkCommon"
if course_contributor_score.nil?
CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :homework_journal_num => 1)
else
score = course_contributor_score.homework_journal_num.to_i + 1
course_contributor_score.update_column(:homework_journal_num, score)
end
# 课程留言
when "Course"
if course_contributor_score.nil?
CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :journal_num => 1)
else
score = course_contributor_score.journal_num.to_i + 1
course_contributor_score.update_column(:journal_num, score)
end
when "Message"
if course_contributor_score.nil?
CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :message_num => 1)
else
score = course_contributor_score.message_num.to_i + 1
course_contributor_score.update_column(:message_num, score)
end
when "MessageReply"
if course_contributor_score.nil?
CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :message_reply_num => 1)
else
score = course_contributor_score.message_reply_num.to_i + 1
course_contributor_score.update_column(:message_reply_num, score)
end
when "NewReply"
if course_contributor_score.nil?
CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :news_reply_num => 1)
else
score = course_contributor_score.news_reply_num.to_i + 1
course_contributor_score.update_column(:news_reply_num, score)
end
when "News"
if course_contributor_score.nil?
CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :news_num => 1)
else
score = course_contributor_score.news_num.to_i + 1
course_contributor_score.update_column(:news_num, score)
end
when "Attachment"
if course_contributor_score.nil?
CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :resource_num => 1)
else
score = course_contributor_score.resource_num.to_i + 1
course_contributor_score.update_column(:resource_num, score)
end
end
end
# 删除某条记录相应减少课程统计数
def down_course_score_num (course_id,user_id,type)
course_contributor_score = CourseContributorScore.where("course_id =? and user_id =?", course_id, user_id).first
case type
when "HomeworkCommon"
unless course_contributor_score.nil?
score = course_contributor_score.homework_journal_num.to_i - 1
course_contributor_score.update_column(:homework_journal_num, score < 0 ? 0 : score)
end
# 课程留言
when "Course"
unless course_contributor_score.nil?
score = course_contributor_score.journal_num.to_i - 1
course_contributor_score.update_column(:journal_num, score < 0 ? 0 : score)
end
when "Message"
unless course_contributor_score.nil?
score = course_contributor_score.message_num.to_i - 1
course_contributor_score.update_column(:message_num, score < 0 ? 0 : score)
end
when "MessageReply"
unless course_contributor_score.nil?
score = course_contributor_score.message_reply_num.to_i - 1
course_contributor_score.update_column(:message_reply_num, score < 0 ? 0 : score)
end
when "NewReply"
unless course_contributor_score.nil?
score = course_contributor_score.news_reply_num.to_i - 1
course_contributor_score.update_column(:news_reply_num, score < 0 ? 0 : score)
end
when "News"
unless course_contributor_score.nil?
score = course_contributor_score.news_num.to_i - 1
course_contributor_score.update_column(:news_num, score < 0 ? 0 : score)
end
when "Attachment"
unless course_contributor_score.nil?
score = course_contributor_score.resource_num.to_i - 1
course_contributor_score.update_column(:resource_num, score < 0 ? 0 : score)
end
end
end
# Added by young
# Define the course menu's link class
# 不是数组的转化成数组然后判断当前menu_item是否在给定的列表
# REVIEW: 目测menu的机制貌似不是很需要转换再说
def link_class(label)
labels = label.is_a?(Array) ? label : ([] << label)
#a = current_menu_item
labels.include?(current_menu_item) ? 'selected' : ''
end
#Ended by young
# Return true if user is authorized for controller/action, otherwise false
def authorize_for(controller, action)
User.current.allowed_to?({:controller => controller, :action => action}, @project)
end
# add by nwb
def authorize_for_course(controller, action)
User.current.allowed_to?({:controller => controller, :action => action}, @course)
end
def authorize_for_contest(controller, action)
User.current.allowed_to?({:controller => controller, :action => action}, @contest)
end
# Display a link if user is authorized
#
# @param [String] name Anchor text (passed to link_to)
# @param [Hash] options Hash params. This will checked by authorize_for to see if the user is authorized
# @param [optional, Hash] html_options Options passed to link_to
# @param [optional, Hash] parameters_for_method_reference Extra parameters for link_to
def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
end
def link_to_if_authorized_course(name, options = {}, html_options = nil, *parameters_for_method_reference)
link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for_course(options[:controller] || params[:controller], options[:action])
end
def link_to_if_authorized_contest(name, options = {}, html_options = nil, *parameters_for_method_reference)
link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for_contest(options[:controller] || params[:controller], options[:action])
end
# Displays a link to user's account page if active
def link_to_user(user, canShowRealName = false, options={})
if user.is_a?(User)
if canShowRealName
name = h(user.realname(options[:format]))
else
name = h(user.name(options[:format]))
end
#if user.active? || (User.current.admin? && user.logged?)
# link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => user.css_classes
#else
# name
#end
link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => user.css_classes
else
h(user.to_s)
end
end
def link_to_isuue_user(user, options={})
if user.is_a?(User)
if options[:format]
name = h(user.name(options[:format]))
else
name = h(user.show_name)
end
link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => "pro_info_p"
else
h(user.to_s)
end
end
def link_to_settings_user(user, options={})
if user.is_a?(User)
name = h(user.name(options[:format]))
link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => "w90 c_orange fl"
else
h(user.to_s)
end
end
#重载上面方法,增加样式显示
def link_to_user_header user,canShowRealName=false,options={}
if user.is_a?(User)
if canShowRealName
name = user.show_name
name = user.login if name == ""
else
name = user.login
end
link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => options[:class]
else
h(user.to_s)
end
end
# Displays a link to +issue+ with its subject.
# Examples:
#
# link_to_issue(issue) # => Defect #6: This is the subject
# link_to_issue(issue, :truncate => 6) # => Defect #6: This i...
# link_to_issue(issue, :subject => false) # => Defect #6
# link_to_issue(issue, :project => true) # => Foo - Defect #6
# link_to_issue(issue, :subject => false, :tracker => false) # => #6
#
def link_to_issue(issue, options={})
title = nil
subject = nil
text = options[:tracker] == false ? "##{issue.id}" : "#{issue.tracker} ##{issue.id}"
if options[:subject] == false
title = truncate(issue.subject, :length => 60)
else
subject = issue.subject
if options[:truncate]
subject = truncate(subject, :length => options[:truncate])
end
end
s = link_to text, issue_path(issue), :class => issue.css_classes, :title => title
s << h(": #{subject}") if subject
s = h("#{issue.project} - ") + s if options[:project]
s
end
def link_to_issue_version(issue, options={})
title = nil
subject = nil
text = options[:tracker] == false ? "##{issue.id}" : "#{issue.tracker} ##{issue.id}"
if options[:subject] == false
title = truncate(issue.subject, :length => 60)
else
subject = issue.subject
if options[:truncate]
subject = truncate(subject, :length => 60)
end
end
# status_id3、已解决 5、已关闭
if issue.status_id == 3
s = link_to text, issue_path(issue), :class => "text_line_s fl", :title => title
elsif issue.status_id == 5
s = link_to text, issue_path(issue), :class => "text_line_s del_line fl", :title => title
else
s = link_to text, issue_path(issue), :class => "c_blue fl", :title => title
end
s << h("<span style='width:450px;display:inline-block;' class='hidden'>: #{subject}</span>".html_safe) if subject
s = h("#{issue.project} - ") + s if options[:project]
s
end
# Generates a link to an attachment.
# Options:
# * :text - Link text (default to attachment filename)
# * :download - Force download (default: false)
def link_to_short_attachment(attachment, options={})
length = options[:length] ? options[:length]:23
text = h(truncate(options.delete(:text) || attachment.filename, length: length, omission: '...'))
route_method = options.delete(:download) ? :download_named_attachment_url_without_domain : :named_attachment_url_without_domain
html_options = options.slice!(:only_path)
url = send(route_method, attachment, attachment.filename, options)
link_to text, url, html_options
end
# Generates a link to an attachment.
# Options:
# * :text - Link text (default to attachment filename)
# * :download - Force download (default: false)
def link_to_attachment(attachment, options={})
token = options[:token] if options[:token]
text = options.delete(:text) || attachment.filename
route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path
html_options = options.slice!(:only_path)
url = send(route_method, attachment, attachment.filename, options)
url << "?token=#{token}" unless token.nil?
link_to text, url, html_options
end
def link_to_attachment_img(attachment, options={})
text = options.delete(:text) || attachment.filename
route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path
html_options = options.slice!(:only_path)
url = send(route_method, attachment, attachment.filename, options)
image_tag url, html_options
end
# Generates a link to a SCM revision
# Options:
# * :text - Link text (default to the formatted revision)
def link_to_revision(revision, repository, options={})
if repository.is_a?(Project)
repository = repository.repository
end
text = options.delete(:text) || format_revision(revision)
rev = revision.respond_to?(:identifier) ? revision.identifier : revision
link_to(
h(text),
{:controller => 'repositories', :action => 'revision', :id => repository.project, :repository_id => repository.identifier_param, :rev => rev},
:title => l(:label_revision_id, format_revision(revision))
)
end
# Generates a link to a message
def link_to_message(message, options={}, html_options = nil)
link_to(
truncate(message.subject, :length => 60),
board_message_path(message.board_id, message.parent_id || message.id, {
:r => (message.parent_id && message.id),
:anchor => (message.parent_id ? "message-#{message.id}" : nil)
}.merge(options)),
html_options
)
end
# Generates a link to a project if active
# Examples:
#
# link_to_project(project) # => link to the specified project overview
# link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options
# link_to_project(project, {}, :class => "project") # => html options with default url (project overview)
#
def link_to_project(project, options={}, html_options = nil)
if project.archived?
h(project.name)
elsif options.key?(:action)
ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0."
url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
link_to project.name, url, html_options
else
link_to project.name, project_path(project, options), html_options
end
end
def link_to_course(course, options={}, html_options = nil)
if course.archived?
h(course.name)
elsif options.key?(:action)
ActiveSupport::Deprecation.warn "#link_to_course with :action option is deprecated and will be removed in Redmine 3.0."
url = {:controller => 'courses', :action => 'show', :id => project}.merge(options)
link_to course.name, url, html_options
else
link_to course.name, course_path(course, options), html_options
end
end
# Generates a link to a project settings if active
def link_to_project_settings(project, options={}, html_options=nil)
if project.active?
link_to project.name, settings_project_path(project, options), html_options
elsif project.archived?
h(project.name)
else
link_to project.name, project_path(project, options), html_options
end
end
def wiki_page_path(page, options={})
url_for({:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title}.merge(options))
end
def thumbnail_tag(attachment)
link_to image_tag(thumbnail_path(attachment)),
named_attachment_path(attachment, attachment.filename),
:title => attachment.filename
end
def thumbnail_issue_tag(attachment)
imagesize = attachment.thumbnail(:size => "200*200")
imagepath = named_attachment_path(attachment, attachment.filename)
if imagesize
link_to image_tag(thumbnail_path(attachment), height: '73', width: '100', class: 'issue_attachment_picture'),
imagepath,
:title => attachment.filename
else
link_to image_tag(imagepath , height: '73', width: '100', class: 'issue_attachment_picture'),
imagepath,
:title => attachment.filename
end
end
def thumbnail_challenge_tag(attachment)
imagepath = named_attachment_path(attachment, attachment.filename)
image_tag(imagepath)
end
# 图片缩略图链接
def thumbnail_small_tag(attachment)
imagesize = attachment.thumbnail(:size => "200*200")
imagepath = named_attachment_path(attachment, attachment.filename)
if imagesize
link_to image_tag(imagesize),
imagepath,
:title => attachment.filename
else
link_to image_tag(imagepath , height: '200', width: '250'),
imagepath,
:title => attachment.filename
end
end
def toggle_link(name, id, options={})
onclick = "$('##{id}').slideToggle(); "
onclick << (options[:focus] ? "$('##{options[:focus]}').focus(); " : "this.blur(); ")
onclick << "return false;"
link_to(name, "javascript:void(0)", :onclick => onclick,:class => options[:class])
end
def image_to_function(name, function, html_options = {})
html_options.symbolize_keys!
tag(:input, html_options.merge({
:type => "image", :src => image_path(name),
:onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
}))
end
def format_activity_title(text)
h(truncate_single_line(text, :length => 100))
end
def format_activity_day(date)
date == User.current.today ? l(:label_today).titleize : format_date(date)
end
def format_activity_description(text)
h(truncate(text.to_s, :length => 120).gsub(%r{[\r\n]*<(pre|code)>.*$}m, '...')).gsub(/[\r\n]+/, "<br />").html_safe
#h(truncate(text.to_s, :length => 120).gsub(/<\/?.*?>/,"")).html_safe
end
def format_version_name(version)
if version.project == @project
h(truncate(version.name,:length=>20))
else
h("#{version.project} - #{truncate(version.name,:length=>20)}")
end
end
def due_date_distance_in_words(date)
if date
l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date))
end
end
# Renders a tree of projects as a nested set of unordered lists
# The given collection may be a subset of the whole project tree
# (eg. some intermediate nodes are private and can not be seen)
#Modified by nie.
def render_project_nested_lists(projects)
s = ''
if projects.any?
ancestors = []
original_project = @project
#modified by nie
projects.each do |project|
# set the project environment to please macros.
@project = project
if (ancestors.empty? || project.is_descendant_of?(ancestors.last))
# s << "<ul class='projects #{ ancestors.empty? ? 'root' : nil}'>\n"
s << "<ul class='projects'>\n"
else
ancestors.pop
s << "</li>"
while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
ancestors.pop
s << "</ul></li>\n"
end
end
classes = (ancestors.empty? ? 'root' : 'child')
s << "<li class='project-table'><div class='#{classes}'>"
if project.try(:project_type) == Project::ProjectType_project
s << h(block_given? ? yield(project) : project.name)
else
end
if project.try(:project_type) == Project::ProjectType_project
unless User.current.member_of?(@project)
s << "<span style = 'float: right;'>"
s << watcher_link(@project, User.current)#, ['whiteButton'])
s << "</span>"
end
s << (render :partial => 'projects/tracker_project', :locals => {:project => project}).to_s
else
s << (render :partial => 'projects/course', :locals => {:project => project}).to_s
end
s << "</div>\n"
ancestors << project
end
s << ("</li></ul>\n" * ancestors.size)
@project = original_project
end
s.html_safe
end
def render_course_nested_lists(courses)
s = ''
if courses.any?
ancestors = []
original_course = @course
#modified by nie
courses.each do |course|
# set the project environment to please macros.
@course = course
if (ancestors.empty? )#|| course.is_descendant_of?(ancestors.last))
s << "<ul class=courses>\n"
else
ancestors.pop
s << "</li>"
while (ancestors.any? )#&& !course.is_descendant_of?(ancestors.last))
ancestors.pop
s << "</ul></li>\n"
end
end
classes = (ancestors.empty? ? 'root' : 'child')
s << "<li class='project-table'><div class='#{classes}'>"
s << (render :partial => 'courses/course', :locals => {:course => course}).to_s
s << "</div>\n"
ancestors << course
end
s << ("</li></ul>\n" * ancestors.size)
@course = original_course
end
s.html_safe
end
#added by young
def render_project_nested_lists_new(projects)
s = ''
if projects.any?
ancestors = []
original_project = @project
projects.sort_by(&:lft).each do |project|
# set the project environment to please macros.
@project = project
if (ancestors.empty? || project.is_descendant_of?(ancestors.last))
# s << "<ul class='projects #{ ancestors.empty? ? 'root' : nil}'>\n"
s << "<ul class='projects'>\n"
else
ancestors.pop
s << "</li>"
while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
ancestors.pop
s << "</ul></li>\n"
end
end
classes = (ancestors.empty? ? 'root' : 'child')
s << h(block_given? ? yield(project) : project.name)
ancestors << project
end
s << ("</li></ul>\n" * ancestors.size)
@project = original_project
end
s.html_safe
end
#end
def render_page_hierarchy(pages, node=nil, options={})
content = ''
if pages[node]
content << "<ul class=\"pages-hierarchy\">\n"
pages[node].each do |page|
content << "<li>"
content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title, :version => nil},
:title => (options[:timestamp] && page.updated_on ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id]
content << "</li>\n"
end
content << "</ul>\n"
end
content.html_safe
end
# Renders flash messages
def render_flash_messages
s = ''
flash.each do |k,v|
s << content_tag('div', v.html_safe, :class => "alert alert-orange mb15 mt15", :id => "flash_#{k}")
end
s.html_safe
end
# Renders tabs and their content
def render_tabs(tabs)
if tabs.any?
render :partial => 'common/tabs', :locals => {:tabs => tabs}
else
content_tag 'p', l(:label_no_data), :class => "nodata"
end
end
def render_project_settings_tabs(tabs)
if tabs.any?
render :partial => 'common/project_tab', :locals => {:tabs => tabs}
else
content_tag 'p', l(:label_no_data), :class => "nodata"
end
end
# Renders the project quick-jump box
def render_project_jump_box
return unless User.current.logged?
projects = User.current.memberships.collect(&:project).compact.select(&:active?).uniq
if projects.any?
options =
("<option value=''>#{ l(:label_jump_to_a_project) }</option>" +
'<option value="" disabled="disabled">---</option>').html_safe
options << project_tree_options_for_select(projects, :selected => @project) do |p|
{ :value => project_path(:id => p, :jump => current_menu_item) }
end
select_tag('project_quick_jump_box', options, :onchange => 'if (this.value != \'\') { window.location = this.value; }')
end
end
def project_tree_options_for_select(projects, options = {})
s = ''
project_tree(projects) do |project, level|
name_prefix = (level > 0 ? '&nbsp;' * 2 * level + '&#187; ' : '').html_safe
tag_options = {:value => project.id}
tag_options[:title] = project.name
if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project))
tag_options[:selected] = 'selected'
else
tag_options[:selected] = nil
end
tag_options.merge!(yield(project)) if block_given?
s << content_tag('option', name_prefix + h(project), tag_options)
end
s.html_safe
end
# Yields the given block for each project with its level in the tree
#
# Wrapper for Project#project_tree
def project_tree(projects, &block)
Project.project_tree(projects, &block)
end
# 项目版本库可见权限判断:
# modules中设置可见
# 版本库存在
# 版本库设置了隐藏则仅仅项目成员或超级管理员可见(hidden_repo:1 隐藏版本库)
# return -> true 可见
def visible_repository?(project)
repository = Repository.where(:project_id => project.id, :type => "Repository::Gitlab").first
if project.enabled_modules.where("name = 'repository'").empty? || repository.nil?
result = false
else
result = (project.hidden_repo && !User.current.admin && !User.current.member_of?(project)) ? false : true
end
end
# 判断成员在项目中的角色 member_role == Reporter/Manager/Developer 报告人员/管理人员/报告人员;
def role_of_members_in_project(project, user_id)
member = Member.where(:project_id => project, :user_id => user_id)
unless member.blank?
member_role = member.first.roles[0].to_s
end
return member_role
end
# 判断用户是不是项目成员
def is_project_member?(user_id, project_id)
@result = false
mem = Member.where("user_id = ? and project_id = ?",user_id, project_id)
unless mem.blank?
@result = true
end
return @result
end
# 更新各类消息为已读
def update_messsages_to_viewed(message_type, forge_message_id)
if(message_type == "CourseMessage")
query = CourseMessage.where(:course_message_type => ["JoinCourse", "RemoveFromCourse"],
:user_id => User.current,
:course_id => forge_message_id,
:viewed => false)
elsif(message_type == "ForgeMessage")
query = ForgeMessage.where(:forge_message_type => ["ProjectInvite", "JoinProject", "RemoveFromProject"],
:user_id => User.current,
:project_id => forge_message_id,
:viewed => false)
elsif(message_type == "ContestMessage")
query = ContestMessage.where(:contest_message_type => ["ContestRequestDealResult", "JoinContest", "RemoveFromContest"],
:user_id => User.current,
:contest_id => forge_message_id,
:viewed => false)
elsif(message_type == "BlogMessage")
query = BlogMessage.where(:blog_message_type => "BlogComment",
:user_id => User.current,
:blog_id => forge_message_id,
:viewed => false)
end
query.update_all(:viewed => true) unless query.blank?
end
def show_attachment_tip container_id, container_type
atts = Attachment.where(:container_id => container_id, :container_type => container_type, :is_public => 0)
atts.count > 0 ? true :false
end
# 必须是项目成员,项目必须提交过代码
def allow_pull_request project
return 0 if project.gpid.nil?
g = Gitlab.client
# 之所以这样比较是为了解决gitlab本身的bug
commit_count = g.project(project.gpid).try(:commit_count).to_i
git_commit_cout = g.user_static(project.gpid, :rev => "master").count
count = commit_count > git_commit_cout ? commit_count : git_commit_cout
count
end
# 判断版本库是否初始为gitlab
def rep_is_gitlab?(project)
rep = project.repositories.where("type =?", "Repository::Gitlab")
return rep.blank? ? true :false
end
# 获取Gitlab版本库提交总数
def commit_count(project, branch)
g = Gitlab.client
#add by hx
if g.commits(project.gpid, :ref_name => @rev , :page=>200).count > 0
count = 4020
elsif g.commits(project.gpid , :page=>25, :ref_name => branch).count==0
count = count_commits(project.gpid , 0 , 25)
elsif g.commits(project.gpid , :page=>50, :ref_name => branch).count ==0
count = count_commits(project.gpid , 25 , 50)+ 25 * 20
elsif g.commits(project.gpid , :page=>75, :ref_name => branch).count ==0
count = count_commits(project.gpid , 50 , 75)+ 50 * 20
elsif g.commits(project.gpid , :page=>100, :ref_name => branch).count== 0
count = count_commits(project.gpid , 75 , 100) + 75 * 20
elsif g.commits(project.gpid , :page=>125, :ref_name => branch).count==0
count = count_commits(project.gpid , 100 , 125) + 100 * 20
elsif g.commits(project.gpid , :page=>150, :ref_name => branch).count==0
count = count_commits(project.gpid , 125 , 150) + 125 * 20
else
count = count_commits(project.gpid , 150 ,200) + 150 * 20
end
end
#add by hx
def count_commits(project_id , left , right)
count = 0
(left..right).each do |page|
if $g.commits(project_id,:page => page).count == 0
break
else
count = count + $g.commits(project_id, :ref_name => @rev, :page => page).count
end
end
return count
end
# 获取单一gitlab项目
def gitlab_repository(project)
rep = Repository.where("project_id =? and type =?", project.id,"Repository::Gitlab" ).first
end
# 获取单一gitlab项目
def shixun_repository(shixun)
rep = Repository.where(:shixun_id => shixun, :type => "Repository::Gitlab" ).first
end
# 判断当前用户是否为项目管理员
def is_project_manager?(user_id, project_id)
@result = false
mem = Member.where("user_id = ? and project_id = ?",user_id, project_id)
unless mem.blank?
@result = mem.first.roles.to_s.include?("Manager") ? true : false
end
return @result
end
# 公开项目资源可以引用admin和管理员和资源上传者拥有设置公开私有权限
def authority_pubilic_for_files(project, file)
@result = false
if (is_project_manager?(User.current.id, @project.id) && User.current.allowed_to?(:manage_files, project)) || file.author_id == User.current.id || User.current.admin &&
project_contains_attachment?(project,file) && file.container_id == project.id && file.container_type == "Project"
@result = true
end
return @result
end
def principals_check_box_tags(name, principals)
s = ''
principals.each do |principal|
s << "<label>#{ check_box_tag name, principal.id, false, :id => nil } #{h principal}</label>\n"
end
s.html_safe
end
# 判断模块是否可见
def project_modules_allow project
@project.enabled_modules.where("name = 'issue_tracking'").empty?
end
# 计算Pull Request的请求数目
def pull_request_count project
g = Gitlab.client
g.merge_requests(project.gpid).count
end
#项目成员列表复选框生成
def project_member_check_box_tags_ex name, principals
s = ''
principals.each do |principal|
s << "<li class='mb5'>#{ check_box_tag name, principal.id, false, :id => nil} #{h link_to principal.userInfo, user_url_in_org( principal), :target => "_blank"}</li>\n"
end
s.html_safe
end
def render_shixun_departments
s = ''
if params[:q] && params[:q].lstrip.rstrip != ""
scope = School.where("name like ?", "%#{params[:q]}%")
else
scope = []
end
scope.each do |name|
s << "<li>#{name}</li>\n"
end
s.html_safe
end
# REDO发现搜索列表的功能还是挺多以前单独写的最好都调用这个方法
# scope[]
def render_mirror_name scope = nil
s = ''
if scope.present?
scope.each do |name|
s << "<li>#{name}</li>\n"
end
end
s.html_safe
end
#缺陷追踪者列表复选框生成
def issue_watcher_check_box_tags_ex name, principals
s = ''
principals.each do |principal|
s << "<li>#{ check_box_tag name, principal.id, false, :id => nil } #{h link_to principal.userInfo, user_path( principal.id)}</li>\n"
end
s.html_safe
end
#扩展的checkbox生成
def principals_check_box_tags_ex(name, principals)
s = ''
principals.each do |principal|
s << "<label>#{ check_box_tag name, principal.id, false, :id => nil } #{h link_to principal.userInfo, user_path( principal.id)}</label>\n"
end
s.html_safe
end
# li标签checkbos扩展
def principals_check_box_tags_li(name, principals)
s = ''
principals.each do |principal|
s << "<li>#{ check_box_tag name, principal.id, false, :id => nil } #{h link_to principal.userInfo, user_path( principal.id) }</li>\n"
end
s.html_safe
end
#扩展的checkbox生成
def principals_radio_box_tags_ex(name, principals)
s = ''
principals.each do |principal|
s << "<label>#{ radio_button_tag name, principal.id, false, :id => nil } #{h principal.userInfo }</label>\n"
end
s.html_safe
end
# Returns a string for users/groups option tags
def principals_options_for_select(collection, selected=nil)
s = ''
if collection.include?(User.current)
s << content_tag('option', "<< #{l(:label_me)} >>", :value => User.current.id)
end
groups = ''
collection.sort.each do |element|
selected_attribute = ' selected="selected"' if option_value_selected?(element, selected)
(element.is_a?(Group) ? groups : s) << %(<option value="#{element.id}"#{selected_attribute}>#{h element.show_name}</option>)
end
unless groups.empty?
s << %(<optgroup label="#{h(l(:label_group_plural))}">#{groups}</optgroup>)
end
s.html_safe
end
def assigned_options_for_select(collection, selected=nil)
conv = Iconv.new("GBK", "utf-8")
s = ''
s << content_tag('option', "#{l(:label_assiged_tip)}", :value => 0)
if collection.include?(User.current)
s << content_tag('option', "<< #{l(:label_me)} >>", :value => User.current.id)
end
groups = ''
collection.sort{|x, y| conv.iconv(x.lastname) <=> conv.iconv(y.lastname)}.each do |element|
selected_attribute = ' selected="selected"' if option_value_selected?(element, selected)
(element.is_a?(Group) ? groups : s) << %(<option value="#{element.id}"#{selected_attribute}>#{h element.show_name}</option>)
end
unless groups.empty?
s << %(<optgroup label="#{h(l(:label_group_plural))}">#{groups}</optgroup>)
end
s.html_safe
end
# Options for the new membership projects combo-box
def options_for_membership_project_select(principal, projects)
options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
options << project_tree_options_for_select(projects) do |p|
{:disabled => principal.projects.to_a.include?(p)}
end
options
end
# Truncates and returns the string as a single line
def truncate_single_line(string, *args)
truncate(string.to_s, *args).gsub(%r{[\r\n]+}m, ' ')
end
# Truncates at line break after 250 characters or options[:length]
def truncate_lines(string, options={})
length = options[:length] || 250
if string.to_s =~ /\A(.{#{length}}.*?)$/m
"#{$1}..."
else
string
end
end
def anchor(text)
text.to_s.gsub(' ', '_')
end
def html_hours(text)
text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>').html_safe
end
def authoring(created, author, options={})
l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)).html_safe
end
def added_time(created)
l(:label_added_time, :age => time_tag(created)).html_safe
end
def user_url_and_time(user_name, user_url, created)
unless user_name.nil? || user_name == ''
l(:label_added_time_by, :author => link_to(user_name, user_url), :age => time_tag(created)).html_safe
else
l(:label_added_time, :age => time_tag(created)).html_safe
end
end
#huang
def betweentime(enddate)
ss=(DateTime.parse("#{enddate.to_date}")-DateTime.parse("#{DateTime.now.to_date}")).to_i
return ss
end
def time_tag(time, *args)
options = args.extract_options!
text = distance_of_time_in_words(Time.now, time)
if @project
content_tag('acronym', text, options.reverse_merge(:title => format_time(time)))
# link_to(text, {:controller => 'activities', :action => 'index', :id => @project, :from => User.current.time_to_date(time)},options.reverse_merge(:title => format_time(time)))
else
content_tag('acronym', text, options.reverse_merge(:title => format_time(time)))
end
end
def syntax_highlight_lines(name, content)
lines = []
syntax_highlight(name, content).each_line { |line| lines << line }
lines
end
def syntax_highlight(name, content)
Redmine::SyntaxHighlighting.highlight_by_filename(content, name)
end
def to_path_param(path)
str = path.to_s.split(%r{[/\\]}).select{|p| !p.blank?}.join("/")
str.blank? ? nil : str
end
def reorder_links(name, url, method = :post)
link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)),
url.merge({"#{name}[move_to]" => 'highest'}),
:method => method, :title => l(:label_sort_highest)) +
link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)),
url.merge({"#{name}[move_to]" => 'higher'}),
:method => method, :title => l(:label_sort_higher)) +
link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)),
url.merge({"#{name}[move_to]" => 'lower'}),
:method => method, :title => l(:label_sort_lower)) +
link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)),
url.merge({"#{name}[move_to]" => 'lowest'}),
:method => method, :title => l(:label_sort_lowest))
end
def breadcrumb(*args)
elements = args.flatten
elements.any? ? content_tag('p', (args.join(" \xc2\xbb ") + " \xc2\xbb ").html_safe, :class => 'wiki_con_tit"') : nil
end
def other_formats_links(&block)
concat('<p class="other-formats fl">'.html_safe + l(:label_export_to))
yield Redmine::Views::OtherFormatsBuilder.new(self)
concat('</p>'.html_safe)
end
def page_header_title
if @project.nil? || @project.new_record?
h(Setting.app_title)
else
b = []
ancestors = (@project.root? ? [] : @project.ancestors.visible.all)
if ancestors.any?
root = ancestors.shift
b << link_to_project(root, {:jump => current_menu_item}, :class => 'root')
if ancestors.size > 2
b << "\xe2\x80\xa6"
ancestors = ancestors[-2, 2]
end
b += ancestors.collect {|p| link_to_project(p, {:jump => current_menu_item}, :class => 'ancestor') }
end
b << h(@project)
b.join(" \xc2\xbb ").html_safe
end
end
def html_title(*args)
#點擊項目版本庫 多觸發一次 字符串為"/"
#暫時解決方法 直接判斷
if(args == ["/"])
args = []
end
# first_page = FirstPage.find_by_page_type('project')
if args.empty?
title = @html_title || []
if @project
title << (@project.name.present? ? @project.name : "项目")
elsif params[:controller] == "projects"
title << "项目"
elsif @welcome
title << "创新源于实践"
elsif @course
title << (@course.name.nil? ? "课堂" : @course.name)
elsif params[:controller] == "homework_bank" || params[:controller] == "question_banks" || params[:controller] == "exercise_bank"
title << ("题库")
elsif params[:controller] == "managements"
title << ("后台管理")
elsif params[:controller] == "colleges" && params[:action] == "statistics"
title << ("#{@school.name}")
elsif params[:controller] == "account" && params[:action] == "help"
if params[:index]
case params[:index]
when "1"
title << ("关于我们")
when "2"
title << ("联系我们")
when "3"
title << ("合作伙伴")
when "4"
title << ("服务协议")
when "5"
title << ("帮助中心")
when "6"
title << ("意见反馈")
end
else
title << ("关于我们")
end
elsif params[:controller] == "courses" && params[:action] == "index"
title << ("翻转课堂")
elsif params[:controller] == "competitions" && params[:action] == "index"
title << ("竞赛")
elsif @competition
title << (@competition.name.nil? ? "竞赛" : @competition.name)
elsif @contest
title << (@contest.name.nil? ? "创新源于实践" : @contest.name)
elsif @shixun
title << (@shixun.name.nil? ? "开发社区" : @shixun.name)
elsif @my_shixun
title << ("我的实训")
elsif params[:controller] == "shixuns" && params[:action] == "index"
title << ("开发社区")
elsif @subject
title << (@subject.name.nil? ? "实训课程" : @subject.name)
elsif params[:controller] == "subjects" && params[:action] == "index"
title << ("实训课程")
elsif @organization
title << (@organization.name.nil? ? "创新源于实践" : @organization.name)
elsif @forum || params[:controller] == "forums"
title << "讨论区"
elsif @my_syllabuses
title << "我的课堂"
elsif params[:controller] == 'ecs'
title << '专业列表'
elsif params[:controller] == 'ec_major_schools'
name = EcMajorSchool.find(params[:id]).name
title << name
elsif params[:controller] == 'ec_years'
if params[:action] == 'training_objectives'
title << '培养目标'
elsif params[:action] == 'graduation_requirement'
title << '毕业要求'
elsif params[:action] == 'requirement_vs_objective'
title << '毕业要求 vs 培养目标'
elsif params[:action] == 'requirement_vs_standard'
title << '毕业要求 vs 通用标准'
elsif params[:action] == 'ec_course_setting' || params[:action] == 'completion_calculation'
title << '课程体系'
else
title << '工程认证'
end
elsif params[:controller] == 'ec_courses'
if params[:action] == 'ec_course_support_setting'
title << '课程体系 vs 毕业要求'
end
elsif @user
if !@project_community.blank? || !@user_projectlist.blank?
title << "项目"
elsif !@course_community.blank? || !@user_courselist.blank?
title << "课堂"
elsif !@contest_community.blank?
title << @contest_community
elsif !@manage_issues.blank?
title << @manage_issues
elsif !@receive_issues.blank?
title << @receive_issues
elsif !@manage_homeworks.blank?
title << @manage_homeworks
elsif !@receive_homeworks.blank?
title << @receive_homeworks
else
title << @user.show_name
end
elsif @syllabus
title << (@syllabus.title.nil? ? "课堂" : @syllabus.title)
else
title << (User.current.id == 2 ? "未登录" : User.current.show_name)
end
# if first_page.nil? || first_page.web_title.nil?
# title << Setting.app_title unless Setting.app_title == title.last
# else
# title << first_page.web_title unless first_page.web_title == title.last
# end
title.select {|t| !t.blank? }.join(' - ')
else
@html_title ||= []
@html_title += args
end
end
# Returns the theme, controller name, and action as css classes for the
# HTML body.
def body_css_classes
css = []
if theme = Redmine::Themes.theme(Setting.ui_theme)
css << 'theme-' + theme.name
end
css << 'controller-' + controller_name
css << 'action-' + action_name
css.join(' ')
end
def accesskey(s)
@used_accesskeys ||= []
key = Redmine::AccessKeys.key_for(s)
return nil if @used_accesskeys.include?(key)
@used_accesskeys << key
key
end
# Formats text according to system settings.
# 2 ways to call this method:
# * with a String: textilizable(text, options)
# * with an object and one of its attribute: textilizable(issue, :description, options)
def textilizable(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
case args.size
when 1
obj = options[:object]
text = args.shift
when 2
obj = args.shift
attr = args.shift
text = obj.send(attr).to_s
else
raise ArgumentError, 'invalid arguments to textilizable'
end
return '' if text.blank?
project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
only_path = options.delete(:only_path) == false ? false : true
text = text.dup
macros = catch_macros(text)
text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr)
@parsed_headings = []
@heading_anchors = {}
@current_section = 0 if options[:edit_section_links]
parse_sections(text, project, obj, attr, only_path, options)
text = parse_non_pre_blocks(text, obj, macros) do |text|
[:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name|
send method_name, text, project, obj, attr, only_path, options
end
end
parse_headings(text, project, obj, attr, only_path, options)
if @parsed_headings.any?
replace_toc(text, @parsed_headings)
end
text.html_safe
end
#
#格式化字符串不转义html代码
def textAreailizable(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
case args.size
when 1
obj = options[:object]
text = args.shift
when 2
obj = args.shift
attr = args.shift
text = obj.send(attr).to_s
else
raise ArgumentError, 'invalid arguments to textilizable'
end
return '' if text.blank?
project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
only_path = options.delete(:only_path) == false ? false : true
text = text.dup
macros = catch_macros(text)
#text = Redmine::WikiFormatting.to_html("CKEditor", text, :object => obj, :attribute => attr)
@parsed_headings = []
@heading_anchors = {}
@current_section = 0 if options[:edit_section_links]
parse_sections(text, project, obj, attr, only_path, options)
text = parse_non_pre_blocks(text, obj, macros) do |text|
[:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name|
send method_name, text, project, obj, attr, only_path, options
end
end
parse_headings(text, project, obj, attr, only_path, options)
if @parsed_headings.any?
replace_toc(text, @parsed_headings)
end
text.html_safe
end
def parse_non_pre_blocks(text, obj, macros)
s = StringScanner.new(text)
tags = []
parsed = ''
while !s.eos?
s.scan(/(.*?)(<(\/)?(pre|code)(.*?)>|\z)/im)
text, full_tag, closing, tag = s[1], s[2], s[3], s[4]
if tags.empty?
yield text
inject_macros(text, obj, macros) if macros.any?
else
inject_macros(text, obj, macros, false) if macros.any?
end
parsed << text
if tag
if closing
if tags.last == tag.downcase
tags.pop
end
else
tags << tag.downcase
end
parsed << full_tag
end
end
# Close any non closing tags
while tag = tags.pop
parsed << "</#{tag}>"
end
parsed
end
def parse_inline_attachments(text, project, obj, attr, only_path, options)
# when using an image link, try to use an attachment, if possible
attachments = options[:attachments] || []
attachments += obj.attachments if obj.respond_to?(:attachments)
if attachments.present?
text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m|
filename, ext, alt, alttext = $1.downcase, $2, $3, $4
# search for the picture in attachments
if found = Attachment.latest_attach(attachments, filename)
image_url = download_named_attachment_path(found, found.filename, :only_path => only_path)
desc = found.description.to_s.gsub('"', '')
if !desc.blank? && alttext.blank?
alt = " title=\"#{desc}\" alt=\"#{desc}\""
end
"src=\"#{image_url}\"#{alt}"
else
m
end
end
end
end
# 判断课程、项目、组织是否有权限删除历史资源
# 项目管理员或者附件的作者可以删除
# (is_project_manager?(User.current.id, @project.id) || User.current.id == history.author_id)
def allow_to_delete_attachment history
attachment = history.attachment
case attachment.try(:container_type)
when "Project"
result = is_project_manager?(User.current.id, attachment.container_id) || User.current.id == history.author_id || User.current.admin?
when "Course"
result = User.current.allowed_to?(:as_teacher, attachment.container) || User.current.id == history.author_id || User.current.admin?
when "OrgSubfield"
result = User.current.id == history.author_id || User.current.admin_of_org?(attachment.container) || User.current.admin?
end
end
# Wiki links
#
# Examples:
# [[mypage]]
# [[mypage|mytext]]
# wiki links can refer other project wikis, using project name or identifier:
# [[project:]] -> wiki starting page
# [[project:|mytext]]
# [[project:mypage]]
# [[project:mypage|mytext]]
def parse_wiki_links(text, project, obj, attr, only_path, options)
text.gsub!(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m|
link_project = project
esc, all, page, title = $1, $2, $3, $5
if esc.nil?
if page =~ /^([^\:]+)\:(.*)$/
identifier, page = $1, $2
link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier)
title ||= identifier if page.blank?
end
if link_project && link_project.wiki
# extract anchor
anchor = nil
if page =~ /^(.+?)\#(.+)$/
page, anchor = $1, $2
end
anchor = sanitize_anchor_name(anchor) if anchor.present?
# check if page exists
wiki_page = link_project.wiki.find_page(page)
url = if anchor.present? && wiki_page.present? && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) && obj.page == wiki_page
"##{anchor}"
else
case options[:wiki_links]
when :local; "#{page.present? ? Wiki.titleize(page) : ''}.html" + (anchor.present? ? "##{anchor}" : '')
when :anchor; "##{page.present? ? Wiki.titleize(page) : title}" + (anchor.present? ? "_#{anchor}" : '') # used for single-file wiki export
else
wiki_page_id = page.present? ? Wiki.titleize(page) : nil
parent = wiki_page.nil? && obj.is_a?(WikiContent) && obj.page && project == link_project ? obj.page.title : nil
url_for(:only_path => only_path, :controller => 'wiki', :action => 'show', :project_id => link_project,
:id => wiki_page_id, :version => nil, :anchor => anchor, :parent => parent)
end
end
link_to(title.present? ? title.html_safe : h(page), User.current.logged? ? url : signin_url_without_domain, :class => ('wiki-page' + (wiki_page ? '' : ' new')))
else
# project or wiki doesn't exist
all
end
else
all
end
end
end
def select_option_helper option
tmp = Hash.new
tmp={"" => ""}
if option.nil?
else
option.each do |project|
tmp[project.name] = project.id
end
end
tmp
end
# Redmine links
#
# Examples:
# Issues:
# #52 -> Link to issue #52
# Changesets:
# r52 -> Link to revision 52
# commit:a85130f -> Link to scmid starting with a85130f
# Documents:
# document#17 -> Link to document with id 17
# document:Greetings -> Link to the document with title "Greetings"
# document:"Some document" -> Link to the document with title "Some document"
# Versions:
# version#3 -> Link to version with id 3
# version:1.0.0 -> Link to version named "1.0.0"
# version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
# Attachments:
# attachment:file.zip -> Link to the attachment of the current object named file.zip
# Source files:
# source:some/file -> Link to the file located at /some/file in the project's repository
# source:some/file@52 -> Link to the file's revision 52
# source:some/file#L120 -> Link to line 120 of the file
# source:some/file@52#L120 -> Link to line 120 of the file's revision 52
# export:some/file -> Force the download of the file
# Forum messages:
# message#1218 -> Link to message with id 1218
#
# Links can refer other objects from other projects, using project identifier:
# identifier:r52
# identifier:document:"Some document"
# identifier:version:1.0.0
# identifier:source:some/file
def parse_redmine_links(text, default_project, obj, attr, only_path, options)
text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-_]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m|
leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, $2, $3, $4, $5, $10, $11, $8 || $12 || $18, $14 || $19, $15, $17
link = nil
project = default_project
if project_identifier
project = Project.visible.find_by_identifier(project_identifier)
end
if esc.nil?
if prefix.nil? && sep == 'r'
if project
repository = nil
if repo_identifier
repository = project.repositories.detect {|repo| repo.identifier == repo_identifier}
else
repository = project.repository
end
# project.changesets.visible raises an SQL error because of a double join on repositories
if repository && (changeset = Changeset.visible.find_by_repository_id_and_revision(repository.id, identifier))
link = link_to(h("#{project_prefix}#{repo_prefix}r#{identifier}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.revision},
:class => 'changeset',
:title => truncate_single_line(changeset.comments, :length => 100))
end
end
elsif sep == '#'
oid = identifier.to_i
case prefix
when nil
if oid.to_s == identifier && issue = Issue.visible.find_by_id(oid, :include => :status)
anchor = comment_id ? "note-#{comment_id}" : nil
link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid, :anchor => anchor},
:class => issue.css_classes,
:title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})")
end
when 'document'
if document = Document.visible.find_by_id(oid)
link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
:class => 'document'
end
when 'version'
if version = Version.visible.find_by_id(oid)
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
:class => 'version'
end
when 'message'
if message = Message.visible.find_by_id(oid, :include => :parent)
link = link_to_message(message, {:only_path => only_path}, :class => 'message')
end
when 'forum'
if board = Board.visible.find_by_id(oid)
link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
:class => 'board'
end
when 'news'
if news = News.visible.find_by_id(oid)
link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
:class => 'news'
end
when 'project'
if p = Project.visible.find_by_id(oid)
link = link_to_project(p, {:only_path => only_path}, :class => 'project')
end
end
elsif sep == ':'
# removes the double quotes if any
name = identifier.gsub(%r{^"(.*)"$}, "\\1")
case prefix
when 'document'
if project && document = project.documents.visible.find_by_title(name)
link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
:class => 'document'
end
when 'version'
if project && version = project.versions.visible.find_by_name(name)
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
:class => 'version'
end
when 'forum'
if project && board = project.boards.visible.find_by_name(name)
link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
:class => 'board'
end
when 'news'
if project && news = project.news.visible.find_by_title(name)
link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
:class => 'news'
end
when 'commit', 'source', 'export'
if project
repository = nil
if name =~ %r{^(([a-z0-9\-_]+)\|)(.+)$}
repo_prefix, repo_identifier, name = $1, $2, $3
repository = project.repositories.detect {|repo| repo.identifier == repo_identifier}
else
repository = project.repository
end
if prefix == 'commit'
if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first)
link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier},
:class => 'changeset',
:title => truncate_single_line(changeset.comments, :length => 100)
end
else
if repository && User.current.allowed_to?(:browse_repository, project)
name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$}
path, rev, anchor = $1, $3, $5
link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param,
:path => to_path_param(path),
:rev => rev,
:anchor => anchor},
:class => (prefix == 'export' ? 'source download' : 'source')
end
end
repo_prefix = nil
end
when 'attachment'
attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
if attachments && attachment = Attachment.latest_attach(attachments, name)
link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment')
end
when 'project'
if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first
link = link_to_project(p, {:only_path => only_path}, :class => 'project')
end
end
end
end
(leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}"))
end
end
HEADING_RE = /(<h(\d)( [^>]+)?>(.+?)<\/h(\d)>)/i unless const_defined?(:HEADING_RE)
def parse_sections(text, project, obj, attr, only_path, options)
return unless options[:edit_section_links]
text.gsub!(HEADING_RE) do
heading = $1
@current_section += 1
if @current_section > 1
content_tag('div',
link_to(image_tag('edit.png'), options[:edit_section_links].merge(:section => @current_section)),
:class => 'contextual',
:title => l(:button_edit_section)) + heading.html_safe
else
heading
end
end
end
# Headings and TOC
# Adds ids and links to headings unless options[:headings] is set to false
def parse_headings(text, project, obj, attr, only_path, options)
return if options[:headings] == false
text.gsub!(HEADING_RE) do
level, attrs, content = $2.to_i, $3, $4
item = strip_tags(content).strip
anchor = sanitize_anchor_name(item)
# used for single-file wiki export
anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version))
@heading_anchors[anchor] ||= 0
idx = (@heading_anchors[anchor] += 1)
if idx > 1
anchor = "#{anchor}-#{idx}"
end
@parsed_headings << [level, anchor, item]
"<a name=\"#{anchor}\"></a>\n<h#{level} #{attrs}>#{content}<a href=\"##{anchor}\" class=\"wiki-anchor\">&para;</a></h#{level}>"
end
end
MACROS_RE = /(
(!)? # escaping
(
\{\{ # opening tag
([\w]+) # macro name
(\(([^\n\r]*?)\))? # optional arguments
([\n\r].*?[\n\r])? # optional block of text
\}\} # closing tag
)
)/mx unless const_defined?(:MACROS_RE)
MACRO_SUB_RE = /(
\{\{
macro\((\d+)\)
\}\}
)/x unless const_defined?(:MACRO_SUB_RE)
# Extracts macros from text
def catch_macros(text)
macros = {}
text.gsub!(MACROS_RE) do
all, macro = $1, $4.downcase
if macro_exists?(macro) || all =~ MACRO_SUB_RE
index = macros.size
macros[index] = all
"{{macro(#{index})}}"
else
all
end
end
macros
end
# Executes and replaces macros in text
def inject_macros(text, obj, macros, execute=true)
text.gsub!(MACRO_SUB_RE) do
all, index = $1, $2.to_i
orig = macros.delete(index)
if execute && orig && orig =~ MACROS_RE
esc, all, macro, args, block = $2, $3, $4.downcase, $6.to_s, $7.try(:strip)
if esc.nil?
h(exec_macro(macro, obj, args, block) || all)
else
h(all)
end
elsif orig
h(orig)
else
h(all)
end
end
end
TOC_RE = /<p>\{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE)
# Renders the TOC with given headings
def replace_toc(text, headings)
text.gsub!(TOC_RE) do
# Keep only the 4 first levels
headings = headings.select{|level, anchor, item| level <= 4}
if headings.empty?
''
else
div_class = 'toc'
div_class << ' right' if $1 == '>'
div_class << ' left' if $1 == '<'
out = "<ul class=\"#{div_class}\"><li>"
root = headings.map(&:first).min
current = root
started = false
headings.each do |level, anchor, item|
if level > current
out << '<ul><li>' * (level - current)
elsif level < current
out << "</li></ul>\n" * (current - level) + "</li><li>"
elsif started
out << '</li><li>'
end
out << "<a href=\"##{anchor}\">#{item}</a>"
current = level
started = true
end
out << '</li></ul>' * (current - root)
out << '</li></ul>'
end
end
end
# Same as Rails' simple_format helper without using paragraphs
def simple_format_without_paragraph(text)
text.to_s.
gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
gsub(/([^\n]\n)(?=[^\n])/, '\1<br />'). # 1 newline -> br
html_safe
end
def wiki_simple_format_without_paragraph(text)
text.to_s.
gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
gsub(/([^\n]\n)(?=[^\n])/, '\1<br />'). # 1 newline -> br
gsub("&amp;nbsp", " "). #gsub(/<\/?.*?>/,"").
gsub(/&lt;\/?.*?&gt;/, "").
gsub("&quot;", "'").
html_safe
end
def lang_options_for_select(blank=true)
{ 'Chinese简体中文 '=> 'zh', :English => :en}
end
def label_tag_for(name, option_tags = nil, options = {})
label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
content_tag("label", label_text)
end
def labelled_form_for(*args, &proc)
args << {} unless args.last.is_a?(Hash)
options = args.last
if args.first.is_a?(Symbol)
options.merge!(:as => args.shift)
end
options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
form_for(*args, &proc)
end
def labelled_fields_for(*args, &proc)
args << {} unless args.last.is_a?(Hash)
options = args.last
options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
fields_for(*args, &proc)
end
def labelled_remote_form_for(*args, &proc)
ActiveSupport::Deprecation.warn "ApplicationHelper#labelled_remote_form_for is deprecated and will be removed in Redmine 2.2."
args << {} unless args.last.is_a?(Hash)
options = args.last
options.merge!({:builder => Redmine::Views::LabelledFormBuilder, :remote => true})
form_for(*args, &proc)
end
def error_messages_for(*objects)
html = ""
# modified by fq
if objects.first.is_a?(Array)
objects = objects.first
end
# end
if objects != nil
objects = objects.map {|o| o.is_a?(String) ? instance_variable_get("@#{o}") : o}.compact
errors = objects.map {|o| o.errors.full_messages}.flatten
if errors.any?
html << "<div id='errorExplanation'><ul class='pt10'>\n"
errors.each do |error|
###by xianbo
if(error!=l(:label_repository_path_not_null))
html << "<li>#{h error}</li>\n"
end
###xianbo
end
###by xianbo
unless params[:repository].nil?
if params[:repository][:upassword]==""
html << "<li>"+ l(:label_password_not_null) +"</li>\n"
end
end
###xianbo
html << "</ul></div>\n"
end
end
html.html_safe
end
def delete_link(url, options={})
options = {
:method => :delete,
:data => {:confirm => l(:text_are_you_sure)},
:class => 'icon icon-del'
}.merge(options)
link_to l(:button_delete), url, options
end
def update_status_link(user)
url = {:controller => 'users', :action => 'update', :id => user, :page => params[:page], :status => params[:status], :tab => nil}
if user.locked?
link_to "解锁", url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'mr10 link-color-blue'
elsif user.registered?
link_to "激活", url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'mr10 link-color-blue'
elsif user != User.current
link_to "加锁", url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :put, :class => 'mr10 link-color-blue'
end
end
def delete_version_link(url, options={})
options = {
:method => :delete,
:data => {:confirm => l(:text_are_you_sure)},
:class => 'icon icon-del'
}.merge(options)
link_to "", url, options
end
def delete_link_version(url, options={})
options = {
:method => :delete,
:data => {:confirm => l(:text_are_you_sure)},
:class => 'c_purple'
}.merge(options)
link_to l(:button_delete), url, options
end
def delete_new_link(url, options={})
options = {
:method => :delete,
:data => {:confirm => l(:text_are_you_sure)},
:class => "c_purple"
}.merge(options)
link_to l(:button_delete), url, options
end
def preview_link(url, form, target='preview', options={})
content_tag 'a', l(:label_preview), {
:href => "#",
:onclick => %|submitPreview("#{escape_javascript url_for(url)}", "#{escape_javascript form}", "#{escape_javascript target}"); return false;|,
:accesskey => accesskey(:preview)
}.merge(options)
end
def link_to_function(name, function, html_options={})
content_tag(:a, name, {:href => '#', :onclick => "#{function}; return false;"}.merge(:class => "BlueCirBtnMini ml10",:style => "display:inline-block; height:20px; line-height:20px;"))
end
def link_to_function_none(name, function, html_options={})
content_tag(:a, name, {:href => '#', :onclick => "#{function}; return false;"}.merge(:style => "display:inline-block; height:20px; line-height:20px;"))
end
# Helper to render JSON in views
def raw_json(arg)
arg.to_json.to_s.gsub('/', '\/').html_safe
end
def back_url
url = params[:back_url]
if url.nil? && referer = request.env['HTTP_REFERER']
url = CGI.unescape(referer.to_s)
end
url
end
def back_url_hidden_field_tag
url = back_url
hidden_field_tag('back_url', url, :id => nil) unless url.blank?
end
def check_all_links(form_name)
link_to_function_none(l(:button_check_all), "checkAll('#{form_name}', true)") + "&nbsp;".html_safe + " | "+ "&nbsp;".html_safe +
link_to_function_none(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
end
# 本次修改,修改为只显示关闭的所占%比
def progress_bar(pcts, options={})
pcts = [pcts] unless pcts.is_a?(Array)
pcts = pcts.collect(&:round)
# pcts[1] = pcts[1] + pcts[0]
pcts << (100 - pcts[0])
width = options[:width] || '100px;'
legend = options[:legend] || ''
content_tag('span',
content_tag('tr',
(pcts[0] > 0 ? content_tag('span', '', :style => "width: #{pcts[0]}%;", :class => 'roadmap_progressbar_inner', :title => "已关闭:#{pcts[0]}%") : ''.html_safe) #+
# (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done', :title => "开发中:#{pcts[1]}%") : ''.html_safe) +
#(pcts[1] > 0 ? content_tag('span', '', :style => "width: #{pcts[1]}%;", :class => 'roadmap_progressbar ml5', :title => "未完成:#{pcts[1]}%") : ''.html_safe), :style => "width: #{width}"
), :class => 'roadmap_progressbar ml5').html_safe
# + content_tag('p', legend, :class => 'percent').html_safe
end
def checked_image(checked=true)
if checked
image_tag 'toggle_check.png'
end
end
def context_menu(url)
unless @context_menu_included
content_for :header_tags do
javascript_include_tag('context_menu') +
stylesheet_link_tag('context_menu')
end
if l(:direction) == 'rtl'
content_for :header_tags do
stylesheet_link_tag('context_menu_rtl')
end
end
@context_menu_included = true
end
javascript_tag "contextMenuInit('#{ url_for(url) }')"
end
def calendar_for(field_id,start_day=nil)
include_calendar_headers_tags(start_day)
javascript_tag("$(function() { $('##{field_id}').datepicker(datepickerOptions); });")
end
def include_calendar_headers_tags(start_day=nil)
if start_day.nil?
unless @calendar_headers_tags_included
@calendar_headers_tags_included = true
content_for :header_tags do
start_of_week = Setting.start_of_week
start_of_week = l(:general_first_day_of_week, :default => '1') if start_of_week.blank?
# Redmine uses 1..7 (monday..sunday) in settings and locales
# JQuery uses 0..6 (sunday..saturday), 7 needs to be changed to 0
start_of_week = start_of_week.to_i % 7
tags = javascript_tag(
"var datepickerOptions={dateFormat: 'yy-mm-dd', firstDay: #{start_of_week}, " +
"showOn: 'button', buttonImageOnly: true, buttonImage: '" +
path_to_image('/images/public_icon.png') +
"', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true};")
jquery_locale = l('jquery.locale', :default => current_language.to_s)
unless jquery_locale == 'en'
tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js")
end
tags
end
end
else
unless @calendar_headers_tags_included
@calendar_headers_tags_included = true
content_for :header_tags do
start_of_week = Setting.start_of_week
start_of_week = l(:general_first_day_of_week, :default => '1') if start_of_week.blank?
# Redmine uses 1..7 (monday..sunday) in settings and locales
# JQuery uses 0..6 (sunday..saturday), 7 needs to be changed to 0
start_of_week = start_of_week.to_i % 7
tags = javascript_tag(
"var datepickerOptions={dateFormat: 'yy-mm-dd',minDate: new Date(), firstDay: #{start_of_week}, " +
"showOn: 'button', buttonImageOnly: true, buttonImage: '" +
path_to_image('/images/public_icon.png') +
"', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true, onClose: function(dateText, inst) {TimeClose(dateText,inst);}, beforeShow : function(input){TimeBeforeShow(input);} };")
jquery_locale = l('jquery.locale', :default => current_language.to_s)
unless jquery_locale == 'en'
tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js")
end
tags
end
end
end
end
# Overrides Rails' stylesheet_link_tag with themes and plugins support.
# Examples:
# stylesheet_link_tag('styles') # => picks styles.css from the current theme or defaults
# stylesheet_link_tag('styles', :plugin => 'foo) # => picks styles.css from plugin's assets
#
def stylesheet_link_tag(*sources)
options = sources.last.is_a?(Hash) ? sources.pop : {}
plugin = options.delete(:plugin)
sources = sources.map do |source|
if plugin
"/plugin_assets/#{plugin}/stylesheets/#{source}"
elsif current_theme && current_theme.stylesheets.include?(source)
current_theme.stylesheet_path(source)
else
source
end
end
super sources, options
end
# Overrides Rails' image_tag with themes and plugins support.
# Examples:
# image_tag('image.png') # => picks image.png from the current theme or defaults
# image_tag('image.png', :plugin => 'foo) # => picks image.png from plugin's assets
#
def image_tag(source, options={})
if plugin = options.delete(:plugin)
source = "/plugin_assets/#{plugin}/images/#{source}"
elsif current_theme && current_theme.images.include?(source)
source = current_theme.image_path(source)
end
super source, options
end
# Overrides Rails' javascript_include_tag with plugins support
# Examples:
# javascript_include_tag('scripts') # => picks scripts.js from defaults
# javascript_include_tag('scripts', :plugin => 'foo) # => picks scripts.js from plugin's assets
#
def javascript_include_tag(*sources)
options = sources.last.is_a?(Hash) ? sources.pop : {}
@sources ||= []
sources = sources.delete_if do|source|
@sources.include?(source)
end
@sources += sources
if plugin = options.delete(:plugin)
sources = sources.map do |source|
if plugin
"/plugin_assets/#{plugin}/javascripts/#{source}"
else
source
end
end
end
if sources && !sources.empty?
super(sources, options)
else
''
end
end
def content_for(name, content = nil, &block)
@has_content ||= {}
@has_content[name] = true
super(name, content, &block)
end
def has_content?(name)
(@has_content && @has_content[name]) || false
end
def sidebar_content?
has_content?(:sidebar) || view_layouts_base_sidebar_hook_response.present?
end
def view_layouts_base_sidebar_hook_response
@view_layouts_base_sidebar_hook_response ||= call_hook(:view_layouts_base_sidebar)
end
def email_delivery_enabled?
!!ActionMailer::Base.perform_deliveries
end
# Returns the avatar image tag for the given +user+ if avatars are enabled
# +user+ can be a User or a string that will be scanned for an email address (eg. 'joe <joe@foo.bar>')
def avatar(user, options = { })
if Setting.gravatar_enabled?
options.merge!({:ssl => (request && request.ssl?), :default => Setting.gravatar_default})
email = nil
if user.respond_to?(:mail)
email = user.mail
elsif user.to_s =~ %r{<(.+?)>}
email = $1
end
return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil
#options ={"class" => ["avatar2"],"width" =>["80px"],"height" =>["80px"]}
#return image_tag url_to_avatar(user), options
else
''
end
end
def sanitize_anchor_name(anchor)
if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java'
anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
else
# TODO: remove when ruby1.8 is no longer supported
anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
end
end
# Returns the javascript tags that are included in the html layout head
def javascript_heads
tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application','jquery.colorbox-min', 'baiduTemplate')
unless User.current.pref.warn_on_leaving_unsaved == '0'
tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
end
tags
end
def javascript_edu_index_heads
tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application')
unless User.current.pref.warn_on_leaving_unsaved == '0'
tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
end
tags
end
# 临时本地版
def javascript_heads_local
tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'jquery.colorbox-min')
unless User.current.pref.warn_on_leaving_unsaved == '0'
tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
end
tags
end
def hubspot_head
tags = javascript_include_tag('hubspot/messenger.min', 'hubspot/messenger-theme-future')
tags << stylesheet_link_tag('hubspot/messenger', 'hubspot/messenger-theme-future', 'hubspot/messenger-theme-flat')
end
def bootstrap_head
tags = stylesheet_link_tag('bootstrap/bootstrap.min', 'bootstrap/bootstrap-theme.min')
tags << javascript_include_tag('bootstrap/affix')
tags << javascript_include_tag('bootstrap/alert')
tags << javascript_include_tag('bootstrap/button')
tags << javascript_include_tag('bootstrap/carousel')
tags << javascript_include_tag('bootstrap/collapse')
tags << javascript_include_tag('bootstrap/dropdown')
tags << javascript_include_tag('bootstrap/modal')
tags << javascript_include_tag('bootstrap/popover')
tags << javascript_include_tag('bootstrap/scrollspy')
tags << javascript_include_tag('bootstrap/tab')
tags << javascript_include_tag('bootstrap/tooltip')
tags << javascript_include_tag('bootstrap/transition')
tags
end
def favicon
"<link rel='shortcut icon' type='image/x-icon' href='https://www.educoder.net/favicon.ico?1537840119' />".html_safe
end
def robot_exclusion_tag
'<meta name="robots" content="noindex,follow,noarchive" />'.html_safe
end
# Returns true if arg is expected in the API response
def include_in_api_response?(arg)
unless @included_in_api_response
param = params[:include]
@included_in_api_response = param.is_a?(Array) ? param.collect(&:to_s) : param.to_s.split(',')
@included_in_api_response.collect!(&:strip)
end
@included_in_api_response.include?(arg.to_s)
end
# Returns options or nil if nometa param or X-Redmine-Nometa header
# was set in the request
def api_meta(options)
if params[:nometa].present? || request.headers['X-Redmine-Nometa']
# compatibility mode for activeresource clients that raise
# an error when unserializing an array with attributes
nil
else
options
end
end
# Add by Tao
def url_to_avatar(source)
source = nil if source.kind_of?(String)
get_avatar(source)
end
# Endof Tao's code
# cxt
# 获取认证照片
def url_to_auth_img(user_id, type)
if File.exist?(disk_auth_filename("UserAuthentication",user_id,type))
File.join(relative_path,avatar_directory("UserAuthentication"), auth_filename(user_id,type))
else
File.join(relative_path,avatar_directory("UserAuthentication"),type)
end
end
def url_to_coop_img(type)
File.join(relative_path,avatar_directory('type'),"*")
end
# 讨论区的平台icon ["Java", "C", "C++", "Python2.7", "Python3.6", "MySQL/Java", "Html", "JFinal", "Docker", "Ethereum", "Dynamips", "MachineLearning", "Verilog","Spark","MySQL/Python3.6","PHP","PHP/Web","Hadoop", "Golang","Android","Matlab","Shell"]
def url_to_platform_icon language
case language
when 'Python2.7', 'Python3.6'
File.join(relative_path,avatar_directory("Platform"), 'Python')
when 'MySQL/Java', 'MySQL/Python3.6'
File.join(relative_path,avatar_directory("Platform"), 'MySQL')
when 'PHP/Web'
File.join(relative_path,avatar_directory("Platform"), 'PHP')
when 'C#'
File.join(relative_path,avatar_directory("Platform"), 'Cxp')
when 'C/C++'
File.join(relative_path,avatar_directory("Platform"), 'Cjia')
when 'Angular2+'
File.join(relative_path,avatar_directory("Platform"), 'Angular2jia')
else
File.join(relative_path,avatar_directory("Platform"), language.nil? ? "" : language)
end
end
def identity_authentication_status user
authorization = user.apply_actions.where(:container_type => "TrialAuthorization").last
case user.try(:certification)
when 0
if authorization.try(:status) == 0
"处理中"
else
"未授权"
end
when 1
"已授权"
when 2
"被拒绝"
end
end
def user_certification_status user
status = ""
if user.authentication
status = "已实名认证"
else
apply_auth = ApplyUserAuthentication.where(:user_id => user.id, :auth_type => 1).last
if apply_auth && apply_auth.status == 0
status = "实名认证中"
elsif apply_auth && apply_auth.status == 2
status = "实名认证未通过"
else
status = "未实名认证"
end
end
end
def pro_certification_status user
status = ""
if user.professional_certification
status = "已职业认证"
else
apply_auth = ApplyUserAuthentication.where(:user_id => user.id, :auth_type => 2).last
if apply_auth && apply_auth.status == 0
status = "职业认证中"
elsif apply_auth && apply_auth.status == 2
status = "职业认证未通过"
else
status = "未职业认证"
end
end
end
def shixun_authentication_status shixun
case shixun.try(:status)
when 0,nil
"编辑中"
when 1
"待审核"
when 2
"已发布"
when 3
"已关闭"
end
end
def date_format_local(time)
date = time.strftime("%Y年%m月%d日")
end
#当TAG数量过多时更多链接
#1代表是user类型 2代表是project类型 3代表是issue类型 4代表需求 9代表课程
def more_tags id,object_flag
a= 1
case object_flag
when "1"
s = link_to l(:label_more_tags),:controller => "users", :action => "show", :id => id
when "2"
s = link_to l(:label_more_tags),:controller => "projects", :action => "show", :id => id
when "3"
s = link_to l(:label_more_tags),:controller => "issues", :action => "show", :id => id
when "4"
s = link_to l(:label_more_tags),:controller => "bids", :action => "show", :id => id
when "9"
s = link_to l(:label_more_tags),:controller => "courses", :action => "show", :id => id
end
s
end
def get_user_identity identity
s = ""
case identity
when 0
s = '教师'
when 1
s = '学生'
when 2
s = '组织'
when 3
s= '开发者'
else
s = '学生'
end
s
end
# 获取issue类型
def get_issue_type_new tracker_id
case tracker_id
when 1
"缺陷"
when 2
"功能"
when 3
"支持"
when 4
"任务"
when 5
"周报"
end
end
def get_memo
@new_memo = Memo.new
@public_forum = Forum.find(1) rescue ActiveRecord::RecordNotFound
end
#获取用户未过期的课程
def get_user_course user
courses_doing = []
user.courses.select("courses.*,(SELECT MAX(created_at) FROM `course_activities` WHERE course_activities.course_id = courses.id) AS a").order("a desc").each do |course|
if !course_endTime_timeout?(course)
courses_doing.push course
end
end
courses_doing
end
def attachment_history_candown attachment_history
if attachment_history.container_type == "Course"
course = Course.find(attachment_history.container_id)
candown = User.current.member_of_course?(course) || (course.is_public && attachment_history.is_public == 1)
elsif attachment_history.container_type == "Project"
project = Project.find(attachment_history.container_id)
candown = User.current.member_of?(project) || (project.is_public && attachment_history.is_public == 1)
elsif attachment_history.container_type == "OrgSubfield"
org = OrgSubfield.find(attachment_history.container_id).organization
candown = User.current.member_of_org?(org) || (org.organization.is_public && attachment_history.is_public == 1 && (User.current.logged? || org.organization.allow_guest_download?))
end
end
def resource_bank_candown resource,type
candown = false
if resource.is_public
candown = true
end
if type == 'syllabus'
candown = syllabus_course_member(User.current, resource.course) || User.current.admin?
end
candown
end
# 课程某个班级的成员
def syllabus_course_member user, course
result = false
syllabus = course.syllabus
if syllabus
syllabus.courses.each do |course|
if user.member_of_course?(course)
result = true
return result
end
end
end
result
end
def attachment_candown attachment
candown = false
if attachment.container
if attachment.container.class.to_s=="PhoneAppVersion"
candown = true
elsif attachment.container.class.to_s != "HomeworkAttach" && attachment.container.class.to_s != "StudentWork" && attachment.container.class.to_s != "ContestantWork" && (attachment.container.has_attribute?(:project) || attachment.container.has_attribute?(:project_id)) && attachment.container.project
project = attachment.container.project
candown= User.current.member_of?(project) || (project.is_public && attachment.is_public == 1)
elsif attachment.container.is_a?(Project)
project = attachment.container
candown = User.current.member_of?(project) || (attachment.is_public == 1) || attachment.get_status_by_attach(User.current.id) == 2
elsif (attachment.container.has_attribute?(:board) || attachment.container.has_attribute?(:board_id)) && attachment.container.board &&
attachment.container.board.project
project = attachment.container.board.project
candown = User.current.member_of?(project) || (project.is_public && attachment.is_public == 1)
elsif (attachment.container.has_attribute?(:course) ||attachment.container.has_attribute?(:course_id) ) && attachment.container.course
course = attachment.container.course
candown = User.current.member_of_course?(course) || (attachment.is_public == 1) || attachment.get_status_by_attach(User.current.id) == 2
elsif attachment.container.is_a?(Course)
course = attachment.container
candown= User.current.member_of_course?(course) || (attachment.is_public == 1) || attachment.get_status_by_attach(User.current.id) == 2
elsif attachment.container.is_a?(OrgSubfield)
org = attachment.container.organization
candown = User.current.member_of_org?(org) || ((attachment.is_public == 1 || attachment.get_status_by_attach(User.current.id) == 2) && org.allow_guest_download == true)
elsif attachment.container.is_a?(OrgDocumentComment)
org = attachment.container.organization
candown = org.allow_guest_download || User.current.member_of_org?(org) || (org.is_public && attachment.is_public == 1)
elsif (attachment.container.has_attribute?(:board) || attachment.container.has_attribute?(:board_id)) && attachment.container.board &&
attachment.container.board.course
course = attachment.container.board.course
candown= User.current.member_of_course?(course) || (course.is_public==1 && attachment.is_public == 1)
elsif attachment.container.class.to_s=="Organization"
candown = true
elsif attachment.container.class.to_s=="HomeworkAttach"
candown = true
elsif attachment.container.class.to_s=="StudentWorksScore"
candown = true
elsif attachment.container.class.to_s=="StudentWork"
candown = true
elsif attachment.container.class.to_s=="Contest"
candown = true
elsif attachment.container.class.to_s=="Work"
candown = true
elsif attachment.container.class.to_s=="ContestantWork"
candown = true
elsif attachment.container.class.to_s=="HomeworkBank"
candown = true
elsif attachment.container.class.to_s=="BlogComment" #博客资源允许下载
candown = true
elsif attachment.container.class.to_s=="Memo" #论坛资源允许下载
candown = true
elsif attachment.container.class.to_s=="Syllabus" #论坛资源允许下载
candown = true
elsif attachment.container.class.to_s=="Competition" #竞赛资源允许下载
candown = true
elsif attachment.container.class.to_s=="Career" #职业路径资源允许下载
candown = true
elsif attachment.container_type == "Inform" #竞赛通知公告允许下载
candown = true
elsif attachment.container.class.to_s == "User"
candown = (attachment.is_public == 1 || attachment.is_public == true || attachment.author_id == User.current.id)
elsif attachment.container_type == "Bid" && attachment.container && attachment.container.courses
course = attachment.container.courses.first
candown = User.current.member_of_course?(attachment.container.courses.first) || (course.is_public == 1 && attachment.is_public == 1)
else
candown = (attachment.is_public == 1 || attachment.is_public == true)
end
else
if attachment.container_type == "MarkDown" || attachment.container_type.nil? || attachment.container_type == 'Subject' || attachment.container_type == "Shixun" || attachment.container_type == "Memo" || attachment.container_type == "Career" || attachment.container_type == "Exercise" || attachment.container_type == "ExerciseBank"
candown = true
end
end
candown
end
def project_type_link(text, value)
if value == 1
link_to "<span class='pr_kafa'></span>#{text}".html_safe,"javascript:void(0)" ,:onClick => "show_window();", :class => "pr_join_a",:id => "setting_project_type"
elsif value == 2
link_to "<span class='pr_keyan'></span>#{text}".html_safe,"javascript:void(0)" ,:onClick => "show_window();", :class => "pr_join_a",:id => "setting_project_type"
else
link_to "<span class='pr_friend'></span>#{text}".html_safe,"javascript:void(0)" ,:onClick => "show_window();", :class => "pr_join_a",:id => "setting_project_type"
end
end
#如果学生作品被打分后修改,应该给老师提示
def send_message_to_teacher student_work
if StudentWork === student_work
student_work_scores = student_work.student_works_scores.where("reviewer_role != 3")
if student_work_scores.any?
student_work.update_column('re_commit', 1)
course = student_work.homework_common.course
course.teachers.where(:user_id => student_work_scores.map(&:user_id).uniq).each do|mem|
student_work.tidings << Tiding.new(:user_id => mem.user_id, :trigger_user_id => student_work.user_id, :container_id => student_work.id, :container_type => "StudentWork", :parent_container_id => student_work.homework_common_id, :parent_container_type => "HomeworkCommon",
:belong_container_id => course.id, :belong_container_type => "Course", :viewed => 0, :tiding_type => "HomeworkCommon", :extra => "resubmit")
end
end
end
end
private
def wiki_helper
helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
extend helper
return self
end
def link_to_content_update(text, url_params = {}, html_options = {})
link_to(text, url_params, html_options)
end
#added by nie
# Display watcher picture
def show_more_watchers?(obj)
if User.watched_by(obj.id).count > 6
return true
else
return false
end
end
def show_watcher_profile(obj)
count = 0
html = ''
if User.watched_by(obj.id).count == 0
html << (content_tag "span", l(:label_no_current_watchers))
end
for user in User.watched_by(obj.id)
html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => "#{user.name}")
count = count + 1
if count >= 12
break
end
end
html.html_safe
end
#display bid project
def show_more_bid_project?(bid)
if bid.projects.where('is_public = 1').count > 12
return true
else
return false
end
end
def show_bid_project(bid)
html = ''
if bid.projects.where('is_public = 1').count == 0
html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter")
else
bid.projects.where('is_public = 1').take(12).each do |project|
html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar")
end
end
html.html_safe
end
def show_bid_fans_picture(obj)
html = ''
if obj.watcher_users.count == 0
html << (content_tag "span", l(:label_project_no_follow))
else
obj.watcher_users.take(12).each do |user|
html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name)
end
end
html.html_safe
end
#display contest project
def show_more_contest_project?(contest)
if contest.projects.where('is_public = 1').count > 12
return true
else
return false
end
end
def show_more_contest_softapplication?(contest)
if contest.softapplications.where('is_public = 1').count > 12
return true
else
return false
end
end
def show_contest_project(bid)
html = ''
if contest.projects.where('is_public = 1').count == 0
html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter")
else
contest.projects.where('is_public = 1').take(12).each do |project|
html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar")
end
end
html.html_safe
end
def show_contest_project(contest)
html = ''
if contest.projects.where('is_public = 1').count == 0
html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter")
else
contest.projects.where('is_public = 1').take(12).each do |project|
html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar")
end
end
html.html_safe
end
def show_contest_softapplication(contest)
html = ''
if contest.softapplications.where('is_public = 1').count == 0
html << (content_tag "p", l(:label_no_contest_softapplication), :class => "font_lighter")
else
contest.softapplications.where('is_public = 1').take(12).each do |softapplication|
html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar")
end
end
html.html_safe
end
def show_contest_fans_picture(obj)
html = ''
if obj.watcher_users.count == 0
html << (content_tag "span", l(:label_project_no_follow))
else
obj.watcher_users.take(12).each do |user|
html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name)
end
end
html.html_safe
end
#display fans picture
def show_more_fans?(obj)
if obj.watcher_users.count > 12
return true
else
return false
end
end
def show_fans_picture(obj)
html = ''
if obj.watcher_users.count == 0
html << (content_tag "span", l(:label_no_current_fans))
else
obj.watcher_users.take(12).each do |user|
html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name)
end
end
html.html_safe
end
# added by bai
def show_more_participate?(obj)
if obj.join_in_contests.count > 12
return true
else
return false
end
end
def show_participate_picture(obj)
html = ''
count = 0
if obj.join_in_contests.count == 0
html << (content_tag "span", l(:label_no_current_participate))
end
for temp in obj.join_in_contests
html << (link_to image_tag(url_to_avatar(temp.user), :class => "avatar"), user_path(temp.user), :class => "avatar", :title => "#{temp.user.name}")
count = count + 1
if count >= 12
break
end
end
html.html_safe
end
#end
# add by huang
def show_watcher_list(user)
html = ''
count = 0
for user in User.watched_by(user.id)
html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => "#{user.name}")
count = count + 1
if count >= 12
break
end
end
html.html_safe
end
# end
#added by william
def get_fans_num(user)
user.watcher_users.count
end
#end
def hadcommittedhomework(cur,curb)
bid = Bid.find_by_id(curb)
return true if bid.nil?
case bid.homework_type
when Bid::HomeworkFile
attaches = HomeworkAttach.where(bid_id: curb)
attaches.map(&:user_id).include? cur
when Bid::HomeworkProject
attaches = BidingProject.where(user_id: User.current, bid_id: bid)
attaches.count > 0 # > 0 则有提交记录
else
true
end
end
def render_dynamic_nav
home_link = link_to l(:field_homepage), {:controller => 'welcome', :action => 'index'}
home_link = "<li class = 'topnav_a fl'>" << home_link << "</li>"
# bootstrap_render_dynamic_nav
content_tag :ul, (home_link.html_safe+bootstrap_render_dynamic_nav)
end
def bootstrap_render_dynamic_nav
hidden_non_project = Setting.find_by_name("hidden_non_project")
visiable = !(hidden_non_project && hidden_non_project.value == "0")
main_course_link = link_to l(:label_course_practice), {:controller => 'welcome', :action => 'index', :host => Setting.host_course}
main_project_link = link_to l(:label_project_deposit), {:controller => 'welcome', :action => 'index', :host => Setting.host_name}
main_contest_link = link_to l(:label_contest_innovate), {:controller => 'welcome', :action => 'index', :host => Setting.host_contest}
# course_all_course_link = link_to l(:label_course_all), {:controller => 'courses', :action => 'index'}
course_teacher_all_link = link_to l(:label_teacher_all), {:controller => 'users', :action => 'index', :role => 'teacher', :host => Setting.host_course}
# courses_link = link_to l(:label_course_practice), {:controller => 'courses', :action => 'index'}
#users_link = link_to l(:label_software_user), {:controller => 'users', :action => 'index', :host => Setting.host_user}
# contest_link = link_to l(:label_contest_innovate), {:controller => 'contests', :action => 'index'}
# bids_link = link_to l(:label_requirement_enterprise), {:controller => 'bids', :action => 'index'}
forum_link = link_to l(:label_forum_all), {:controller => "forums", :action => "index"}
stores_link = link_to l(:label_stores_index), {:controller => 'stores', :action=> 'index'}
school_all_school_link = link_to l(:label_school_all), {:controller => 'school', :action => 'index'}
project_new_link = link_to l(:label_project_new), {:controller => 'projects', :action => 'new', :host => Setting.host_name}
# project_mine_link = link_to l(:label_my_project), {:controller => 'users', :action => 'user_projects', :host => Setting.host_name}
#@nav_dispaly_project_label
nav_list = Array.new
nav_list.push(school_all_school_link) if @nav_dispaly_course_all_label && @show_course == 1 && visiable
# nav_list.push(course_all_course_link) if @nav_dispaly_course_all_label && @show_course == 1
nav_list.push(course_teacher_all_link) if @nav_dispaly_teacher_all_label && @show_course == 1 && visiable
nav_list.push(main_project_link) if @nav_dispaly_main_project_label
nav_list.push(main_course_link) if @nav_dispaly_main_course_label && @show_course == 1 && visiable
nav_list.push(main_contest_link) if @nav_dispaly_main_contest_label && @show_contest == 1 && visiable
nav_list.push(courses_link) if @nav_dispaly_course_label && @show_course == 1 && visiable
nav_list.push(project_new_link) if @nav_dispaly_project_label
# nav_list.push(project_mine_link) if @nav_dispaly_main_project_label
# nav_list.push(projects_link) if @nav_dispaly_project_label
#nav_list.push(users_link) if @nav_dispaly_user_label
# nav_list.push(contest_link) if @nav_dispaly_contest_label && @show_contest == 1
nav_list.push(bids_link) if @nav_dispaly_bid_label && visiable
nav_list.push(forum_link) if @nav_dispaly_forum_label && visiable
nav_list.push(stores_link) if @nav_dispaly_store_all_label && visiable
content_li = ''
nav_list.collect do |nav_item|
content_li << content_tag(:li, nav_item, :class => 'topnav_a fl')
end
content_li.html_safe
end
def current_user
User.current
end
# def hadcommittedforcontest(curu)
# message = JournalsForMessage.find_by_sql("select * from journals_for_messages where jour_type = 'Softapplication' ")
# message.each do |createmessage|
# if createmessage.user_id == curu
# return true
# end
# end
# end
# 获取用户的认证状态
def get_authentication_status user
result = ''
if user.authentication
result += '<li class="fl white-icon-ring mr5"><i class="fa fa-user color-light-green" data-tip-down="已实名认证"></i></li>'
else
apply_auth = ApplyUserAuthentication.where(:user_id => user.id, :auth_type => 1).last
if apply_auth && apply_auth.status == 0
result += '<li class="fl white-icon-ring mr5"><i class="fa fa-user u-color-light-red" data-tip-down="实名认证中"></i></li>'
else
result += '<li class="fl white-icon-ring mr5"><i class="fa fa-user u-color-light-grey" data-tip-down="还未实名认证"></i></li>'
end
end
if user.professional_certification
result += '<li class="fl white-icon-ring mr5"><i class="fa fa-list-alt color-light-green" data-tip-down="已职业认证"></i></li>'
else
apply_auth = ApplyUserAuthentication.where(:user_id => user.id, :auth_type => 2).last
if apply_auth && apply_auth.status == 0
result += '<li class="fl white-icon-ring mr5"><i class="fa fa-list-alt u-color-light-red" aria-hidden="true" data-tip-down="职业认证中"></i></li>'
else
result += '<li class="fl white-icon-ring mr5"><i class="fa fa-list-alt u-color-light-grey" data-tip-down="还未职业认证" aria-hidden="true"></i></li>'
end
end
return result.html_safe
end
def footer_logo(ul_class=nil, li_class=nil)
logos = []
logos.push(link_to image_tag('/images/footer_logo/nudt.png',:alt=>"nudt"),"http://www.nudt.edu.cn/special.asp?classid=12" )
logos.push(link_to image_tag('/images/footer_logo/peking_eecs.png', :alt=>"peking_eecs"), "http://www.sei.pku.edu.cn/" )
logos.push(link_to image_tag('/images/footer_logo/buaa_scse.png', :alt=>"buaa_scse"), "http://scse.buaa.edu.cn/" )
logos.push(link_to image_tag('/images/footer_logo/iscas.png', :alt=>"iscas"), "http://www.iscas.ac.cn" )
logos.push(link_to image_tag('/images/footer_logo/inforbus.png', :alt=>"inforbus"), "http://www.inforbus.com" )
logos.collect! { |logo|
content_tag(:li, logo.html_safe, :class => li_class.to_s)
}
content_tag(:ul, logos.join("").html_safe, :class => ul_class.to_s).html_safe
end
def sort_homework_path(bid, sort, direction)
case self.action_name
when 'show_courseEx'
get_not_batch_homework_homework_attach_index_path(bid_id: bid.id, sort: sort, direction: 'asc')
when 'get_not_batch_homework'
get_not_batch_homework_homework_attach_index_path(bid_id: bid.id, sort: sort, direction: direction)
when 'get_batch_homeworks'
get_batch_homeworks_homework_attach_index_path(bid_id: bid.id, sort: sort, direction: direction)
when 'get_homeworks'
get_homeworks_homework_attach_index_path(bid_id: bid.id, sort: sort, direction: direction)
else
'#'
end
end
def anonymous_comment_link(bid, course)
link = case bid.comment_status
when 0
confirm_info = "开启匿评后学生将不能对作品进行提交、修改、删除等操作\n"
confirm_info += anonymous_comment_notice(bid,course)
confirm_info += '是否确定开启匿评?'
link_to '启动匿评', start_anonymous_comment_bid_path(bid), id: "#{bid.id}_start_anonymous_comment", remote: true, :confirm => confirm_info, disable_with: '加载中...'
when 1
confirm_info = "关闭匿评后所有同学将不能继续进行匿评,且将公开已提交作品列表\n"
confirm_info += anonymous_comment_notice(bid,course)
confirm_info += '是否确定关闭匿评?'
link_to '关闭匿评', stop_anonymous_comment_bid_path(bid), id: "#{bid.id}_stop_anonymous_comment", remote: true, :confirm => confirm_info
when 2
'匿评结束'
end
content_tag('span', link, id: "#{bid.id}_anonymous_comment")
end
def anonymous_comment_notice(bid, course)
case bid.comment_status
when 0
@student_size ||= searchStudent(course).size
@homework_size = bid.homeworks.size
percent = @homework_size.to_f / (@student_size == 0 ? 1 : @student_size)
confirm_info = "目前#{@student_size}个学生,总共提交了#{@homework_size}份作品,占#{number_to_percentage(percent * 100, precision: 1)}\n"
when 1
@homework_evaluations = 0
bid.homeworks.map { |homework| @homework_evaluations += homework.homework_evaluations.count}
teachers = "("
teacher_members = searchTeacherAndAssistant(course)
teacher_members.each do |member|
if member == teacher_members.last
teachers += member.user_id.to_s + ")"
else
teachers += member.user_id.to_s + ","
end
end
@has_evaluations = 0
bid.homeworks.map { |homework| @has_evaluations += homework.rates(:quality).where("seems_rateable_rates.rater_id not in #{teachers}").count}
percent = @has_evaluations.to_f / (@homework_evaluations == 0 ? 1 : @homework_evaluations)
confirm_info = "目前总共分配了#{@homework_evaluations}份匿评作品,已评价#{@has_evaluations}份作品,占#{number_to_percentage(percent * 100, precision: 1)}\n"
end
confirm_info
end
def get_technical_title user
if user.user_extensions.technical_title == "Professor" || user.user_extensions.technical_title == "教授"
technical_title = l(:label_technicl_title_professor)
elsif user.user_extensions.technical_title == "Associate professor" || user.user_extensions.technical_title == "副教授"
technical_title = l(:label_technicl_title_associate_professor)
elsif user.user_extensions.technical_title == "Lecturer" || user.user_extensions.technical_title == "讲师"
technical_title = l(:label_technicl_title_lecturer)
elsif user.user_extensions.technical_title == "Teaching assistant" || user.user_extensions.technical_title == "助教"
technical_title = l(:label_technicl_title_teaching_assistant)
end
technical_title
end
# 用户竞赛总数
def user_contest_count
@user.favorite_contests.visible.where("is_delete =?", 0).count
end
# 用户项目总数
def user_project_count
@my_projects = @user.projects.visible.where("status != 9")
@my_project_total = @my_projects.count
end
# 用户的课程总数
def user_course_count
@my_course_count = @user.syllabuses.count
sy_courses = @user.courses.visible.not_deleted
syllabus_ids = sy_courses.empty? ? '(-1)' : "(" + sy_courses.map{|course| !course.syllabus_id.nil? && course.syllabus_id}.join(",") + ")"
syllabus_members = SyllabusMember.where("user_id = #{@user.id}")
syllabus_member_ids = syllabus_members.empty? ? "(-1)" : "(" + syllabus_members.map{|syl_mem| syl_mem.syllabus_id}.join(',') + ")"
@join_syllabuses = Syllabus.where("(id in #{syllabus_ids} or id in #{syllabus_member_ids}) and user_id != #{@user.id}")
@my_joined_course_count = @join_syllabuses.count
@user_course_total = @my_joined_course_count + @my_course_count
end
# 用户发布的作业数
def user_manage_homework_count
tea_courses = @user.courses.visible.not_deleted.select{|course| @user.has_teacher_role(course)}
tea_course_ids = tea_courses.map{|course| course.id}
@manage_homeworks = HomeworkCommon.where(:course_id => tea_course_ids).count
end
# 用户收到的作业数
def user_receive_homework_count
stu_courses = @user.courses.visible.not_deleted.select{|course| @user.has_student_role(course)}
stu_course_ids = stu_courses.empty? ? "(-1)" : "(" + stu_courses.map{|course| course.id}.join(',') + ")"
@homeworks = HomeworkCommon.where("course_id in #{stu_course_ids} and publish_time <= '#{Time.now}'").count
end
# 用户发布的issue数
def issues_author_is_self_count
Issue.where(:author_id => @user.id).count
end
# 用户收到的issue数
def issues_assigned_is_self_count
Issue.where( :assigned_to_id => @user.id ).count
end
def get_user_roll user
technical_title = ""
case user.user_extensions.identity.to_s
when "0"
technical_title = get_technical_title user
when "1"
technical_title = l(:label_account_identity_student)
when "2"
technical_title = l(:label_account_identity_enterprise)
when "3"
technical_title = l(:label_account_identity_developer)
end
technical_title
end
def ie8?
request.env["HTTP_USER_AGENT"] =~ /MSIE 8.0/
end
#获取指定资源列表的TAG的集合以及每个TAG的数量降序排序
def attachment_tag_list attachments
tag_list = Hash.new
attachments.each do |attachment|
attachment.tag_list.map{|tag| tag_list.has_key?(tag) ? tag_list[tag] = tag_list[tag] + 1 : tag_list[tag] = 1}
end
tag_list.sort {|a,b| b[1]<=>a[1]}
end
#获取课程资源的TAG云
def get_course_tag_list course
all_attachments = course.attachments
if User.current.admin? || User.current.allowed_to?(:as_teacher, course)
all_attachments = all_attachments.reorder("created_on desc")
elsif User.current.member_of_course?(course)
member = course.members.where(:user_id => User.current.id).first
if member.try(:course_group_id).to_i == 0
all_attachments = all_attachments.where("is_publish = 1 and unified_setting = 1")
else
not_atta_ids = course.attachment_group_settings.where("course_group_id = #{member.try(:course_group_id)} and publish_time > '#{Time.now}'")
not_atta_ids = not_atta_ids.blank? ? "(-1)" : "(" + not_atta_ids.map(&:attachment_id).join(",") + ")"
all_attachments = all_attachments.where("is_publish = 1 and attachments.id not in #{not_atta_ids}")
end
else
all_attachments = all_attachments.where("is_publish = 1 and unified_setting = 1")
end
tag_list = attachment_tag_list all_attachments
tag_list
end
# 获取项目资源的Tag云
def get_project_tag_list project
all_attachments = project.attachments.select{|attachment| attachment.is_public? ||
(attachment.container_type == "Project" && User.current.member_of?(project))||
attachment.author_id == User.current.id
}
tag_list = attachment_tag_list all_attachments
tag_list
end
# 获取项目fork成员数
def project_fork_count
@forked_projects = Project.where(:forked_from_project_id => @project.id)
@forked_count = @forked_projects.count
end
def get_org_subfield_tag_list org_subfield
all_attachments = org_subfield.attachments.select{|attachment| attachment.is_public? ||
(attachment.container_type == "OrgSubfield" && User.current.member_of_org?(org_subfield.organization))||
attachment.author_id == User.current.id
}
tag_list = attachment_tag_list all_attachments
tag_list
end
#获取匿评相关连接代码
def homework_anonymous_comment (homework, hw_status, user_activity_id = -1)
if homework.homework_detail_manual.comment_status == 0 || homework.end_time >= Time.now
link = link_to "启动匿评","javascript:void(0)", :class => "wpostOptionLink", :title => "作业截止日期之前不可以启动匿评"
elsif homework.student_works.has_committed.count >= 2 && homework.homework_detail_manual#作业份数大于2
case homework.homework_detail_manual.comment_status
when 1
link = link_to '启动匿评', Setting.protocol + "://" + Setting.host_name + "/homework_common/" + homework.id.to_s + "/alert_anonymous_comment?hw_status=" + hw_status.to_s + "&user_activity_id=" + user_activity_id.to_s, id: "#{homework.id}_start_anonymous_comment", remote: true, disable_with: '加载中...',:class => 'wpostOptionLink'
when 2
link = link_to '关闭匿评', Setting.protocol + "://" + Setting.host_name + "/homework_common/" + homework.id.to_s + "/alert_anonymous_comment?hw_status=" + hw_status.to_s + "&user_activity_id=" + user_activity_id.to_s, id: "#{homework.id}_stop_anonymous_comment", remote: true,:class => 'wpostOptionLink'
when 3
# link = link_to "匿评结束","javascript:void(0)", :class => "postOptionLink", :title => "匿评结束"
end
else
link = link_to "启动匿评","javascript:void(0)", :class => "wpostOptionLink", :title => "学生提交作业数大于等于2时才可以启动匿评"
end
link
end
#学生根据传入作业确定显示为编辑作品还是新建作品
def student_new_homework homework
work = cur_user_works_for_homework homework
if work.nil?
link_to "提交作品", new_student_work_path(:homework => homework.id),:class => 'fr mr10 work_edit'
else
if homework.homework_type == 1 && homework.homework_detail_manual && homework.homework_detail_manual.comment_status != 1 #匿评作业,且作业状态不是在开启匿评之前
link_to "作品已交", "javascript:void(0);", :class => 'fr mr10 pr_join_span c_white', :title => "开启匿评后不可修改作品"
elsif homework.homework_type == 2 #编程作业修改作品
if homework.homework_detail_manual && homework.homework_detail_manual.comment_status != 1
link_to "作品已交", "javascript:void(0);", :class => 'fr mr10 pr_join_span c_white', :title => "开启匿评后不可修改作品"
else
link_to "修改作品", new_student_work_path(:homework => homework.id),:class => 'fr mr10 work_edit'
end
else
link_to "修改作品", edit_student_work_path(work.id),:class => 'fr mr10 work_edit'
end
end
end
#动态列表中,确定学生是该提交还是进列表
def student_work_activity_submit_status(opt={})
default_opt = {class: 'c_blue'}.merge(opt)
is_teacher = User.current.user_extensions && User.current.user_extensions.identity == 0 && User.current.allowed_to?(:add_course, nil, :global => true)
homework = default_opt[:homework]
work = cur_user_works_for_homework homework
if work.nil? && !is_teacher
link_to "提交("+homework.student_works.count.to_s+")", new_student_work_path(:homework => homework.id,:host=> Setting.host_course), :class=> default_opt[:class]
else
link_to "提交("+homework.student_works.count.to_s+")", student_work_index_path(:homework => homework.id,:host=> Setting.host_course), :class=> default_opt[:class]
end
end
# 试卷动态的按钮
def user_for_exercise exercise,is_teacher
count = exercise.exercise_users.where(:commit_status => 1, :user_id => exercise.course.student.map(&:student_id)).count
if User.current.logged?
if User.current.member_of_course?(exercise.course)
if is_teacher #老师显示作品数量
link_to "作品&nbsp;(#{count})".html_safe, student_exercise_list_exercise_path(exercise), :class => "c_blue homepagePostSubmit"
else #学生显示提交作品、修改作品等按钮
work = exercise.exercise_users.where("user_id = ?",User.current).first
member = exercise.course.members.where(:user_id => User.current.id).first
setting_time = exercise_group_setting exercise, member.try(:course_group)
if work
if work.commit_status > 0
link_to "查看答题(#{count})", exercise.exercise_status < 3 ? exercise_path(exercise,:user_id => User.current.id) : show_student_result_exercise_path(exercise,:user_id => User.current.id), :class => "c_blue homepagePostSubmit"
else
if setting_time.publish_time < Time.now && setting_time.end_time > Time.now
link_to (work.start_at.nil? ? "开始答题(#{count})" : "继续答题(#{count})"), exercise_path(exercise,:user_id => User.current.id), :class => "c_blue homepagePostSubmit"
else
link_to "查看作品(#{count})".html_safe, student_exercise_list_exercise_path(exercise), :class => "c_blue homepagePostSubmit"
end
end
else
if setting_time.publish_time < Time.now && setting_time.end_time > Time.now
link_to "开始答题(#{count})", exercise_path(exercise,:user_id => User.current.id), :class => "c_blue homepagePostSubmit"
else
link_to "查看作品(#{count})".html_safe, student_exercise_list_exercise_path(exercise), :class => "c_blue homepagePostSubmit"
end
end
end
else
link_to "作品&nbsp;(#{count})".html_safe, "javascript:void(0)", :class => "c_blue homepagePostSubmit", :onclick => "notice_sure_box('您不是班级成员,不能答题<br/>请先从老师处获取邀请码后加入班级,再答题')"
end
else
link_to "作品&nbsp;(#{count})".html_safe, "javascript:void(0)", :class => "c_blue homepagePostSubmit", :onclick => "login_notice_box('#{signin_url_without_domain}');"
end
end
# 问卷动态的按钮
def user_for_poll poll,is_teacher
count = poll.poll_users.where(:commit_status => 1, :user_id => poll.course.student.map(&:student_id)).count
if User.current.logged?
if User.current.member_of_course?(poll.course)
if is_teacher #老师显示作品数量
link_to "作品&nbsp;(#{count})".html_safe, student_poll_list_poll_path(poll), :class => "c_blue homepagePostSubmit"
else #学生显示提交作品、修改作品等按钮
work = poll.poll_users.where("user_id = ?",User.current).first
member = poll.course.members.where(:user_id => User.current.id).first
setting_time = poll_group_setting poll, member.try(:course_group)
if work
if work.commit_status > 0
link_to "查看答题(#{count})", poll_path(poll,:user_id => User.current.id), :class => "c_blue homepagePostSubmit"
elsif setting_time.publish_time < Time.now && setting_time.end_time > Time.now
link_to (work.start_at.nil? ? "开始答题(#{count})" : "继续答题(#{count})"), poll_path(poll,:user_id => User.current.id), :class => "c_blue homepagePostSubmit"
else
link_to "查看作品(#{count})".html_safe, student_poll_list_poll_path(poll), :class => "c_blue homepagePostSubmit"
end
else
if setting_time.publish_time < Time.now && setting_time.end_time > Time.now
link_to "开始答题(#{count})", poll_path(poll,:user_id => User.current.id), :class => "c_blue homepagePostSubmit"
else
link_to "查看作品(#{count})".html_safe, student_poll_list_poll_path(poll), :class => "c_blue homepagePostSubmit"
end
end
end
else
link_to "作品&nbsp;(#{count})".html_safe, "javascript:void(0)", :class => "c_blue homepagePostSubmit", :onclick => "notice_sure_box('您不是班级成员,不能答题<br/>请先从老师处获取邀请码后加入班级,再答题')"
end
else
link_to "作品&nbsp;(#{count})".html_safe, "javascript:void(0)", :class => "c_blue homepagePostSubmit", :onclick => "login_notice_box('#{signin_url_without_domain}');"
end
end
#根据传入作业确定显示为编辑作品还是新建作品,或者显示作品数量
def user_for_homework_common homework,work
if User.current.logged?
project = cur_user_projects_for_homework homework if homework.homework_type == 3
member = homework.course.members.where(:user_id => User.current.id).first
setting_time = homework_group_setting homework, member.try(:course_group_id)
if homework.homework_type == 4
if work.nil?
link_to "开始实战", shixun_path(homework.homework_commons_shixuns.shixun), :class => 'edu-default-btn user_bluebg_btn fr mr20 pl7 pr7',:target => "_blank"
else
myshixun = Myshixun.where(:id => work.myshixun_id).first
# is_modify = ShixunModify.where(:myshixun_id => myshixun.try(:id), :shixun_id => myshixun.shixun.try(:id), :status => 1).first
link_to "继续实战", shixun_path(myshixun.shixun), :class => "edu-default-btn user_orangebg_btn fr mr20 pl7 pr7", :target => "_blank"
# if myshixun && is_modify.blank?
# link_to "继续实战", myshixun_game_path(myshixun.current_task, :myshixun_id => myshixun), :class => "edu-default-btn user_orangebg_btn fr mr20 pl7 pr7", :target => "_blank"
# elsif myshixun
# link_to "继续实战", 'javascript:void(0);', :onclick => "sure_box_redirect('#{myshixun_reset_myshixun_path(myshixun)}', '实训已经更新啦,系统正在为您重置');", :class => "edu-default-btn user_orangebg_btn fr mr20 pl7 pr7"
# end
end
elsif work.nil? && setting_time.end_time >= Time.now
if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1
link_to "提交作品", "javascript:void(0)", :class => 'edu-default-btn user_bluebg_btn fr mr20 pl7 pr7',:style=>"cursor:not-allowed",:title => '请先关联项目再提交作品'
else
link_to "提交作品", new_student_work_url_without_domain(homework.id),:class => 'edu-default-btn user_bluebg_btn fr mr20 pl7 pr7'
end
elsif work.nil? && setting_time.end_time < Time.now
if homework.allow_late && !homework.course.is_end
if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1
link_to "补交作品", "javascript:void(0)", :class => 'edu-default-btn user_orangebg_btn fr mr20 pl7 pr7',:style=>"cursor:not-allowed",:title => '请先关联项目再补交作品'
else
link_to "补交作品", new_student_work_url_without_domain(homework.id),:class => 'edu-default-btn user_orangebg_btn fr mr20 pl7 pr7'
end
end
elsif work
work_ids = "(" + homework.student_works.has_committed.map(&:id).join(",") + ")"
if homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 3 && User.current.student_works_evaluation_distributions.where("student_work_id IN #{work_ids}").count > 0 #匿评作业,且作业状态不是在开启匿评之前
link_to "作品匿评", student_work_index_path(:homework => homework.id), :class => 'edu-default-btn user_orangebg_btn fr mr20 pl7 pr7', :title => "开启匿评后不可修改作品"
elsif homework.homework_detail_manual && homework.homework_detail_manual.comment_status > 3
link_to "查看作品",student_work_path(work), :class => 'edu-default-btn user_greybg_btn fr mr20 pl7 pr7', :title => "匿评已结束"
elsif setting_time.end_time >= Time.now && work.user_id == User.current.id
link_to "修改作品", edit_student_work_url_without_domain(work.id),:class => 'edu-default-btn user_orangebg_btn fr mr20 pl7 pr7'
else
link_to "查看作品", student_work_path(work), :class => 'edu-default-btn user_greybg_btn fr mr20 pl7 pr7', :title => "作业截止后不可修改作品"
end
end
else
link_to "作品".html_safe, "javascript:void(0)", :class => "edu-default-btn user_greybg_btn fr mr20 pl7 pr7", :onclick => "login_notice_box('#{signin_url_without_domain}');"
end
end
#根据传入作业确定显示为编辑作品还是新建作品,或者显示作品数量
def user_for_contest_work homework,is_contestant,work
count = homework.contestant_works.has_committed.count
if User.current.logged?
if User.current.member_of_contest?(homework.contest) || User.current.admin?
if !is_contestant #老师显示作品数量
link_to "作品(#{count})", contestant_works_path(:work =>homework.id, :tab => 2), :class => "c_blue"
else #学生显示提交作品、修改作品等按钮
work = cur_user_works_for_work homework
project = cur_user_projects_for_work homework
if work.nil? && homework.work_status == 1
if homework.work_type ==3 && project.nil? && homework.work_detail_group.base_on_project
link_to "提交作品(#{count})","javascript:void(0)", :class => 'c_grey',:style=>"cursor:not-allowed",:title => '请先关联项目再提交作品'
else
link_to "提交作品(#{count})", new_contestant_work_path(:work => homework.id),:class => 'c_blue'
end
elsif work.nil? && homework.work_status > 1
if homework.work_type ==3 && project.nil? && homework.work_detail_group.base_on_project
link_to "补交作品(#{count})","javascript:void(0)", :class => 'c_grey',:style=>"cursor:not-allowed",:title => '请先关联项目再补交作品'
else
link_to "补交作品(#{count})", new_contestant_work_path(:work => homework.id),:class => 'c_blue'
end
else
if homework.work_status == 1 && work.user_id == User.current.id
link_to "修改作品(#{count})", edit_contestant_work_path(work.id),:class => 'c_blue'
else
link_to "查看作品(#{count})", contestant_works_path(:work =>homework.id, :tab => 2), :class => 'c_blue', :title => "不可修改作品"
end
end
end
else
link_to "作品(#{count})", "javascript:void(0)", :class => "c_blue", :onclick => "notice_sure_box('您不是参赛者,不能提交作品<br/>请加入竞赛,待审批通过后再提交作品')"
end
else
link_to "作品(#{count})", "javascript:void(0)", :class => "c_blue", :onclick => "login_notice_box('#{signin_url_without_domain}');"
end
end
#根据传入作业确定显示为提交作品、补交作品、查看作品等
def student_for_homework_common homework
if User.current.allowed_to?(:as_teacher, homework.course)
link_to "查看作品", student_work_index_url_in_org(homework.id, 2), :class => 'hw_btn_green fr mt5', :title => "查看作品", :target => '_blank'
else User.current.member_of_course?(homework.course)
work = cur_user_works_for_homework homework
project = cur_user_projects_for_homework homework
if work.nil? && homework.end_time >= Time.now
if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1
link_to "关联项目", student_work_index_url_in_org(homework.id, 1), :class => 'hw_btn_green fr mt5',:title => '查看分组作业详情', :target => '_blank'
else
link_to "提交作品", new_student_work_url_without_domain(homework.id),:class => 'hw_btn_green fr mt5', :target => '_blank'
end
elsif work.nil? && homework.end_time < Time.now
if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1
link_to "关联项目", student_work_index_url_in_org(homework.id, 1), :class => 'hw_btn_green fr mt5',:title => '查看分组作业详情', :target => '_blank'
else
link_to "补交作品", new_student_work_url_without_domain(homework.id),:class => 'btn_orange_big fr mt5', :target => '_blank'
end
else
if homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 2 #匿评作业,且作业状态不是在开启匿评之前
link_to "作品匿评", student_work_index_url_in_org(homework.id, 2), :class => 'hw_btn_green fr mt5', :title => "开启匿评后不可修改作品", :target => '_blank'
elsif homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 3
link_to "查看作品",student_work_index_url_in_org(homework.id, 2), :class => 'hw_btn_green fr mt5', :title => "匿评已结束", :target => '_blank'
elsif homework.homework_type == 2 && homework.end_time >= Time.now#编程作业不能修改作品
link_to "修改作品", new_student_work_url_without_domain(homework.id),:class => 'hw_btn_green fr mt5', :target => '_blank'
elsif homework.end_time >= Time.now && work.user_id == User.current.id
link_to "修改作品", edit_student_work_url_without_domain(work.id),:class => 'hw_btn_green fr mt5', :target => '_blank'
else
link_to "查看作品", student_work_index_url_in_org(homework.id, 2), :class => 'hw_btn_green fr mt5', :title => "作业截止后不可修改作品", :target => '_blank'
end
end
end
end
def relate_project homework,is_teacher,is_in_course,user_activity_id,course_activity
if User.current.member_of_course?(homework.course)
if is_teacher
#link_to "已关联(#{homework.student_work_projects.count})",student_work_index_path(:homework => homework.id),:class => "c_blue"
else
projects = cur_user_projects_for_homework homework
works = cur_user_works_for_homework homework
if works.nil? && projects.nil?
link_to "关联项目",new_student_work_project_student_work_index_path(:homework => homework.id,:is_in_course=>is_in_course,:user_activity_id=>user_activity_id,:course_activity=>course_activity),remote: true,:class=> 'c_blue', :title=> '请选择分组作业关联的项目'
elsif works.nil?
link_to "取消关联",cancel_relate_project_student_work_index_path(:homework => homework.id,:is_in_course=>is_in_course,:user_activity_id=>user_activity_id,:course_activity=>course_activity), :confirm => "您确定要取消关联吗?", remote: true,:class => "c_blue", :title=> '取消关联项目'
else
#link_to "已关联(#{homework.student_work_projects.count})",student_work_index_path(:homework => homework.id),:class => "c_blue"
end
end
end
end
def student_anonymous_comment homework
if homework.homework_detail_manual
case homework.homework_detail_manual.comment_status
when 1
"<span class='fr mr10 pr_join_span '>未开启匿评</span>".html_safe
when 2
"<span class='fr mr10 pr_join_span '>正在匿评中</span>".html_safe
when 3
"<span class='fr mr10 pr_join_span '>匿评已结束</span>".html_safe
end
end
end
#获取当前用户在指定作业下提交的作业的集合
def cur_user_works_for_homework homework
work = homework.student_works.where("user_id = ? && work_status != 0",User.current).first
# if homework.homework_type == 3
# pro = homework.student_work_projects.where("user_id = #{User.current.id}").first
# if pro.nil? || pro.student_work_id == "" || pro.student_work_id.nil?
# work = nil
# else
# work = StudentWork.find pro.student_work_id
# end
# end
work
end
#获取当前用户在指定作业下关联的项目的集合
def cur_user_projects_for_homework homework
homework.student_works.where("user_id = ? and project_id != 0",User.current).first
end
#获取当前用户在指定题目下提交的作业的集合
def cur_user_works_for_work homework
work = homework.contestant_works.where("user_id = ? && work_status != 0",User.current).first
if homework.work_type == 3
pro = homework.contestant_work_projects.where("user_id = #{User.current.id}").first
if pro.nil? || pro.contestant_work_id == "" || pro.contestant_work_id.nil?
work = nil
else
work = ContestantWork.find pro.contestant_work_id
end
end
work
end
#获取当前用户在指定题目下关联的项目的集合
def cur_user_projects_for_work work
work.contestant_work_projects.where("user_id = ?",User.current).first
end
#获取当前作业的提交截止时间/互评截止时间
def cur_homework_end_time homework
str = ""
if homework.anonymous_comment == 0 && homework.end_time && homework.end_time < Time.now && homework.homework_detail_manual
str = "互评截止:#{format_date homework.homework_detail_manual.evaluation_end}"
else
str = "提交截止:#{homework.end_time ? (format_date homework.end_time) : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'}"
end
str
end
def file_preview_tag(file, html_options={})
if %w(pdf pptx doc docx xls xlsx).any?{|x| file.filename.downcase.end_with?(x)}
link_to '预览', download_named_attachment_path(file.id, file.filename, preview: true),html_options
end
end
def file_preview_eye(file, html_options={})
if %w(pdf pptx doc docx xls xlsx).any?{|x| file.filename.downcase.end_with?(x)}
link_to '', User.current.logged? ? download_named_attachment_path(file.id, file.filename, preview: true) : signin_url_without_domain, html_options
end
end
#将文本内的/n转换为<br>
def text_format text
text.gsub("&","&amp;").gsub("<","&lt;").gsub(">","&gt;").gsub("\n","<br/>").html_safe
end
#评分规则显示
def scoring_rules late_penalty,homework_id,is_teacher,absence_penalty=nil
if absence_penalty
if late_penalty.to_i == 0 && absence_penalty.to_i == 0
notice = "尚未设置评分规则"
if is_teacher
notice += ",请&nbsp" + link_to("设置",edit_homework_common_path(homework_id),:class => "c_green")
end
elsif late_penalty.to_i != 0 && absence_penalty.to_i == 0
notice = "迟交扣#{late_penalty}分,缺评扣分未设置"
elsif late_penalty.to_i == 0 && absence_penalty.to_i != 0
notice = "迟交扣分未设置,缺评一个作品扣#{absence_penalty}"
elsif late_penalty.to_i != 0 && absence_penalty.to_i != 0
notice = "迟交扣#{late_penalty}分,缺评一个作品扣#{absence_penalty}"
end
else
if late_penalty.to_i == 0
notice = "尚未设置评分规则"
if is_teacher
notice += ",请&nbsp" + link_to("设置",edit_homework_common_path(homework_id),:class => "c_green")
end
else
notice = "迟交扣#{late_penalty}"
end
end
notice.html_safe
end
#老师C语言的标准代码
def c_stantard_code_teacher
"// 老师您好这是一个C语言的样例程序
// 程序功能:输入两个整数,输出两者之和
// 测试集合:老师可以给出多组测试集,例如:
// 输入1和2输出3
// 输入3和4输出7
// ... ...
// 系统将根据您给出的测试集对学生代码进行自动评分
// 特别提醒程序采用命令行传参方式输入通过argv传入
// 否则您的作业标准代码将不能通过测试
#include <stdio.h> //引用必须头文件
int main(int argc, char** argv) {
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
printf(\"%d\",a+b); //输出a+b
return 0;
}".html_safe
end
#老师C++语言的标准代码
def c_stantard_code_teacher_
"// 老师您好这是一个C++语言的样例程序
// 程序功能:输入两个整数,输出两者之和
// 测试集合:老师可以给出多组测试集,例如:
// 输入1和2输出3
// 输入3和4输出7
// ... ...
// 系统将根据您给出的测试集对学生代码进行自动评分
// 特别提醒程序采用命令行传参方式输入通过argv传入
// 否则您的作业标准代码将不能通过测试
#include <iostream> //引用必须头文件
#include <cstdlib>
using namespace std;
int main(int argc, char** argv){
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
cout<<a+b; //输出a+b
return 0;
}".html_safe
end
#学生C语言的标准代码
def c_stantard_code_student
"// 同学好这是一个C语言的样例程序
// 程序功能:输入两个整数,输出两者之和
// 测试集合:老师可以给出多组测试集,例如:
// 输入1和2输出3
// 输入3和4输出7
// ... ...
// 系统将根据您给出的测试集对学生代码进行自动评分
// 特别提醒程序采用命令行传参方式输入通过argv传入
// 否则您的作业标准代码将不能通过测试
#include <stdio.h> //引用必须头文件
int main(int argc, char** argv) {
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
printf(\"%d\",a+b); //输出a+b
return 0;
}".html_safe
end
#学生C++语言的标准代码
def c_stantard_code_student_
"// 同学好这是一个C++语言的样例程序
// 程序功能:输入两个整数,输出两者之和
// 测试集合:老师可以给出多组测试集,例如:
// 输入1和2输出3
// 输入3和4输出7
// ... ...
// 系统将根据您给出的测试集对学生代码进行自动评分
// 特别提醒程序采用命令行传参方式输入通过argv传入
// 否则您的作业标准代码将不能通过测试
#include <iostream> //引用必须头文件
#include <cstdlib>
using namespace std;
int main(int argc, char** argv){
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
cout<<a+b; //输出a+b
return 0;
}".html_safe
end
def compile_command
"compile(){
# 编译命令
compileCommand=\"COMPILECOMMAND\"
# 取当前关卡的编译文件
challengeProgramName=${challengeProgramNames[$1 - 1]}
# 获取编译结果(此处编译无输出则说明编译通过,否则输出编译错误信息,请按实训实际情况调整)
compileResult=$($compileCommand $challengeProgramName 2>&1 | base64)
if [ -z \"$compileResult\" ]; then
compileResult=$(echo -n \"compile successfully\" | base64)
fi
}
compile $1"
end
def execute_command
"execute(){
#执行命令
executeCommand=\"EXECUTECOMMAND\"
#执行文件名
sourceClassName=${sourceClassNames[$1 - 1]}
challengeStage=$1
output=''
i=0
while [[ i -lt ${#ins[*]} ]]; do
#执行,并拼接执行结果
result=$(echo \"${ins[$i]}\" | base64 -d | $executeCommand $sourceClassName 2>&1 | base64)
#拼接输出结果
output=$output\\\"$result\\\",
let i++
done
output=\"[${output%?}]\"
}
execute $1
"
end
def challenge_file_path
"#用户打开的文件名,之所以传过来这个,是因为可以从这个里面提取出来执行文件名
challengeProgramNames=(CHALLENGEPROGRAMNAMES)"
end
def import_ke(default_opt={})
opt = {enable_at: false, prettify: false, init_activity: false}.merge default_opt
ss = ''
unless Setting.at_enabled?
opt[:enable_at] = false
end
ss += javascript_include_tag("/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg')
if opt[:enable_at]
ss += javascript_include_tag('/assets/kindeditor/at/jquery.caret.min.js', '/assets/kindeditor/at/jquery.atwho.js', '/assets/kindeditor/at/config.js')
ss += stylesheet_link_tag("/assets/kindeditor/at/jquery.atwho.css")
end
if opt[:prettify]
ss += javascript_include_tag 'prettify'
ss += stylesheet_link_tag 'prettify'
end
if opt[:init_activity]
ss += javascript_include_tag "create_kindeditor"
end
ss.html_safe
end
#竞赛动态的更新
def update_contest_activity type, id
contest_activity = ContestActivity.where("contest_act_type=? and contest_act_id =?", type.to_s, id).first
if contest_activity
contest_activity.updated_at = Time.now
contest_activity.save
end
end
#课程动态的更新
def update_course_activity type, id
course_activity = CourseActivity.where("course_act_type=? and course_act_id =?", type.to_s, id).first
if course_activity
course_activity.updated_at = Time.now
course_activity.save
end
end
#首页动态更新
def update_user_activity type, id
=begin
user_activity = UserActivity.where("act_type=? and act_id =?", type.to_s, id).first
if user_activity
user_activity.updated_at = Time.now
user_activity.save
end
=end
end
#项目动态更新
def update_forge_activity type, id
forge_activity = ForgeActivity.where("forge_act_type=? and forge_act_id=?", type.to_s, id).first
if forge_activity
forge_activity.updated_at = Time.now
forge_activity.save
end
end
#组织动态更新
def update_org_activity type , id
=begin
org_activity = OrgActivity.where("org_act_type=? and org_act_id =?", type.to_s, id).first
if org_activity
org_activity.updated_at = Time.now
org_activity.save
end
=end
end
#个人动态更新
def update_principal_activity type, id
=begin
principal_activity = PrincipalActivity.where("principal_act_type=? and principal_act_id =?", type.to_s, id).first
if principal_activity
principal_activity.updated_at = Time.now
principal_activity.save
end
=end
end
#项目按更新时间排序
def project_sort_update projects
unless projects.empty?
project_ids = '('+projects.map{|pro|pro.project_id}.join(',')+')'
sort_projects = ForgeActivity.find_by_sql("SELECT MAX(updated_at) AS updated_at,user_id, project_id FROM forge_activities WHERE project_id IN #{project_ids} GROUP BY project_id ORDER BY MAX(updated_at) DESC")
#sort_projects = sort_projects.sort_by{|sp| (!sp.project.project_score.nil? && !sp.project.project_score.commit_time.nil?) ? '' : sp.project.project_score.commit_time}
return sort_projects
end
end
def project_sort_first projects
unless projects.empty?
project_ids = '('+projects.map{|pro|pro.project_id}.join(',')+')'
sort_projects = ForgeActivity.find_by_sql("SELECT updated_at,user_id, project_id FROM forge_activities WHERE project_id IN #{project_ids} ORDER BY updated_at DESC limit 1")
return sort_projects
end
end
def sort_tag(content, opts)
options = {}
options[:sort_by] = opts.delete(:name)
is_current_sort = params[:sort_by].to_s == options[:sort_by]
options[:sort_direction] = is_current_sort && params[:sort_direction].to_s == 'desc' ? 'asc' : 'desc'
path = opts.delete(:path) + "?" + params.merge(options).to_query
arrow_class = case params[:sort_direction].to_s
when 'desc' then 'fa-long-arrow-down'
when 'asc' then 'fa-long-arrow-up'
else ''
end
content_tag(:span, opts) do
link_to path, remote: true do
content += content_tag(:i, '', class: "fa color-light-green ml5 #{arrow_class}") if is_current_sort
raw content
end
end
end
end
def user_url_in_org(user_id)
Setting.protocol + "://" + Setting.host_name + "/users/" + user_id.to_s
end
def project_issues_url_in_org(project_id)
Setting.protocol + "://" + Setting.host_name + "/projects/" + project_id.to_s + "/issues"
end
def issue_url_in_org(id)
Setting.protocol + "://" + Setting.host_name + "/issues/" + id.to_s
end
def project_boards_url_in_org(id)
Setting.protocol + "://" + Setting.host_name + "/projects/" + id.to_s + "/boards"
end
def board_message_url_in_org(board_id, message_id)
Setting.protocol + "://" + Setting.host_name + "/boards/" + board_id.to_s + "/topics/" + message_id.to_s
end
def project_url_in_org(id)
Setting.protocol + "://" + Setting.host_name + "/projects/" + id.to_s
end
def homework_common_index_url_in_org(course_id)
Setting.protocol + "://" + Setting.host_name + "/homework_common?course=" + course_id.to_s
end
def student_work_index_url_in_org(homework_id, tab = 1, is_focus = '', show_work_id = '')
if is_focus != ''
Setting.protocol + "://" + Setting.host_name + "/student_work?homework=" + homework_id.to_s + "&tab=" + tab.to_s + "&is_focus=" + is_focus.to_s
elsif show_work_id != ''
Setting.protocol + "://" + Setting.host_name + "/student_work?homework=" + homework_id.to_s + "&tab=" + tab.to_s + "&show_work_id=" + show_work_id.to_s
else
Setting.protocol + "://" + Setting.host_name + "/student_work?homework=" + homework_id.to_s + "&tab=" + tab.to_s
end
end
def contestant_work_index_url_in_org(work_id, tab = 1, is_focus = '', show_work_id = '')
if is_focus != ''
Setting.protocol + "://" + Setting.host_name + "/contestant_work?work=" + work_id.to_s + "&tab=" + tab.to_s + "&is_focus=" + is_focus.to_s
elsif show_work_id != ''
Setting.protocol + "://" + Setting.host_name + "/contestant_work?work=" + work_id.to_s + "&tab=" + tab.to_s + "&show_work_id=" + show_work_id.to_s
else
Setting.protocol + "://" + Setting.host_name + "/contestant_work?work=" + work_id.to_s + "&tab=" + tab.to_s
end
end
def course_url_in_org(course_id)
Setting.protocol + "://" + Setting.host_name + "/courses/" + course_id.to_s
end
def user_watchlist_url_in_org(id)
Setting.protocol + "://" + Setting.host_name + "/users/" + id.to_s + "/user_watchlist"
end
def user_fanslist_url_in_org(id)
Setting.protocol + "://" + Setting.host_name + "/users/" + id.to_s + "/user_fanslist"
end
def user_blogs_url_in_org(user_id)
Setting.protocol + "://" + Setting.host_name + "/users/" + user_id.to_s + "/blogs"
end
def feedback_url_in_org(user_id)
Setting.protocol + "://" + Setting.host_name + "/users/" + user_id.to_s + "/user_newfeedback"
end
def user_activities_url_in_org(user_id)
Setting.protocol + "://" + Setting.host_name + "/users/" + user_id.to_s + "/user_activities"
end
def course_news_index_url_in_org(course_id)
Setting.protocol + "://" + Setting.host_name + "/courses/" + course_id.to_s + "/news"
end
def news_url_in_org(news_id)
Setting.protocol + "://" + Setting.host_name + "/news/" + news_id.to_s
end
def course_boards_url_in_org(course_id)
Setting.protocol + "://" + Setting.host_name + "/courses/" + course_id.to_s + "/boards"
end
def logout_url_without_domain
Setting.protocol + "://" + Setting.host_name + "/logout"
end
def signin_url_without_domain
Setting.protocol + "://" + Setting.host_name + "/login?login=true"
end
def register_url_without_domain
Setting.protocol + "://" + Setting.host_name + "/login?login=false"
end
def new_student_work_url_without_domain(homework_id)
Setting.protocol + "://" + Setting.host_name + "/student_work/new?homework=" + homework_id.to_s
end
def edit_student_work_url_without_domain(homework_id)
Setting.protocol + "://" + Setting.host_name + "/student_work/" + homework_id.to_s + "/edit"
end
def download_named_attachment_url_without_domain(id, filename, option={})
attachment_id = (Attachment === id ? id.id : id)
Setting.protocol + "://" + Setting.host_name + "/attachments/download/" + attachment_id.to_s + "/" + filename
end
def named_attachment_url_without_domain(id, filename, option={})
attachment_id = (Attachment === id ? id.id : id)
Setting.protocol + "://" + Setting.host_name + "/attachments/" + attachment_id.to_s + "/" + filename
end
#判断是否为默认的组织栏目
def is_default_field? field
(field.name == 'activity' || field.name == 'course' || field.name == 'project' ) && field.field_type == 'default'
end
def host_with_protocol
return Setting.protocol + "://" + Setting.host_name
end
def secdomain_with_protocol secdomain
return Setting.protocol + "://" + secdomain + ".trustie.net"
end
#根据回复类型获取回复
def get_reply_by_type type, reply_id
reply = nil
case type
when 'HomeworkCommon', 'Work', 'GraduationTopic', 'GraduationTask'
reply = JournalsForMessage.find reply_id
when 'JournalsForMessage'
reply = JournalsForMessage.find reply_id
when 'Message'
reply = Message.find reply_id
when 'BlogComment'
reply = BlogComment.find reply_id
when 'OrgDocumentComment'
reply = OrgDocumentComment.find reply_id
when 'News','Comment'
reply = Comment.find reply_id
when 'Issue', 'TrainingTask'
reply = Journal.find reply_id
when 'Journal'
reply = Journal.find reply_id
when 'Syllabus'
reply = JournalsForMessage.find reply_id
when 'Memo'
reply = Memo.find reply_id
when 'Challenge'
reply = Discuss.find reply_id
end
reply
end
#获取不包含子节点的回复(前三个)
def get_no_children_comments comments
result = {}
no_children_comments = []
count = 0
three_more = false
comments.each do |comment|
if comment.children.blank?
count = count + 1
if count > 3
three_more = true
end
break if count > 3
no_children_comments << comment
end
end
result[:three_more] = three_more
result[:no_children_comments] = no_children_comments
result
end
#获取不包含子节点的回复(所有)
def get_no_children_comments_all comments
no_children_comments = []
comments.each do |comment|
if comment.children.blank?
no_children_comments << comment
end
end
no_children_comments
end
#获取回复的所有父节点
def get_reply_parents parents_rely, comment
unless comment.parent.nil?
parents_rely << comment.parent
get_reply_parents parents_rely, comment.parent
end
parents_rely
end
#获取回复的所有父节点(不包括根节点)
def get_reply_parents_no_root parents_rely, comment
if !comment.parent.nil? && !comment.parent.parent.nil?
parents_rely << comment.parent
get_reply_parents_no_root parents_rely, comment.parent
end
parents_rely
end
def get_all_children_ex result, jour
if jour.kind_of? Message
jour.children.includes(:author, :praise_tread_cache).each do |jour_child|
result << jour_child
get_all_children_ex result, jour_child
end
elsif (jour.kind_of? JournalsForMessage) || (jour.kind_of? BlogComment) || (jour.kind_of? OrgDocumentComment)
jour.children.each do |jour_child|
result << jour_child
get_all_children_ex result, jour_child
end
end
result
end
#获取所有子节点
def get_all_children result, jour
if jour.kind_of? Message
jour.children.includes(:author, :praise_tread_cache).each do |jour_child|
result << jour_child
get_all_children_ex result, jour_child
end
elsif (jour.kind_of? JournalsForMessage) || (jour.kind_of? BlogComment) || (jour.kind_of? OrgDocumentComment)
jour.children.each do |jour_child|
result << jour_child
get_all_children_ex result, jour_child
end
end
if jour.respond_to?(:created_on)
result.sort! { |a,b| b.created_on <=> a.created_on }
elsif jour.respond_to?(:created_at)
result.sort! { |a,b| b.created_at <=> a.created_at }
end
result
end
#获取该节点所在的帖子
def get_root_parent comment
while comment.parent
comment = comment.parent
end
comment
end
#将有置顶属性的提到数组前面
def sort_by_sticky topics
tmpTopics = []
tmpIndex = 0
topics.each do |topic|
if topic.sticky == 1
tmpTopics[tmpIndex] = topic
tmpIndex = tmpIndex + 1
end
end
topics.each do |topic|
if topic.sticky == 0
tmpTopics[tmpIndex] = topic
tmpIndex = tmpIndex + 1
end
end
return tmpTopics
end
#按人气排序的时候 相同的人气必须按某种时间顺序排序 有置顶属性
def sortby_time_countcommon_hassticky topics,sortstr
tmpTopics = []
tmpTopics = topics
tStart = -1
tEnd = -1
tmpTopics_1 = []
tmpIndex = 0
tmpTopics.each_with_index do |topic,index|
if topic.sticky == 0
if tStart == -1
if (index != tmpTopics.count-1) && (topic[:infocount] == tmpTopics[index+1][:infocount])
tStart = index
end
else
if ((topic[:infocount] == tmpTopics[index-1][:infocount]) && ((index != tmpTopics.count-1) && (topic[:infocount] == tmpTopics[index+1][:infocount])))
tEnd = index
else
if (topic[:infocount] == tmpTopics[index-1][:infocount])
tEnd = index
end
if tEnd > tStart
for i in tStart..tEnd
tmpTopics_1[tmpIndex] = tmpTopics[i]
tmpIndex = tmpIndex + 1
end
if sortstr == "created_at"
tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:created_at].to_i <=> x[:created_at].to_i }
elsif sortstr == "created_on"
tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:created_on].to_i <=> x[:created_on].to_i }
elsif sortstr == "updated_at"
tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:updated_at].to_i <=> x[:updated_at].to_i }
elsif sortstr == "updated_on"
tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:updated_on].to_i <=> x[:updated_on].to_i }
end
tmpIndex = 0
for i in tStart..tEnd
tmpTopics[i] = tmpTopics_1[tmpIndex]
tmpIndex = tmpIndex + 1
end
end
tStart = -1
tEnd = -1
tmpTopics_1 = []
tmpIndex = 0
end
end
end
end
return tmpTopics
end
#按人气排序的时候 相同的人气必须按某种时间顺序排序 无置顶属性
def sortby_time_countcommon_nosticky topics,sortstr
tmpTopics = []
tmpTopics = topics
tStart = -1
tEnd = -1
tmpTopics_1 = []
tmpIndex = 0
tmpTopics.each_with_index do |topic,index|
if tStart == -1
if (index != tmpTopics.count-1) && (topic[:infocount] == tmpTopics[index+1][:infocount])
tStart = index
end
else
if ((topic[:infocount] == tmpTopics[index-1][:infocount]) && ((index != tmpTopics.count-1) && (topic[:infocount] == tmpTopics[index+1][:infocount])))
tEnd = index
else
if (topic[:infocount] == tmpTopics[index-1][:infocount])
tEnd = index
end
if tEnd > tStart
for i in tStart..tEnd
tmpTopics_1[tmpIndex] = tmpTopics[i]
tmpIndex = tmpIndex + 1
end
if sortstr == "created_at"
tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:created_at].to_i <=> x[:created_at].to_i }
elsif sortstr == "created_on"
tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:created_on].to_i <=> x[:created_on].to_i }
elsif sortstr == "updated_at"
tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:updated_at].to_i <=> x[:updated_at].to_i }
elsif sortstr == "updated_on"
tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:updated_on].to_i <=> x[:updated_on].to_i }
end
tmpIndex = 0
for i in tStart..tEnd
tmpTopics[i] = tmpTopics_1[tmpIndex]
tmpIndex = tmpIndex + 1
end
end
tStart = -1
tEnd = -1
tmpTopics_1 = []
tmpIndex = 0
end
end
end
return tmpTopics
end
def strip_html(text,len=0,endss="...")
ss = ""
if !text.nil? && text.length>0
ss=text.gsub(/<\/?.*?>/, '').strip
ss = ss.gsub(/&nbsp;*/, ' ')
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
return ss
end
def message_content content
content = (strip_html content).strip
content = content.gsub(/\s+/, " ")
if content.gsub(" ", "") == ""
content = "[非文本消息]"
end
content
end
def get_work_index(hw,is_teacher)
if is_teacher
works = hw.contest.works.order("created_at asc")
else
works = hw.contest.works.where("publish_time <= '#{Date.today}'").order("created_at asc")
end
hw_ids = works.map{|hw| hw.id} if !works.empty?
index = hw_ids.index(hw.id).to_i
return index
end
def get_poll_index(poll, course, is_teacher)
if is_teacher
polls = course.polls.order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
elsif User.current.member_of_course?(course)
member = course.members.where(:user_id => User.current.id).first
if member.try(:course_group_id).to_i == 0
polls = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
else
not_poll_ids = course.poll_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)")
not_poll_ids = not_poll_ids.blank? ? "(-1)" : "(" + not_poll_ids.map(&:poll_id).join(",") + ")"
polls = course.polls.where("publish_time <= '#{Time.now}' and id not in #{not_poll_ids}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
end
else
polls = course.polls.where("publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
end
poll_ids = polls.map{|poll| poll.id} if !polls.blank?
index = poll_ids.length - 1 - poll_ids.index(poll.id).to_i
return index
end
def get_ex_index(exercise, course, is_teacher)
if is_teacher
exercises = course.exercises.order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
elsif User.current.member_of_course?(course)
member = course.members.where(:user_id => User.current.id).first
if member.try(:course_group_id).to_i == 0
exercises = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
else
not_exercise_ids = course.exercise_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)")
not_exercise_ids = not_exercise_ids.blank? ? "(-1)" : "(" + not_exercise_ids.map(&:exercise_id).join(",") + ")"
exercises = course.exercises.where("publish_time <= '#{Time.now}' and id not in #{not_exercise_ids}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
end
else
exercises = course.exercises.where("publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
end
ex_ids = exercises.map{|ex| ex.id} if !exercises.blank?
index = ex_ids.length - 1 - ex_ids.index(exercise.id).to_i
return index
end
def get_task_index task, is_teacher
if is_teacher
tasks = task.course.graduation_tasks.order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
else
tasks = task.course.graduation_tasks.where("publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
end
task_ids = tasks.pluck(:id)
index = task_ids.length - task_ids.index(task.id).to_i
return index
end
def get_hw_index(hw,is_teacher,type=0)
homework_commons = hw.course.homework_commons
course = hw.course
category_str = hw.course_homework_category_id.nil? ? "is null" : "= #{hw.course_homework_category_id}"
if is_teacher
if type != 0
homeworks = homework_commons.where("homework_commons.homework_type = #{type} and course_homework_category_id #{category_str}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
else
homeworks = homework_commons.where("course_homework_category_id #{category_str}").order("publish_time desc")
end
elsif User.current.member_of_course?(course)
member = course.members.where(:user_id => User.current.id).first
if member.try(:course_group_id).to_i == 0
if type != 0
homeworks = homework_commons.where("course_homework_category_id #{category_str} and homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' and unified_setting = 1").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
else
homeworks = homework_commons.where("course_homework_category_id #{category_str} and publish_time <= '#{Time.now}' and unified_setting = 1").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
end
else
not_homework_ids = course.homework_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)")
not_homework_ids = not_homework_ids.blank? ? "(-1)" : "(" + not_homework_ids.map(&:homework_common_id).join(",") + ")"
if type != 0
homeworks = homework_commons.where("course_homework_category_id #{category_str} and homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' and id not in #{not_homework_ids}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
else
homeworks = homework_commons.where("course_homework_category_id #{category_str} and publish_time <= '#{Time.now}' and id not in #{not_homework_ids}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
end
end
else
if type != 0
homeworks = homework_commons.where("course_homework_category_id #{category_str} and homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
else
homeworks = homework_commons.where("course_homework_category_id #{category_str} and publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
end
end
hw_ids = homeworks.map{|hw| hw.id} if !homeworks.blank?
index = hw_ids.blank? ? 1 : (hw_ids.length - 1 - hw_ids.index(hw.id).to_i)
return index
end
def get_hw_status homework_common
str = ""
if homework_common.homework_detail_manual
if homework_common.homework_detail_manual.comment_status == 0 && homework_common.publish_time.nil?
str += '<span class="grey_homework_btn_cir ml5">未发布</span>'
elsif homework_common.homework_detail_manual.comment_status == 0
str += '<span class="grey_homework_btn_cir ml5">未发布</span>'
elsif homework_common.homework_detail_manual.comment_status == 1
if homework_common.anonymous_comment == 0
str += '<span class="grey_homework_btn_cir ml5">未开启匿评</span>'
else
str += '<span class="grey_homework_btn_cir ml5">匿评已禁用</span>'
end
if homework_common.end_time >= Time.now
str += '<span class="green_homework_btn_cir ml5">作品提交中</span>'
elsif homework_common.end_time < Time.now && homework_common.anonymous_comment == 1 && User.current.allowed_to?(:as_teacher, homework_common.course)
str += '<span class="green_homework_btn_cir ml5" title="目前教师和教辅正在评阅">教师评阅中</span>'
else
str += '<span class="red_homework_btn_cir ml5">作品补交中</span>'
end
elsif homework_common.homework_detail_manual.comment_status == 2
if homework_common.anonymous_comment == 0
str += '<span class="green_homework_btn_cir ml5">匿评中</span>'
else
str += '<span class="grey_homework_btn_cir ml5">匿评已禁用</span>'
end
str += '<span class="green_homework_btn_cir ml5" title="目前教师和教辅正在评阅">教师评阅中</span>'
elsif homework_common.homework_detail_manual.comment_status == 3
if homework_common.anonymous_comment == 0
str += '<span class="grey_homework_btn_cir ml5">匿评已结束</span>'
else
str += '<span class="grey_homework_btn_cir ml5">匿评已禁用</span>'
end
str += '<span class="green_homework_btn_cir ml5" title="目前教师和教辅正在评阅">教师评阅中</span>'
end
end
str
end
def get_cw_status contest_work
str = ""
if contest_work.work_status == 0 && contest_work.publish_time.nil?
str += '<span class="grey_homework_btn_cir ml5">挂起</span>'
elsif contest_work.work_status == 0
str += '<span class="grey_homework_btn_cir ml5">未发布</span>'
elsif contest_work.work_status == 1
if Time.parse(contest_work.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d")
str += '<span class="green_homework_btn_cir ml5">作品提交中</span>'
else
str += '<span class="red_homework_btn_cir ml5">作品补交中</span>'
end
elsif contest_work.work_status == 2
str += '<span class="red_homework_btn_cir ml5">提交已截止</span>'
elsif contest_work.work_status == 3
str += '<span class="green_homework_btn_cir ml5">在线评审中</span>'
elsif contest_work.work_status == 4
str += '<span class="red_homework_btn_cir ml5">评审已截止</span>'
end
str
end
def get_group_member_names user_ids
result = ""
user_ids.each do |user_id|
user = User.where(:id => user_id).first
unless user.nil?
if result != ""
result += "#{user.show_name}"
else
result += user.show_name
end
end
end
result
end
def get_contest_group_member_names work
result = ""
unless work.nil?
work.contestant_work_projects.each do |member|
user = User.where(:id => member.user_id).first
unless user.nil?
if result != ""
result += "#{user.show_name}"
else
result += user.show_name
end
end
end
end
result
end
def course_syllabus_option syllabus_id = nil
syllabus_members = SyllabusMember.where("user_id = #{User.current.id}")
syllabus_ids = syllabus_members.map{|mem| mem.syllabus_id}
if syllabus_id && !syllabus_ids.include?(syllabus_id)
syllabus_ids << syllabus_id
end
syllabus_ids = syllabus_ids.empty? ? "(-1)" : "(" + syllabus_ids.join(',') + ")"
syllabuses = Syllabus.where("id in #{syllabus_ids}")
type = []
option1 = []
option1 << "请选择课程"
option1 << 0
type << option1
unless syllabuses.empty?
syllabuses.each do |syllabus|
option = []
option << syllabus.title
option << syllabus.id
type << option
end
end
type
end
def create_polls_tiding poll, members
tid_str = ""
if poll.tidings.where(:parent_container_type => "PollPublish", :user_id => poll.course.teachers.map(&:user_id)).count == 0
poll.course.teachers.find_each do |member|
tid_str += "," if tid_str != ""
tid_str += "(#{member.user_id}, #{poll.user_id}, #{poll.id}, 'Poll', #{poll.id}, 'PollPublish', #{poll.course.id}, 'Course', 0, 'Poll', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
end
members.find_each do |student|
tid_str += "," if tid_str != ""
tid_str += "(#{student.user_id}, #{poll.user_id}, #{poll.id}, 'Poll', #{poll.id}, 'PollPublish', #{poll.course_id}, 'Course', 0, 'Poll', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
if tid_str != ""
tid_sql = "insert into tidings (user_id, trigger_user_id, container_id, container_type, parent_container_id, parent_container_type, belong_container_id, belong_container_type, viewed, tiding_type, created_at, updated_at) values" + tid_str
ActiveRecord::Base.connection.execute tid_sql
end
end
def create_polls_list poll
str = ""
poll.course.student.find_each do |student|
str += "," if str != ""
str += "(#{student.user_id},#{poll.id}, 0, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
if str != ""
sql = "insert into poll_users (user_id, poll_id, commit_status, created_at, updated_at) values" + str
ActiveRecord::Base.connection.execute sql
end
end
def create_exercises_tiding exercise, members
tid_str = ""
if exercise.tidings.where(:parent_container_type => "ExercisePublish", :user_id => exercise.course.teachers.map(&:user_id)).count == 0
exercise.course.teachers.find_each do |member|
tid_str += "," if tid_str != ""
tid_str += "(#{member.user_id}, #{exercise.user_id}, #{exercise.id}, 'Exercise', #{exercise.id}, 'ExercisePublish', #{exercise.course.id}, 'Course', 0, 'Exercise', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
end
members.find_each do |student|
tid_str += "," if tid_str != ""
tid_str += "(#{student.user_id}, #{exercise.user_id}, #{exercise.id}, 'Exercise', #{exercise.id}, 'ExercisePublish', #{exercise.course_id}, 'Course', 0, 'Exercise', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
if tid_str != ""
tid_sql = "insert into tidings (user_id, trigger_user_id, container_id, container_type, parent_container_id, parent_container_type, belong_container_id, belong_container_type, viewed, tiding_type, created_at, updated_at) values" + tid_str
ActiveRecord::Base.connection.execute tid_sql
end
end
def create_exercises_list exercise
str = ""
exercise.course.student.find_each do |student|
str += "," if str != ""
str += "(#{student.user_id}, #{exercise.id}, 0, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
if str != ""
sql = "insert into exercise_users (user_id, exercise_id, commit_status, created_at, updated_at) values" + str
ActiveRecord::Base.connection.execute sql
end
end
def create_works_tiding homework, members
tid_str = ""
if homework.tidings.where(:parent_container_type => "HomeworkPublish", :user_id => homework.course.teachers.map(&:user_id)).count == 0
homework.course.teachers.find_each do |member|
tid_str += "," if tid_str != ""
tid_str += "(#{member.user_id}, #{homework.user_id}, #{homework.id}, 'HomeworkCommon', #{homework.id}, 'HomeworkPublish', #{homework.course.id}, 'Course', 0, 'HomeworkCommon', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
end
members.find_each do |student|
tid_str += "," if tid_str != ""
tid_str += "(#{student.user_id}, #{homework.user_id}, #{homework.id}, 'HomeworkCommon', #{homework.id}, 'HomeworkPublish', #{homework.course_id}, 'Course', 0, 'HomeworkCommon', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
if tid_str != ""
tid_sql = "insert into tidings (user_id, trigger_user_id, container_id, container_type, parent_container_id, parent_container_type, belong_container_id, belong_container_type, viewed, tiding_type, created_at, updated_at) values" + tid_str
ActiveRecord::Base.connection.execute tid_sql
end
end
def create_works_list homework
if homework.course.present? && homework.course.student.count > 0
str = ""
name = homework.name
name_str = name + "的作品提交"
homework.course.student.each do |student|
str += "," if str != ""
str += "('#{name_str}',#{homework.id},#{student.user_id}, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
if str != ""
sql = "insert into student_works (name, homework_common_id, user_id, created_at, updated_at) values" + str
ActiveRecord::Base.connection.execute sql
end
end
end
def add_to_homework_bank_f homework
homework_bank = HomeworkBank.new(:name => homework.name, :description => homework.description, :user_id => User.current.id, :homework_type => homework.homework_type,
:quotes => 1, :is_public => 0, :applicable_syllabus => homework.course.course_list_name, :homework_common_id => homework.id,
:reference_answer => homework.reference_answer, :course_list_id => homework.course.course_list_id)
if homework.homework_type == 2 && homework.homework_detail_programing
homework_bank.language = homework.homework_detail_programing.language
homework.homework_tests.each_with_index do |homework_test|
homework_bank.homework_bank_tests << HomeworkBankTest.new(
input: homework_test.input,
output: homework_test.output
)
end
homework.homework_samples.each_with_index do |homework_test|
homework_bank.homework_bank_samples << HomeworkBankSample.new(
input: homework_test.input,
output: homework_test.output
)
end
elsif homework.homework_type == 3 && homework.homework_detail_group
homework_bank.min_num = homework.homework_detail_group.min_num
homework_bank.max_num = homework.homework_detail_group.max_num
homework_bank.base_on_project = homework.homework_detail_group.base_on_project
end
homework.attachments.each do |attachment|
att = attachment.copy
att.container_id = nil
att.container_type = nil
att.author_id = homework_bank.user_id
att.copy_from = attachment.id
att.save
homework_bank.attachments << att
end
homework_bank
end
# 获取项目动态更新时间
def get_forge_act_message(act, type)
forge_act = ForgeActivity.where(:forge_act_id => act.id, :forge_act_type => type).first
format_time(forge_act.nil? ? act.created_on : forge_act.try(:updated_at))
end
#作业类型
def homework_type_option
type = []
option0 = []
option0 << "请选择作业类型"
option0 << 0
option1 = []
option1 << "普通作业"
option1 << 1
option2 = []
option2 << "编程作业"
option2 << 2
option3 = []
option3 << "分组作业"
option3 << 3
type << option0
type << option1
type << option2
type << option3
type
end
# 竞赛题目类型
def work_type_option
type = []
option0 = []
option0 << "请选择竞赛类型"
option0 << 0
option1 = []
option1 << "普通竞赛"
option1 << 1
# option2 = []
# option2 << "编程作业"
# option2 << 2
option3 = []
option3 << "团队竞赛"
option3 << 3
type << option0
type << option1
#type << option2
type << option3
type
end
# 当前用户可见的某竞赛下的作品数
def visable_contest_work contest
if User.current.admin? || User.current.admin_of_contest?(contest)
work_num = contest.works.count
else
work_num = contest.works.where("work_status > 0").count
end
work_num
end
def searchstudent_by_name users, name
mems = []
if name != ""
name = name.to_s.downcase
users.each do |m|
username = m.lastname.to_s.downcase + m.firstname.to_s.downcase
if(m.login.to_s.downcase.include?(name) || m.user_extensions[:student_id].to_s.downcase.include?(name) || username.include?(name))
mems << m
end
end
else
mems = users
end
mems
end
def contest_feedback_count
@contest.journals_for_messages.where('m_parent_id IS NULL').count
end
def add_reply_adapter obj, options
#modify by nwb
#添加对课程留言的支持
#留言回复应该不关系其所属的Class而关心的是其所属的父留言
case obj.jour_type
when 'Principal'
obj.jour.add_jour(nil, nil, nil, options)
when 'Project'
Project.add_new_jour(nil, nil, obj.jour_id, options)
when 'Course'
Course.add_new_jour(nil, nil, obj.jour_id, options)
when 'Contest'
Contest.add_new_jour(nil, nil, obj.jour_id, options)
#when 'Bid'
# obj.jour.add_jour(nil, nil, nil, options)
#when 'Contest'
# obj.jour.add_jour(nil, nil, obj.jour_id, options)
#when 'Softapplication'
# obj.jour.add_jour(nil, nil, obj.jour_id, options)
#when 'HomeworkAttach'
# obj.jour.add_jour(nil, nil, obj.jour_id, options)
end
# obj = obj_distinguish_url_origin || User.find_by_id(2)
# if obj.kind_of? User
# obj.add_jour(nil, nil, nil, options)
# elsif obj.kind_of? Project
# Project.add_new_jour(nil, nil, obj.id, options)
# elsif obj.kind_of? Course
# Course.add_new_jour(nil, nil, obj.id, options)
# elsif obj.kind_of? Bid
# obj.add_jour(nil, nil, nil, options)
# elsif obj.kind_of? Contest
# obj.add_jour(nil, nil, obj.id, options) #new added
# elsif obj.kind_of? Softapplication
# obj.add_jour(nil, nil, obj.id, options) #new added
# elsif obj.kind_of? HomeworkAttach
# obj.add_jour(nil, nil, obj.id, options) #new added
# else
# raise "create reply obj unknow type.#{obj.class}"
# end
end
def sy_resources syllabus
courses = syllabus.courses.not_deleted
attachments = Attachment.where(:container_type => 'Course', :container_id => courses.map(&:id))
resources = ResourceBank.where(:id => attachments.map(&:resource_bank_id))
resources
end
def sy_homeworks syllabus
courses = syllabus.courses.not_deleted
homeworks = HomeworkCommon.where(:course_id => courses.map(&:id))
homeworks = HomeworkBank.where(:id => homeworks.map(&:homework_bank_id))
homeworks
end
# 课堂学生的评测次数
def course_eval_count course
Output.find_by_sql("select sum(g.evaluate_count) as evaluating_count from games g inner join
(select myshixun_id from student_works sw inner join homework_commons hc on sw.homework_common_id=hc.id and
sw.myshixun_id !=0 and hc.course_id=#{course.id} and homework_type=4) aa on g.myshixun_id=aa.myshixun_id").first.try(:evaluating_count).to_i
end
# 可以查看到资源库的资源
def visable_attachemnts_incourse course
return[] unless course
result = []
course.attachments.each do |attachment|
if attachment.unified_setting
if attachment.is_public? && attachment.is_publish == 1 || User.current == attachment.author || User.current.allowed_to?(:as_teacher,course) || (User.current.member_of_course?(course) && attachment.is_publish == 1) || User.current.admin?
result << attachment
end
else
if attachment.is_public? && attachment.is_publish == 1 && !User.current.member_of_course?(course) || User.current == attachment.author || User.current.allowed_to?(:as_teacher,course) || User.current.admin?
result << attachment
elsif User.current.member_of_course?(course) && attachment.is_publish == 1
member = course.members.where(:user_id => User.current.id).first
if member.try(:course_group_id).to_i == 0 && attachment.unified_setting
result << attachment
elsif attachment.attachment_group_settings.where("course_group_id = #{member.try(:course_group_id)} and publish_time > '#{Time.now}'").count == 0
result << attachment
end
end
end
end
result
end
def visable_course_poll course, is_teacher
if is_teacher
poll_num = course.polls.count
elsif User.current.member_of_course?(course)
member = course.members.where(:user_id => User.current.id).first
if member.try(:course_group_id).to_i == 0
poll_num = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1").count
else
not_poll_ids = course.poll_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)")
not_poll_ids = not_poll_ids.blank? ? "(-1)" : "(" + not_poll_ids.map(&:poll_id).join(",") + ")"
poll_num = course.polls.where("publish_time <= '#{Time.now}' and id not in #{not_poll_ids}").count
end
else
poll_num = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1").count
end
poll_num
end
def visable_course_exercise course, is_teacher
if is_teacher
exercise_num = course.exercises.count
elsif User.current.member_of_course?(course)
member = course.members.where(:user_id => User.current.id).first
if member.try(:course_group_id).to_i == 0
exercise_num = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1").count
else
not_exercise_ids = course.exercise_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)")
not_exercise_ids = not_exercise_ids.blank? ? "(-1)" : "(" + not_exercise_ids.map(&:exercise_id).join(",") + ")"
exercise_num = course.exercises.where("publish_time <= '#{Time.now}' and id not in #{not_exercise_ids}").count
end
else
exercise_num = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1").count
end
exercise_num
end
def visable_course_homework course, type=0, is_teacher, category_id
category_str = category_id.nil? ? "is null" : "= #{category_id}"
if is_teacher
if type != 0
homework_num = course.homework_commons.where("homework_type = #{type} and course_homework_category_id #{category_str}").count
else
homework_num = course.homework_commons.where(:homework_type => [1,3,4]).count
end
elsif User.current.member_of_course?(course)
member = course.members.where(:user_id => User.current.id).first
if member.try(:course_group_id).to_i == 0
if type != 0
homework_num = course.homework_commons.where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' and unified_setting = 1 and course_homework_category_id #{category_str}").count
else
homework_num = course.homework_commons.where("homework_type in (1, 3, 4) and publish_time <= '#{Time.now}' and unified_setting = 1").count
end
else
not_homework_ids = course.homework_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)")
not_homework_ids = not_homework_ids.blank? ? "(-1)" : "(" + not_homework_ids.map(&:homework_common_id).join(",") + ")"
if type != 0
homework_num = course.homework_commons.where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' and id not in #{not_homework_ids} and course_homework_category_id #{category_str}").count
else
homework_num = course.homework_commons.where("homework_type in (1, 3, 4) and publish_time <= '#{Time.now}' and id not in #{not_homework_ids}").count
end
end
else
if type != 0
homework_num = course.homework_commons.where("homework_type = #{type} and publish_time <= '#{Time.now}' and unified_setting = 1 and course_homework_category_id #{category_str}").count
else
homework_num = course.homework_commons.where("homework_type in (1, 3, 4) and publish_time <= '#{Time.now}' and unified_setting = 1").count
end
end
homework_num
end
def visible_task_count course, is_teacher
task_count = 0
if is_teacher
task_count = course.graduation_tasks.count
else
task_count = course.graduation_tasks.where("publish_time <= '#{Time.now}'").count
end
task_count
end
def update_shixun_work_status homework
shixun = homework.shixuns.first
student_works = homework.student_works.where(:work_status => 0)
homework_challenge_settings = homework.homework_challenge_settings
challeng_ids = homework_challenge_settings.map(&:challenge_id)
# 取已发布的作品
if homework.unified_setting
student_works = student_works
else
setting = homework.homework_group_settings.where("publish_time < '#{Time.now}'")
if setting.blank?
student_works = student_works.none
else
users = homework.course.members.where(:course_group_id => setting.map(&:course_group_id))
student_works = student_works.where(:user_id => users.map(&:user_id))
end
end
# 已发布作品且状态为未提交的作品 如果有开启过实训则更新状态
myshixuns = Myshixun.where(:shixun_id => shixun.id, :user_id => student_works.map(&:user_id))
myshixuns.each do |myshixun|
work = student_works.where(:user_id => myshixun.user_id).first
member = homework.course.members.find_by_user_id(work.user_id)
setting_time = homework_group_setting homework, member.try(:course_group_id)
games = myshixun.games.where(:challenge_id => challeng_ids)
myshixun_endtime = games.select{|game| game.status == 2}.size == games.size ? games.map(&:end_time).max : nil
compelete_status = 0
if myshixun_endtime.present? && myshixun_endtime < setting_time.end_time
if myshixun_endtime < setting_time.publish_time
compelete_status = 2
else
compelete_status = 1
end
end
if setting_time.end_time > Time.now
work.update_attributes(:work_status => 1, :late_penalty => 0, :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id, :compelete_status => compelete_status)
else
work.update_attributes(:work_status => ((myshixun.is_complete? && (myshixun.done_time < setting_time.end_time)) ? 1 : 2), :late_penalty => (myshixun.is_complete? && (myshixun.done_time < setting_time.end_time) ? 0 : homework.late_penalty), :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id, :compelete_status => compelete_status)
end
set_shixun_final_score work, homework.homework_detail_manual.answer_open_evaluation, homework_challenge_settings
end
# 更新所有学生的效率分
update_student_eff_score HomeworkCommon.where(:id => homework.id).first
=begin
student_works.each do |work|
if work.work_status == 0
myshixun = Myshixun.where(:shixun_id => shixun.id, :user_id => work.user_id).first
if myshixun
member = Member.find_by_sql("select course_group_id from members where course_id = #{homework.course_id} and user_id = #{User.current.id}").first
setting_time = homework_group_setting homework, member.try(:course_group_id)
if setting_time.end_time > Time.now
work.update_attributes(:work_status => 1, :late_penalty => 0, :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id)
else
work.update_attributes(:work_status => ((myshixun.is_complete? && (myshixun.done_time < setting_time.end_time)) ? 1 : 2), :late_penalty => (myshixun.is_complete? && (myshixun.done_time < setting_time.end_time) ? 0 : homework.late_penalty), :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id)
end
end
end
set_shixun_final_score work, homework.homework_detail_manual.answer_open_evaluation, homework_challenge_settings
end
=end
end
#成绩计算
def set_final_score homework,student_work
if homework && homework.homework_detail_manual && !student_work.ultimate_score
if !homework.homework_detail_manual.final_mode
tea_ass_proportion = homework.homework_detail_manual.ta_proportion
tea_proportion = homework.homework_detail_manual.te_proportion
if homework.homework_type != 2 #非编程作业
if student_work.teacher_score
if student_work.teaching_asistant_score.nil?
if student_work.student_score.nil?
student_work.final_score = student_work.teacher_score
else
te_proportion = tea_proportion + tea_ass_proportion / 2
final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{te_proportion}")
final_s_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{te_proportion}"))
final_score = final_te_score + final_s_score
student_work.final_score = format("%.2f",final_score.to_f)
end
else
if student_work.student_score.nil?
te_proportion = tea_proportion + (1.0 - tea_proportion - tea_ass_proportion) / 2
final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{te_proportion}")
final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{te_proportion}"))
final_score = final_te_score + final_ta_score
student_work.final_score = format("%.2f",final_score.to_f)
else
final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{tea_proportion}")
final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * BigDecimal.new("#{tea_ass_proportion}")
final_s_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{tea_proportion}") - BigDecimal.new("#{tea_ass_proportion}"))
final_score = final_te_score + final_ta_score + final_s_score
student_work.final_score = format("%.2f",final_score.to_f)
end
end
else
if student_work.teaching_asistant_score.nil?
student_work.final_score = student_work.student_score
elsif student_work.student_score.nil?
student_work.final_score = student_work.teaching_asistant_score
else
ta_proportion = tea_ass_proportion + tea_proportion / 2
final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * BigDecimal.new("#{ta_proportion}")
final_s_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}"))
final_score = final_ta_score + final_s_score
student_work.final_score = format("%.2f",final_score.to_f)
end
end
elsif homework.homework_type == 2 && homework.homework_detail_programing #编程作业-----设定:系统评分必定不为空
#if homework.teacher_priority == 1 #教师优先
sy_proportion = homework.homework_detail_programing.ta_proportion
if student_work.teacher_score
if student_work.teaching_asistant_score.nil? #教辅未评分
if student_work.student_score.nil?
ta_proportion = tea_proportion + (1 - tea_proportion - sy_proportion) / 2
final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{ta_proportion}")
final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}"))
final_score = final_sy_score + final_te_score
student_work.final_score = format("%.2f",final_score.to_f)
else
rest_proportion = tea_ass_proportion / 3
final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{sy_proportion + rest_proportion}")
final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{tea_proportion + rest_proportion}")
final_st_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{sy_proportion + rest_proportion}") - BigDecimal.new("#{tea_proportion + rest_proportion}"))
final_score = final_sy_score + final_te_score + final_st_score
student_work.final_score = format("%.2f",final_score.to_f)
end
elsif student_work.student_score.nil? #学生未评分
rest_proportion = (1 - tea_proportion - sy_proportion - tea_ass_proportion) / 3
final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{sy_proportion + rest_proportion}")
final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{tea_proportion + rest_proportion}")
final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{sy_proportion + rest_proportion}") - BigDecimal.new("#{tea_proportion + rest_proportion}"))
final_score = final_sy_score + final_te_score + final_ta_score
student_work.final_score = format("%.2f",final_score.to_f)
else
final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{sy_proportion}")
final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{tea_proportion}")
final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * BigDecimal.new("#{tea_ass_proportion}")
final_s_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{sy_proportion}") - BigDecimal.new("#{tea_proportion}") - BigDecimal.new("#{tea_ass_proportion}"))
final_score = final_sy_score + final_ta_score + final_te_score + final_st_score
student_work.final_score = format("%.2f",final_score.to_f)
end
else
if student_work.teaching_asistant_score.nil? #教辅未评分
if student_work.student_score.nil?
student_work.final_score = student_work.system_score
else
ta_proportion = sy_proportion + (tea_ass_proportion + tea_proportion) / 2
final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{ta_proportion}")
final_st_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}"))
final_score = final_sy_score + final_st_score
student_work.final_score = format("%.2f",final_score.to_f)
end
elsif student_work.student_score.nil? #学生未评分
if student_work.teaching_asistant_score.nil?
student_work.final_score = student_work.system_score
else
ta_proportion = sy_proportion + (1.0 - tea_ass_proportion - sy_proportion) / 2
final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{ta_proportion}")
final_ts_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}"))
final_score = final_sy_score + final_ts_score
student_work.final_score = format("%.2f",final_score.to_f)
end
else
rest_proportion = tea_proportion / 3
final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{sy_proportion + rest_proportion}")
final_ts_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * BigDecimal.new("#{tea_ass_proportion + rest_proportion}")
final_st_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{sy_proportion + rest_proportion}") - BigDecimal.new("#{tea_ass_proportion + rest_proportion}"))
final_score = final_sy_score + final_ts_score + final_st_score
student_work.final_score = format("%.2f",final_score.to_f)
end
end
end
else
if homework.homework_type != 2
if student_work.teacher_score
student_work.final_score = student_work.teacher_score
else
if student_work.teaching_asistant_score.nil?
student_work.final_score = student_work.student_score
else
student_work.final_score = student_work.teaching_asistant_score
end
end
elsif homework.homework_type == 2 && homework.homework_detail_programing
if student_work.teacher_score
student_work.final_score = student_work.teacher_score
else
if student_work.teaching_asistant_score
student_work.final_score = student_work.teaching_asistant_score
else
if student_work.system_score
student_work.final_score = student_work.system_score
else
student_work.final_score = student_work.student_score
end
end
end
end
end
if student_work.final_score
score = student_work.final_score - student_work.absence_penalty - student_work.late_penalty - student_work.appeal_penalty
student_work.work_score = format("%.2f",(score < 0 ? 0 : score).to_f) if score
else
student_work.work_score = nil
end
end
end
# 计算实训作品学生的效率分
def update_student_eff_score homework
if homework.work_efficiency && homework.max_efficiency != 0
homework.student_works.where("compelete_status != 0").each do |student_work|
eff_score = student_work.efficiency / homework.max_efficiency * homework.eff_score
student_work.eff_score = format("%.2f", eff_score)
unless student_work.ultimate_score
work_score = student_work.final_score + student_work.eff_score - student_work.late_penalty
student_work.work_score = format("%.2f", work_score < 0 ? 0 : work_score)
end
student_work.save
end
else
homework.student_works.where("compelete_status != 0").each do |student_work|
student_work.eff_score = 0
unless student_work.ultimate_score
work_score = student_work.final_score + student_work.eff_score - student_work.late_penalty
student_work.work_score = format("%.2f", work_score < 0 ? 0 : work_score)
end
student_work.save
end
end
end
# 实训作业的评分
def set_shixun_final_score student_work, answer_open_evaluation, homework_challenge_settings
unless student_work.work_status == 0
myshixun = student_work.myshixun
final_score = 0
compelete = true
max_endtime = ""
user_total_score = 0
pass_consume_time = 0
homework_challenge_settings.each do |setting|
game = myshixun.games.where(:challenge_id => setting.challenge_id, :status => 2).first
unless game.nil?
pass_consume_time += (game.cost_time / 60.0).to_f
user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i
adjust_score = student_work.challenge_work_scores.where(:challenge_id => setting.challenge_id).last
final_score += adjust_score.present? ? adjust_score.score : (answer_open_evaluation ? setting.score : (game.final_score >= 0 ? setting.score : 0))
max_endtime = max_endtime == "" ? game.end_time : (game.end_time > max_endtime ? game.end_time : max_endtime)
else
compelete = false
end
end
efficiency = (pass_consume_time == 0 ? 0 : Math.log((user_total_score / pass_consume_time.to_f) + 1.0))
student_work.efficiency = efficiency < 0 ? 0 : format("%.2f", efficiency)
if compelete && max_endtime != ""
homework = student_work.homework_common
member = Member.find_by_sql("select course_group_id from members where course_id = #{homework.course_id} and user_id = #{student_work.user_id}").first
setting_time = homework_group_setting homework, member.try(:course_group_id)
if setting_time.publish_time.present? && setting_time.end_time.present?
if max_endtime < setting_time.publish_time
student_work.compelete_status = 2
else
if max_endtime < setting_time.end_time || (homework.allow_late && (homework.course.end_date.nil? || max_endtime < homework.course.end_date.end_of_day))
student_work.compelete_status = 1
student_work.cost_time = max_endtime.to_i - setting_time.publish_time.to_i
else
student_work.compelete_status = 0
end
end
end
if homework.work_efficiency
if homework.max_efficiency < student_work.efficiency
homework.max_efficiency = student_work.efficiency
homework.update_column("max_efficiency", homework.max_efficiency)
end
eff_score = homework.max_efficiency == 0 ? 0 : student_work.efficiency / homework.max_efficiency * homework.eff_score
student_work.eff_score = format("%.2f", eff_score)
else
student_work.eff_score = 0
end
elsif !compelete
student_work.compelete_status = 0
end
student_work.final_score = format("%.2f", final_score.to_f)
score = student_work.final_score + student_work.eff_score - student_work.late_penalty
student_work.work_score = format("%.2f", score < 0 ? 0 : score.to_f) unless student_work.ultimate_score
student_work.save!
end
end
# 用户评测时更新实训作业成绩
def update_myshixun_work_score myshixun
ActiveRecord::Base.transaction do
student_works = myshixun.student_works
#logger.info("#############student_works_count: #{student_works.count}")
if student_works.count > 0
student_works.each do |work|
homework = work.homework_common
member = Member.find_by_sql("select course_group_id from members where course_id = #{homework.course_id} and user_id = #{User.current.id}").first
#logger.info("#############member_course_group_id: #{member.try(:course_group_id)}")
setting_time = homework_group_setting homework, member.try(:course_group_id)
if setting_time.end_time.present? && (setting_time.end_time > Time.now || (homework.allow_late && !homework.course.is_end))
#logger.info("#############setting_time: #{setting_time.end_time}")
user_total_score = 0
pass_consume_time = 0
final_score = 0
homework.homework_challenge_settings.each do |setting|
game = myshixun.games.where(:challenge_id => setting.challenge_id, :status => 2).first
unless game.nil?
pass_consume_time += (game.cost_time / 60.0).to_f
user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i
adjust_score = work.challenge_work_scores.where(:challenge_id => setting.challenge_id).last
final_score += adjust_score.present? ? adjust_score.score : (homework.homework_detail_manual.answer_open_evaluation ? setting.score : (game.final_score >= 0 ? setting.score : 0))
end
end
if work.work_status == 0
is_complete = myshixun.is_complete? && (myshixun.done_time < setting_time.end_time)
work.work_status = setting_time.end_time > Time.now ? 1 : (is_complete ? 1 : 2)
work.late_penalty = setting_time.end_time > Time.now ? 0 : (is_complete ? 0 : homework.late_penalty)
work.commit_time = myshixun.created_at > setting_time.publish_time ? setting_time.publish_time : myshixun.created_at
work.myshixun_id = myshixun.id
end
efficiency = (pass_consume_time == 0 ? 0 : Math.log((user_total_score / pass_consume_time.to_f) + 1.0))
work.efficiency = format("%.2f", efficiency)
games = myshixun.games.where(:challenge_id => homework.homework_challenge_settings.map(&:challenge_id))
myshixun_endtime = games.select{|game| game.status == 2}.size == games.size ? games.map(&:end_time).max : nil
if myshixun_endtime.present?
min_efficiency_changed = min_efficiency_changed.present? ? min_efficiency_changed : false
work.compelete_status = 1
work.cost_time = myshixun_endtime.to_i - setting_time.publish_time.to_i
# 计算作品的效率分(已完成才计算)
if homework.work_efficiency
# 如果作业的最大效率值有变更则更新所有作品的效率分
if homework.max_efficiency < work.efficiency
homework.max_efficiency = work.efficiency
homework.update_column("max_efficiency", homework.max_efficiency)
update_student_eff_score homework
end
eff_score = homework.max_efficiency == 0 ? 0 : work.efficiency / homework.max_efficiency * homework.eff_score
work.eff_score = format("%.2f", eff_score)
end
end
work.update_time = Time.now
# 为迁移的数据做特殊处理, 若分数小于当前通关分数则不更新
work.final_score = final_score if work.final_score.nil? || final_score > work.final_score
score = work.final_score + work.eff_score - work.late_penalty
work.work_score = format("%.2f",(score < 0 ? 0 : score).to_f) unless work.ultimate_score
#logger.info("#############work_score: #{score}")
work.save!
end
end
end
end
end
# 用户开启实训时更新作品状态
def update_myshixun_work_status myshixun
student_works = StudentWork.find_by_sql("SELECT sw.* FROM student_works sw, homework_commons_shixuns hcs WHERE sw.user_id = #{User.current.id} AND sw.`homework_common_id` = hcs.`homework_common_id` AND hcs.`shixun_id` = #{myshixun.shixun_id} and sw.work_status = 0")
logger.info("#############student_works_count: #{student_works.count}")
if student_works.count > 0
student_works.each do |work|
homework = work.homework_common
member = Member.find_by_sql("select course_group_id from members where course_id = #{homework.course_id} and user_id = #{User.current.id}").first
setting_time = homework_group_setting homework, member.try(:course_group_id)
if setting_time.end_time.present? && (setting_time.end_time > Time.now || (homework.allow_late && !homework.course.is_end))
logger.info("#############setting_time: #{setting_time.end_time}")
work.work_status = setting_time.end_time > Time.now ? 1 : 2
work.late_penalty = setting_time.end_time > Time.now ? 0 : homework.late_penalty
work.update_time = Time.now
work.commit_time = Time.now
work.myshixun_id = myshixun.id
work.save
end
end
end
end
def quote_resource_bank resource, course
atta = Attachment.new(:filename => resource.filename, :disk_filename => resource.disk_filename, :filesize => resource.filesize, :digest => resource.digest, :downloads => 0, :is_publish => 0,
:author_id => User.current.id, :description => resource.description, :disk_directory => resource.disk_directory, :is_public => 0, :copy_from => resource.copy_from.nil? ? resource.id : resource.copy_from,
:quotes => 0, :resource_bank_id => resource.id, :created_on => Time.now, :content_type =>resource.content_type)
if course.attachments << atta
# 更新引用次数
quotes = resource.quotes.to_i + 1
resource.update_attribute(:quotes, quotes)
end
end
def quote_homework_bank homework, course
ActiveRecord::Base.transaction do
new_homework = HomeworkCommon.new(:name => homework.name, :user_id => User.current.id, :description => homework.description, :homework_type => homework.homework_type, :late_penalty => 5,
:course_id => course.id, :teacher_priority => 1, :anonymous_comment => 1, :quotes => 0, :is_open => 0, :homework_bank_id => homework.id, :score_open => 1,
:anonymous_appeal => 0, :is_public => 0, :reference_answer => homework.reference_answer, :answer_public => 1, :allow_late => 1)
new_homework.homework_detail_manual = HomeworkDetailManual.new
new_homework_detail_manual = new_homework.homework_detail_manual
new_homework_detail_manual.te_proportion = 1.0
new_homework_detail_manual.ta_proportion = 0
new_homework_detail_manual.comment_status = 0
new_homework_detail_manual.evaluation_num = 0
new_homework_detail_manual.absence_penalty = 0
if new_homework.homework_type == 2
new_homework.homework_detail_programing = HomeworkDetailPrograming.new
new_homework.homework_detail_programing.ta_proportion = 0
new_homework.homework_detail_programing.language = homework.language
homework.homework_bank_tests.each_with_index do |homework_test|
new_homework.homework_tests << HomeworkTest.new(
input: homework_test.input,
output: homework_test.output
)
end
homework.homework_bank_samples.each_with_index do |homework_test|
new_homework.homework_samples << HomeworkSample.new(
input: homework_test.input,
output: homework_test.output
)
end
end
if new_homework.homework_type == 3
new_homework.homework_detail_group = HomeworkDetailGroup.new
new_homework.homework_detail_group.min_num = homework.min_num
new_homework.homework_detail_group.max_num = homework.max_num
new_homework.homework_detail_group.base_on_project = homework.base_on_project
end
homework.attachments.each do |attachment|
att = attachment.copy
att.container_id = nil
att.container_type = nil
att.author_id = homework.user_id
att.copy_from = attachment.id
att.save
new_homework.attachments << att
end
if new_homework.save
if new_homework.homework_type == 4
HomeworkCommonsShixuns.create(:homework_common_id => new_homework.id, :shixun_id => homework.homework_bank_shixun.shixun_id)
end
new_homework_detail_manual.save if new_homework_detail_manual
new_homework.homework_detail_programing.save if new_homework.homework_detail_programing
new_homework.homework_detail_group.save if new_homework.homework_detail_group
create_works_list new_homework
homework.update_column(:quotes, homework.quotes+1)
QuestionBank.where(:container_id => homework.id, :container_type => ["Common", "Shixun", "Group"]).update_all(:quotes => homework.quotes)
end
return new_homework
end
end
def quote_exercise_bank exercise, course
ActiveRecord::Base.transaction do
new_exercise = Exercise.new(:exercise_name => exercise.name, :exercise_description => exercise.description, :user_id => User.current.id, :is_public => 0,
:exercise_status => 1, :show_result => 1, :course_id => course.id, :time => -1, :exercise_bank_id => exercise.id)
exercise.exercise_bank_questions.each do |q|
option = {
:question_title => q[:question_title],
:question_type => q[:question_type] || 1,
:question_number => q[:question_number],
:question_score => q[:question_score],
:shixun_id => q[:shixun_id],
:shixun_name => q[:shixun_name]
}
exercise_question = new_exercise.exercise_questions.new option
if q.question_type != 5
for i in 1..q.exercise_bank_choices.count
choice_option = {
:choice_position => i,
:choice_text => q.exercise_bank_choices[i-1][:choice_text]
}
exercise_question.exercise_choices.new choice_option
end
for i in 1..q.exercise_bank_standard_answers.count
standard_answer_option = {
:exercise_choice_id => q.exercise_bank_standard_answers[i-1][:exercise_bank_choice_id],
:answer_text => q.exercise_bank_standard_answers[i-1][:answer_text]
}
exercise_question.exercise_standard_answers.new standard_answer_option
end
else
for i in 1..q.exercise_bank_shixun_challenges.count
challenge_option = {
:position => i,
:challenge_id => q.exercise_bank_shixun_challenges[i-1][:challenge_id],
:shixun_id => q.exercise_bank_shixun_challenges[i-1][:shixun_id],
:question_score => q.exercise_bank_shixun_challenges[i-1][:question_score]
}
exercise_question.exercise_shixun_challenges.new challenge_option
end
end
end
if new_exercise.save
create_exercises_list new_exercise
exercise.update_column(:quotes, exercise.quotes+1)
QuestionBank.where(:container_id => exercise.id, :container_type => "Exercise").update_all(:quotes => exercise.quotes)
end
return new_exercise
end
end
def quote_poll_bank poll, course
ActiveRecord::Base.transaction do
new_poll = Poll.new(:polls_name => poll.name, :polls_description => poll.description, :user_id => User.current.id, :is_public => 0,
:polls_status => 1, :show_result => 1, :polls_type => 'Course', :course_id => course.id, :exercise_bank_id => poll.id)
poll.exercise_bank_questions.each do |q|
option = {
:question_title => q[:question_title],
:question_type => q[:question_type] || 1,
:is_necessary => q[:is_necessary],
:question_number => q[:question_number],
:max_choices => q[:max_choices],
:min_choices => q[:min_choices]
}
poll_question = new_poll.poll_questions.new option
for i in 1..q.exercise_bank_choices.count
choice_option = {
:answer_position => i,
:answer_text => q.exercise_bank_choices[i-1][:choice_text]
}
poll_question.poll_answers.new choice_option
end
end
if new_poll.save
create_polls_list new_poll
poll.update_column(:quotes, poll.quotes+1)
QuestionBank.where(:container_id => poll.id, :container_type => "Poll").update_all(:quotes => poll.quotes)
end
return new_poll
end
end
def major_level_option
content = []
option0 = []
option0 << "选择课程所属专业层级"
option0 << 0
option1 = []
option1 << "专科"
option1 << 3
option2 = []
option2 << "本科"
option2 << 2
option3 = []
option3 << "研究生"
option3 << 1
content << option0
content << option1
content << option2
content << option3
content
end
def discipline_category_option major_level = 3
content = []
option0 = []
option0 << "选择课程所属学科门类"
option0 << 0
content << option0
DisciplineCategory.where(:major_level => major_level).each do |dis|
option = []
option << dis.name.to_s
option << dis.id
content << option
end
content
end
def first_level_discipline_option disc_ca = 27
content = []
option0 = []
option0 << "选择课程所属一级学科"
option0 << 0
content << option0
FirstLevelDiscipline.where(:discipline_category_id => disc_ca).each do |fir_dis|
option = []
option << fir_dis.name.to_s
option << fir_dis.id
content << option
end
content
end
def syllabus_major_option fir_dis = 213
content = []
option0 = []
option0 << "选择课程所属专业"
option0 << 0
content << option0
Major.where(:first_level_discipline_id => fir_dis).each do |major|
option = []
option << major.name.to_s
option << major.id
content << option
end
content
end
def convert_to_char(str)
result = ""
length = str.length
unless str.nil?
if length === 1
result += (str.to_i + 64).chr
return result
elsif length > 1
for i in 0...length
result += (str[i].to_i + 64).chr
end
return result
end
end
return result
end
def convert_to_chi_num num
result = ""
case num.to_i
when 1
result = '一'
when 2
result = '二'
when 3
result = '三'
when 4
result = '四'
when 5
result = '五'
when 6
result = '六'
when 7
result = '七'
when 8
result = '八'
when 9
result = '九'
end
return result
end
#根据条件过滤作业结果
def search_work_member works,name
if name == ""
select_works = works
else
name = name.downcase
select_works = works.joins(user: :user_extensions).where("concat(lastname, firstname) like ?
or student_id like ?", "%#{name}%", "%#{name}%")
end
select_works
end
# 作业的分班设置时间
def homework_group_setting homework, group_id
setting = nil
if homework.homework_group_settings.where(:course_group_id => group_id).first
setting = homework.homework_group_settings.where(:course_group_id => group_id).first
else
setting = homework
end
setting
end
# 试卷的分班设置时间
def exercise_group_setting exercise, group
setting = nil
if exercise.exercise_group_settings.where(:course_group_id => group.try(:id)).first
setting = exercise.exercise_group_settings.where(:course_group_id => group.id).first
else
setting = exercise
end
setting
end
# 问卷的分班设置时间
def poll_group_setting poll, group
setting = nil
if poll.poll_group_settings.where(:course_group_id => group.try(:id)).first
setting = poll.poll_group_settings.where(:course_group_id => group.id).first
else
setting = poll
end
setting
end
# 资源的分班设置时间
def attacment_group_setting attachment, group
setting = nil
if attachment.attachment_group_settings.where(:course_group_id => group.try(:id)).first
setting = attachment.attachment_group_settings.where(:course_group_id => group.id).first
else
setting = attachment
end
setting
end
#统计答题百分比,统计结果保留两位小数
def statistics_result_percentage(e, t)
e = e.to_f
t = t.to_f
t == 0 ? 0 : format("%.1f", e*100/t)
end
def subject_data subject
result = {}
subject_choices = 0
subject_shixuns = 0
subject_score = 0
subject.stage_shixuns.each do |stage_shixun|
shixun = stage_shixun.shixun
subject_choices += shixun.challenges.where(:st => [1, 2]).count
subject_shixuns += shixun.challenges.where(:st => 0).count
subject_score += shixun.shixun_score
end
result[:subject_choices] = subject_choices
result[:subject_shixuns] = subject_shixuns
result[:subject_score] = subject_score
result
end
def tiding_url tiding
case tiding.container_type
when "ApplyUserAuthentication"
if tiding.tiding_type == "Apply"
tiding.container.auth_type == 1 ? identity_authentication_managements_path : professional_authentication_managements_path
else
tiding.container.auth_type == 1 ? authentication_account_path : professional_certification_account_path
end
when "CancelUserAuthentication"
authentication_account_path
when "CancelUserProCertification"
professional_certification_account_path
when "ApplyAddDepartment"
tiding.tiding_type == "Apply" ? depart_managements_path() : my_account_path()
when "ApplyAddSchools"
tiding.tiding_type == "Apply" ? unit_managements_path() : my_account_path()
when "ApplyAction"
tiding.tiding_type == "System" ? (tiding.parent_container_type == "ApplyShixun" ? shixun_path(Shixun.find(tiding.parent_container_id).identifier):(tiding.parent_container_type == "TrialAuthorization" ? user_path(tiding.user_id) : subject_path(tiding.parent_container_id))):(tiding.parent_container_type == "ApplyShixun" ? shixun_authorization_managements_path():(tiding.parent_container_type == "TrialAuthorization"? trial_authorization_managements_path(): subject_authorization_managements_path()))
when 'JoinCourse'
course_path(tiding.container_id, :type => "JoinCourse")
when 'StudentJoinCourse', 'DealCourse', 'TeacherJoinCourse'
course_path(tiding.container_id)
when 'Course', 'ArchiveCourse'
course_path(tiding.container_id)
when 'Shixun'
'/shixuns/' + tiding.container.identifier
when 'Subject'
'/paths/' + tiding.container_id.to_s
when 'JournalsForMessage'
case tiding.parent_container_type
when "Principal"
feedback_path(tiding.parent_container_id)
when "HomeworkCommon"
student_work_index_path(:homework => tiding.parent_container_id, :tab => 2)
when "GraduationTopic"
graduation_topic_path(tiding.parent_container_id, :tab => 2)
when "StudentWorksScore"
student_work_path(:id => tiding.container.try(:jour).try(:student_work_id))
end
when 'Message'
board_message_path(tiding.container.board_id, tiding.parent_container_id)
when 'Memo'
forum_path(tiding.parent_container_id)
when 'Watcher'
user_path(tiding.trigger_user_id)
when 'PraiseTread'
try = tiding.parent_container_type.constantize
object = try.find(tiding.parent_container_id)
case tiding.parent_container_type
when "Challenge"
myshixun_id = Myshixun.where(:user_id => tiding.trigger_user_id, :shixun_id => Challenge.find(tiding.parent_container_id).shixun_id).first
myshixun_game_path(Game.where(:myshixun_id => myshixun_id.id, :challenge_id => tiding.parent_container_id).first, :myshixun_id => myshixun_id)
when "Discuss"
myshixun_game_path(object.user_game, :myshixun_id => object.user_myshixun)
when "Message"
object.parent.present? ? board_message_path(object.board_id, object.root_id) : board_message_path(object.board_id, object)
when "Memo"
object.parent.present? ? forum_path(object.root_id) : forum_path(object)
when "JournalsForMessage"
case object.jour_type
when "Principal"
feedback_path(object.jour_id)
when "HomeworkCommon"
student_work_index_path(:homework => object.jour_id, :tab => 2)
when "StudentWorksScore"
student_work_path(:id => object.try(:jour).try(:student_work_id))
end
when "HomeworkCommon"
student_work_index_path(:homework => tiding.parent_container_id, :tab => 2)
when "Issue"
issue_path(tiding.parent_container_id)
when "Journal"
issue_path(object.journalized_id)
end
when 'Discuss'
shixun_discuss_shixun_path(tiding.container.dis)
when 'Grade'
user_grade_user_path(User.current)
when 'JoinProject'
project_path(tiding.container_id, :type => "applied_project")
when 'ReporterJoinProject', 'DealProject', 'ManagerJoinProject'
project_path(tiding.container_id)
when 'Poll'
case tiding.parent_container_type
when 'CommitPoll'
student_poll_list_poll_path(tiding.container, :tab => 2)
else
student_poll_list_poll_path(tiding.container)
end
when 'Exercise'
case tiding.parent_container_type
when 'CommitExercise', 'ExerciseScore'
show_student_result_exercise_path(tiding.container,:user_id => tiding.trigger_user_id)
else
student_exercise_list_exercise_path(tiding.container)
end
when 'StudentGraduationTopic', 'DealStudentTopicSelect'
graduation_topic_path(tiding.parent_container_id)
when 'GraduationTask'
graduation_task_path(tiding.container_id)
when 'GraduationWork'
graduation_work_path(tiding.container_id)
when 'GraduationWorkScore'
graduation_work_path(tiding.parent_container_id)
when 'HomeworkCommon'
case tiding.parent_container_type
when 'AnonymousCommentFail'
student_work_index_path(:homework => tiding.container_id, :tab => 4)
when 'HomeworkPublish'
student_work_index_path(:homework => tiding.container_id, :tab => 2)
when 'AnonymousAppeal'
work = tiding.container.student_works(:user_id => User.current.id).first
work.present? ? student_work_path(work.try(:id)) : "javascript:void(0)"
else
student_work_index_path(:homework => tiding.container_id)
end
when 'StudentWork'
student_work_path(tiding.container_id)
when 'StudentWorksScore', 'StudentWorksScoresAppeal'
student_work_path(tiding.parent_container_id)
when 'ChallengeWorkScore'
homework_common_path(tiding.container.try(:student_work).try(:homework_common_id))
when 'SendMessage'
mirror_repository_managements_path
when 'Journal'
issue_path(tiding.parent_container_id)
when 'Issue'
issue_path(tiding.container_id)
when 'PullRequest'
project_pull_requests_path(tiding.parent_container_id)
when 'Department'
my_account_path
end
end
def create_shixun_homework_cha_setting homework, shixun
if shixun.present?
sum_score = 0
total_score = 100.0 - homework.eff_score
shixun.challenges.each_with_index do |challeng, index|
if index < shixun.challenges.length - 1
score = ((total_score / shixun.challenges.length) * total_score).floor / total_score
sum_score += score
else
score = total_score - sum_score
end
HomeworkChallengeSetting.create(:homework_common_id => homework.id, :challenge_id => challeng.id, :shixun_id => shixun.id, :score => score)
end
end
end