Merge branch 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

issues25489
杨树林 5 years ago
commit d50063c786

@ -78,12 +78,17 @@ class AccountsController < ApplicationController
return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked? return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
login_control = LimitForbidControl::UserLogin.new(@user) login_control = LimitForbidControl::UserLogin.new(@user)
return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回登录密码,") if login_control.forbid? return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
password_ok = @user.check_password?(params[:password].to_s) password_ok = @user.check_password?(params[:password].to_s)
unless password_ok unless password_ok
if login_control.remain_times-1 == 0
normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
else
normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
end
login_control.increment! login_control.increment!
return normal_status(-2, "你已经输错密码#{login_control.error_times}次,还剩余#{login_control.remain_times}次机会") return
end end
successful_authentication(@user) successful_authentication(@user)

@ -191,6 +191,7 @@ class AttachmentsController < ApplicationController
candown = current_user.member_of_course?(course) candown = current_user.member_of_course?(course)
end end
tip_exception(403, "您没有权限进入") if course.present? && !candown tip_exception(403, "您没有权限进入") if course.present? && !candown
tip_exception(403, "您没有权限进入") if @file.container.is_a?(ApplyUserAuthentication)
end end
end end
end end

@ -46,7 +46,7 @@ class Competitions::CompetitionsController < Competitions::BaseController
@competition_modules = @competition.unhidden_competition_modules @competition_modules = @competition.unhidden_competition_modules
# 未登录、未获奖用户,不展示获奖证书栏目 # 未登录、未获奖用户,不展示获奖证书栏目
if !current_user.logged? || !current_competition.finished? || !current_competition.competition_prize_users.exists?(user: current_user) if !current_user.logged? || !current_competition.finished? || (!current_competition.competition_prize_users.exists?(user: current_user) && !current_user.admin_or_business?)
@competition_modules = @competition_modules.select { |mod| mod.name != '获奖证书' } @competition_modules = @competition_modules.select { |mod| mod.name != '获奖证书' }
end end

@ -18,7 +18,7 @@ class CoursesController < ApplicationController
:left_banner, :top_banner, :apply_to_join_course, :exit_course, :course_groups] :left_banner, :top_banner, :apply_to_join_course, :exit_course, :course_groups]
before_action :set_course, only: [:show, :update, :destroy, :settings, :set_invite_code_halt, before_action :set_course, only: [:show, :update, :destroy, :settings, :set_invite_code_halt,
:set_public_or_private, :search_teacher_candidate, :teachers, :apply_teachers, :set_public_or_private, :search_teacher_candidate, :teachers, :apply_teachers,
:top_banner, :left_banner, :add_teacher_popup, :add_teacher, :top_banner, :left_banner, :add_teacher_popup, :add_teacher, :inform_up, :inform_down,
:graduation_group_list, :create_graduation_group, :join_graduation_group, :graduation_group_list, :create_graduation_group, :join_graduation_group,
:course_group_list, :set_course_group, :change_course_admin, :change_course_teacher, :course_group_list, :set_course_group, :change_course_admin, :change_course_teacher,
:delete_course_teacher, :teacher_application_review, :students, :all_course_groups, :delete_course_teacher, :teacher_application_review, :students, :all_course_groups,
@ -41,7 +41,7 @@ class CoursesController < ApplicationController
:set_course_group, :create_group_by_importing_file, :set_course_group, :create_group_by_importing_file,
:update_task_position, :tasks_list] :update_task_position, :tasks_list]
before_action :teacher_or_admin_allowed, only: [:graduation_group_list, :create_graduation_group, :join_graduation_group, before_action :teacher_or_admin_allowed, only: [:graduation_group_list, :create_graduation_group, :join_graduation_group,
:change_course_teacher, :course_group_list, :change_member_role, :change_course_teacher, :course_group_list, :change_member_role,:inform_up, :inform_down,
:teacher_application_review, :apply_teachers, :delete_course_teacher] :teacher_application_review, :apply_teachers, :delete_course_teacher]
before_action :validate_course_name, only: [:create, :update] before_action :validate_course_name, only: [:create, :update]
before_action :find_board, only: :board_list before_action :find_board, only: :board_list
@ -281,13 +281,43 @@ class CoursesController < ApplicationController
end end
def informs def informs
@informs = @course.informs @informs = @course.informs.order("position desc")
end
def inform_up
inform = @course.informs.find_by(id: params[:inform_id])
next_inform = inform.next_inform
ActiveRecord::Base.transaction do
if next_inform
render_error('已经到达最顶部')
else
inform.update_attribute(:position, (position + 1))
next_inform.update_attribute(:position, last_inform.position - 1)
render_ok
end
end
end
def inform_down
inform = @course.informs.find_by(id: params[:inform_id])
last_inform = inform.last_inform
ActiveRecord::Base.transaction do
if last_inform
render_error('已经到达最底部')
else
inform.update_attribute(:position, (position - 1))
last_inform.update_attribute(:position, last_inform.position + 1)
render_ok
end
end
end end
def new_informs def new_informs
inform = Inform.new(container: @course) inform = Inform.new(container: @course)
inform.name = params[:name] inform.name = params[:name]
inform.description = params[:description] inform.description = params[:description]
inform.position = @course.informs.maximum(:position) + 1
inform.save! inform.save!
normal_status("创建成功") normal_status("创建成功")
end end
@ -300,6 +330,7 @@ class CoursesController < ApplicationController
def delete_informs def delete_informs
inform = @course.informs.find_by(id: params[:inform_id]) inform = @course.informs.find_by(id: params[:inform_id])
@course.informs.where("position > ?", inform.position).update_all("position = position - 1")
inform.destroy! inform.destroy!
normal_status("删除成功") normal_status("删除成功")
end end

@ -16,6 +16,7 @@ class TrustieHacksController < ApplicationController
end end
@hackathon_users_count = hacks ? 0 : hacks.sum(:hack_users_count) @hackathon_users_count = hacks ? 0 : hacks.sum(:hack_users_count)
@hacks_count = hacks.count
@hacks = hacks.page(page).per(limit) @hacks = hacks.page(page).per(limit)

@ -17,6 +17,6 @@ class Users::AuthenticationAppliesController < Users::BaseAccountController
private private
def create_params def create_params
params.permit(:name, :gender, :id_number, :upload_image) params.permit(:name, :gender, :id_number, :upload_image, attachment_ids: [])
end end
end end

@ -17,6 +17,6 @@ class Users::ProfessionalAuthAppliesController < Users::BaseAccountController
private private
def create_params def create_params
params.permit(:school_id, :department_id, :identity, :extra, :upload_image) params.permit(:school_id, :department_id, :identity, :extra, :upload_image, attachment_ids: [])
end end
end end

@ -1,10 +1,11 @@
class Users::ApplyAuthenticationForm class Users::ApplyAuthenticationForm
include ActiveModel::Model include ActiveModel::Model
attr_accessor :name, :id_number, :gender, :upload_image attr_accessor :name, :id_number, :gender, :upload_image, :attachment_ids
validates :name, presence: true validates :name, presence: true
validate :validate_ID_number validate :validate_ID_number
validate :validate_attachment_ids
def validate_ID_number def validate_ID_number
@ -12,4 +13,10 @@ class Users::ApplyAuthenticationForm
raise("身份证格式不对") raise("身份证格式不对")
end end
end end
def validate_attachment_ids
unless attachment_ids.is_a?(Array) || attachment_ids.length != 1
raise("图片参数不对")
end
end
end end

@ -1,10 +1,17 @@
class Users::ApplyProfessionalAuthForm class Users::ApplyProfessionalAuthForm
include ActiveModel::Model include ActiveModel::Model
attr_accessor :school_id, :department_id, :identity, :extra, :upload_image attr_accessor :school_id, :department_id, :identity, :extra, :upload_image, :attachment_ids
validates :school_id, presence: true, numericality: { only_integer: true, greater_than: 0 } validates :school_id, presence: true, numericality: { only_integer: true, greater_than: 0 }
validates :department_id, numericality: { only_integer: true, greater_than: 0 }, allow_blank: true validates :department_id, numericality: { only_integer: true, greater_than: 0 }, allow_blank: true
validates :identity, presence: true, inclusion: { in: %w(student teacher professional) } validates :identity, presence: true, inclusion: { in: %w(student teacher professional) }
validates :extra, presence: true validates :extra, presence: true
validate :validate_attachment_ids
def validate_attachment_ids
unless attachment_ids.is_a?(Array) || attachment_ids.length != 1
raise("图片参数不对")
end
end
end end

@ -4,6 +4,7 @@ class ApplyUserAuthentication < ApplicationRecord
belongs_to :user belongs_to :user
has_many :tidings, :as => :container, :dependent => :destroy has_many :tidings, :as => :container, :dependent => :destroy
has_one :attachment, as: :container, dependent: :destroy
scope :real_name_auth, -> { where(auth_type: 1) } scope :real_name_auth, -> { where(auth_type: 1) }
scope :professional_auth, -> { where(auth_type: 2) } scope :professional_auth, -> { where(auth_type: 2) }

@ -5,4 +5,13 @@ class Inform < ApplicationRecord
validates :description, length: { maximum: 5000 } validates :description, length: { maximum: 5000 }
has_many :attachments, as: :container, dependent: :destroy has_many :attachments, as: :container, dependent: :destroy
def next_inform
Inform.where(position: self.position+1, container_id: self.course_id, container_type: 'Course')
end
def last_inform
Inform.where(position: self.position-1, container_id: self.course_id, container_type: 'Course')
end
end end

@ -14,7 +14,8 @@ class Admins::IdentityAuths::AgreeApplyService < ApplicationService
RewardGradeService.call(user, container_id: user.id, container_type: 'Authentication', score: 500) RewardGradeService.call(user, container_id: user.id, container_type: 'Authentication', score: 500)
deal_tiding! deal_tiding!
delete_auth_file! apply.attachment&.destroy
# delete_auth_file!
end end
end end

@ -12,7 +12,8 @@ class Admins::IdentityAuths::RefuseApplyService < ApplicationService
apply.update!(status: 2, remarks: reason) apply.update!(status: 2, remarks: reason)
deal_tiding! deal_tiding!
delete_auth_file! apply.attachment&.destroy
# delete_auth_file!
end end
end end

@ -14,7 +14,8 @@ class Admins::ProfessionalAuths::AgreeApplyService < ApplicationService
RewardGradeService.call(user, container_id: user.id, container_type: 'Professional', score: 500) RewardGradeService.call(user, container_id: user.id, container_type: 'Professional', score: 500)
deal_tiding! deal_tiding!
delete_auth_file! apply.attachment&.destroy
# delete_auth_file!
end end
end end

@ -12,7 +12,8 @@ class Admins::ProfessionalAuths::RefuseApplyService < ApplicationService
apply.update!(status: 2, remarks: reason) apply.update!(status: 2, remarks: reason)
deal_tiding! deal_tiding!
delete_auth_file! apply.attachment&.destroy
# delete_auth_file!
end end
end end

@ -22,9 +22,11 @@ class Users::ApplyAuthenticationService < ApplicationService
user.user_extension.update!(gender: params[:gender].to_i) if params[:gender].present? user.user_extension.update!(gender: params[:gender].to_i) if params[:gender].present?
user.apply_user_authentication.create!(auth_type: 1, status: 0) apply = user.apply_user_authentication.create!(auth_type: 1, status: 0)
move_image_file! unless params[:upload_image].to_s == 'false' Attachment.associate_container(params[:attachment_ids], apply.id, apply.class) if params[:attachment_ids]
# move_image_file! unless params[:upload_image].to_s == 'false'
end end
# sms_notify_admin # sms_notify_admin

@ -34,9 +34,11 @@ class Users::ApplyProfessionalAuthService < ApplicationService
user.save! user.save!
extension.save! extension.save!
user.apply_user_authentication.create!(auth_type: 2, status: 0) apply = user.apply_user_authentication.create!(auth_type: 2, status: 0)
move_image_file! unless params[:upload_image].to_s == 'false' Attachment.associate_container(params[:attachment_ids], apply.id, apply.class) if params[:attachment_ids]
# move_image_file! unless params[:upload_image].to_s == 'false'
end end
# sms_notify_admin # sms_notify_admin

@ -51,8 +51,8 @@
<% unless is_processed %> <% unless is_processed %>
<td> <td>
<% if File.exists?(disk_real_name_auth_filename(user.id)) %> <% if apply.attachment %>
<%= image_tag(real_name_auth_file_url(user.id).to_s + "?#{Time.now.to_i}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %> <%= image_tag("/api/attachments/#{apply.attachment.id}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %>
<% else %> <% else %>
<%= content_tag(:span, '图片已删除', class: 'text-secondary') %> <%= content_tag(:span, '图片已删除', class: 'text-secondary') %>
<% end %> <% end %>

@ -48,8 +48,8 @@
<% unless is_processed %> <% unless is_processed %>
<td> <td>
<% if File.exists?(disk_professional_auth_filename(user.id)) %> <% if apply.attachment %>
<%= image_tag(professional_auth_file_url(user.id).to_s + "?#{Time.now.to_i}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %> <%= image_tag("/api/attachments/#{apply.attachment.id}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %>
<% else %> <% else %>
<%= content_tag(:span, '图片已删除', class: 'text-secondary') %> <%= content_tag(:span, '图片已删除', class: 'text-secondary') %>
<% end %> <% end %>

@ -5,7 +5,7 @@ json.students do
json.name student.user.try(:real_name) json.name student.user.try(:real_name)
json.name_link user_path(student.user) json.name_link user_path(student.user)
json.student_id student.user.try(:student_id) json.student_id student.user.try(:student_id)
json.course_group_name student.course_group.try(:name) json.course_group_name student.course_group_name
json.course_member_id student.id json.course_member_id student.id
if @user_course_identity < Course::ASSISTANT_PROFESSOR && !params[:course_group_id].present? if @user_course_identity < Course::ASSISTANT_PROFESSOR && !params[:course_group_id].present?
json.member_roles student.user.course_role(@course) json.member_roles student.user.course_role(@course)

@ -2,7 +2,7 @@ json.hackathon do
json.(@hackathon, :id, :name, :description) json.(@hackathon, :id, :name, :description)
json.hackathon_users_count @hackathon_users_count json.hackathon_users_count @hackathon_users_count
end end
json.hacks_count @hacks_count
json.hacks @hacks do |hack| json.hacks @hacks do |hack|
json.(hack, :id, :name, :description, :hack_users_count) json.(hack, :id, :name, :description, :hack_users_count)
json.entry_info hack.entry_info(current_user.id) json.entry_info hack.entry_info(current_user.id)

@ -381,6 +381,8 @@ Rails.application.routes.draw do
get 'work_score' get 'work_score'
get 'act_score' get 'act_score'
get 'statistics' get 'statistics'
post :inform_up
post :inform_down
end end
collection do collection do

@ -0,0 +1,111 @@
class Migrate2808ExerciseScore < ActiveRecord::Migration[5.2]
def challenge_path(path)
cha_path = path.present? ? path.split("") : []
cha_path.reject(&:blank?)[0].try(:strip)
end
# 版本库文件内容,带转码
def git_fle_content(repo_path, path)
begin
Rails.logger.info("git file content: repo_path is #{repo_path}, path is #{path}")
content = GitService.file_content(repo_path: repo_path, path: path)
Rails.logger.info("git file content: content is #{content}")
decode_content = nil
if content.present?
content = content["content"] #6.24 -hs 这个为新增,因为当实训题里含有选择题时,这里会报错,undefined method `[]' for nil:NilClass
content = Base64.decode64(content)
cd = CharDet.detect(content)
Rails.logger.info "encoding: #{cd['encoding']} confidence: #{cd['confidence']}"
# 字符编码问题GB18030编码识别率不行
decode_content =
if cd["encoding"] == 'GB18030' && cd['confidence'] > 0.8
content.encode('UTF-8', 'GBK', {:invalid => :replace, :undef => :replace, :replace => ' '})
else
content.force_encoding('UTF-8')
end
end
decode_content
rescue Exception => e
Rails.logger.error(e.message)
raise Educoder::TipException.new("文档内容获取异常")
end
end
def calculate_student_score(exercise,user)
score5 = 0.0 #实训题
exercise_questions = exercise.exercise_questions.includes(:exercise_standard_answers,:exercise_shixun_challenges)
exercise_questions.each do |q|
if q.question_type == 5
q.exercise_shixun_challenges.each do |exercise_cha|
game = Game.user_games(user.id,exercise_cha.challenge_id)&.first #当前用户的关卡
if game.present?
exercise_cha_score = 0.0
answer_status = 0
# if game.status == 2 && game.final_score >= 0
if game.final_score > 0 && game.end_time < exercise.end_time
exercise_cha_score = game.real_score(exercise_cha.question_score)
# exercise_cha_score = exercise_cha.question_score #每一关卡的得分
answer_status = 1
end
ex_shixun_answer_content = exercise_cha.exercise_shixun_answers.where(user_id:user.id,exercise_question_id:q.id)
code = nil
if exercise_cha.challenge&.path.present?
cha_path = challenge_path(exercise_cha.challenge&.path)
game_challenge = game.game_codes.search_challenge_path(cha_path)&.first
if game_challenge.present?
game_code = game_challenge
code = game_code.try(:new_code)
else
begin
code = git_fle_content(game.myshixun.repo_path,cha_path)
rescue
code = ""
end
end
end
if ex_shixun_answer_content.blank? #把关卡的答案存入试卷的实训里
### Todo 实训题的_shixun_details里的代码是不是直接从这里取出就可以了涉及到code的多个版本库的修改
sx_option = {
:exercise_question_id => q.id,
:exercise_shixun_challenge_id => exercise_cha.id,
:user_id => user.id,
:score => exercise_cha_score.round(1),
:answer_text => code,
:status => answer_status
}
ExerciseShixunAnswer.create!(sx_option)
else
ex_shixun_answer_content.first.update_attributes!(score:exercise_cha_score.round(1),answer_text:code,status:answer_status)
end
score5 += exercise_cha_score
else
score5 += 0.0
end
end
end
end
score5
end
def change
exercise = Exercise.find_by(id: 2808)
if exercise
exercise_users = exercise.exercise_users.where("start_at is not null and commit_status = 0")
exercise_users.each do |exercise_user|
calculate_score = calculate_student_score(exercise, exercise_user.user)
subjective_score = exercise_user.subjective_score
total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score
total_score = calculate_score + total_score_subjective_score
if exercise_user.end_at.nil?
exercise_user.update_attributes!(score:total_score,objective_score:calculate_score,end_at:exercise.end_time,commit_status:1,status:1,commit_method:3)
end
puts exercise_user.id
end
end
end
end

@ -0,0 +1,17 @@
class AddPositionForInforms < ActiveRecord::Migration[5.2]
def change
add_column :informs, :position, :integer, :default => 1
course_ids = Inform.where(container_type: 'Course').pluck(:container_id).uniq
courses = Course.where(id: course_ids)
courses.find_each do |course|
next if course.informs.count == 1
informs = course.informs.order("created_at asc")
informs.each_with_index do |inform, index|
inform.update_attribute(:position, index+1)
end
end
end
end

@ -144,7 +144,8 @@ class CompetitionsIndex extends Component{
<span>报名截止时间{item.enroll_end_time}</span>, <span>报名截止时间{item.enroll_end_time}</span>,
]} ]}
extra={ extra={
<div className={"pt50"} style={{"width":'305px'}}> <div className={"pt50"} style={{"width":'314px'}}>
<Row gutter={16}> <Row gutter={16}>
<Col className="gutter-row" span={6}> <Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels">奖金</div> <div className="gutter-box CompetitionsIndexdadels">奖金</div>

@ -88,7 +88,8 @@
} }
.CompetitionsIndex .gutter-row{ .CompetitionsIndex .gutter-row{
margin-right:20px; /*margin-right:20px;*/
width: 33%;
} }
.pt50{ .pt50{

@ -399,4 +399,8 @@
.color000{ .color000{
color: #000; color: #000;
}
.cursorpointer{
cursor: pointer;
} }

@ -72,16 +72,19 @@ class CompetitionCommon extends Component{
} }
//获取头部信息 //获取头部信息
getbannerdata=()=>{ getbannerdata=()=>{
let menuid=this.props.location.search.replace('?menu=', ''); // let menuid=this.props.location.search.replace('?menu=', '');
let query=this.props.location&&this.props.location.search;
const types = query.split('&')
const menuid = types[0].split('?menu=')
let url=`/competitions/${this.props.match.params.identifier}/common_header.json`; let url=`/competitions/${this.props.match.params.identifier}/common_header.json`;
axios.get(url).then((response) => { axios.get(url).then((response) => {
if(response.status===200){ if(response.status===200){
this.setState({ this.setState({
data: response.data, data: response.data,
thiskeys: menuid === undefined || menuid === "" ? response.data.competition_modules[0].id : menuid, thiskeys: menuid[1] === undefined || menuid[1] === "" ? response.data.competition_modules[0].id : menuid[1],
mode: response.data.mode mode: response.data.mode
}) })
if(menuid===undefined||menuid===""){ if(menuid[1]===undefined||menuid[1]===""){
this.getrightdata( this.getrightdata(
response.data.competition_modules[0].id, response.data.competition_modules[0].id,
response.data.competition_modules[0].module_type, response.data.competition_modules[0].module_type,
@ -91,7 +94,7 @@ class CompetitionCommon extends Component{
}else{ }else{
let newlist=response.data.competition_modules; let newlist=response.data.competition_modules;
newlist.map((item,key)=>{ newlist.map((item,key)=>{
if(`${item.id}`===`${menuid}`){ if(`${item.id}`===`${menuid[1]}`){
this.getrightdata( this.getrightdata(
item.id, item.id,
item.module_type, item.module_type,
@ -224,6 +227,18 @@ class CompetitionCommon extends Component{
Competitionedittype:false Competitionedittype:false
}) })
}
newgotocourse=(url)=>{
if(this.props.checkIfLogin()===false){
this.props.showLoginDialog()
return
}
if(this.props.checkIfProfileCompleted()===false){
this.props.showProfileCompleteDialog()
return
}
window.open(url);
} }
gotocourse=(url)=>{ gotocourse=(url)=>{
@ -255,7 +270,9 @@ class CompetitionCommon extends Component{
).then((response) => { ).then((response) => {
if (response.data.status === 0) { if (response.data.status === 0) {
// this.props.history.replace(); // this.props.history.replace();
this.Personalregistration(`/courses/${data.course_id}`) this.getbannerdata()
window.open(`/courses/${data.course_id}`);
} }
}) })
@ -267,7 +284,7 @@ class CompetitionCommon extends Component{
let urls = `/competitions/${this.props.match.params.identifier}/enroll`; let urls = `/competitions/${this.props.match.params.identifier}/enroll`;
this.Personalregistration(urls) this.Personalregistration(urls)
} else { } else {
this.props.history.replace(url); window.open(url);
} }
} }
@ -293,6 +310,7 @@ class CompetitionCommon extends Component{
if (response.data) { if (response.data) {
this.props.showNotification(`报名成功,预祝您夺得桂冠!`); this.props.showNotification(`报名成功,预祝您夺得桂冠!`);
// this.props.history.replace(urls); // this.props.history.replace(urls);
this.getbannerdata()
window.open(urls) window.open(urls)
} }
} }
@ -355,7 +373,15 @@ class CompetitionCommon extends Component{
className={"color000"}>{data && data.start_time}{data && data.end_time}</span></Col> className={"color000"}>{data && data.start_time}{data && data.end_time}</span></Col>
{/*<Col></Col>*/} {/*<Col></Col>*/}
</Col> </Col>
<style>
{
`
.ant-col-6{
width: 30%;
}
`
}
</style>
<Col className={"competitionbannerdiv mt10"}> <Col className={"competitionbannerdiv mt10"}>
<Row gutter={16}> <Row gutter={16}>
<Col className="gutter-row" span={6}> <Col className="gutter-row" span={6}>
@ -379,8 +405,24 @@ class CompetitionCommon extends Component{
className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516">{data.competition_status === "nearly_published" ? "--" : data && data.visits_count}</div> className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516">{data.competition_status === "nearly_published" ? "--" : data && data.visits_count}</div>
</Col> </Col>
<Col className="gutter-row rankbeicenter" span={6}> <Col className="gutter-row rankbeicenter" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516"
onClick={data.competition_status === "nearly_published" ? "" : () => this.gotocourse(`/competitions/${this.props.match.params.identifier}/enroll`)}>{data.competition_status === "nearly_published" ? "--" : data && data.member_count}</div> {data.competition_status === "ended" ?
<div className={data.mode === 2 ?data.member_of_course==true?"gutter-box CompetitionsIndexbottomvalue Competitioncolor516 cursorpointer":"gutter-box CompetitionsIndexbottomvalue Competitioncolor516":"gutter-box CompetitionsIndexbottomvalue Competitioncolor516 cursorpointer"}
// 已结束onClick={data.competition_status === "nearly_published" ? "" : () => this.gotocourse(`/competitions/${this.props.match.params.identifier}/enroll`)}
onClick={ data.mode === 2 ?data.member_of_course==true?() => this.newgotocourse(`/courses/${data.course_id}`):"":() => this.newgotocourse(`/competitions/${this.props.match.params.identifier}/enroll`)}
>{data && data.member_count}</div>
:data.competition_status === "nearly_published" ?
<div className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516"
// onClick={data.competition_status === "nearly_published" ? "" : () => this.gotocourse(`/competitions/${this.props.match.params.identifier}/enroll`)}
>{"--"}</div> :
data.competition_status === "progressing" ?
data.mode === 2 ?
<div className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516 cursorpointer" onClick={() => this.gotocourse()}>{data && data.member_count}</div> : signupdata && signupdata.personal === true ?
<div className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516 cursorpointer" onClick={() => this.gotocourse("personal")}>{data && data.member_count}</div> : <div
className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516 cursorpointer"
onClick={() => this.gotocourse(`/competitions/${this.props.match.params.identifier}/enroll`)}>{data && data.member_count}</div>
:""}
</Col> </Col>
</Row> </Row>
</Col> </Col>

@ -213,6 +213,13 @@ class UseBank extends Component{
text-overflow:ellipsis; text-overflow:ellipsis;
white-space:nowrap white-space:nowrap
} }
.bankwidth76{
width:76px !important;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
text-align: center;
}
.bankwidth2{ .bankwidth2{
width:24% !important; width:24% !important;
overflow:hidden; overflow:hidden;
@ -224,7 +231,7 @@ class UseBank extends Component{
Margin-left:15px Margin-left:15px
} }
.with63{ .with63{
width: 63% !important; width: 60% !important;
box-sizing: border-box; box-sizing: border-box;
margin-left: 15px; margin-left: 15px;
} }
@ -306,15 +313,21 @@ class UseBank extends Component{
<p className="clearfix mb7" key={item.id}> <p className="clearfix mb7" key={item.id}>
<Checkbox className="fl" value={item.id} key={item.id}></Checkbox> <Checkbox className="fl" value={item.id} key={item.id}></Checkbox>
<span className={nav_my === 'myself' ? "fl with58" : "fl with63"}> <span className={nav_my === 'myself' ? "fl with58" : "fl with63"}>
<label className="task-hide fl" title={item.name && item.name.length > 30 ? item.name:""} style={{"maxWidth":"100%"}}>{item.name}</label> <label className="task-hide fl" title={item.name && item.name.length > 30 ? item.name : ""}
style={{"maxWidth": "100%"}}>
<a title={item.name}>{item.name}</a>
</label>
</span> </span>
<span title={item.course_list_name && item.course_list_name.length > 10 && item.course_list_name} <span title={item.course_list_name && item.course_list_name.length > 10 && item.course_list_name}
className={nav_my === 'myself' ? "fl with30 color-grey-6 task-hide pl5 bankwidth" : "fl with30 color-grey-6 task-hide pl5 bankwidth2"} className={nav_my === 'myself' ? "fl with30 color-grey-6 task-hide pl5 bankwidth" : "fl with30 color-grey-6 task-hide pl5 bankwidth2"}
>{item.course_list_name}</span> ><a title={item.course_list_name}>{item.course_list_name}</a></span>
{ {
nav_my === 'public' && nav_my === 'public' &&
<span className="fl with16 color-grey-6 task-hide pl10">{item.username}</span> <span className="fl with16 color-grey-6 task-hide pl10 bankwidth76"><a
title={item.username} style={{
width: "76px"
}}>{item.username}</a></span>
} }
{nav_my === "myself" ? {nav_my === "myself" ?
(this.props.object_type && this.props.object_type === "normal" ? (this.props.object_type && this.props.object_type === "normal" ?

@ -107,7 +107,7 @@ const buildColumns = (that,isParent) => {
} }
]; ];
if (course_groups && course_groups.length) { if (that.hasGroupModule()) {
that.isStudentPage && columns.push({ that.isStudentPage && columns.push({
title: '分班', title: '分班',
dataIndex: 'course_group_name', dataIndex: 'course_group_name',
@ -249,6 +249,13 @@ class studentsList extends Component{
console.log(error) console.log(error)
}); });
} }
hasGroupModule = () => {
const { course_modules } = this.props;
const result = course_modules && course_modules.filter( item => {
return item.type == 'course_group'
})
return result && result.length > 0
}
Downloadcal=()=>{ Downloadcal=()=>{
this.setState({ this.setState({

@ -37,4 +37,33 @@
font-weight:400; font-weight:400;
color:rgba(5,16,26,1); color:rgba(5,16,26,1);
line-height:24px; line-height:24px;
}
.ant-input::-webkit-input-placeholder{
color: #999;
font-size: 14px;
}
.ant-input:-moz-placeholder {
color: #999;
font-size: 14px;
}
.ant-input::-moz-placeholder{
color: #999;
font-size: 14px;
}
.ant-input:-ms-input-placeholder{
color: #999;
font-size: 14px;
}
.Searchant-btn-primary .ant-btn-primary{
background: #4CACFF;
border-color: #4CACFF;
}
.Searchant-btn-primary .ant-input-group .ant-input{
height:42px;
} }

@ -1,6 +1,6 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import axios from 'axios'; import axios from 'axios';
import {SnackbarHOC, WordsBtn,getImageUrl} from 'educoder'; import {SnackbarHOC, WordsBtn,getImageUrl,markdownToHTML} from 'educoder';
import {Row, Col,Input,Divider,Card,Button} from 'antd'; import {Row, Col,Input,Divider,Card,Button} from 'antd';
import { TPMIndexHOC } from '../tpm/TPMIndexHOC'; import { TPMIndexHOC } from '../tpm/TPMIndexHOC';
import { CNotificationHOC } from '../courses/common/CNotificationHOC'; import { CNotificationHOC } from '../courses/common/CNotificationHOC';
@ -11,13 +11,35 @@ class Osshackathon extends Component {
constructor(props) { constructor(props) {
super(props) super(props)
this.state = { this.state = {
page:1,
limit:10,
search:undefined,
data:undefined
} }
} }
componentDidMount() { componentDidMount() {
this.getosshackathon();
} }
getosshackathon=()=>{
let {page,limit,search}=this.state;
let url=`/osshackathon.json`;
axios.get(url,{params:{
page:page,
limit:limit,
search:search,
}}).then((result)=>{
if(result.status==200){
console.log(result)
this.setState({
data:result.data
})
}
}).catch((error)=>{
console.log(error);
})
}
componentDidUpdate = (prevProps) => { componentDidUpdate = (prevProps) => {
@ -25,10 +47,21 @@ class Osshackathon extends Component {
} }
render() { render() {
// let {} = this.state; let{data}=this.state;
console.log(this.state.data)
return ( return (
<div className="newMain clearfix newMainybot"> <div className="newMain clearfix newMainybot">
<style>
{
`
.ant-btn-primary{
background: #4CACFF;
border-color: #4CACFF;
}
`
}
</style>
<div className={"educontent mb20 persmstyle"} style={{width: "1200px", marginTop: "26px"}}> <div className={"educontent mb20 persmstyle"} style={{width: "1200px", marginTop: "26px"}}>
@ -37,24 +70,28 @@ class Osshackathon extends Component {
></div> ></div>
<Row className={"mt20"}> <Row className={"mt20"}>
<Col span={6}> <Col span={6}>
<Search <Search
className={"Searchant-btn-primary"}
placeholder="请输入项目名称进行搜索" placeholder="请输入项目名称进行搜索"
enterButton="搜索" enterButton="搜索"
size="large" size="large"
onSearch={value => console.log(value)} onSearch={value => console.log(value)}
/> />
</Col> </Col>
<Col span={3} className={"fr textright"}> <Col span={3} className={"fr textright"}>
<div> <div>
报名整数<span className={"color-red"}>280</span> 报名整数<span className={"color-red"}>{data&&data.hackathon.hackathon_users_count}</span>
</div> </div>
</Col> </Col>
</Row> </Row>
<Row className={"mt20"}> <Row className={"mt20"}>
<Col span={6} className={"Osshackathonfont"}> <Col span={6} className={"Osshackathonfont"}>
大赛介绍 {data&&data.hackathon.name}
</Col> </Col>
<Col span={3} className={"fr textright"}> <Col span={3} className={"fr textright"}>
<Button type="primary">编辑</Button> <Button type="primary">编辑</Button>
@ -73,12 +110,18 @@ class Osshackathon extends Component {
<Divider /> <Divider />
<p className={"Osshackathonfontlist mb30"}> <p className={"Osshackathonfontlist mb30"}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista {data&&data.hackathon.description===null?"":<div className={"markdown-body"}
probare, quae sunt a te dicta? Refert tamen, quo modo. dangerouslySetInnerHTML={{__html: markdownToHTML(data&&data.hackathon.description).replace(/▁/g, "▁▁▁")}}></div>}
</p> </p>
{
data&&data.hacks.length==0?"":data&&data.hacks.map((item,key)=>{
return(
<span></span>
)
})
}
{/*学生身份*/} {/*学生身份*/}
<Card className={"OsshackathonCard"}> <Card className={"OsshackathonCard mb20"}>
<Row> <Row>
<Col span={6} className={"OsshackathonCardtitle"}> <Col span={6} className={"OsshackathonCardtitle"}>

@ -221,4 +221,8 @@ TPI SSH
VNCDisplay VNCDisplay
使用的github上的代码 https://github.com/novnc/noVNC/ 使用的github上的代码 https://github.com/novnc/noVNC/
tpi拖拽改变视图大小代码
js_min_all.js中搜索 doc.live('mousemove touchmove',function(e){

@ -44,6 +44,7 @@ class RealNameCertificationModal extends Component{
this.state={ this.state={
identity:"teacher", identity:"teacher",
departmentsName:undefined, departmentsName:undefined,
fileID:undefined,
filterSchoolList:undefined, filterSchoolList:undefined,
filterDepartments :undefined, filterDepartments :undefined,
school:undefined, school:undefined,
@ -269,7 +270,8 @@ class RealNameCertificationModal extends Component{
axios.post((url),{ axios.post((url),{
name:values.name || basicInfo.name, name:values.name || basicInfo.name,
gender:parseInt(values.sex), gender:parseInt(values.sex),
id_number:values.credentials id_number:values.credentials,
attachment_ids:[this.state.fileID]
}).then((result)=>{ }).then((result)=>{
if(result){ if(result){
this.props.showNotification("申请已提交,请等待审核!"); this.props.showNotification("申请已提交,请等待审核!");
@ -295,7 +297,8 @@ class RealNameCertificationModal extends Component{
school_id:this.state.school_id, school_id:this.state.school_id,
department_id:this.state.department_id, department_id:this.state.department_id,
identity:this.state.identity, identity:this.state.identity,
extra: values.job == "student" ? values.student_No : values.job == "teacher" ? values.job1 : values.job2 extra: values.job == "student" ? values.student_No : values.job == "teacher" ? values.job1 : values.job2,
attachment_ids:[this.state.fileID]
}).then((result)=>{ }).then((result)=>{
if(result){ if(result){
this.props.showNotification("申请已提交,请等待审核!"); this.props.showNotification("申请已提交,请等待审核!");
@ -327,20 +330,7 @@ class RealNameCertificationModal extends Component{
const { course_lists, checkBoxValues } = this.state const { course_lists, checkBoxValues } = this.state
this.onSendOk() this.onSendOk()
} }
handleChange = (info) => {
if (info.file.status === 'uploading') {
this.setState({ loading: true });
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => this.setState({
imageUrl,
loading: false,
}));
}
}
handleChange2 = (info) => { handleChange2 = (info) => {
if (info.file.status === 'uploading') { if (info.file.status === 'uploading') {
this.setState({ loading: true }); this.setState({ loading: true });
@ -348,9 +338,11 @@ class RealNameCertificationModal extends Component{
} }
if (info.file.status === 'done') { if (info.file.status === 'done') {
// Get this url from response in real world. // Get this url from response in real world.
console.log(info.file.response);
getBase64(info.file.originFileObj, imageUrl2 => this.setState({ getBase64(info.file.originFileObj, imageUrl2 => this.setState({
imageUrl2, imageUrl2,
loading: false, loading: false,
fileID:info.file.response && info.file.response.id
})); }));
} }
} }

Loading…
Cancel
Save