# 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, phone: current_user.phone} end def find_career id Career.includes(:career_faqs, career_stages: [career_stage_subjects: :subject]).find id end end