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/services/shixuns_service.rb

181 lines
10 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
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