|
|
# encoding: utf-8
|
|
|
# status 1:完成实训
|
|
|
# modified_time:为实训TPM有改动(非版本库);reset_time:为版本库修改时间
|
|
|
class Myshixun < ActiveRecord::Base
|
|
|
attr_accessible :description, :name, :parent_id, :user_id, :gpid, :forked_from, :visits, :is_public, :identifier, :shixun_id,
|
|
|
:modify_time, :reset_time, :updated_at, :created_at, :status, :git_url, :onclick_time, :commit_id
|
|
|
# has_many :users, :through => :myshixun_members
|
|
|
has_many :myshixun_members, :dependent => :destroy
|
|
|
has_one :repository, :dependent => :destroy
|
|
|
has_many :games, :dependent => :destroy, :order => "games.id ASC"
|
|
|
belongs_to :shixun, counter_cache: true
|
|
|
has_one :shixun_modify, :dependent => :destroy
|
|
|
has_one :webssh, :dependent => :destroy
|
|
|
has_many :student_works
|
|
|
belongs_to :user
|
|
|
validates_uniqueness_of :shixun_id, :scope => :user_id, :message => "error"
|
|
|
# validates :shixun_id, :uniqueness => {:scope => :user_id, :message => "不能被重复开启"}
|
|
|
scope :min, lambda { select([:id, :shixun_id, :identifier, :gpid, :status, :user_id, :commit_id, :modify_time, :reset_time, :system_tip]) }
|
|
|
scope :finished, lambda{where(status: 1)}
|
|
|
|
|
|
def output_times
|
|
|
times = Output.where(:game_id => self.games.map(&:id), :test_set_position => 1).count
|
|
|
times
|
|
|
end
|
|
|
|
|
|
def mirror_name
|
|
|
self.shixun.mirror_repositories.map(&:type_name).blank? ? "" : self.shixun.mirror_repositories.map(&:type_name)
|
|
|
end
|
|
|
|
|
|
def main_mirror
|
|
|
self.shixun.mirror_repositories.published_main_mirror.try(:first)
|
|
|
end
|
|
|
|
|
|
def total_stage
|
|
|
self.games.count
|
|
|
end
|
|
|
|
|
|
def current_stage
|
|
|
game = self.games.where(:status => 0).first
|
|
|
position = game.blank? ? games.count : game.challenge.try(:position)
|
|
|
return position
|
|
|
end
|
|
|
|
|
|
def current_stages
|
|
|
game = self.games.where(:status => 1).first
|
|
|
position = game.blank? ? 1 : game.challenge.try(:position)
|
|
|
return position
|
|
|
end
|
|
|
|
|
|
# 通关时间
|
|
|
def done_time
|
|
|
time = ""
|
|
|
if self.status == 1 || self.games.where(:status => 2).count == self.shixun.challenges.count
|
|
|
time = self.games.map(&:end_time).max
|
|
|
end
|
|
|
time
|
|
|
end
|
|
|
|
|
|
def is_complete?
|
|
|
self.status == 1 || self.games.where(:status => 2).count == self.games.count
|
|
|
end
|
|
|
|
|
|
def total_spend_time
|
|
|
time = 0
|
|
|
self.games.each do |game|
|
|
|
if game.status == 2
|
|
|
time += (game.end_time.to_i - game.open_time.to_i) > 0 ? (game.end_time.to_i - game.open_time.to_i) : 0
|
|
|
end
|
|
|
end
|
|
|
time
|
|
|
end
|
|
|
|
|
|
# 准确率
|
|
|
def total_accuracy
|
|
|
accuracy = 0
|
|
|
count = 0
|
|
|
self.games.where(:status => 2).each do |game|
|
|
|
count += 1
|
|
|
accuracy += game.accuracy ? game.accuracy : 0
|
|
|
end
|
|
|
accuracy.to_f / count
|
|
|
end
|
|
|
|
|
|
# 通过的关卡理应得到的总经验值(看与不看参考答案无影响)
|
|
|
def sum_score
|
|
|
score = 0
|
|
|
self.games.each do |game|
|
|
|
if game.status == 2
|
|
|
total_exp = game.challenge.score.to_i
|
|
|
score += total_exp
|
|
|
end
|
|
|
end
|
|
|
score
|
|
|
end
|
|
|
|
|
|
# 获得的经验值
|
|
|
def total_score
|
|
|
score = 0
|
|
|
self.games.where(:status => 2).each do |game|
|
|
|
score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i
|
|
|
end
|
|
|
score
|
|
|
end
|
|
|
|
|
|
def total_gold
|
|
|
score = 0
|
|
|
self.games.each do |game|
|
|
|
if game.status == 2
|
|
|
total_gold =game.answer_open? ? -game.challenge.score.to_i : game.final_score.to_i
|
|
|
score += total_gold
|
|
|
end
|
|
|
end
|
|
|
score
|
|
|
end
|
|
|
|
|
|
|
|
|
# id 转换成 identifier
|
|
|
def to_param
|
|
|
identifier
|
|
|
end
|
|
|
|
|
|
# 当前任务:一个实训中只可能一个未完成任务(status 0或1只会存在一条记录)
|
|
|
# status:0 可以测评的,正在测评的
|
|
|
# 如果都完成,则当前任务为最后一个任务
|
|
|
def current_task
|
|
|
games = self.games
|
|
|
current_game = games.select{|game| game.status == 1 || game.status == 0}.first
|
|
|
if current_game.blank?
|
|
|
current_game = Game.find_by_sql("SELECT g.* FROM games g, challenges c where g.myshixun_id=#{self.id} and g.challenge_id = c.id and g.status = 2 order by c.position desc").first
|
|
|
end
|
|
|
return current_game
|
|
|
#
|
|
|
# if self.status == 1
|
|
|
# current_game = Game.find_by_sql("SELECT g.* FROM games g, challenges c where g.myshixun_id=#{self.id} and g.challenge_id = c.id and g.status = 2 order by c.position desc").first
|
|
|
# else
|
|
|
# current_game = self.games.select{|game| game.status == 1 || game.status == 0}.first
|
|
|
# end
|
|
|
# return current_game
|
|
|
end
|
|
|
|
|
|
def owner
|
|
|
self.user
|
|
|
rescue ActiveRecord::RecordNotFound
|
|
|
end
|
|
|
|
|
|
def score
|
|
|
game = self.games.where(:status => [0, 1]).first
|
|
|
unless game.blank?
|
|
|
score = game.challenge.try(:score)
|
|
|
end
|
|
|
return score
|
|
|
end
|
|
|
|
|
|
end
|