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/careers_service.rb

515 lines
19 KiB

6 years ago
# encoding=utf-8
class CareersService
include ApplicationHelper
# (localhost:3000/api/v1/careers/create)传参格式:
# {
# "name": "name",
# "video_name": "video_name",
# "video_description": "video_description",
# "faq": [
# {
# "question": "question1",
# "answer": "answer1"
# },
# {
# "question": "question2",
# "answer": "answer2"
# }
# ]
# }
# params:
# [:name] -> 职业路径名称
# [:video_name] -> 视频名称
# [:video_description] -> 视频描述
# [:faq][:questions] -> 常见问题 类型: 字符串数组
# [:faq][:answers] -> 常见问题 类型: 字符串数组
# return
# status: 0 成功 -1 失败
# career_id: 职业路径的id
def create params, current_user
begin
career = Career.create!(:name => params[:name],
:video_name => params[:video_name],
:video_description => params[:video_description],
:user_id => current_user.id)
if params[:attachments].present?
attachment = Attachment.find params[:attachments][:attachment_id]
attachment.update_attributes(:container_id => career.id, :container_type => "Career")
end
# 创建常见问题
if params[:faq]
params[:faq].each_with_index do |faq, index|
CareerFaq.create!(:question => faq.question, :answer => faq.answer, :career_id => career.id)
end
end
{status: 0, message: "职业路径创建成功!", career_id: career.id}
rescue Exception => e
{status: -1, message: "#{e.message}"}
end
end
#localhost:3000/api/v1/careers/1/edit
# return:
# {
# "name": "name",
# "video_name": "video_name",
# "video_description": "video_description",
# "url": "/attachments/download//",
# "faq": [
# {
# "question": "问题1",
# "answer": "答案1"
# },
# {
# "question": "问题2",
# "answer": "答案2"
# }
# ],
# "stages_info": [
# {
# "stage_name": "阶段名称",
# "stage_description": "阶段描述",
# "subject_list": [
# {
# "subject_name": "实训路径名称",
# "subject_id": "实训路径id",
# # 实训列表
# "shixun_list": [
# {"shixun_id": 1, "shixun_name": "C++之整数性质判断"},
# {"shixun_id": 2, "shixun_name": "C++之整数计算基础"},
# {"shixun_id": 3, "shixun_name": "C++之整数基本应用I"}
# ]
#
# },
# {
# "subject_name": "实训路径名称",
# "subject_id": "实训路径ID",
# # 实训列表
# "shixun_list": [
# {"shixun_id": 4, "shixun_name": "数据结构与算法 - 线性表"},
# {"shixun_id": 6, "shixun_name": "数据结构与算法 - 队列"},
# {"shixun_id": 7, "shixun_name": "数据结构与算法 - 栈"},
# {"shixun_id": 7, "shixun_name": "数据结构与算法 - 计算表达式"}
# ]
# }
# ]
# }
# ]
# }
def edit params
career = find_career params[:id]
video = career.attachments.first
faq = career.career_faqs.map{|faq| {question: faq.question, answer: faq.answer} }
stages_info = []
career.career_stages.each do |stage|
subject_list = []
stage.subjects.each do |subject|
shixun_list = subject.shixuns.map{|shixun| {shixun_id: shixun.id, shixun_name: shixun.name} }
subject_list << {subject_name: subject.name, subject_id: subject.id, shixun_list: shixun_list}
end
stages_info << {stage_id: stage.id, stage_name: stage.name, stage_description: stage.description, subject_list: subject_list}
end
{name: career.name,
video_name: career.video_name,
video_description: career.video_description,
video_url: "/attachments/download/#{video.try(:id)}/#{video.try(:filename)}",
video_delete_url: "/attachments/delete_career?attachment_id=#{video.try(:id)}",
attachment_id: video.try(:id),
attachment_name: video.try(:filename),
faq: faq,
stages_info: stages_info}
end
# params:
# [:id] -> tab的repertoire的id
# [:search] -> 搜索创建者名称或实训路径名称
# [:stage_id] -> 编辑模式下需要传职业路径阶段id
# return:
# repertoire -> 表示tab的数据
# subjects_counts -> 表示检索结果
# subjects_list -> 表示列表数据
def get_paths_info params
page = params[:page] ? params[:page].to_i - 1 : params[:page].to_i
offset = page * 15
sql =
if params[:id]
"id = #{params[:id]}"
else
"1=1"
end
repertoires = Repertoire.select([:id, :name]).order("created_at asc")
repertoire = repertoires.where("#{sql}")
sql1 =
if params[:search]
user_ids = User.where("CONCAT(lastname,firstname) like '%#{params[:search]}%'").pluck(:id)
user_ids = user_ids.blank? ? -1 : user_ids.join(',')
"(user_id in (#{user_ids}) or name like '%#{params[:search]}%') and repertoire_id in (#{repertoire.pluck(:id).join(",")})"
else
"repertoire_id in (#{repertoire.pluck(:id).join(",")})"
end
career_stage =
if params[:stage_id]
CareerStage.find params[:stage_id]
end
subjects = Subject.select([:id, :name, :user_id, :status]).where("#{sql1}").order("visits desc")
subjects_count = subjects.count
subjects = subjects.offset(offset).limit(15)
Rails.logger.info("#######################subjects_count: #{subjects_count}")
subjects_list = format_subject_list subjects, career_stage
{repertoire: repertoires, subjects_count: subjects_count, subjects_list: subjects_list}
end
# (localhost:3000/api/v1/careers/add_paths)传参格式:
# {
# "id": [3,5]
# }
# params:
# [id] -> 多个实训路径的id类型为“数组”
# return:
# subject_list-> 都是按章节 按课时排好序的路径信息
def add_paths params
subjects = []
ids = params[:id]
# REDO 为了按照传过来的id排序才这样做(这里需要优化如何用RAM的方式或者mysql的方式查询最好)
ids.each do |id|
subjects << Subject.select([:id, :name]).includes(stage_shixuns: :shixun).find(id)
end
subject_list = []
subjects.each do |subject|
shixun_list = []
subject.shixuns.each do |shixun|
shixun_list << {shixun_name: shixun.name, shixun_link: "/shixuns/#{shixun.identifier}"}
end
subject_list << {subject_name: subject.name, subject_id: subject.id, shixun_list: shixun_list}
end
{subject_list: subject_list}
end
# (localhost:3000/api/v1/careers/4/create_career_stages)传参格式:
# {
# "career_stages": [
# {
# "name": "name1",
# "description": "description1",
# "subject_id": [1,2,3,4]
# },
# {
# "name": "name2",
# "description": "description2",
# "subject_id": [1,2,3,4]
# }
# ]
# }
# return: status -> 0成功 -1 失败
def create_career_stages params
begin
career = Career.find params[:id]
params[:career_stages].each_with_index do |c_stage, index|
stage = CareerStage.create!(:name => c_stage.name,
:description => c_stage.description,
:career_id => career.id,
:position => index + 1)
c_stage.subject_id.each do |subject|
CareerStageSubject.create!(:subject_id => subject, :career_stage_id => stage.id)
end
end
{status: 0, message: "创建职业路径内容成功!", career_id: career.id}
rescue Exception => e
{status: -1, message: "#{e.message}"}
end
end
#(localhost:3000/api/v1/careers/1/introduction)
# return:
# video_info: 视频模块信息
# shixuns_info 实训模块信息
# faq FAQ 常见问题
def introduction params
career = find_career params[:id]
video = career.attachments.first
video_info = {name: career.video_name, description: career.video_description, url: "/attachments/download/#{video.try(:id)}/#{video.try(:filename)}"}
shixuns_info = []
career.career_stages.each do |stage|
subjects = stage.subjects
subjects.each do |subject|
subject.shixuns.each do |shixun|
# 去除图片的链接
description = shixun.description.gsub(/!\[\](.*)\)/, "")
shixuns_info << {id: shixun.id, name: shixun.name, description: description}
break if shixuns_info.length > 7
end
end
end
faq = career.career_faqs.select([:question, :answer])
{career_name: career, video_info: video_info, shixuns_info: shixuns_info, faq: faq}
end
# (localhost:3000/api/v1/careers/1/update_introduction)传参格式:
# {
# "name": "name",
# "video_name": "video_name",
# "video_description": "video_description",
# "faq": [
# {
# "question": "question1",
# "answer": "answer1"
# },
# {
# "question": "question2",
# "answer": "answer2"
# }
# ]
# }
# params:
# [:name] -> 职业路径名称
# [:video_name] -> 视频名称
# [:video_description] -> 视频描述
# [:faq][:questions] -> 常见问题 类型: 字符串数组
# [:faq][:answers] -> 常见问题 类型: 字符串数组
# return
# status: 0 成功 -1 失败
# career_id: 职业路径的id
def update_introduction params
ActiveRecord::Base.transaction do
begin
career = find_career params[:id]
career.update_attributes(:name => params[:name], :video_name => params[:video_name], :video_description => params[:video_description])
if params[:attachments]
if params[:attachments][:attachment_id] != career.attachments.first.try(:id)
career.attachments.destroy_all
attachment = Attachment.find params[:attachments][:attachment_id]
attachment.update_attributes(:container_id => career.id, :container_type => "Career")
end
end
career.career_faqs.destroy_all
# 创建常见问题
if params[:faq]
params[:faq].each_with_index do |faq, index|
CareerFaq.create!(:question => faq.question, :answer => faq.answer, :career_id => career.id)
end
end
{status: 0, message: "更新成功", career_id: career.id}
rescue Exception => e
{status: -1, message: "#{e.message}"}
raise ActiveRecord::Rollback
end
end
end
#(localhost:3000/api/v1/careers/1/contents)
# return:
# {
# 用户信息
# "user_info": {
# "learn_level": 用户已学习的百分比(整数),
# "user_experences": 用户经验值,
# "experences_level": 高于平台经验的用户比例
# },
# # 阶段信息(数组)
# "career_info": [
# {
# # "badge_url": 设计总徽章
# "shixun_count": 阶段的实训总数,
# "stage_name": 阶段名称,
# "stage_score": 阶段总经验,
# "stage_description": 阶段描述,
# # 实训路径信息(数组)
# "subject_info": [
# {
# "subject_name": 实训路径名称,
# "my_progress": 我的实训路径进度,
# "all_progress": 阶段实训进度,
# "score": 实训路径经验值,
# "completed": 路径是否全完成 0 未完成 1 完成,
# # 实训信息(数组)
# "shixun_info": [
# {
# "shixun_name": 实训名称,
# "published": 实训发布与否
# "status": 用户实训状态(-1 未开启, 0 未完成, 1 已完成),
# "url": 实训开启链接(如:"/shixuns/qmeb65oa/shixun_exec"
# }
# ]
# }
# ]
# }
# ]
# }
def contents params, current_user
career = find_career params[:id]
career_info = []
# 职业路径完成的实训数
my_completed_count = 0
# 所有实训数
all_shixun_count = 0
shixun_ids = []
# 阶段循环(获取实训路径)
career.career_stages.each do |stage|
subject_info = []
# 阶段经验值
stage_score = 0
# 实训个数
shixun_count = 0
# 实训路径循环(获取实训)
stage.subjects.each do |subject|
# 实训路径是否完成: 1 完成 0未完成
completed = 0
shixuns = subject.shixuns
shixun_count += shixuns.count
# 路径经验值
subject_score = subject.subject_score
stage_score += subject_score
# 总进度
all_progress = shixuns.count
all_shixun_count += all_progress
# 我完成的进度
my_progress = 0
shixun_info = []
shixuns.each do |shixun|
shixun_ids << shixun.id
status = shixun.myshixuns.where(:user_id => current_user.id).first.try(:status)
status ||= -1
my_progress += 1 if status == 1
# status -1 未开启, 0 未完成, 1 已完成
published = shixun.status == 2 ? true : (shixun.status == 3 && status != -1 ? true : false)
shixun_info << {shixun_name: shixun.name, published: published, status: status, url: "/shixuns/#{shixun.identifier}/shixun_exec"}
end
completed = 1 if my_progress == all_progress
my_completed_count += my_progress
subject_info << {subject_name: subject.name, my_progress: my_progress, all_progress: all_progress, score: subject_score, completed: completed, shixun_info: shixun_info}
end
career_info << {career_name: career.name, shixun_count: shixun_count, stage_name: stage.name, stage_score: stage_score, stage_description: stage.description, subject_info: subject_info}
end
myshixuns = Myshixun.select([:id, :status, :user_id]).where(:shixun_id => shixun_ids)
myshixun_ids = myshixuns.blank? ? -1 : myshixuns.pluck(:id).join(",")
games = Game.find_by_sql("select @:=@+1 pos,a.score experences, a.user_id user_id from
(SELECT sum(c.score) score, g.user_id FROM `games` g join `challenges` c
on c.id = g.challenge_id where g.status = 2 and myshixun_id in(#{myshixun_ids}) group by g.user_id order by score asc, g.cost_time asc) a,
(SELECT @:=0) r;")
passed_count = myshixuns.where(:status => 1, :user_id => current_user.id).count
shixun_count = shixun_ids.count
Rails.logger.info("##################shixuns: ##{passed_count}")
Rails.logger.info("##################shixuns_count: ##{shixun_count}")
play_count = games.count
user_level = 0
Rails.logger.info("##################games: ##{games}")
user_experences = 0
games.each do |g|
if g.user_id == current_user.id
Rails.logger.info("####################{g}")
user_level = g.pos
user_experences = g.experences
end
end
experences_level = play_count == 0 ? 0 : ((user_level / play_count.to_f) * 100).to_i
learn_level = shixun_count == 0 ? 0 : ((passed_count / shixun_count.to_f) * 100).to_i
#down_user = User.where("experience < #{current_user.experience}").count
#all_user = User.count
#experences_level = ((down_user / all_user.to_f) * 100).to_i
#learn_level = all_shixun_count != 0 ? ((my_completed_count / all_shixun_count.to_f) * 100).to_i : 0
user_info = {learn_level: learn_level, user_experences: user_experences, experences_level: "#{experences_level}%"}
{user_info: user_info, career_info: career_info, badge_url: "/images/avatars/Career/#{career.id}"}
end
# (localhost:3000/api/v1/careers/1/update_contents)传参格式:
# {
# "career_stages": [
# {
# "name": "name1",
# "description": "description1",
# "subject_id": [1,2,3,4]
# },
# {
# "name": "name2",
# "description": "description2",
# "subject_id": [1,2,3,4]
# }
# ],
#
# }
# return: status -> 0成功 -1 失败
def update_contents params
ActiveRecord::Base.transaction do
begin
career = find_career params[:id]
career.career_stages.destroy_all
stages = params[:career_stages]
stages.each_with_index do |c_stage, index|
stage = CareerStage.create!(:name => c_stage.name,
:description => c_stage.description,
:career_id => career.id,
:position => index + 1)
c_stage.subject_id.each do |subject|
CareerStageSubject.create!(:subject_id => subject, :career_stage_id => stage.id)
end
end
{status: 0, message: "创建职业路径内容成功!", career_id: career.id}
rescue Exception => e
{status: -1, message: "#{e.message}"}
end
end
end
def get_published_careers params
career = Career.select([:id, :name]).published.order("created_at asc")
career.map{|c| c.attributes.dup }
end
# 公共接口
# localhost:3000/api/v1/careers/get_current_user
# return:
# current_user: 当前用户的头像下拉信息
def get_current_user params, current_user
current_user_info = format_for_current_user current_user if current_user
{current_user: current_user_info}
end
# GET /api/v1/careers/get_career_navigation_url
def get_navigation_url
careers = Career.published.order("created_at asc")
careers_info = careers.map{|c| {name: c.name, url:"/careers/#{c.id}/introduction"}}
{careers_info: careers_info}
end
private
def format_subject_list subjects, career_stage
subjects_list = []
Rails.logger.info("####################subjects: #{subjects}")
subjects.each do |subject|
selected =
if career_stage
subject_ids = career_stage.subjects.pluck(:id)
subject_ids.include?(subject.id)
else
false
end
user = User.find(subject.user_id)
status = subject.status == 2 ? "已发布" : "未发布"
subjects_list << {id: subject.id, name: subject.name, username: user.show_real_name, user_link: "/users/#{user.login}", status: status, selected: selected}
end
subjects_list
end
def format_for_current_user current_user
new_tidings_count = current_user.tidings.where("created_at > '#{current_user.onclick_time.onclick_time}'").count
new_pri_message_count = current_user.private_messages.where("created_at > '#{current_user.onclick_time.onclick_time}'").count
count = new_tidings_count + new_pri_message_count
{username: current_user.show_name, login: current_user.login,
user_id: current_user.id, image_url: url_to_avatar(current_user),
admin: current_user.admin?, is_teacher: current_user.user_extensions.try(:identity) == 0,
tidding_count: count}
end
def find_career id
Career.includes(:career_faqs, career_stages: [career_stage_subjects: :subject]).find id
end
end