# encoding=utf-8
class ShixunsService
include ApplicationHelper
include GamesHelper
LIMIT = 10
# reuturn star_info打星情况
def show_shixun params , current_user
shixun = Shixun . select ( [ :id , :identifier , :name , :fork_from , :user_id , :myshixuns_count , :trainee , :can_copy , :status , :propaedeutics ] ) . find_by_identifier ( params [ :identifier ] )
star_info = shixun . shixun_preference_info
image_url = url_to_avatar ( current_user )
username = current_user . try ( :show_name )
is_certification_teacher = current_user . is_certification_teacher
manager = current_user . manager_of_shixun? ( shixun , current_user )
owner = shixun . owner
watched = owner . watched_by? ( current_user )
shixun_count = owner . shixuns . where ( :status = > [ 2 , 3 ] ) . count
myshixun = Myshixun . select ( [ :id , :user_id , :identifier , :shixun_id , :status ] ) . where ( :user_id = > current_user , :shixun_id = > shixun . id ) . first
if shixun . fork_from
fork_shixun = Shixun . select ( [ :id , :name , :user_id ] ) . find ( shixun . fork_from )
fork_info = { :name = > fork_shixun . name , :username = > fork_shixun . owner . try ( :show_name ) }
end
currentUser = { :image_url = > image_url , :username = > username , :is_certification_teacher = > is_certification_teacher , :manager = > manager ,
:admin = > current_user . admin? , :mail = > current_user . try ( :mail ) , :login = > current_user . try ( :login ) }
creator = { :owner_id = > owner . id , :image_url = > url_to_avatar ( owner ) , :username = > owner . show_name , :watching = > owner . watcher_users . count ,
:shixun_count = > shixun_count , :login = > owner . login }
fork_count = Shixun . where ( :fork_from = > shixun . id ) . count
recommends = [ ]
recommend_shixuns = recommend_shixun ( shixun )
recommend_shixuns . each do | rec |
recommends << { :name = > rec . name , :myshixuns_count = > rec . myshixuns . count , :trainee = > rec . trainee , :image_url = > url_to_avatar ( rec ) , :identifier = > rec . identifier }
end
challenge_tags = [ ]
user_get_tags = user_get_tags shixun . challenges . pluck ( :id ) , current_user
ChallengeTag . where ( :challenge_id = > shixun . challenges . pluck ( :id ) ) . pluck ( :name ) . uniq . each do | tag |
if user_get_tags . include? ( tag )
challenge_tags << { :name = > tag , :type = > 2 }
else
challenge_tags << { :name = > tag , :type = > 1 }
end
end
recommend_paths = [ ]
paths = Subject . where ( :id = > shixun . stage_shixuns . map ( & :subject_id ) , :hidden = > 0 ) . limit ( 2 )
paths . each do | path |
experience = path . subject_shixun_score + path . subject_shixun_choose_score
learn_count = path . respond_to? ( " myshixun_member_count " ) ? path . myshixun_member_count : Myshixun . where ( :shixun_id = > path . stage_shixuns . map ( & :shixun_id ) ) . count
recommend_paths << { url : " /paths/ #{ path . id } " ,
image_url : " /images/ #{ url_to_avatar ( path ) } " ,
name : path . name ,
stages_count : path . stages_count ,
experience : experience ,
learn_count : learn_count }
end
return { :current_user = > currentUser , :shixun = > shixun . try ( :attributes ) , :fork_info = > fork_info , :creator = > creator , :star_info = > star_info ,
:myshixuns_count = > shixun . myshixuns . count , :shixun_score = > shixun . shixun_score , :shixun_level = > shixun . shixun_level ,
:fork_count = > fork_count , :recommend_shixuns = > recommends , :myshixun = > myshixun . try ( :attributes ) , :watched = > watched ,
:recommend_paths = > recommend_paths , :challenge_tags = > challenge_tags }
end
# 实训讨论帖子
def shixun_discuss params , current_user
page = params [ :page ] . to_i
offset = page * LIMIT
dis_id = params [ :container_id ] # 如: shixun_id
dis = Shixun . select ( [ :id , :user_id ] ) . find ( dis_id )
dis_type = params [ :container_type ] # 如:"Shixun"
# 总数,分页使用
if current_user . admin?
disscuss_count = Discuss . where ( :dis_id = > dis_id , :dis_type = > dis_type , :root_id = > nil ) . count
discusses = Discuss . limit ( LIMIT ) . where ( :dis_id = > dis_id , :dis_type = > dis_type ,
:root_id = > nil ) . includes ( :user , :praise_tread ) . offset ( offset )
else
disscusses = Discuss . where ( " dis_id = :dis_id and dis_type = :dis_type and root_id is null and
( hidden = :hidden or user_id = :user_id ) " ,
{ dis_id : dis_id , dis_type : dis_type , hidden : false , user_id : current_user . id } )
disscuss_count = disscusses . count
discusses = disscusses . limit ( LIMIT ) . includes ( :user , :praise_tread ) . offset ( offset )
end
base_data discusses , dis , current_user
return { :children_list = > @children_list , :disscuss_count = > disscuss_count }
end
# 获取某条消息的具体位置(比如在分页中的某一页)
def anchor params , current_user
discuss_id = params [ :discuss_id ] . to_i
dis_id = params [ :container_id ] # 如: shixun_id
dis = Shixun . select ( [ :id , :user_id ] ) . find ( dis_id )
dis_type = params [ :container_type ] # 如:"Shixun"
# 注意:此处查询的条件必须和列表的条件一致,否则结果定位可能会有问题
position_discusses = Discuss . find_by_sql ( " SELECT @rowno:=@rowno+1 as rowno, r.id from discusses r,(select @rowno:=0) m where root_id is null and
dis_id = #{dis_id} and dis_type='#{dis_type}' order by created_at desc")
disscuss_count = position_discusses . size
# 标记是否找到评论
find_status = false
if disscuss_count > 0
position = position_discusses . select { | discuss | discuss . id == discuss_id } . first . try ( :rowno )
page = position . to_i / LIMIT
offset = page * LIMIT
find_status = true if position
end
discusses = Discuss . limit ( LIMIT ) . where ( :dis_id = > dis_id , :dis_type = > dis_type , :root_id = > nil ) . includes ( :user , :praise_tread ) . offset ( offset )
base_data discusses , dis , current_user
Myshixun . find ( params [ :myshixun_id ] ) . update_attribute ( :onclick_time , Time . now )
return { :children_list = > @children_list , :disscuss_count = > disscuss_count , :page = > page . to_i , :find_status = > find_status }
end
# 判断当前用户是否有新的评论消息
def new_message params , current_user
onclick_time = Myshixun . find ( params [ :myshixun_id ] ) . try ( :onclick_time )
dis_id = params [ :container_id ]
dis_type = params [ :container_type ]
# 获取当前用户发布的帖子,如果帖子有非自己的回复则通知我
ids = Discuss . where ( " user_id =? and dis_id =? and dis_type =? and root_id is null " , current_user . id , dis_id , dis_type ) . pluck ( :id )
user_discuss = Discuss . where ( " user_id !=? and created_at >? " , current_user . id , onclick_time ) . where ( :root_id = > ids , :dis_id = > dis_id , :dis_type = > dis_type ) . first
return { :new_message = > user_discuss }
end
# 公共数据结构
# 注意: shixun_id如果是非实训类型的, 一定要主要其中的权限判断( 目前只适用于实训)
def base_data discusses , dis , current_user
@children_list = [ ]
# 目前只取十个, 不多N+1问题不大
# 需要彻底解决则需要改数据路结构, 比如Nested算法可以解决
if discusses . present?
discusses . each do | d |
# 总点赞数
praise_count = d . praise_tread . where ( :praise_or_tread = > 1 ) . count
user_praise = d . praise_tread . select { | pt | pt . user_id == current_user . id } . length > 0 ? true : false
# 实训( TPM) 的管理员可以看到隐藏的评论
manager = current_user . manager_of_shixun? ( dis , current_user )
game_url =
if manager
position = d . position . nil? ? 1 : d . position
game_identifier = Game . find_by_sql ( " SELECT g.identifier FROM games g JOIN challenges c on g.challenge_id = c.id
WHERE c . shixun_id = #{dis.id} AND c.position = #{position} AND g.user_id = #{d.user_id}").first.try(:identifier)
" /tasks/ #{ game_identifier } "
else
" "
end
parents = { :id = > d . id , :content = > d . content , :time = > time_from_now ( d . created_at ) , :position = > d . position ,
:user_id = > d . user . try ( :id ) , :reward = > d . reward , :image_url = > url_to_avatar ( d . user ) ,
:username = > d . username , :user_login = > d . user . try ( :login ) , :shixun_id = > dis . id , :hidden = > d . hidden ,
:manager = > manager , :praise_count = > praise_count , game_url : game_url ,
:user_praise = > user_praise , :admin = > current_user . admin? }
# 现在没有二级回复, 所以查询的时候直接从root_id取
children =
if current_user . admin?
Discuss . where ( root_id : d . id ) . includes ( :user ) . reorder ( " created_at asc " )
else
Discuss . where ( " root_id = :root_id and (hidden = :hidden or user_id = :user_id " ,
{ root_id : d . id , hidden : false , user_id : current_user . id } ) . includes ( :user ) . reorder ( " created_at asc " )
end
@children_list << parents . merge ( { :children = > ( children . map { | child | [ :content = > child . content , :time = > time_from_now ( child . created_at ) , :position = > child . position , :reward = > child . reward , :hidden = > child . hidden ,
:image_url = > url_to_avatar ( child . user ) , :username = > child . username , :user_id = > child . user_id , :user_login = > child . user . try ( :login ) ,
:can_delete = > child . can_delete_api ( current_user , child . user_id ) , :id = > child . id ] } . flatten if children . present? ) } )
end
end
end
def myshixun_git params , current_user
page = params [ :page ] . to_i
offset = page * LIMIT
shixun = Shixun . select ( [ :id , :user_id ] ) . find_by_identifier ( params [ :identifier ] )
myshixuns = Myshixun . limit ( LIMIT ) . where ( :shixun_id = > shixun . id ) . includes ( :user ) . offset ( offset )
list = [ ]
myshixuns . each do | myshixun |
git_url = gitlab_address_url myshixun
list << { :identifier = > myshixun . identifier , :git_url = > git_url , :username = > myshixun . owner . show_name , :user_id = > myshixun . owner . try ( :id ) }
end
return list
end
end