diff --git a/app/controllers/admins/shixun_settings_controller.rb b/app/controllers/admins/shixun_settings_controller.rb index d635ae8df..216c9d909 100644 --- a/app/controllers/admins/shixun_settings_controller.rb +++ b/app/controllers/admins/shixun_settings_controller.rb @@ -65,19 +65,20 @@ class Admins::ShixunSettingsController < Admins::BaseController sheet1.row(0).default_format = blue sheet1.row(0).concat(["实训ID","实训名称","技术平台", "Fork源", "实践任务","选择题任务","挑战人数", "通关人数", "状态","创建者", "单位", "职业", "关卡序号","关卡名称","技能标签"]) count_row = 1 - shixuns.find_each do |shixun| + shixuns.includes(:fork_shixuns, :myshixuns, :mirror_repositories, challenges: [:challenge_tags], user: [user_extension: :school]).find_each do |shixun| sheet1[count_row, 0] = shixun.identifier sheet1[count_row, 1] = shixun.name - sheet1[count_row, 2] = shixun.shixun_main_name + sheet1[count_row, 2] = shixun.mirror_repositories.select{|mr| mr.main_type == "1"}.first&.type_name + sheet1[count_row, 3] = shixun.fork_identifier - sheet1[count_row, 4] = shixun.challenges.practice_type.count - sheet1[count_row, 5] = shixun.challenges.choose_type.count - sheet1[count_row, 6] = shixun.myshixuns.count - sheet1[count_row, 7] = shixun.myshixuns.finished.count + sheet1[count_row, 4] = shixun.challenges.select{|c| c.st == 0}.size + sheet1[count_row, 5] = shixun.challenges.select{|c| c.st == 1}.size + sheet1[count_row, 6] = shixun.myshixuns_count + sheet1[count_row, 7] = shixun.myshixuns.select{|m| m.status == 1}.size sheet1[count_row, 8] = shixun.shixun_status - sheet1[count_row, 9] = shixun.owner.show_real_name - sheet1[count_row, 10] = shixun.owner.school_name - sheet1[count_row, 11] = shixun.owner.identity + sheet1[count_row, 9] = shixun.user.show_real_name + sheet1[count_row, 10] = shixun.user.school_name + sheet1[count_row, 11] = shixun.user.identity shixun.challenges.each do |challenge| sheet1[count_row, 12] = "第#{challenge.position}关" sheet1[count_row, 13] = challenge.subject diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1bc2bad7d..f04d126f4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -45,6 +45,13 @@ class ApplicationController < ActionController::Base check_account tip_exception(@course.excellent ? 410 : 409, "您没有权限进入") end + if @user_course_identity == Course::STUDENT + # 实名认证和职业认证的身份判断 + tip_exception(-2, "你的实名认证和职业认证审核未通过") if @course.authentication && + @course.professional_certification && (!current_user.authentication && !current_user.professional_certification) + tip_exception(-2, "你的实名认证审核未通过") if @course.authentication && !current_user.authentication + tip_exception(-2, "你的职业认证审核未通过") if @course.professional_certification && !current_user.professional_certification + end uid_logger("###############user_course_identity:#{@user_course_identity}") end diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index fff320323..bf7f465d5 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1760,19 +1760,12 @@ class ExercisesController < ApplicationController else ques_number = q.question_number end + ques_status = 0 if q.question_type != Exercise::PRACTICAL ques_vote = q.exercise_answers.select{|answer| answer.user_id == user_id} - else - ques_vote = q.exercise_shixun_answers.select{|answer| answer.user_id == user_id} - end - ques_status = 0 - if ques_vote.present? - if q.question_type == Exercise::PRACTICAL - if ques_vote.pluck(:exercise_shixun_challenge_id).sort == q.exercise_shixun_challenges.pluck(:id).sort #用户的总得分等于问题的分数 - ques_status = 1 #全部回答了,才算已答 - question_answered += 1 - end - else #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 + + if ques_vote.present? + #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 vote_answer_id = ques_vote.pluck(:exercise_choice_id).reject(&:blank?) vote_text_count = ques_vote.pluck(:answer_text).reject(&:blank?).size if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 @@ -1780,11 +1773,6 @@ class ExercisesController < ApplicationController ques_status = 1 question_answered += 1 end - elsif q.question_type == Exercise::COMPLETION #填空题的时候,需要有选项和内容,才算回答 - if vote_answer_id.uniq.sort == q.exercise_standard_answers.pluck(:exercise_choice_id).uniq.sort - ques_status = 1 - question_answered += 1 - end else if vote_text_count > 0 #主观题,必选有内容,才算回答 ques_status = 1 @@ -1792,6 +1780,11 @@ class ExercisesController < ApplicationController end end end + else + if Myshixun.exists?(user_id: user_id, shixun_id: q.shixun_id) + ques_status = 1 + question_answered += 1 + end end question_status = { :ques_id => q.id, diff --git a/app/controllers/hack_user_lastest_codes_controller.rb b/app/controllers/hack_user_lastest_codes_controller.rb index fcbecec0d..9602673e5 100644 --- a/app/controllers/hack_user_lastest_codes_controller.rb +++ b/app/controllers/hack_user_lastest_codes_controller.rb @@ -136,7 +136,9 @@ class HackUserLastestCodesController < ApplicationController if @my_hack.hack_user_debug.present? @my_hack.hack_user_debug.update_attributes!(debug_params) else - @my_hack.hack_user_debug.create!(debug_params) + debug = HackUserDebug.new(debug_params) + debug.hack_user_lastest_code_id = @my_hack.id + debug.save! end end diff --git a/app/helpers/weapps/courses_helper.rb b/app/helpers/weapps/courses_helper.rb index a58127c4c..94769fc2e 100644 --- a/app/helpers/weapps/courses_helper.rb +++ b/app/helpers/weapps/courses_helper.rb @@ -23,6 +23,7 @@ module Weapps::CoursesHelper data = data.sort do |a, b| [a[:letter]] <=> [b[:letter]] end + data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后 return data end @@ -49,6 +50,7 @@ module Weapps::CoursesHelper data = data.sort do |a, b| [a[:letter]] <=> [b[:letter]] end + data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后 return data end diff --git a/app/models/shixun.rb b/app/models/shixun.rb index a0f88260b..e8aa1b186 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -28,6 +28,7 @@ class Shixun < ApplicationRecord has_one :first_tag_repertoire, through: :first_shixun_tag_repertoire, source: :tag_repertoire has_many :homework_commons_shixuns, class_name: 'HomeworkCommonsShixun' + has_many :fork_shixuns, foreign_key: "fork_from", class_name: 'Shixun' #实训的关卡 has_many :exercise_shixun_challenges, :dependent => :destroy @@ -97,7 +98,7 @@ class Shixun < ApplicationRecord end def fork_identifier - self.fork_from.nil? ? "--" : Shixun.where(id: self.fork_from).first.try(:identifier) + self.fork_from.nil? ? "--" : fork_shixuns.first&.identifier end def shixun_status @@ -171,7 +172,7 @@ class Shixun < ApplicationRecord end def owner - User.find(self.user_id) + User.find_by_id(self.user_id) end def shixun_main_name diff --git a/app/services/admins/identity_auths/refuse_apply_service.rb b/app/services/admins/identity_auths/refuse_apply_service.rb index 7ac2e6c38..dfc9168a9 100644 --- a/app/services/admins/identity_auths/refuse_apply_service.rb +++ b/app/services/admins/identity_auths/refuse_apply_service.rb @@ -10,6 +10,7 @@ class Admins::IdentityAuths::RefuseApplyService < ApplicationService def call ActiveRecord::Base.transaction do apply.update!(status: 2, remarks: reason) + user.update!(authentication: false) deal_tiding! apply.attachment&.destroy diff --git a/app/services/admins/professional_auths/refuse_apply_service.rb b/app/services/admins/professional_auths/refuse_apply_service.rb index a055488c3..014fbab0b 100644 --- a/app/services/admins/professional_auths/refuse_apply_service.rb +++ b/app/services/admins/professional_auths/refuse_apply_service.rb @@ -10,6 +10,7 @@ class Admins::ProfessionalAuths::RefuseApplyService < ApplicationService def call ActiveRecord::Base.transaction do apply.update!(status: 2, remarks: reason) + user.update!(professional_certification: false) deal_tiding! apply.attachment&.destroy diff --git a/app/services/users/apply_authentication_service.rb b/app/services/users/apply_authentication_service.rb index 1b9b02c91..a6b02f431 100644 --- a/app/services/users/apply_authentication_service.rb +++ b/app/services/users/apply_authentication_service.rb @@ -10,7 +10,7 @@ class Users::ApplyAuthenticationService < ApplicationService raise Error, '请先完善基本信息' unless user.profile_completed? Users::ApplyAuthenticationForm.new(params).validate! - raise Error, '您已经申请过实名认证了' if ApplyUserAuthentication.real_name_auth.processing.exists?(user_id: user.id) + # raise Error, '您已经申请过实名认证了' if ApplyUserAuthentication.real_name_auth.processing.exists?(user_id: user.id) user.lastname = params[:name].to_s.strip user.firstname = '' @@ -18,7 +18,9 @@ class Users::ApplyAuthenticationService < ApplicationService user.show_realname = params[:show_realname].to_s == 'true' if params[:show_realname].to_s.present? ActiveRecord::Base.transaction do - user.authentication = false + ApplyUserAuthentication.real_name_auth.processing.where(user_id: user.id).destroy_all + + user.authentication = true user.save! user.user_extension.update!(gender: params[:gender].to_i) if params[:gender].present? diff --git a/app/services/users/apply_professional_auth_service.rb b/app/services/users/apply_professional_auth_service.rb index 81cd11a4c..c94481890 100644 --- a/app/services/users/apply_professional_auth_service.rb +++ b/app/services/users/apply_professional_auth_service.rb @@ -12,15 +12,15 @@ class Users::ApplyProfessionalAuthService < ApplicationService raise Error, '请先完善基本信息' unless user.profile_completed? Users::ApplyProfessionalAuthForm.new(params).validate! - raise Error, '您已经申请过职业认证了' if ApplyUserAuthentication.professional_auth.processing.exists?(user_id: user.id) - - user.professional_certification = false + # raise Error, '您已经申请过职业认证了' if ApplyUserAuthentication.professional_auth.processing.exists?(user_id: user.id) extension = user.user_extension extension.school_id = params[:school_id] extension.department_id = params[:department_id] extension.identity = params[:identity] + user.professional_certification = params[:identity] != "teacher" + extra = params[:extra].to_s.strip.presence if extension.identity.to_s == 'student' extension.technical_title = nil @@ -31,6 +31,7 @@ class Users::ApplyProfessionalAuthService < ApplicationService end ActiveRecord::Base.transaction do + ApplyUserAuthentication.professional_auth.processing.where(user_id: user.id).destroy_all user.save! extension.save! diff --git a/app/views/admins/shixun_settings/shared/_td.html.erb b/app/views/admins/shixun_settings/shared/_td.html.erb index ddbbdff02..f4a05f178 100644 --- a/app/views/admins/shixun_settings/shared/_td.html.erb +++ b/app/views/admins/shixun_settings/shared/_td.html.erb @@ -27,7 +27,7 @@ <%= raw '
' if weappImageExists %> <%= javascript_void_link weappImageExists ? '重新上传' : '上传图片', class: 'action upload-shixun-weapp-image-action', data: { source_id: shixun.id, source_type: 'Shixun', suffix: '_weapp', toggle: 'modal', target: '.admin-upload-file-modal' } %> -<%= link_to shixun.owner.try(:real_name),"/users/#{shixun.owner.login}",target:'_blank' %> +<%= link_to shixun.owner.try(:real_name),"/users/#{shixun.owner&.login}",target:'_blank' %> <% if shixun.status.to_i < 3 %> <%= link_to "关闭", admins_shixun_setting_path(shixun,status:3,page_no:page_no),method: :put, :class => "", :remote => true %> diff --git a/app/views/courses/apply_teachers.json.jbuilder b/app/views/courses/apply_teachers.json.jbuilder index bd88d5fbe..b81f5d77b 100644 --- a/app/views/courses/apply_teachers.json.jbuilder +++ b/app/views/courses/apply_teachers.json.jbuilder @@ -9,6 +9,7 @@ json.application_list do json.name_link user_path(application.application_user) json.login application.application_user.login json.image_url url_to_avatar(application.application_user) + json.school_name application.application_user.school_name json.role application.content.to_i == 3 || application.content.to_i == 7 ? "助教" : application.content.to_i == 2 || application.content.to_i == 9 ? "教师" : "" end end \ No newline at end of file diff --git a/db/migrate/20191120123353_add_code_forhack_user_debugs.rb b/db/migrate/20191120123353_add_code_forhack_user_debugs.rb new file mode 100644 index 000000000..d3285f26b --- /dev/null +++ b/db/migrate/20191120123353_add_code_forhack_user_debugs.rb @@ -0,0 +1,5 @@ +class AddCodeForhackUserDebugs < ActiveRecord::Migration[5.2] + def change + add_column :hack_user_debugs, :code, :text + end +end diff --git a/db/migrate/20191121025552_modify_execute_time_for_hack_user_code.rb b/db/migrate/20191121025552_modify_execute_time_for_hack_user_code.rb new file mode 100644 index 000000000..c66e13a03 --- /dev/null +++ b/db/migrate/20191121025552_modify_execute_time_for_hack_user_code.rb @@ -0,0 +1,6 @@ +class ModifyExecuteTimeForHackUserCode < ActiveRecord::Migration[5.2] + def change + change_column :hack_user_debugs, :execute_time, :float + change_column :hack_user_codes, :execute_time, :float + end +end diff --git a/public/react/src/App.js b/public/react/src/App.js index 6b4ba7399..fedd0a3cd 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -20,6 +20,7 @@ import Trialapplicationysl from './modules/login/Trialapplicationysl'; import Trialapplicationreview from './modules/user/Trialapplicationreview'; import Addcourses from "./modules/courses/coursesPublic/Addcourses"; import AccountProfile from "./modules/user/AccountProfile"; +import Accountnewprofile from './modules/user/Accountnewprofile'; import Trialapplication from './modules/login/Trialapplication'; import Certifiedprofessional from './modules/modals/Certifiedprofessional'; import NotFoundPage from './NotFoundPage' @@ -466,6 +467,7 @@ class App extends Component { + this.Modifyloginvalue()}> diff --git a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js index 503c73a10..5f3704a33 100644 --- a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js +++ b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js @@ -130,16 +130,28 @@ class CoursesBanner extends Component { axios.get(url,{params: dataqueryss }).then((result) => { - if( result!=undefined){ - let data = result.data; - this.setState({ - coursedata: data, - excellent:data.excellent, - }) - this.props.ispostexcellenttype(data.excellent) + if(result.data.status===-2){ + // this.setState({ + // AccountProfiletype:true, + // content:result.data.message, + // okText:"立即认证", + // cannelText:"稍后认证", + // okHref:`/account/certification`, + // Accounturltype:true + // }) }else{ - this.onloadupdatabanner() + if( result!=undefined){ + let data = result.data; + this.setState({ + coursedata: data, + excellent:data.excellent, + }) + this.props.ispostexcellenttype(data.excellent) + }else{ + this.onloadupdatabanner() + } } + }) }; foo=(url)=> { @@ -452,7 +464,12 @@ class CoursesBanner extends Component { hideAccountProfile=()=>{ this.setState({ - AccountProfiletype:false + AccountProfiletype:false, + content:undefined, + okText:undefined, + okHref:undefined, + cannelText:undefined, + Accounturltype:undefined }) }; ysljoinmodalCancel=()=>{ diff --git a/public/react/src/modules/courses/shixunHomework/shixunreport/ConclusionEvaluation.js b/public/react/src/modules/courses/shixunHomework/shixunreport/ConclusionEvaluation.js index 5430b9e8c..8d678f335 100644 --- a/public/react/src/modules/courses/shixunHomework/shixunreport/ConclusionEvaluation.js +++ b/public/react/src/modules/courses/shixunHomework/shixunreport/ConclusionEvaluation.js @@ -1,6 +1,6 @@ import React, {Component} from "react"; import {WordsBtn} from 'educoder'; -import {Table,Tooltip,} from "antd"; +import {Table,Tooltip} from "antd"; import {Link,Switch,Route,Redirect} from 'react-router-dom'; class ConclusionEvaluation extends Component { @@ -23,10 +23,10 @@ class ConclusionEvaluation extends Component { dataIndex: 'type', key: 'type', render: (text, record) => ( - {record.type} + {record.type} ), }, { - title: '获得经验值', + title:'获得经验值', dataIndex: 'empirical', key: 'empirical', render: (text, record) => ( diff --git a/public/react/src/modules/courses/statistics/Statistics.js b/public/react/src/modules/courses/statistics/Statistics.js index bb1ed9a09..00a47a81d 100644 --- a/public/react/src/modules/courses/statistics/Statistics.js +++ b/public/react/src/modules/courses/statistics/Statistics.js @@ -72,32 +72,34 @@ class Statistics extends Component{ }) } - getDynamiclistdatas=(group_ids)=>{ - - let courseId=this.props.match.params.coursesId; - let url=`/courses/${courseId}/act_score.json`; - let data={ - group_ids:group_ids, - } - axios.get(url,{params: - data - }).then((result) => { - if (result) { + getDynamiclistdatas=(group_ids,key)=>{ + if(key==='2') { + let courseId = this.props.match.params.coursesId; + let url = `/courses/${courseId}/act_score.json`; + let data = { + group_ids: group_ids, + } + axios.get(url, { + params: + data + }).then((result) => { + if (result) { + this.setState({ + course_members: result.data.course_members, + bomisSpin: false + }) + } + }).catch((error) => { + console.log(error); this.setState({ - course_members:result.data.course_members, - bomisSpin:false + bomisSpin: false, }) - } - }).catch((error) => { - console.log(error); - this.setState({ - bomisSpin:false, }) - }) + } } - getwork_scoredata=(page,group_ids,sort)=>{ - let {activeKey}=this.state; + getwork_scoredata=(page,group_ids,sort,key)=>{ + this.setState({ page:page, sort:sort, @@ -105,7 +107,7 @@ class Statistics extends Component{ bomisSpin:true, }) - if(activeKey==='1'){ + if(key==='1'||key===undefined){ let courseId=this.props.match.params.coursesId; let url=`/courses/${courseId}/work_score.json`; let data={ @@ -141,10 +143,10 @@ class Statistics extends Component{ if(key==="1"){ let {page,group_ids,sort}=this.state; // this.getdatas() - this.getwork_scoredata(page,group_ids,sort) - }else{ + this.getwork_scoredata(page,group_ids,sort,key) + }else if(key==="2"){ let{group_ids}=this.state; - this.getDynamiclistdatas(group_ids) + this.getDynamiclistdatas(group_ids,key) } this.setState({ activeKey:key diff --git a/public/react/src/modules/osshackathon/Osshackathon.css b/public/react/src/modules/osshackathon/Osshackathon.css index 679f4afb0..227bd1150 100644 --- a/public/react/src/modules/osshackathon/Osshackathon.css +++ b/public/react/src/modules/osshackathon/Osshackathon.css @@ -37,11 +37,9 @@ } .OsshackathonCardtitle{ - height:24px; font-size:24px; font-weight:400; color:rgba(5,16,26,1); - line-height:24px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; diff --git a/public/react/src/modules/osshackathon/Osshackathon.js b/public/react/src/modules/osshackathon/Osshackathon.js index 7edc18d63..67c81381c 100644 --- a/public/react/src/modules/osshackathon/Osshackathon.js +++ b/public/react/src/modules/osshackathon/Osshackathon.js @@ -119,14 +119,11 @@ class Osshackathon extends Component { } //判断是否绑定邮箱 - if(this.props.user.email===null){ - this.props.showhideAccountPhoneemailDialog() - return - } - if(this.props.user.phone===null){ + if(this.props.user.email===null&&this.props.user.phone===null){ this.props.showhideAccountPhoneemailDialog() return } + this.props.confirm({ content: `是否确认报名?`, onOk: () => { @@ -357,6 +354,7 @@ class Osshackathon extends Component { + 报名人数:{item.hack_users_count} {item.entry_info===true?:} diff --git a/public/react/src/modules/user/AccountProfile.js b/public/react/src/modules/user/AccountProfile.js index ea8d20b8a..1774a9fd5 100644 --- a/public/react/src/modules/user/AccountProfile.js +++ b/public/react/src/modules/user/AccountProfile.js @@ -31,18 +31,23 @@ class AccountProfile extends Component { } - gotoback=()=>{ - if(this.props.AccountProfiletype!=undefined){ - this.setState({ - AccountProfiletype:false - }) - this.props.hideAccountProfile() - }else{ + gotoback=(type)=>{ + if(type===true){ window.location.href="/"; - this.setState({ - AccountProfiletype:false - }) + }else{ + if(this.props.AccountProfiletype!=undefined){ + this.setState({ + AccountProfiletype:false + }) + this.props.hideAccountProfile() + }else{ + window.location.href="/"; + this.setState({ + AccountProfiletype:false + }) + } } + } @@ -52,7 +57,7 @@ okText: '立即完成', okHref: '/account/certification' */ render() { - const { content, okText, okHref } = this.props; + const { content, okText, okHref,cannelText,Accounturltype} = this.props; return(

{content || '您需要去完善您的个人资料,才能使用此功能'}

- this.gotoback()}>稍后完善 + this.gotoback(Accounturltype)}>{cannelText ||'稍后完善'} {okText || '立即完善'}
diff --git a/public/react/src/modules/user/Accountnewprofile.js b/public/react/src/modules/user/Accountnewprofile.js new file mode 100644 index 000000000..c8f81d340 --- /dev/null +++ b/public/react/src/modules/user/Accountnewprofile.js @@ -0,0 +1,69 @@ +import React, { Component } from 'react'; +import {getImageUrl} from 'educoder'; +import {Modal} from 'antd'; +import axios from 'axios'; +class Accountnewprofile extends Component { + constructor(props) { + super(props); + this.state = { + newAccountProfiletype:false + } + } + componentDidMount() { + axios.interceptors.response.use((response) => { + if(response!=undefined) + if (response&&response.data.status === 411) { + this.setState({ + newAccountProfiletype:true, + content:response.data.message, + okText:"立即认证", + cannelText:"稍后认证", + okHref:`/account/certification`, + }) + } + return response; + }, (error) => { + + }); + } + + gotoback=()=>{ + window.location.href="/"; + this.setState({ + newAccountProfiletype:false + }) + } + + + + /** + content: '您需要去完成您的职业认证,才能使用此功能', + okText: '立即完成', + okHref: '/account/certification' + */ + render() { + const { content, okText, okHref,cannelText} = this.state; + return( + +
+

{content}

+ +
+
+ ) + } +} + +export default Accountnewprofile; \ No newline at end of file