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

issues25489
hjm 5 years ago
commit 3754c78ffb

@ -486,8 +486,8 @@ $(document).on('turbolinks:load', function(){
' <div class="col-6 no_padding ">\n' +
' <input type="number" class="form-control" onchange="change_total(this)" value="3" name="stage[][entry]">\n' +
' </div></div>\n' +
' <div class="row col-4"><span class="col-3 text-right mt-2 no_padding">成绩来源:</span>\n' +
' <div class="col-7 no_padding ">\n' +
' <div class="row col-3"><span class="col-4 text-right mt-2 no_padding">成绩来源:</span>\n' +
' <div class="col-6 no_padding ">\n' +
' <select class="form-control" name="stage[][score_source]">\n' +
' <option value="0">经验值</option>\n' +
' <option value="1">预测准确率</option>\n' +
@ -562,8 +562,8 @@ $(document).on('turbolinks:load', function(){
' <div class="col-6 no_padding ">\n' +
' <input type="number" class="form-control" onchange="change_total(this)" value="3" name="stage[][entry]">\n' +
' </div></div>\n' +
' <div class="row col-4"><span class="col-3 mr10 text-right mt-2 no_padding">成绩来源:</span>\n' +
' <div class="col-7 no_padding ">\n' +
' <div class="row col-3"><span class="col-4 mr10 text-right mt-2 no_padding">成绩来源:</span>\n' +
' <div class="col-6 no_padding ">\n' +
' <select class="form-control" name="stage[][score_source]">\n' +
' <option value="0">经验值</option>\n' +
' <option value="1">预测准确率</option>\n' +
@ -764,8 +764,8 @@ function addNewTab(competition_id) {
' <div class="col-6 no_padding ">\n' +
' <input type="number" class="form-control" onchange="change_total(this)" value="3" name="stage[][entry]">\n' +
' </div></div>\n' +
' <div class="row col-4"><span class="col-3 text-right mt-2 no_padding mr10">成绩来源:</span>\n' +
' <div class="col-7 no_padding ">\n' +
' <div class="row col-3"><span class="col-4 text-right mt-2 no_padding mr10">成绩来源:</span>\n' +
' <div class="col-6 no_padding ">\n' +
' <select class="form-control" name="stage[][score_source]">\n' +
' <option value="0">经验值</option>\n' +
' <option value="1">预测准确率</option>\n' +

@ -41,12 +41,18 @@ $(document).on('turbolinks:load', function () {
// 上传图片
$('.modal.admin-upload-file-modal').on('upload:success', function (e, data) {
if(data.suffix == '_qrcode'){
var $imageElement = $('.subject-weapp-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
} else {
var $imageElement = $('.subject-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
})
}
});
// 定义状态切换监听事件
var defineStatusChangeFunc = function (doElement, undoElement, url, callback) {
$('.subject-list-container').on('click', doElement, function () {

@ -101,16 +101,16 @@
max-width: 25%;
}
.task_Input_div:nth-child(3n){
flex: 0 0 33.3%;
max-width: 33.3%;
}
.task_Input_div:nth-child(3n) > span.col-4{
flex: 0 0 25%;
max-width: 25%;
}
.task_Input_div:nth-child(3n) > span.col-4{
flex: 0 0 33.3%;
max-width: 33.3%;
}
.task_Input_div:nth-child(3n) > div.col-6{
flex: 0 0 58.3%;
max-width: 58.3%;
flex: 0 0 50%;
max-width: 50%;
}
}
}

@ -60,7 +60,7 @@ class Admins::CompetitionStagesController < Admins::BaseController
end
# 如果计算的是最后一个阶段,则同时计算总成绩(只有一个阶段则不需计算)
if current_stage.max_end_time == current_competition.max_stage_end_time && current_competition.competition_stages.size != 0
if current_stage.max_end_time == current_competition.max_stage_end_time && current_competition.competition_stages.size > 1
calculate_total_score current_competition
end
end
@ -174,6 +174,7 @@ class Admins::CompetitionStagesController < Admins::BaseController
end
def calculate_total_score competition
competition.competition_scores.where(competition_stage_id: 0).destroy_all
competition.competition_teams.each do |team|
total_score = 0
total_time = 0
@ -183,8 +184,11 @@ class Admins::CompetitionStagesController < Admins::BaseController
total_score += stage_score.try(:score).to_f * stage.score_rate
total_time += stage_score.try(:cost_time).to_i
end
unless team.competition_scores.exists?(competition_id: competition.id, competition_stage_id: 0)
CompetitionScore.create!(user_id: team.user_id, competition_team_id: team.id, competition_id: competition.id,
competition_stage_id: 0, score: total_score, cost_time: total_time)
end
end
end
end

@ -11,9 +11,9 @@ class Competitions::CertificatesController < Competitions::BaseController
end
def team
team = CompetitionTeam.find(id: params[:id])
team = CompetitionTeam.find(params[:id])
return render_forbidden unless team.team_members.exists?(user_id: current_user.id)
return render_not_found unless team.certificate_exist?
return render_not_found unless team.certificate_exists?
prize = team.competition_prize_users.first.competition_prize
filename = "#{current_competition.name}-#{prize.name}-#{team.name}.pdf"

@ -7,7 +7,7 @@ class Competitions::CompetitionModulesController < Competitions::BaseController
@modules = current_competition.unhidden_competition_modules.order(position: :asc)
# 未登录、未获奖用户,不展示获奖证书栏目
if !current_user.logged? || !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)
@modules = @modules.select { |mod| mod.name != '获奖证书' }
end
end

@ -44,6 +44,12 @@ class Competitions::CompetitionsController < Competitions::BaseController
def common_header
@competition = current_competition
@competition_modules = @competition.unhidden_competition_modules
# 未登录、未获奖用户,不展示获奖证书栏目
if !current_user.logged? || !current_competition.finished? || !current_competition.competition_prize_users.exists?(user: current_user)
@competition_modules = @competition_modules.select { |mod| mod.name != '获奖证书' }
end
@user = current_user
current_competition.increment!(:visits)
@ -113,6 +119,8 @@ class Competitions::CompetitionsController < Competitions::BaseController
@competition = current_competition
if params[:stage_id]
@stage = @competition.competition_stages.find_by(id: params[:stage_id])
elsif @competition.competition_stages.count == 1
@stage = @competition.competition_stages.take
end
@records = @competition.competition_teams.joins(:competition_scores).where(competition_scores: {competition_stage_id: @stage&.id.to_i})

@ -2,9 +2,9 @@ class Competitions::PrizesController < Competitions::BaseController
before_action :require_prize_user!
def show
self_prizes = current_competition.competition_prize_users.where(user_id: current_user.id).includes(:competition_team)
self_prizes = current_competition.competition_prize_users.where(user_id: current_user.id).includes(:competition_team).order(:competition_prize_id)
@leader = self_prizes.any?(&:leader?) # 是否为队长
@leader = self_prizes.any?{ |prize_user| prize_user.leader? && prize_user.competition_prize.category == 'bonus' } # 是否为队长并且有奖金奖励
if @leader
@bank_account = self_prizes.find(&:leader?).extra
@bank_account_editable = self_prizes.select(&:leader?).all?(&:pending?)

@ -1498,7 +1498,8 @@ class CoursesController < ApplicationController
WHERE cm.role = 4 and
(concat(users.lastname, users.firstname) like '%#{search}%' or ue.student_id like '%#{search}%')}
elsif group_id.present?
sql_select += %Q{ WHERE cm.role = 4 and cm.course_id = #{@course.id} and cm.course_group_id = #{group_id}}
group_id = group_id.is_a?(Array) ? group_id.map(&:to_i) : [group_id.to_i]
sql_select += %Q{ WHERE cm.role = 4 and cm.course_id = #{@course.id} and cm.course_group_id in (#{group_id.join(",")})}
else
sql_select += %Q{ WHERE cm.role = 4 and cm.course_id = #{@course.id}}
end

@ -290,6 +290,7 @@ class GamesController < ApplicationController
answer_deduction = challenge.challenge_answers.where("level <= #{@answer.level}").sum(:score)
@game.update_attributes!(:answer_open => answer_open, :answer_deduction => answer_deduction)
end
GameAnswer.create!(challenge_answer_id: @answer.id, user_id: current_user.id, game_id: @game.id, view_time: Time.now)
rescue Exception => e
uid_logger_error("#######金币扣除异常: #{e.message}")
@ -317,6 +318,7 @@ class GamesController < ApplicationController
@game.update_attributes!(:answer_open => 1, :answer_deduction => 100)
end
@challenge_chooses = @challenge.challenge_chooses
GameAnswer.create!(user_id: current_user.id, game_id: @game.id, view_time: Time.now)
rescue Exception => e
uid_logger_error("#######金币扣除异常: #{e.message}")
raise ActiveRecord::Rollback

@ -5,7 +5,7 @@ class SubjectsController < ApplicationController
before_action :find_subject, except: [:index, :create, :new, :append_to_stage]
before_action :allowed, only: [:update, :edit, :destroy, :publish, :cancel_publish, :cancel_has_publish,
:search_members, :add_subject_members, :statistics, :shixun_report, :school_report,
:up_member_position, :down_member_position]
:up_member_position, :down_member_position, :update_team_title]
include ApplicationHelper
include SubjectsHelper
@ -264,6 +264,12 @@ class SubjectsController < ApplicationController
end
end
def update_team_title
tip_exception("team_title参数不能为空") if params[:team_title].blank?
@subject.update_attributes!(team_title: params[:team_title])
normal_status("更新成功")
end
def search_members
tip_exception("搜索内容不能为空") unless params[:search]
page = params[:page] || 1

@ -39,10 +39,12 @@ module CompetitionsHelper
stages = []
statistic_stages = competition.competition_stages.where("score_rate > 0")
unless statistic_stages.size == 1
end_time = competition.max_stage_end_time || competition.end_time
if end_time && end_time < Time.now
stages << {id: nil, name: statistic_stages.size > 1 ? "总排行榜" : "排行榜", rate: 1.0, start_time: competition.start_time, end_time: competition.end_time}
end
end
statistic_stages.each do |stage|
if stage.max_end_time && stage.max_end_time < Time.now

@ -11,4 +11,8 @@ module MyshixunsHelper
nil
end
end
def view_answer_time game, user_id
game.game_answers.where(user_id: user_id).last&.view_time
end
end

@ -0,0 +1,5 @@
module PdfkitHelper
def download_image(url)
'data:image/png;base64,' + Base64.encode64(open(url) { |io| io.read })
end
end

@ -0,0 +1,19 @@
# 生成竞赛个人证书Job
class GenerateCompetitionPersonalCertificateJob < ApplicationJob
queue_as :default
def perform(prize_user_id)
@prize_user = CompetitionPrizeUser.find_by(id: prize_user_id)
return if @prize_user.blank? || @prize_user.certificate_exist?
template = @prize_user.user.is_teacher? ? 'teacher' : 'personal'
file = File.open(Rails.root.join("app/templates/competition_certificates/#{template}.html.erb"))
html = ERB.new(file.read).result(binding)
kit = PDFKit.new(html, page_width: 842, page_height: 595)
path = @prize_user.certificate_path
dir = File.dirname(path)
FileUtils.mkdir_p(dir) unless File.directory?(dir)
kit.to_pdf(path)
end
end

@ -0,0 +1,24 @@
# 生成竞赛团体证书Job
class GenerateCompetitionTeamCertificateJob < ApplicationJob
queue_as :default
def perform(competition_team_id)
@team = CompetitionTeam.find_by(id: competition_team_id)
@prize = @team&.competition_prize_users&.first&.competition_prize
return if @team.blank? || !@prize.team_certificate_exists? || @team.certificate_exists?
members = @team.team_members.includes(user: :user_extension).to_a
@member_names = members.select { |m| !m.user.is_teacher? }.map(&:user_name).join('、')
@teacher_names = members.select { |m| m.user.is_teacher? }.map(&:user_name).join('、')
file = File.open(Rails.root.join("app/templates/competition_certificates/team.html.erb"))
html = ERB.new(file.read).result(binding)
kit = PDFKit.new(html, page_width: 842, page_height: 595)
path = @team.certificate_path
dir = File.dirname(path)
FileUtils.mkdir_p(dir) unless File.directory?(dir)
kit.to_pdf(path)
end
end

@ -1,4 +1,9 @@
class ChallengeAnswer < ApplicationRecord
default_scope { order("challenge_answers.level asc") }
belongs_to :challenge
has_many :game_answers, :dependent => :destroy
def view_answer_time(user_id)
game_answers.where(user_id: user_id).last&.view_time
end
end

@ -7,6 +7,30 @@ class CompetitionPrize < ApplicationRecord
enumerize :category, in: %i[bonus unset]
def member_certificate_exists?
Util::FileManage.exists?(self, self.class.member_suffix)
end
def teacher_certificate_exists?
Util::FileManage.exists?(self, self.class.teacher_suffix)
end
def team_certificate_exists?
Util::FileManage.exists?(self, self.class.team_suffix)
end
def member_certificate_path
Util::FileManage.source_disk_filename(self, self.class.member_suffix)
end
def teacher_certificate_path
Util::FileManage.source_disk_filename(self, self.class.teacher_suffix)
end
def team_certificate_path
Util::FileManage.source_disk_filename(self, self.class.team_suffix)
end
def self.member_suffix
'_member'
end

@ -25,7 +25,7 @@ class CompetitionPrizeUser < ApplicationRecord
delegate :bank, :second_bank, :card_no, to: :extra, allow_nil: true
def user_certified?
user.certification? && user.professional_certification?
user.authentication? && user.professional_certification?
end
def certificate_exist?

@ -15,7 +15,7 @@ class Game < ApplicationRecord
belongs_to :user
belongs_to :challenge
has_one :run_code_message, :dependent => :destroy
has_many :game_answers, :dependent => :destroy
#全部关卡数
scope :ch_games, lambda { |challenge_id| where(challenge_id:challenge_id) }

@ -0,0 +1,5 @@
class GameAnswer < ApplicationRecord
belongs_to :user
belongs_to :game
belongs_to :challenge_answer
end

@ -13,4 +13,8 @@ class TeamMember < ApplicationRecord
def en_role
is_teacher? ? 'teacher' : 'member'
end
def user_name
user&.real_name
end
end

@ -1,7 +1,8 @@
class Admins::ApproveCompetitionPrizeUserService < ApplicationService
attr_reader :prize_user, :approver
attr_reader :competition, :prize_user, :approver
def initialize(prize_user, approver)
@competition = prize_user.competition
@prize_user = prize_user
@approver = approver
end
@ -10,17 +11,25 @@ class Admins::ApproveCompetitionPrizeUserService < ApplicationService
raise Error, '请勿重复审批' if prize_user.approved?
raise Error, '该用户未认证完成' unless prize_user.user_certified?
prize = prize_user.competition_prize
ActiveRecord::Base.transaction do
prize_user.approve
prize_user.approver = approver
prize_user.approved_at = Time.now
prize_user.save!
if prize_user.competition_team.all_prize_approved?
# TODO: 生成团队证书
# 生成个人证书
# 是老师并且教师证书模板存在 或者是学生而且个人证书模板存在
if (prize_user.user.is_teacher? && prize.teacher_certificate_exists?) ||
(!prize_user.user.is_teacher? && prize.member_certificate_exists?)
GenerateCompetitionPersonalCertificateJob.perform_later(prize_user.id)
end
# TODO: 生成个人证书
# 生成团队证书
if !competition.personal? && prize_user.competition_team.all_prize_approved? && prize.team_certificate_exists?
GenerateCompetitionTeamCertificateJob.perform_later(prize_user.competition_team.id)
end
end
end
end

@ -10,7 +10,7 @@ class Competitions::SavePrizeTeamAccountService < ApplicationService
def call
Competitions::SavePrizeTeamAccountForm.new(params).validate!
prize_leaders = competition.competition_prize_users.where(competition.competition_prize_users)
prize_leaders = competition.competition_prize_users.where(user_id: user.id, leader: true)
raise Error, '审批通过后不能修改' if prize_leaders.exists?(status: :approved)

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<div class="competition-certificate" style="position: absolute;font-size: 85px;font-family: SimSun;">
<img src="<%= ApplicationController.helpers.download_image(@prize_user.competition_prize.member_certificate_path) %>"/>
<div class="competition-certificate-body" style="position: absolute;width: 82%;top: 35%;left: 9%;">
<p><%= @prize_user.user.school_name %> <%= @prize_user.user.real_name %>(学号 <%= @prize_user.user.student_id %></p>
<p style="padding-left:2em;line-height: 1.8">
荣获第二届“<b>全国高校绿色计算大赛</b>”( <%= @prize_user.competition.sub_title %> )“<b>全国<%= @prize_user.competition_prize.name %></b>”。
<br/>特发此证,以资鼓励。
</p>
</div>
</div>
</body>
</html>

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<div class="competition-certificate" style="position: absolute;font-size: 85px;font-family: SimSun;">
<img src="<%= ApplicationController.helpers.download_image(@prize_user.competition_prize.teacher_certificate_path) %>"/>
<div class="competition-certificate-body" style="position: absolute;width: 82%;top: 35%;left: 9%;">
<p><%= @prize_user.user.school_name %> <%= @prize_user.user.real_name %> 老师:</p>
<p style="text-indent:2em;line-height: 1.8;margin-bottom: 0px;">
在第二届“<b>全国高校绿色计算大赛</b>”(<%= @prize_user.competition.sub_title %>)中,带领学生团队 表现突出,成绩优异,荣获“<b>优秀指导教师</b>”称号。
</p>
<p style="text-indent:2em;line-height: 1.8;margin-top: 0px;">特发此证,以资鼓励。</p>
</div>
</div>
</body>
</html>

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<div class="competition-certificate" style="position: absolute;font-size: 85px;font-family: SimSun;">
<img src="<%= ApplicationController.helpers.download_image(@prize.team_certificate_path) %>"/>
<div class="competition-certificate-body" style="position: absolute;width: 82%;top: 35%;left: 9%;">
<p style="text-indent:2em;line-height: 1.8;margin-bottom: 0px;">
<%= @member_names %>(指导老师:<%= @teacher_names %> 在第二届“<b>全国高校绿色计算大赛</b>”(<%= @prize.competition.sub_title %>)中成绩突出,荣获“<b>团体 <%= @prize.name %></b>”。
</p>
<p style="text-indent:2em;line-height: 1.8;margin-top: 0px;">特发此证,以资鼓励。</p>
</div>
</div>
</body>
</html>

@ -249,6 +249,7 @@
autoRefresh: true,
smartIndent: true,//智能换行
styleActiveLine: true,
lineWrapping: true,
lint: true,
readOnly: "nocursor"
});

@ -14,6 +14,11 @@
<td><%= display_text prize_user.approver&.real_name %></td>
<td class="action-container">
<% if prize_user.leader? && prize_user.competition_prize.category == 'bonus' %>
<% bank_content = [prize_user.extra&.[]('bank'), prize_user.extra&.[]('second_bank'), prize_user.extra&.[]('card_no')].compact.join('<br>').presence || '无' %>
<%= javascript_void_link('查看银行账户', data: { toggle: 'tooltip', title: bank_content.html_safe, html: true, placement: 'left', trigger: 'click' }) %>
<% end %>
<% if prize_user.pending? %>
<%= link_to('审批通过', approve_admins_competition_competition_prize_user_path(prize_user.competition, prize_user),
data: { confirm: '确认审批通过吗?' },

@ -395,9 +395,9 @@
<input type="number" class="form-control task_all" value="<%= section.entry %>" onchange="change_total(this)" name="stage[][entry]"/>
</div>
</div>
<div class="row col-4">
<span class="col-3 text-right mt-2 no_padding mr10">成绩来源:</span>
<div class="col-7 no_padding">
<div class="row col-3">
<span class="col-4 text-right mt-2 no_padding mr10">成绩来源:</span>
<div class="col-6 no_padding">
<select class="form-control" name="stage[][score_source]">
<option value="0" <%= section.score_source == 0 ? "selected='selected'" : "" %>>经验值</option>
<option value="1" <%= section.score_source == 1 ? "selected='selected'" : "" %>>预测准确率</option>
@ -465,9 +465,9 @@
<input type="number" class="form-control task_all" onchange="change_total(this)" value="3" name="stage[][entry]"/>
</div>
</div>
<div class="row col-4">
<span class="col-3 text-right mt-2 no_padding mr10">成绩来源:</span>
<div class="col-7 no_padding">
<div class="row col-3">
<span class="col-4 text-right mt-2 no_padding mr10">成绩来源:</span>
<div class="col-6 no_padding">
<select class="form-control" name="stage[][score_source]">
<option value="0">经验值</option>
<option value="1">预测准确率</option>
@ -513,7 +513,9 @@
<div class="card-header d-flex justify-content-between align-items-center">
<span class="flex-1">奖项配置</span>
<% unless @competition.competition_prize_users.exists? %>
<%= link_to '新增奖项', new_admins_competition_competition_prize_path(@competition), remote: true, class: 'btn btn-primary btn-sm add-competition-prize-btn' %>
<% end %>
<% if @competition.finished? && !@competition.competition_prize_users.exists? %>
<%= javascript_void_link '生成获奖记录', class: 'btn btn-primary btn-sm ml-2 generate-prize-user-action' %>

@ -7,12 +7,13 @@
<th width="8%">技术体系</th>
<th width="8%">等级体系</th>
<th width="8%">封面</th>
<th width="8%">二维码图片</th>
<th width="7%">创建者</th>
<th width="10%">单位</th>
<th width="8%">开课人数</th>
<th width="6%">开课人数</th>
<th width="10%"><%= sort_tag('创建时间', name: 'created_at', path: admins_subjects_path) %></th>
<th width="7%">状态</th>
<th width="15%">操作</th>
<th width="9%">操作</th>
</tr>
</thead>
<tbody>
@ -33,6 +34,13 @@
<%= image_tag(image_exists ? Util::FileManage.source_disk_file_url(subject) : '', height: 40, class: "w-100 preview-image subject-image-#{subject.id}", style: image_exists ? '' : 'display:none') %>
<%= javascript_void_link image_exists ? '重新上传' : '上传图片', class: 'action upload-image-action', data: { source_id: subject.id, source_type: 'Subject', toggle: 'modal', target: '.admin-upload-file-modal' } %>
</td>
<td class="subject-setting-qrcode-image">
<% codeImageExists = Util::FileManage.exists?(subject, '_qrcode') %>
<% imageUrl = codeImageExists ? Util::FileManage.source_disk_file_url(subject, '_qrcode') : '' %>
<%= image_tag(imageUrl, width: 60, height: 40, class: "preview-image subject-weapp-image-#{subject.id}", data: { toggle: 'tooltip', title: '点击预览' }, style: codeImageExists ? '' : 'display:none') %>
<%= raw '<br/>' if codeImageExists %>
<%= javascript_void_link codeImageExists ? '重新上传' : '上传图片', class: 'action upload-subject-qrcode-image-action', data: { source_id: subject.id, source_type: 'Subject', suffix: '_qrcode', toggle: 'modal', target: '.admin-upload-file-modal' } %>
</td>
<td><%= subject.user.real_name %></td>
<td><%= subject.user.school_name %></td>
<td><%= subject.student_count %></td>

@ -7,13 +7,13 @@ end
json.personal_certifications do
json.array! @self_prizes do |prize_user|
json.url personal_competitions_certificate_path(current_competition, prize_user)
json.url personal_competition_certificate_path(current_competition.identifier, prize_user)
end
end
json.team_certifications do
json.array! @team_prizes do |team|
json.url team_competitions_certificate_path(current_competition, team)
json.url team_competition_certificate_path(current_competition.identifier, team)
end
end

@ -7,6 +7,7 @@ json.message do
json.answer_id answer.id
json.answer_name answer.name
json.answer_score answer.score
json.view_time answer.view_answer_time(current_user.id)
# 高层级不给答案
if @power || @game.answer_open >= index
json.answer_contents answer.contents

@ -6,4 +6,6 @@ json.array! @games do |game|
json.identifier get_game_identifier(@shixun.task_pass, game, @identity)
json.get_gold game.user_get_gold_and_experience(@shixun.status, challenge)[0]
json.get_experience game.user_get_gold_and_experience(@shixun.status, challenge)[1]
json.view_answer_time view_answer_time(game, current_user.id)
json.finished_time game.end_time
end

@ -1,9 +1,12 @@
json.qrcode_img Util::FileManage.exists?(@subject, '_qrcode') ? Util::FileManage.source_disk_file_url(@subject, '_qrcode') : nil
json.members @members do |member|
json.partial! 'subject_member', locals: { user: member.user }
json.role member.role
end
json.team_title @subject.team_title
# 技能标签
json.tags @tags do |tag|
unless tag.blank?

@ -1077,6 +1077,7 @@ Rails.application.routes.draw do
post :cancel_homepage_show
post :excellent
post :cancel_excellent
post :update_team_title
end
end
end

@ -0,0 +1,13 @@
class CreateGameAnswers < ActiveRecord::Migration[5.2]
def change
create_table :game_answers do |t|
t.references :challenge_answer
t.references :user
t.references :game
t.datetime :view_time
t.timestamps
end
end
end

@ -0,0 +1,5 @@
class AddIndexForGameAnswers < ActiveRecord::Migration[5.2]
def change
add_index :game_answers, [:challenge_answer_id, :user_id], :unique => true
end
end

@ -0,0 +1,5 @@
class AddTeamTitleToSubjects < ActiveRecord::Migration[5.2]
def change
add_column :subjects, :team_title, :string, default: "教学团队"
end
end

File diff suppressed because one or more lines are too long

@ -136556,8 +136556,8 @@ $(document).on('turbolinks:load', function(){
' <div class="col-6 no_padding ">\n' +
' <input type="number" class="form-control" onchange="change_total(this)" value="3" name="stage[][entry]">\n' +
' </div></div>\n' +
' <div class="row col-4"><span class="col-3 text-right mt-2 no_padding">成绩来源:</span>\n' +
' <div class="col-7 no_padding ">\n' +
' <div class="row col-3"><span class="col-4 text-right mt-2 no_padding">成绩来源:</span>\n' +
' <div class="col-6 no_padding ">\n' +
' <select class="form-control" name="stage[][score_source]">\n' +
' <option value="0">经验值</option>\n' +
' <option value="1">预测准确率</option>\n' +
@ -136632,8 +136632,8 @@ $(document).on('turbolinks:load', function(){
' <div class="col-6 no_padding ">\n' +
' <input type="number" class="form-control" onchange="change_total(this)" value="3" name="stage[][entry]">\n' +
' </div></div>\n' +
' <div class="row col-4"><span class="col-3 mr10 text-right mt-2 no_padding">成绩来源:</span>\n' +
' <div class="col-7 no_padding ">\n' +
' <div class="row col-3"><span class="col-4 mr10 text-right mt-2 no_padding">成绩来源:</span>\n' +
' <div class="col-6 no_padding ">\n' +
' <select class="form-control" name="stage[][score_source]">\n' +
' <option value="0">经验值</option>\n' +
' <option value="1">预测准确率</option>\n' +
@ -136834,8 +136834,8 @@ function addNewTab(competition_id) {
' <div class="col-6 no_padding ">\n' +
' <input type="number" class="form-control" onchange="change_total(this)" value="3" name="stage[][entry]">\n' +
' </div></div>\n' +
' <div class="row col-4"><span class="col-3 text-right mt-2 no_padding mr10">成绩来源:</span>\n' +
' <div class="col-7 no_padding ">\n' +
' <div class="row col-3"><span class="col-4 text-right mt-2 no_padding mr10">成绩来源:</span>\n' +
' <div class="col-6 no_padding ">\n' +
' <select class="form-control" name="stage[][score_source]">\n' +
' <option value="0">经验值</option>\n' +
' <option value="1">预测准确率</option>\n' +

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -32,7 +32,7 @@ module.exports = {
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
// devtool: "cheap-module-eval-source-map",
// 开启调试
//devtool: "source-map", // 开启调试
devtool: "source-map", // 开启调试
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
// The first two entry points enable "hot" CSS and auto-refreshes for JS.

@ -1503,7 +1503,7 @@ class PersonModal extends Component {
color: "#D0021B",
fontSize: "12px",
marginTop: "9px"
}}>战队导师为{GetenrollmentAPI.teacher_staff.minimum}-{GetenrollmentAPI.teacher_staff.maximum},{Thecurrentnumber}</p>
}}>导师{GetenrollmentAPI.teacher_staff.minimum}-{GetenrollmentAPI.teacher_staff.maximum},{Thecurrentnumber}</p>
: ""
) :
@ -1518,7 +1518,7 @@ class PersonModal extends Component {
color: "#D0021B",
fontSize: "12px",
marginTop: "9px"
}}>战队队员{GetenrollmentAPI.member_staff.minimum}-{GetenrollmentAPI.member_staff.maximum},{Thecurrentnumberstu}</p>
}}>战队成员需{GetenrollmentAPI.member_staff.minimum}-{GetenrollmentAPI.member_staff.maximum},{Thecurrentnumberstu}</p>
: ""
) :

@ -3,9 +3,10 @@ import { Breadcrumb,Layout,Table, Divider, Tag,Badge,Row, Col,Button, Menu, Icon
import { Link } from 'react-router-dom';
import axios from 'axios';
import {markdownToHTML,getImageUrl} from 'educoder';
import CompetitionContents from './CompetitionContents';
import CompetitionContentsChart from './CompetitionContentsChart';
import CompetitionContentsMd from './CompetitionContentsMd';
import CompetitionContents from './CompetitionCommonChild/CompetitionContents';
import CompetitionContentsChart from './CompetitionCommonChild/CompetitionContentsChart';
import CompetitionContentsMd from './CompetitionCommonChild/CompetitionContentsMd';
import CompetitionContentspdf from './CompetitionCommonChild/CompetitionContentspdf';
import './CompetitionCommon.css';
@ -22,7 +23,8 @@ class CompetitionCommon extends Component{
chart_rules: undefined,
Competitionedittype: false,
chartdata: undefined,
has_url:false
has_url: false,
signupdata: undefined
}
}
@ -229,9 +231,43 @@ class CompetitionCommon extends Component{
}
}
}else{
if (url === "personal") {
this.Personalregistration()
} else {
this.props.history.replace(url);
}
}
}
Personalregistration = () => {
let {signupdata} = this.state;
let urls = `/competitions/${this.props.match.params.identifier}/enroll`;
if (signupdata.enroll_ended === true) {
//已截止
this.props.showNotification(`报名已截止`);
return;
}
if (signupdata.enrolled === true) {
this.props.showNotification(`你已经报名,不能重复报名!`);
return;
}
const url = `/competitions/${this.props.match.params.identifier}/competition_teams.json`;
axios.post(url).then((response) => {
if (response) {
if (response.data) {
this.props.showNotification(`报名成功,预祝您夺得桂冠!`);
this.props.history.replace(urls);
}
}
}).catch((error) => {
});
}
Competitioncallback=(key)=>{
this.setState({
@ -252,8 +288,9 @@ class CompetitionCommon extends Component{
}
render() {
let {data,thiskeys,Competitionedittype}=this.state;
let {data, module_type, Competitionedittype, signupdata} = this.state;
return (
data===undefined?"":<div className={"educontent clearfix mt20 "}>
@ -272,14 +309,17 @@ class CompetitionCommon extends Component{
<img className={"Commonimg"}
src={data.competition_status === "ended" ? getImageUrl(`images/educoder/competitions/groups1.png`) : data.competition_status === "nearly_published" ? getImageUrl(`images/educoder/competitions/groups2.png`) : data.competition_status === "progressing" ? getImageUrl(`images/educoder/competitions/groups3.png`) : ""}/>
<Col span={15} className={"Commonimgbox"}>
<img className={"image_urlbox"} src={data===undefined?getImageUrl(`images/educoder/competitions/mainbanner.jpg`):data.avatar_url===null?getImageUrl(`images/educoder/competitions/mainbanner.jpg`):getImageUrl(data.avatar_url)}/>
<img className={"image_urlbox"}
src={data === undefined ? getImageUrl(`images/educoder/competitions/mainbanner.jpg`) : data.avatar_url === null ? getImageUrl(`images/educoder/competitions/mainbanner.jpg`) : getImageUrl(data.avatar_url)}/>
</Col>
<Col className={"CompetitionCommonbannerfont"} span={9}>
<Col className={data&&data.name.length>15?"competitionbannerdiv mt30":"competitionbannerdiv mt30"}>{data&&data.name}</Col>
<Col
className={data && data.name.length > 15 ? "competitionbannerdiv mt30" : "competitionbannerdiv mt30"}>{data && data.name}</Col>
<Col className={"competitionbannerdiv mt10"}>
<Col className={"Competitioncolor9b"}>竞赛时间<span className={"color000"}>{data&&data.start_time}{data&&data.end_time}</span></Col>
<Col className={"Competitioncolor9b"}>竞赛时间<span
className={"color000"}>{data && data.start_time}{data && data.end_time}</span></Col>
{/*<Col></Col>*/}
</Col>
@ -298,13 +338,16 @@ class CompetitionCommon extends Component{
<Row gutter={16}>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516">¥{data&&data.bonus}</div>
<div
className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516">¥{data && data.bonus}</div>
</Col>
<Col className="gutter-row ml20 rankbeicenter" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516">{data.competition_status==="nearly_published"?"--":data&&data.visits_count}</div>
<div
className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516">{data.competition_status === "nearly_published" ? "--" : data && data.visits_count}</div>
</Col>
<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>
<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>
</Col>
</Row>
</Col>
@ -333,21 +376,28 @@ class CompetitionCommon extends Component{
{data.competition_status === "ended" ?
<Button type="primary" block className={"Competitionfontsize22"} disabled={true}>
已结束
</Button>:data.enroll_end===true?<Button type="primary" block className={"Competitionfontsize22"} disabled={true}>
</Button> : data.enroll_end === true ?
<Button type="primary" block className={"Competitionfontsize22"} disabled={true}>
{data.competition_status === "nearly_published" ? "未发布" : "报名截止"}
</Button> :
data.competition_status==="progressing"?<Button type="primary" block className={"Competitionfontsize22"}>
{data.mode===2?<a onClick={()=>this.gotocourse()}>立即报名</a>:<a onClick={()=>this.gotocourse(`/competitions/${this.props.match.params.identifier}/enroll`)}></a>}
data.competition_status === "progressing" ?
<Button type="primary" block className={"Competitionfontsize22"}>
{data.mode === 2 ?
<a onClick={() => this.gotocourse()}>立即报名</a> : signupdata && signupdata.personal === true ?
<a onClick={() => this.gotocourse("personal")}>立即报名</a> : <a
onClick={() => this.gotocourse(`/competitions/${this.props.match.params.identifier}/enroll`)}>立即报名</a>}
</Button>:""}
</Col>
<Col className={"mt10 Competitionfontsize16"}>{data&&data.enroll_end_time===null?"":`报名截止时间:${data&&data.enroll_end_time}`}</Col>
<Col
className={"mt10 Competitionfontsize16"}>{data && data.enroll_end_time === null ? "" : `报名截止时间:${data && data.enroll_end_time}`}</Col>
</Col>
</Row>
</div>
<Layout className={'teamsLayout mt40'}>
<Sider>
<Menu mode="inline" className="CompetitionMenu" selectedKeys={[`${this.state.thiskeys}`]} onClick={(e)=>this.getrightdatas(e)}>
<Menu mode="inline" className="CompetitionMenu" selectedKeys={[`${this.state.thiskeys}`]}
onClick={(e) => this.getrightdatas(e)}>
{data && data.competition_modules.map((item, key) => {
if (item.module_type != "enroll") {
return (
@ -365,9 +415,15 @@ class CompetitionCommon extends Component{
}
})}
</Menu>
{/*<Menu mode="inline" className="CompetitionMenu" onClick={(e)=>this.isdownloadpdf(e)}>*/}
{/*<Menu.Item>*/}
{/*<a>证书下载</a>*/}
{/*</Menu.Item>*/}
{/*</Menu>*/}
</Sider>
<Layout className={"teamsLayoutleft CompetitionContents mb30"}>
{module_type === "certificate" ? "" : <Layout className={"teamsLayoutleft CompetitionContents mb30"}>
{this.state.module_type === "chart" ? Competitionedittype === false ? <CompetitionContentsChart
{...this.props}
{...this.state}
@ -389,8 +445,14 @@ class CompetitionCommon extends Component{
{...this.props}
{...this.state}
/> : ""}
</Layout>
</Layout>}
{module_type === "certificate" ? <Layout className={"teamsLayoutleft CompetitionContents mb30"}>
<CompetitionContentspdf
{...this.props}
{...this.state}
/>
</Layout> : ""}
</Layout>
</div>

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import {Button, Card, Row, Col ,Upload,Icon,message,Tabs} from 'antd';
import axios from 'axios';
import {getImageUrl,getUrl,appendFileSizeToUploadFileAll,appendFileSizeToUploadFile} from 'educoder';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor';
const { TabPane } = Tabs;
class CompetitionContentsMd extends Component{
constructor(props) {

@ -0,0 +1,57 @@
import React, { Component } from 'react';
import {Tabs} from 'antd';
import axios from 'axios';
import {markdownToHTML,getImageUrl,AttachmentList} from 'educoder';
import CompetitionContentspdfdownload from './CompetitionContentspdfChild/CompetitionContentspdfdownload';
import CompetitionContentspdfpeopledata from './CompetitionContentspdfChild/CompetitionContentspdfpeopledata';
// import NoneData from "../../../courses/shixunHomework/shixunHomework";
const { TabPane } = Tabs;
class CompetitionContentspdf extends Component{
constructor(props) {
super(props)
this.state={
Tabskey:"1"
}
}
componentDidMount(){
window.document.title = '竞赛';
}
Competitioncallback=(key)=>{
this.setState({
Tabskey:key
})
}
render() {
return (
<div className={"fr"}>
<div className={"mb100 "}>
<Tabs defaultActiveKey="1" onChange={(e) => this.Competitioncallback(e)} activeKey={this.state.Tabskey}>
<TabPane tab="获奖证书下载" key="1" >
{this.state.Tabskey==="1"?<CompetitionContentspdfdownload
{...this.props}
{...this.state}
Competitioncallback={(e)=>this.Competitioncallback(e)}
/>:""}
</TabPane>
<TabPane tab="完善个人信息" key="2">
{this.state.Tabskey==="2"?<CompetitionContentspdfpeopledata
{...this.props}
{...this.state}
/>:""}
</TabPane>
</Tabs>
</div>
</div>
)
}
}
export default CompetitionContentspdf;

@ -0,0 +1,215 @@
import React, {Component} from 'react';
import {Button, Layout, Input, Form} from 'antd';
import axios from 'axios';
import {getImageUrl} from 'educoder';
import mycompetotionchild from './mycompetotionchild.css';
import {getHiddenName} from "../../../../user/account/AccountBasicEdit";
import '../../../../courses/css/Courses.css'
export const identityMap = {"teacher": "教师", "student": "学生", "professional": "专业人士"}
class Bankcardnumberverification extends Component {
constructor(props) {
super(props)
this.state = {
basicInfo: {},
updating: '',
secondsFlag: false,
seconds: 60,
phonebool: false,
emailbool: false,
formationdata: [],
bank_account_editable: false,
leader: false,
bank_account: undefined,
certification: 1
}
}
componentDidMount() {
window.document.title = '竞赛';
// console.log("3获取用户信息");
// console.log(this.props)
//初始化值
if (this.props.bank_account) {
this.props.form.setFieldsValue({
openingbank: this.props.bank_account.bank,
subbranch: this.props.bank_account.second_bank,
subbranchs: this.props.bank_account.card_no,
})
}
}
yhBankstrue = () => {
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
let url = `/competitions/${this.props.match.params.identifier}/prize_leader_account.json`;
axios.patch(url, {
bank: values.openingbank,
second_bank: values.subbranchs,
card_no: values.subbranch
})
.then((result) => {
try {
if (result.data.status == 0) {
// console.log(JSON.stringify(result));
this.props.showNotification(`提交成功,等待审核!`);
this.props.getdata();
this.props.GetawardinformationAPI();
}
} catch (e) {
}
}).catch((error) => {
console.log(error);
})
}
})
}
render() {
const {getFieldDecorator} = this.props.form;
const {updating, seconds, secondsFlag, basicInfo, phonebool, emailbool, certification, formationdata, bank_account_editable, leader, bank_account} = this.state
return (
<div>
<div className="flexdirections mt36">
<p className="fontcolorsyslhei font-16">//开户行及银行卡号</p>
<p className="fontcolorsyslhui font-14 ml11">为保障奖金的及时发放请队长如实填写你名下的银行卡信息</p>
</div>
<div className="ml38">
<style>{`
.flexRow {
padding: 20px 0;
}
.flexRow .name {
margin-left: 12px;
color: #666666;
text-align: center;
flex: 0 0 100px;
}
.flexRow .description {
margin-left: 10px;
flex: 1;
color: #CDCDCD;
}
.description span {
margin-right: 20px;
color: #05101A;
}
.flexRow .status {
width: 100px;
color: #28AC7F;
text-align: right;
}
.flexTable .flexTable {
border-bottom: 1px solid #EBEBEB;
}
.settingFormsy label{
color: #666666;
font-size: 14px !important ;
}
.settingFormsy input {
width: 340px;
height: 40px;
}
.settingFormsy input.validateInput {
width: 220px;
}
.settingFormsy .formItemInline button {
width: 110px;
margin-left: 10px;
}
.settingFormsy .ant-form-item-label {
width: 60px;
text-align: left;
}
.formItemInline .ant-form-explain{
position:absolute;
bottom:-22px;
left:0px;
width:100%;
}
.yslzxueshi .ant-input{
height: 40px !important;
width: 276px !important
}
// class="ant-col ant-form-item-label"
`}</style>
<div className="settingFormsy">
<React.Fragment>
<Form>
<Form.Item
label="开户行:"
className="formItemInline hideRequireTag mb20 mt20"
>
{getFieldDecorator('openingbank', {
rules: [{
// initialValue: this.state.cityDefaultValue,
required: true,
message: '请输入开户行',
}],
})(
<Input placeholder={`例如:中国工商银行`}></Input>
)}
</Form.Item>
<Form.Item
label="支行:"
className="formItemInline hideRequireTag mb20 mt20"
>
{getFieldDecorator('subbranch', {
rules: [{
// initialValue: this.state.cityDefaultValue,
required: true,
message: '请输入支行',
}],
})(
<Input placeholder={`例如:长沙天河支行`}></Input>
)}
</Form.Item>
<Form.Item
label="账号:"
className="formItemInline hideRequireTag mb20 mt20"
>
{getFieldDecorator('subbranchs', {
rules: [{
// initialValue: this.state.cityDefaultValue,
required: true,
message: '请输入账号',
}],
})(
<Input placeholder={`请填写银行卡账号`}></Input>
)}
</Form.Item>
<div className="flexdirections yslzxueshi ml38 mt34">
<p className="fontcolorsyslhui1 font-14 w300 myysllineheight myyslminwidth"></p>
<div className="myyslminwidth276 flexdirections">
{/*<div className="buttongo mycompitcursor" onClick={()=>this.yhBanksfalse()}><p className="fontwenzi mycompitcursor" >取消</p></div>*/}
<Button type="primary" onClick={() => this.yhBankstrue()}>确定</Button>
</div>
</div>
</Form>
</React.Fragment>
</div>
</div>
</div>
)
}
}
const Bankcardnumberverifications = Form.create({name: 'Bankcardnumberverification'})(Bankcardnumberverification);
export default Bankcardnumberverifications;

@ -0,0 +1,24 @@
.pdfdownload {
max-width: 791px;
height: 40px;
background: rgba(249, 249, 249, 1);
line-height: 40px;
padding-left: 15px;
}
.pdfpicture {
font-size: 16px;
color: rgba(0, 0, 0, 1);
}
.pdfdownloadfont4CACFF {
color: #4CACFF !important;
}
.pdfdownloadfont00CC5F {
color: #00CC5F;
}
.pdfdownloadfontFF6602 {
color: #FF6602;
}

@ -0,0 +1,202 @@
import React, { Component } from 'react';
import {Button,Layout,Row, Col,Divider,Table} from 'antd';
import axios from 'axios';
import {getImageUrl} from 'educoder';
import './CompetitionContentspdfdownload.css';
// import NoneData from "../../../courses/shixunHomework/shixunHomework";
class CompetitionContentspdfdownload extends Component{
constructor(props) {
super(props)
this.state={
data:undefined,
teams:undefined
}
}
componentDidMount(){
window.document.title = '竞赛';
let url=`/competitions/${this.props.match.params.identifier}/prize.json`;
axios.get(url).then((response) => {
if(response.status===200){
let datas=response.data.teams;
if(datas.length>0){
datas.map((item,key)=>{
let lista=item.team_members;
if(lista.length>0){
console.log(lista)
lista.map((i,k)=>{
i["bank_account"]=item.bank_account;
})
}
})
}
this.setState({
data:response.data,
teams:datas,
})
}
}).catch((error) => {
console.log(error)
})
}
render() {
let {data,teams}=this.state;
const columns = [
{
title: '角色',
dataIndex: 'type',
key: 'type',
render: (text, record) => (
<span>
{record.role}
</span>
),
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
render: (text, record) => (
<span>
{record.name}
</span>
),
},
{
title: '实名认证',
dataIndex: 'namecertify',
key: 'namecertify',
render: (text, record) => (
<span>
{record.real_name_auth==="authed"?<span className={"pdfdownloadfont00CC5F"}>已认证</span>:record.real_name_auth==="authing"?<span className={"pdfdownloadfontFF6602"}></span>:record.real_name_auth==="not_authed"?<span className={"color-red"}></span>:""}
</span>
),
},
{
title: '职业认证',
key: 'certify',
dataIndex: 'certify',
render: (text, record) => (
<span>
{record.professional_auth==="authed"?<span className={"pdfdownloadfont00CC5F"}>已认证</span>:record.professional_auth==="authing"?<span className={"pdfdownloadfontFF6602"}></span>:record.professional_auth==="not_authed"?<span className={"color-red"}></span>:""}
</span>
),
},
{
title: '手机绑定',
key: 'mobile',
dataIndex: 'mobile',
render: (text, record) => (
<span>
{record.phone_binded===true?<span className={"pdfdownloadfont00CC5F"}>已绑定</span>:<span className={"color-red"}></span>}
</span>
),
},
{
title: '邮箱绑定',
key: 'mail',
dataIndex: 'mail',
render: (text, record) => (
<span>
{record.email_binded===true?<span className={"pdfdownloadfont00CC5F"}>已绑定</span>:<span className={"color-red"}></span>}
</span>
),
},
{
title: '开户行及银行卡号信息(队长填写)',
key: 'idcard',
dataIndex: 'idcard',
render: (value, record, index) => {
if (index === 0&&record.bank_account!=null) {
return {
children: <span>{record.bank_account.bank + record.bank_account.second_bank + record.bank_account.card_no}</span>,
};
}
},
},
];
let people=[ { url: '/api/competitions/xxxxx/certificates/1/personal' },
{ url: '/api/competitions/xxxxx/certificates/2/personal' },]
return (
<React.Fragment>
<Row>
<Col className={"pdfdownload"}>温馨提示填写的个人信息经审批后将提供个人获奖证书下载团队队员信息全部审批后将提供团队获奖证书下载</Col>
</Row>
<Row className={"mt30"}>
<Col className={"pdfpicture"}>证书情况</Col>
</Row>
<Row className={"mt30"}>
<Col>个人证书{data&&data.personal_certifications.length===0?<span><span className={"pdfpicture font-14"}>暂未生成</span> <span className={"ml20"}><span className={"pdfpicture font-14"}></span><a className={"pdfdownloadfont4CACFF"} onClick={()=>this.props.Competitioncallback("2")}></a></span></span>:
data&&data.personal_certifications.map((item,key)=>{
return(
<span className={"mr10"} key={key}>
<img src={ getImageUrl(`images/educoder/pdfs.png`)} />
<a className={"pdfdownloadfont4CACFF ml10"} href={item.url} download=""
title="下载" mce_href="#">立即下载</a>
</span>
)
})}</Col>
</Row>
<Row className={"mt30"}>
<Col>团队证书
{data&&data.team_certifications.length===0?<span className={"pdfpicture font-14"}>暂未生成</span>
:data&&data.team_certifications.map((item,key)=>{
return(
<span className={"mr10"} key={key}>
<img src={ getImageUrl(`images/educoder/pdfs.png`)} />
<a className={"pdfdownloadfont4CACFF ml10"} href={item.url} download=""
title="下载" mce_href="#">立即下载</a>
</span>
)
})}
</Col>
</Row>
<Divider />
<style>
{
`
.pdfdownloadTable .ant-table-column-title{
color:#000;
}
.pdfdownloadTable .ant-table-tbody > tr > td{
color:#666666;
border-bottom: 1px solid transparent;
}
.pdfdownloadTable .ant-table-thead > tr > th, .ant-table-tbody > tr > td{
text-align: center;
}
`
}
</style>
{teams&&teams.map((item,key)=>{
return(
<Row className={"mt30"} key={key}>
<Col className={"pdfpicture mb20"}>{item.name}战队信息填报概况</Col>
<Table columns={columns} dataSource={item.team_members} className={"pdfdownloadTable"} pagination={false}/>
</Row>
)
})
}
</React.Fragment>
)
}
}
export default CompetitionContentspdfdownload;

@ -0,0 +1,530 @@
import React, {Component} from 'react';
import {Button, Layout, Input, Form} from 'antd';
import axios from 'axios';
import {getImageUrl} from 'educoder';
import mycompetotionchild from './mycompetotionchild.css';
import {getHiddenName} from "../../../../user/account/AccountBasicEdit";
import '../../../../courses/css/Courses.css'
import RealNameCertificationModal from "../../../../user/modal/RealNameCertificationModal";
import Phonenumberverifications from './Phonenumberverification';
import Mailboxvalidations from './Mailboxvalidation'
import Bankcardnumberverifications from './Bankcardnumberverification'
export const identityMap = {"teacher": "教师", "student": "学生", "professional": "专业人士"}
class CompetitionContentspdfpeopledata extends Component {
constructor(props) {
super(props)
this.state = {
basicInfo: {},
updating: '',
secondsFlag: false,
seconds: 60,
phonebool: false,
emailbool: false,
formationdata: [],
bank_account_editable: false,
leader: false,
bank_account: undefined,
certification: 1
}
}
componentDidMount() {
window.document.title = '竞赛';
console.log("获取用户信息");
console.log(this.props);
this.getdata();
this.GetawardinformationAPI();
}
GetawardinformationAPI = () => {
let url = `/competitions/${this.props.match.params.identifier}/prize.json`;
axios.get(url).then((result) => {
if (result.data) {
this.setState({
formationdata: result.data.formationdata,
bank_account_editable: result.data.bank_account_editable, //队长是否可以编辑
leader: result.data.leader, //是否是队长
bank_account: result.data.bank_account, //队长银行卡号信息
})
}
}).catch((error) => {
console.log(error);
})
}
getdata = () => {
this.setState({
certification: 3
})
let url = `/users/accounts/${this.props.current_user.login}.json`;
axios.get(url).then((result) => {
if (result.data) {
if (result.data && result.data.base_info_completed == false) {
this.props.history.push(`/account/profile/edit`);
}
// "authentication": "uncertified", // "uncertified" | "applying" | "certified"
this.setState({
basicInfo: Object.assign({}, {...result.data}, {
avatar_url: `${result.data.avatar_url}`,
gender: result.data.gender == null || result.data.gender == undefined ? 0 : result.data.gender
}),
certification: 3
})
}
}).catch((error) => {
console.log(error);
})
};
// 绑定手机
onPhoneSubmit = () => {
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
let {login} = this.props.current_user;
let reg = /^1\d{10}$/;
if (reg.test(values.phone)) {
let url = `/users/accounts/${login}/phone_bind.json`
axios.post((url), {
phone: values.phone,
code: values.phoneValidateCode
}).then((result) => {
if (result) {
this.props.showNotification("手机号码绑定成功!");
this.setState({
phonebool: false
})
this.getdata();
}
}).catch((error) => {
console.log(error);
})
} else {
this.props.showNotification("请输入有效的11位手机号码");
}
}
})
}
// 绑定邮箱
onEmailSubmit = () => {
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
let {login} = this.props.current_user;
let reg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
if (reg.test(values.email)) {
let url = `/users/accounts/${login}/email_bind.json`
axios.post((url), {
email: values.email,
code: values.emailValidateCode
}).then((result) => {
if (result) {
this.props.showNotification("邮箱地址绑定成功!");
this.setState({
emailbool: false
})
this.getdata();
}
}).catch((error) => {
console.log(error);
})
} else {
this.props.showNotification("请输入正确的邮箱地址");
}
}
})
}
//取消编辑
hideUpdating = (i) => {
if (i === 1) {
this.setState({
phonebool: false
})
} else if (i === 2) {
this.setState({
emailbool: false
})
} else if (i === 3) {
}
}
// 获取验证码
getCode = (index) => {
let url = `/accounts/get_verification_code.json`
let login = '';
let values = this.props.form.getFieldsValue();
if (index == 3) {
//绑定手机号码
login = values.phone;
let reg = /^1\d{10}$/;
if (reg.test(login) == false) {
this.props.showNotification(`请先输入正确的手机号码`);
return;
}
} else if (index == 4) {
// 绑定邮箱
login = values.email;
let reg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
if (reg.test(login) == false) {
this.props.showNotification(`请先输入正确的邮箱地址`);
return;
}
}
let type = index;
if (!login) {
this.props.showNotification(`请先输入${index == 3 ? "手机号码" : "邮箱地址"}`);
return;
}
axios.get((url), {
params: {
login, type
}
}).then((result) => {
if (result) {
// 倒计时
this.setState({
secondsFlag: true
})
this.remainTime();
}
}).catch((error) => {
console.log(error);
})
}
// 获取验证码倒计时
remainTime = () => {
this.setState({
seconds: 60
})
this.timer = setInterval(() => {
let {seconds} = this.state;
let s = parseInt(seconds) - 1;
if (s > -1) {
this.setState({
seconds: s
})
} else {
this.setState({
secondsFlag: false
})
clearInterval(this.timer);
}
}, 1000)
}
phonebools = () => {
this.setState({
phonebool: true
})
}
emailbools = () => {
console.log("点击了邮箱");
this.setState({
emailbool: true
})
}
//立即认证
checkBasicInfo = (index) => {
if (this.state.basicInfo.base_info_completed == true) {
this.showRealNameCertificationModal(index)
} else {
try {
this.props.confirm({
okText: `立即完善`,
content: `请先完善基本信息`,
onOk: () => {
this.props.history.push('/account/profile/edit')
}
})
} catch (e) {
this.props.history.push(`/account/profile/edit`);
}
}
}
showRealNameCertificationModal = (index) => {
this.setState({
certification: index,
}, () => {
if (index == 1) {
this.realNameCertificationModal1.setVisible(true)
} else if (index == 2) {
this.realNameCertificationModal2.setVisible(true)
}
})
}
//绑定银行确认
yhBankstrue = () => {
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
let url = `/competitions/${this.props.match.params.identifier}/prize_leader_account.json`;
axios.patch(url, {
bank: values.openingbank,
second_bank: values.subbranchs,
card_no: values.subbranch
})
.then((result) => {
try {
if (result.data.status == 0) {
// console.log(JSON.stringify(result));
this.props.showNotification(`提交成功成功`);
this.getdata();
this.GetawardinformationAPI();
}
} catch (e) {
}
}).catch((error) => {
console.log(error);
})
}
})
}
//取消认证弹框
onCancel = () => {
this.getdata();
}
//撤销认证
Cancellationofapplication = (index) => {
let url = ""
if (index === 1) {
url = `/users/accounts/${this.props.user.user_id}/authentication_apply.json`;
} else if (index === 2) {
url = `/users/accounts/${this.props.user.user_id}/professional_auth_apply.json`;
}
axios.delete(url)
.then((response) => {
try {
if (response.data.status == 0) {
if (index === 1) {
this.props.showNotification('撤销实名认证成功')
} else if (index === 2) {
this.props.showNotification('撤销职业认证成功')
}
this.getdata();
}
} catch (e) {
}
})
.catch(function (error) {
console.log(error);
});
}
render() {
const {updating, seconds, secondsFlag, basicInfo, phonebool, emailbool, certification, formationdata, bank_account_editable, leader, bank_account} = this.state
return (
<div className="flexdidirectionss mt17">
{this.state.certification === 1 ?
<RealNameCertificationModal {...this.props} {...this.state} basicInfo={this.state.basicInfo}
wrappedComponentRef={(form) => this.realNameCertificationModal1 = form}
certification={certification}
Getdata={() => this.getdata()}
onCancel={() => this.onCancel()}
></RealNameCertificationModal> : ""}
{this.state.certification === 2 ?
<RealNameCertificationModal {...this.props} {...this.state} basicInfo={this.state.basicInfo}
wrappedComponentRef={(form) => this.realNameCertificationModal2 = form}
certification={certification}
Getdata={() => this.getdata()}
onCancel={() => this.onCancel()}
></RealNameCertificationModal> : ""}
<div className="flexdirections ">
<p className="fontcolorsyslhei font-16 w98"><span className="fontcolorsysl font-16">*</span><span></span>
</p>
{basicInfo && basicInfo.authentication == "uncertified" ?
<p className="fontcolorsyslhui font-14 w200">通过实名认证后才能获得证书</p> : ""
}
{basicInfo && basicInfo.authentication == "uncertified" ?
<p className="fontcolorsysllan font-14 ml3 mycompitcursor"
onClick={() => this.checkBasicInfo(1)}>立即认证</p> : ""
}
</div>
<div className="flexdirections ml38 mt23">
<p className="fontcolorsyslhui1">姓名</p>
<p className="fontcolorsyslhei flexdirections">{basicInfo && basicInfo.name}
{
basicInfo && basicInfo.authentication == "uncertified" ? "" :
basicInfo && basicInfo.authentication == "applying" ?
<p className="flexdirections"><p className="iconfont icon-tishi colorgreenorg font-14 ml20"></p><p
className="colorgreenorg font-14 ml6">待审核</p><p
className="fontcolorsysllan borcolors font-12 w64 mycompitcursor"
onClick={() => this.Cancellationofapplication(1)}>撤销认证</p></p>
:
<p className="flexdirections">
<p className="iconfont icon-wancheng colorgreenlight font-14 ml20"></p><p
className="colorgreenlight font-14 ml6">已认证</p>
</p>
}
</p>
</div>
<div className="flexdirections ml38 mt19">
<p className="fontcolorsyslhui1">性别</p>
<p className="fontcolorsyslhei"> {basicInfo && basicInfo.gender == 0 ? "男" : "女"}</p>
</div>
<div className="flexdirections mt36 ">
<p className="fontcolorsyslhei font-16 w98"><span className="fontcolorsysl font-16">*</span><span></span>
</p>
{
basicInfo && basicInfo.professional_certification == "uncertified" ?
<p className="fontcolorsyslhui font-14 w200">通过职业认证后才能获得证书</p>
: ""}
{
basicInfo && basicInfo.professional_certification == "uncertified" ?
<p className="fontcolorsysllan font-14 ml3 mycompitcursor" onClick={() => this.checkBasicInfo(2)}>立即认证</p>
: ""}
</div>
<div className="flexdirections ml38 mt23">
<p className="fontcolorsyslhui1">职业</p>
<p
className="fontcolorsyslhei flexdirections">{basicInfo && basicInfo.identity && identityMap[basicInfo.identity]}
{
basicInfo && basicInfo.professional_certification == "uncertified" ?
"" :
basicInfo && basicInfo.professional_certification == "applying" ?
<p className="flexdirections">
<p className="iconfont icon-tishi colorgreenorg font-14 ml20"></p><p
className="colorgreenorg font-14 ml6">待审核</p><p
className="fontcolorsysllan borcolors font-12 w64 mycompitcursor ml6"
onClick={() => this.Cancellationofapplication(2)}>撤销认证</p>
</p>
:
<p className="flexdirections">
<p className="iconfont icon-wancheng colorgreenlight font-14 ml20"></p><p
className="colorgreenlight font-14 ml6">已认证</p>
<p className="fontcolorsysllan borcolors font-12 w64 mycompitcursor ml6"
onClick={() => this.checkBasicInfo(2)}>重新认证</p>
</p>
}
</p>
</div>
<div className="flexdirections ml38 mt19">
<p
className="fontcolorsyslhui1">{basicInfo && basicInfo.technical_title ? "职称:" : ""}{basicInfo && basicInfo.student_id ? "学号:" : ""}</p>
<p className="fontcolorsyslhei">{basicInfo && (basicInfo.technical_title || basicInfo.student_id)}</p>
</div>
<div className="flexdirections ml38 mt19">
<p className="fontcolorsyslhui1">学校</p>
<p className="fontcolorsyslhei">{basicInfo && basicInfo.school_name}</p>
</div>
<div className="flexdirections ml38 mt19">
<p className="fontcolorsyslhui1">院系</p>
<p className="fontcolorsyslhei"> {basicInfo && basicInfo.department_name}</p>
</div>
<div className="flexdirections mt36 ">
<p className="fontcolorsyslhei font-16 w98"><span className="fontcolorsysl font-16">*</span><span></span>
</p>
</div>
<div className="flexdirections ml38 mt23">
<p className="fontcolorsyslhui1 w60 ">手机号</p>
{
basicInfo && basicInfo.phone ?
<p className="fontcolorsyslhei w200 ">{basicInfo && basicInfo.phone}</p>
:
<p className="fontcolorsysljin w200 ">未绑定</p>
}
<p className="fontcolorsysllan mycompitcursor"
onClick={() => this.phonebools()}>{basicInfo && basicInfo.phone ? (phonebool === false ? "更换" : "") : (phonebool === false ? "立即绑定" : "")}</p>
</div>
{/*手机号绑定*/}
{
phonebool === true ?
<Phonenumberverifications {...this.props} {...this.state} basicInfo={this.state.basicInfo}
hideUpdating={(i) => this.hideUpdating(i)}
getdata={() => this.getdata()}></Phonenumberverifications>
: ""
}
<div className="flexdirections ml38 mt19">
<p className="fontcolorsyslhui1 w60">Email</p>
<p className="fontcolorsyslhei w200">{basicInfo && basicInfo.mail}</p>
<p className="fontcolorsysllan mycompitcursor"
onClick={() => this.emailbools()}>{basicInfo && basicInfo.mail ? (emailbool === false ? "更换" : "") : (emailbool === false ? "立即绑定" : "")}</p>
</div>
{
emailbool === false ? "" :
<Mailboxvalidations {...this.props} {...this.state} basicInfo={this.state.basicInfo}
hideUpdating={(i) => this.hideUpdating(i)}
getdata={() => this.getdata()}></Mailboxvalidations>
}
{
leader === true ?
<div>
{
bank_account_editable === true ?
<Bankcardnumberverifications {...this.props} {...this.state} basicInfo={this.state.basicInfo}
hideUpdating={(i) => this.hideUpdating(i)}
getdata={() => this.getdata()}
GetawardinformationAPI={() => this.GetawardinformationAPI()}
bank_account={this.state.bank_account}
></Bankcardnumberverifications>
:
<div>
<div className="flexdirections mt36">
<p className="fontcolorsyslhei font-16">//开户行及银行卡号</p>
<p className="fontcolorsyslhui font-14 ml11">为保障奖金的及时发放请队长如实填写你名下的银行卡信息</p>
</div>
{
bank_account && bank_account ?
<div>
<div className="flexdirections ml38 mt19">
<p className="fontcolorsyslhui1 w56">开户行</p>
<p className="fontcolorsyslhei">{bank_account && bank_account.bank}</p>
</div>
<div className="flexdirections ml38 mt19">
<p className="fontcolorsyslhui1 w56" style={{textAlign: "right"}}>支行</p>
<p className="fontcolorsyslhei">{bank_account && bank_account.second_bank}</p>
</div>
<div className="flexdirections ml38 mt19">
<p className="fontcolorsyslhui1 w56" style={{textAlign: "right"}}>账号</p>
<p className="fontcolorsyslhei"> {bank_account && bank_account.card_no}</p>
</div>
</div>
:
""
}
</div>
}
</div>
: ""
}
</div>
)
}
}
export default CompetitionContentspdfpeopledata;

@ -0,0 +1,270 @@
import React, {Component} from 'react';
import {Button, Layout, Input, Form} from 'antd';
import axios from 'axios';
import {getImageUrl} from 'educoder';
import mycompetotionchild from './mycompetotionchild.css';
import {getHiddenName} from "../../../../user/account/AccountBasicEdit";
import '../../../../courses/css/Courses.css'
export const identityMap = {"teacher": "教师", "student": "学生", "professional": "专业人士"}
class Mailboxvalidation extends Component {
constructor(props) {
super(props)
this.state = {
basicInfo: {},
updating: '',
secondsFlag: false,
seconds: 60,
phonebool: false,
emailbool: false,
formationdata: [],
bank_account_editable: false,
leader: false,
bank_account: undefined,
certification: 1
}
}
componentDidMount() {
window.document.title = '竞赛';
// console.log("3获取用户信息");
// console.log(this.props);
}
// 绑定邮箱
onEmailSubmit = () => {
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
let {login} = this.props.current_user;
let reg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
if (reg.test(values.email)) {
let url = `/users/accounts/${login}/email_bind.json`
axios.post((url), {
email: values.email,
code: values.emailValidateCode
}).then((result) => {
if (result) {
this.props.showNotification("邮箱地址绑定成功!");
this.hideUpdating(2);
this.props.getdata();
}
}).catch((error) => {
console.log(error);
})
} else {
this.props.showNotification("请输入正确的邮箱地址");
}
}
})
}
//取消编辑
hideUpdating = (i) => {
if (i === 1) {
this.props.hideUpdating(1);
} else if (i === 2) {
this.props.hideUpdating(2);
} else if (i === 3) {
}
}
// 获取验证码
getCode = (index) => {
let url = `/accounts/get_verification_code.json`
let login = '';
let values = this.props.form.getFieldsValue();
if (index == 3) {
//绑定手机号码
login = values.phone;
let reg = /^1\d{10}$/;
if (reg.test(login) == false) {
this.props.showNotification(`请先输入正确的手机号码`);
return;
}
} else if (index == 4) {
// 绑定邮箱
login = values.email;
let reg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
if (reg.test(login) == false) {
this.props.showNotification(`请先输入正确的邮箱地址`);
return;
}
}
let type = index;
if (!login) {
this.props.showNotification(`请先输入${index == 3 ? "手机号码" : "邮箱地址"}`);
return;
}
axios.get((url), {
params: {
login, type
}
}).then((result) => {
if (result) {
// 倒计时
this.setState({
secondsFlag: true
})
this.remainTime();
}
}).catch((error) => {
console.log(error);
})
}
// 获取验证码倒计时
remainTime = () => {
this.setState({
seconds: 60
})
this.timer = setInterval(() => {
let {seconds} = this.state;
let s = parseInt(seconds) - 1;
if (s > -1) {
this.setState({
seconds: s
})
} else {
this.setState({
secondsFlag: false
})
clearInterval(this.timer);
}
}, 1000)
}
phonebools = () => {
this.setState({
phonebool: true
})
}
emailbools = () => {
console.log("点击了邮箱");
this.setState({
emailbool: true
})
}
render() {
const {getFieldDecorator} = this.props.form;
const {updating, seconds, secondsFlag, basicInfo, phonebool, emailbool, certification, formationdata, bank_account_editable, leader, bank_account} = this.state
console.log(emailbool);
return (
<div>
<style>{`
.flexRow {
padding: 20px 0;
}
.flexRow .name {
margin-left: 12px;
color: #666666;
text-align: center;
flex: 0 0 100px;
}
.flexRow .description {
margin-left: 10px;
flex: 1;
color: #CDCDCD;
}
.description span {
margin-right: 20px;
color: #05101A;
}
.flexRow .status {
width: 100px;
color: #28AC7F;
text-align: right;
}
.flexTable .flexTable {
border-bottom: 1px solid #EBEBEB;
}
.settingForm label{
color: #666666;
font-size: 14px !important ;
}
.settingForm input {
width: 340px;
height: 40px;
}
.settingForm input.validateInput {
width: 220px;
}
.settingForm .formItemInline button {
width: 110px;
margin-left: 10px;
}
.settingForm .ant-form-item-label {
text-align: left;
width: 84px;
}
.formItemInline .ant-form-explain{
position:absolute;
bottom:-22px;
left:0px;
width:100%;
}
`}</style>
<div className="settingForm ml38">
<React.Fragment>
<Form>
<Form.Item
label="邮箱地址"
className="formItemInline hideRequireTag mb20 mt20"
>
{getFieldDecorator('email', {
rules: [{
// initialValue: this.state.cityDefaultValue,
required: true,
message: basicInfo && basicInfo.mail ? '请输入要更换的新邮箱地址' : '请输入邮箱地址',
}],
})(
<Input placeholder={`${basicInfo && basicInfo.mail ? '请输入要更换的新邮箱地址' : '请输入邮箱地址'}`}></Input>
)}
</Form.Item>
<Form.Item
label="邮箱验证码"
className="mb20 formItemInline hideRequireTag"
>
{getFieldDecorator('emailValidateCode', {
rules: [{
// initialValue: this.state.cityDefaultValue,
required: true,
message: '请输入邮箱收到的验证码',
}],
})(
<Input placeholder="请输入邮箱收到的验证码" className="validateInput"></Input>
)}
<Button type="primary" disabled={secondsFlag} onClick={() => this.getCode(4)}>
{!secondsFlag ? "获取验证码" : `重新发送${seconds}s`}</Button>
</Form.Item>
<div className="mb20" style={{marginLeft: '204px'}}>
<Button type="primary" onClick={() => this.onEmailSubmit()}>确定</Button>
<Button type="primary grayBtn" style={{marginLeft: '20px'}}
onClick={() => this.hideUpdating(2)}>取消</Button>
</div>
</Form>
</React.Fragment>
</div>
</div>
)
}
}
const Mailboxvalidations = Form.create({name: 'Mailboxvalidation'})(Mailboxvalidation);
export default Mailboxvalidations;

@ -0,0 +1,262 @@
import React, {Component} from 'react';
import {Button, Layout, Input, Form} from 'antd';
import axios from 'axios';
import {getImageUrl} from 'educoder';
import mycompetotionchild from './mycompetotionchild.css';
import {getHiddenName} from "../../../../user/account/AccountBasicEdit";
import '../../../../courses/css/Courses.css'
import RealNameCertificationModal from "../../../../user/modal/RealNameCertificationModal";
export const identityMap = {"teacher": "教师", "student": "学生", "professional": "专业人士"}
class Phonenumberverification extends Component {
constructor(props) {
super(props)
this.state = {
updating: '',
secondsFlag: false,
seconds: 60,
phonebool: false,
emailbool: false,
formationdata: [],
bank_account_editable: false,
leader: false,
bank_account: undefined,
certification: 1
}
}
componentDidMount() {
window.document.title = '竞赛';
// console.log("获取用户信息");
// console.log(this.props);
}
// 绑定手机
onPhoneSubmit = () => {
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
let {login} = this.props.current_user;
let reg = /^1\d{10}$/;
if (reg.test(values.phone)) {
let url = `/users/accounts/${login}/phone_bind.json`
axios.post((url), {
phone: values.phone,
code: values.phoneValidateCode
}).then((result) => {
if (result) {
this.props.showNotification("手机号码绑定成功!");
this.props.hideUpdating()
this.props.getdata();
}
}).catch((error) => {
console.log(error);
})
} else {
this.props.showNotification("请输入有效的11位手机号码");
}
}
})
}
//取消编辑
hideUpdating = (i) => {
if (i === 1) {
this.props.hideUpdating(1);
} else if (i === 2) {
this.props.hideUpdating(2);
} else if (i === 3) {
}
}
// 获取验证码
getCode = (index) => {
let url = `/accounts/get_verification_code.json`
let login = '';
let values = this.props.form.getFieldsValue();
if (index == 3) {
//绑定手机号码
login = values.phone;
let reg = /^1\d{10}$/;
if (reg.test(login) == false) {
this.props.showNotification(`请先输入正确的手机号码`);
return;
}
} else if (index == 4) {
// 绑定邮箱
login = values.email;
let reg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
if (reg.test(login) == false) {
this.props.showNotification(`请先输入正确的邮箱地址`);
return;
}
}
let type = index;
if (!login) {
this.props.showNotification(`请先输入${index == 3 ? "手机号码" : "邮箱地址"}`);
return;
}
axios.get((url), {
params: {
login, type
}
}).then((result) => {
if (result) {
// 倒计时
this.setState({
secondsFlag: true
})
this.remainTime();
}
}).catch((error) => {
console.log(error);
})
}
// 获取验证码倒计时
remainTime = () => {
this.setState({
seconds: 60
})
this.timer = setInterval(() => {
let {seconds} = this.state;
let s = parseInt(seconds) - 1;
if (s > -1) {
this.setState({
seconds: s
})
} else {
this.setState({
secondsFlag: false
})
clearInterval(this.timer);
}
}, 1000)
}
phonebools = () => {
this.setState({
phonebool: true
})
}
render() {
const {getFieldDecorator} = this.props.form;
const {updating, seconds, secondsFlag, phonebool, emailbool, certification, formationdata, bank_account_editable, leader, bank_account} = this.state
const {basicInfo} = this.props
console.log(emailbool);
return (
<div>
<style>{`
.flexRow {
padding: 20px 0;
}
.flexRow .name {
margin-left: 12px;
color: #666666;
text-align: center;
flex: 0 0 100px;
}
.flexRow .description {
margin-left: 10px;
flex: 1;
color: #CDCDCD;
}
.description span {
margin-right: 20px;
color: #05101A;
}
.flexRow .status {
width: 100px;
color: #28AC7F;
text-align: right;
}
.flexTable .flexTable {
border-bottom: 1px solid #EBEBEB;
}
.settingForm label{
color: #666666;
font-size: 14px !important ;
}
.settingForm input {
width: 340px;
height: 40px;
}
.settingForm input.validateInput {
width: 220px;
}
.settingForm .formItemInline button {
width: 110px;
margin-left: 10px;
}
.settingForm .ant-form-item-label {
text-align: left;
width: 84px;
}
.formItemInline .ant-form-explain{
position:absolute;
bottom:-22px;
left:0px;
width:100%;
}
`}</style>
<div className="settingForm ml38">
<React.Fragment>
<Form>
<Form.Item
label="你的手机号"
className="formItemInline hideRequireTag mb20 mt20"
>
{getFieldDecorator('phone', {
rules: [{
// initialValue: this.state.cityDefaultValue,
required: true,
message: `请输入要${basicInfo.phone ? '更换' : '绑定'}的手机号码`,
}],
})(
<Input placeholder={`请输入要${basicInfo.phone ? '更换' : '绑定'}的手机号码`}></Input>
)}
</Form.Item>
<Form.Item
label="手机验证码"
className="mb20 formItemInline hideRequireTag"
>
{getFieldDecorator('phoneValidateCode', {
rules: [{
// initialValue: this.state.cityDefaultValue,
required: true,
message: '请输入手机获取的验证码',
}],
})(
<Input placeholder="请输入手机获取的验证码" className="validateInput"></Input>
)}
<Button type="primary" disabled={secondsFlag} onClick={() => this.getCode(3)}>
{!secondsFlag ? "获取验证码" : `重新发送${seconds}s`}
</Button>
</Form.Item>
<div className="mb20" style={{marginLeft: '204px'}}>
<Button type="primary" onClick={() => this.onPhoneSubmit()}>确定</Button>
<Button type="primary grayBtn" style={{marginLeft: '20px'}}
onClick={() => this.hideUpdating(1)}>取消</Button>
</div>
</Form>
</React.Fragment>
</div>
</div>
)
}
}
const Phonenumberverifications = Form.create({name: 'Phonenumberverification'})(Phonenumberverification);
export default Phonenumberverifications;

@ -0,0 +1,314 @@
/*
*/
.flexdirectionjust {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.directstwebkitflex {
display: flex;
display: -webkit-flex;
flex-direction: column;
align-items: center;
}
.diredisplayitflex {
display: flex;
display: -webkit-flex;
align-items: center;
}
/*垂直布局*/
/*
*/
.flexdirection {
display: flex;
flex-direction: row;
}
.flexdirections {
display: flex;
flex-direction: initial;
}
/*
*/
/*靠右侧八 七 六 五 四 三 二 一*/
.flexdirectionss {
display: flex;
flex-direction: row-reverse;
}
/*
*/
.flexdidirectionss {
display: flex;
flex-direction: column;
}
/*
*/
.flexdidireverses {
display: flex;
flex-direction: column-reverse;
}
.fontcolorsysl {
color: #FF0000
}
.fontcolorsyslhei {
color: #000000
}
.fontcolorsyslhui {
color: #888888
}
.fontcolorsyslhui1 {
color: #666666;
}
.fontcolorsysllan {
color: #4CACFF
}
.fontcolorsysljin {
color: #DD7600
}
.w200 {
width: 200px;
}
.w64 {
width: 64px;
}
.w60 {
width: 60px;
}
.w98 {
width: 98px;
}
.myysllineheight {
line-height: 40px;
}
.myyslminwidth {
min-width: 60px;
}
.myyslminwidth276 {
width: 276px;
}
.buttongo {
background: #E7E7E7;
border: 1px solid #E7E7E7;
width: 60px;
height: 30px;
border-radius: 4px;
color: #999999;
font-size: 16px;
}
.buttongo2 {
background: #4CACFF;
border: 1px solid #4CACFF;
width: 64px;
height: 32px;
border-radius: 4px;
color: #FFFFFF;
font-size: 16px;
}
.fontwenzi {
text-align: center;
line-height: 30px;
}
.mt17 {
margin-top: 17px;
}
.mt36 {
margin-top: 36px;
}
.mt23 {
margin-top: 23px;
}
.mt19 {
margin-top: 19px;
}
.mt23 {
margin-top: 23px;
}
.mt34 {
margin-top: 34px;
}
.ml11 {
margin-left: 11px;
}
.ml38 {
margin-left: 38px;
}
.ml7 {
margin-left: 7px;
}
.colorgreenlight {
color: #6EC76E
}
.colorgreenorg {
color: #FF7300;
}
.borcolors {
border: 1px solid #4CACFF;
text-align: center;
}
.mycompitcursor {
cursor: pointer;
}
.basicForm {
background: #fff;
padding: 30px;
margin-bottom: 10px;
box-sizing: border-box;
width: 100%;
min-height: 390px;
}
.basicForm .title {
font-size: 16px;
padding-left: 30px;
margin-bottom: 10px;
}
.flexTable {
display: flex;
flex-direction: column;
}
.flexRow {
display: flex;
}
.mb15 {
margin-bottom: 15px !important;
}
/* BUTTOn */
.ant-btn {
border-radius: 2px;
}
button.ant-btn.ant-btn-primary.grayBtn {
background: #CBCBCB;
border-color: #CBCBCB;
}
.borderBottom {
border-bottom: 1px solid #4CACFF;
}
/* form ---------------- START */
.formItemInline {
display: flex;
}
.formItemInline .ant-form-item-control-wrapper {
display: inline-block;
}
.hideRequireTag .ant-form-item-required:before {
display: none;
}
/* .basicForm .ant-form-item-label {
width: 100px;
padding-right: 10px;
}
.basicForm .ant-form-item-label label {
color: #979797
} */
.courseNormalForm .ant-select-show-search {
height: 40px;
}
.courseNormalForm .ant-select-auto-complete.ant-select .ant-input {
height: 40px;
}
.courseNormalForm .ant-select-search__field__mirror {
height: 40px;
}
.courseNormalForm .ant-input-lg {
height: 40px;
}
.courseNormalForm .ant-select-selection--single {
height: 40px;
}
.courseNormalForm .ant-select-auto-complete.ant-select .ant-select-selection--single {
height: 40px
}
.courseNormalForm .ant-input-affix-wrapper {
height: 40px;
}
/* 职业 */
.courseNormalForm .ant-select-selection-selected-value {
line-height: 38px
}
.courseNormalForm input {
height: 40px;
}
.w300 {
width: 300px;
}
.w56 {
width: 56px;
}

@ -40,13 +40,16 @@
width: 60px;
height: 60px;
border-radius: 50%;
box-shadow: 0px 0px 12px rgba(0,0,0,0.2);
border:1px solid #F4F4F4;
/*box-shadow: 0px 0px 12px rgba(0,0,0,0.2);*/
}
.huangguans{
width: 36px;
height: 17px;
position: absolute;
top: -30px;
left: 72px;
top: -6px;
left: 71px;
}
.relatives{

@ -6,8 +6,9 @@ import Dropdownbox from './Dropdownbox';
import Dynamiclist from './Dynamiclist';
import NoneData from "../../courses/coursesPublic/NoneData";
import './Statistics.css';
const qs = require('qs');
const { TabPane } = Tabs;
class Statistics extends Component{
constructor(props){
super(props);
@ -26,7 +27,7 @@ class Statistics extends Component{
activeKey:'1',
visible: false,
group_ids:[],
course_members:[]
course_members:undefined
}
}
@ -159,41 +160,18 @@ class Statistics extends Component{
derivefun=(url)=>{
let{group_ids}=this.state;
let data={
group_id:group_ids
}
axios.get(url,{params:
data
}).then((response)=>{
if(response === undefined){
return
}
if(response.data.status&&response.data.status===-1){
this.props.showNotification(response.data.message);
}else if(response.data.status&&response.data.status===-2){
// if(response.data.message === "100"){
// // 已超出文件导出的上限数量100 ),建议:
//
// this.setState({
// DownloadType:true,
// DownloadMessageval:100
// })
// }else {
// //因附件资料超过500M
// this.setState({
// DownloadType:true,
// DownloadMessageval:500
// })
// }
this.props.showNotification(response.data.message);
let list=group_ids;
let urllist="";
if(list!=undefined&&list.length!=0)
list.map((item,key)=>{
if(key===0){
urllist=`group_id[]=${item}`
}else{
// this.props.showNotification(`正在下载中`);
// window.open("/api"+url, '_blank');
this.props.slowDownload(url);
urllist=urllist+`&group_id[]=${item}`
}
}).catch((error) => {
console.log(error)
});
})
this.props.slowDownload(`${url}?${urllist}`);
}
@ -383,7 +361,7 @@ class Statistics extends Component{
{...this.state}
postwork_scoredata={(group_idss)=>this.getwork_scoredata(1,group_idss,'desc')}
/>}
<a className={"ml20 ant-btn-link"} onClick={()=>this.derivefun(`/courses/${this.props.match.params.coursesId}/export_member_scores_excel.xlsx`)}>导出</a>
<a className={"ml20 ant-btn-link"} onClick={()=>this.derivefun(this.state.activeKey==="1"?`/courses/${this.props.match.params.coursesId}/export_member_scores_excel.xlsx`:`/courses/${this.props.match.params.coursesId}/export_member_act_score.xlsx`)}>导出</a>
</React.Fragment>;
return(
<React.Fragment>
@ -434,7 +412,7 @@ class Statistics extends Component{
return(
<Col span={5} className={"relatives"}>
<li className="pr rankingss">
<img src="https://test-newweb.educoder.net/images/educoder/huangguan.png" className="huangguans mb5" />
<img src={getImageUrl("images/educoder/imperialcrown.png")} className="huangguans mb5" />
<a href={`/users/${item.user_login}`} className="color-dark">
<img src={getImageUrl(`images/${item.avatar_url}`)} className={"mb10 mt5"}/>
</a>

@ -86,7 +86,8 @@ class PathDetailIndex extends Component{
pathtopskey:1,
dataquerys:{},
MenuItemsindex:1,
MenuItemsindextype:0
MenuItemsindextype:0,
qrcode_img:null
}
this.onDragEnd = this.onDragEnd.bind(this);
@ -250,7 +251,7 @@ class PathDetailIndex extends Component{
}
this.setState({
// detailInfoList:result.data,
qrcode_img:result.data.qrcode_img,
tags:result.data.tags,
progress:result.data.progress,
members:result.data.members,
@ -472,7 +473,7 @@ class PathDetailIndex extends Component{
progress,
members,
tags,
courses,
qrcode_img,
MenuItemsindex,
MenuItemsindextype
} = this.state
@ -538,6 +539,10 @@ class PathDetailIndex extends Component{
></DetailCards>
</div>
<div className="with35 fr pl20">
{qrcode_img===null?"":<div className="edu-back-white newmustlearn mb10">
<img src={`${qrcode_img}`} />
<div className="font-16 color181818">优惠报名扫码入群</div>
</div>}
<div className="edu-back-white mustlearn mb10">
<p className="clearfix mb30">
<span className="font-16 ">课程须知</span>

@ -259,3 +259,12 @@
.ml37{
margin-left: 37px;
}
.newmustlearn {
padding: 34px 25px;
text-align: center;
}
.color181818{
color: #181818;
}

@ -235,6 +235,10 @@ class NewHeader extends Component {
}
tojoinitem=()=>{
if(this.props.user&&this.props.user.email===undefined||this.props.user&&this.props.user.email===null||this.props.user&&this.props.user.email===""){
this.openNotification("请先绑定邮箱,谢谢");
return
}
let{user} =this.state;
if(user===undefined){
this.setState({
@ -609,7 +613,7 @@ submittojoinclass=(value)=>{
getUser=(url,type)=>{
if(type==="projects"){
if(!this.props.user&&this.props.user.email){
if(this.props.user&&this.props.user.email===undefined||this.props.user&&this.props.user.email===null||this.props.user&&this.props.user.email===""){
this.openNotification("请先绑定邮箱,谢谢");
return
}

@ -28,6 +28,8 @@ const Option = Select.Option;
const RadioGroup = Radio.Group;
const { TextArea } = Input;
function create_editorMD(id, width, high, placeholder, imageUrl, callback) {
var editorName = window.editormd(id, {
width: width,
@ -1155,19 +1157,22 @@ export default class TPMevaluation extends Component {
</a>
</Tooltip>
</p>
<textarea className="textareavalue mb15" name="test_set[input][]"
<TextArea className="textareavalue mb15" name="test_set[input][]"
placeholder="输入"
value={item.input}
id={"textareavalue"+key}
autoHeight="true"
autoSize={{ minRows: 3, maxRows: 5 }}
onInput={(e)=>this.evaluationoninputvalue(e,key,"sr")}
></textarea>
<textarea className="textareavalue" name="test_set[output][]"
></TextArea>
<TextArea className="textareavalue" name="test_set[output][]"
placeholder="预期输出"
value={item.output}
id={key+"textareavalue"}
autoHeight="true"
autoSize={{ minRows: 3, maxRows: 5 }}
onInput={(e)=>this.evaluationoninputvalue(e,key,"yq")}
></textarea>
></TextArea>
<div className="clearfix lineh-30">
<span className="fl mr10 color-grey-6">匹配规则</span>
<RadioGroup className="fl" value={item.match_rule} onChange={(e)=>this.changeEvaluationRule(e,key)}>

@ -4,6 +4,7 @@ import { SnackbarHOC, getImageUrl, City, ConditionToolTip } from 'educoder';
import { Form, Button, Input, Radio, Select, Tooltip, Icon, AutoComplete } from 'antd'
import ApplyForAddOrgModal from '../modal/ApplyForAddOrgModal'
import ApplyForAddChildOrgModal from '../modal/ApplyForAddChildOrgModal'
import AccountBasicEditItem from './AccountBasicEditItem';
import axios from 'axios'
import { identityMap } from './AccountBasic'
const RadioGroup = Radio.Group;
@ -282,7 +283,9 @@ class AccountBasic extends Component {
getDepartments=(e,flag)=>{
let arr=this.state.schoolList.filter(function(item){
return item.name == e;
if(item.name.indexOf(e) > -1){
return item.name;
}
});
if (!arr[0]) {
if (!e) {
@ -354,20 +357,7 @@ class AccountBasic extends Component {
})
}
// 切换职称
changeJob=(e)=>{
this.setState({
identity:e
})
let {basicInfo}=this.props;
if(basicInfo){
this.props.form.setFieldsValue({
job1:basicInfo && basicInfo.identity=="teacher" ? basicInfo.technical_title:"教授",
job2:basicInfo && basicInfo.identity=="professional" ? basicInfo.technical_title:"企业管理者",
})
}
}
addOrgSuccess = (name) => {
// const schoolList = this.state.schoolList.slice(0)
@ -407,6 +397,19 @@ class AccountBasic extends Component {
}
callback(`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`);
}
// 切换职称
changeJob=(e)=>{
this.setState({
identity:e
})
let {basicInfo}=this.props;
if(basicInfo){
this.props.form.setFieldsValue({
job1:basicInfo && basicInfo.identity=="teacher" ? basicInfo.technical_title:"教授",
job2:basicInfo && basicInfo.identity=="professional" ? basicInfo.technical_title:"企业管理者",
})
}
}
render() {
let{
@ -422,10 +425,17 @@ class AccountBasic extends Component {
}=this.state;
const { getFieldDecorator } = this.props.form;
let{ basicInfo }=this.props
// 已职业认证的账户不能修改职业,学校/单位,院系/部门产品还未确定先默认为false--可以更改
// basicInfo && basicInfo.professional_certification == "certified"
const professionalFlag = false;
let common = {
changeJob:this.changeJob,
filterList:this.filterList,
changeList:this.changeList,
searchDepartment:this.searchDepartment,
changeDepartment:this.changeDepartment,
showApplyForAddOrgModal:this.showApplyForAddOrgModal,
showApplyForAddChildOrgModal:this.showApplyForAddChildOrgModal
}
// 已职业认证的账户不能修改职业,学校/单位,院系/部门true为disable
const professionalFlag = basicInfo && basicInfo.professional_certification == "certified" ;
// form合并了
const propsWithoutForm = Object.assign({}, this.props)
@ -599,177 +609,22 @@ class AccountBasic extends Component {
<City></City>
)}
</Form.Item>
<div className="clearfix">
<Form.Item
label="职业"
className="formItemInline fl"
>
{getFieldDecorator('job', {
rules: [{
initialValue:"teacher",
required: true,
message: '请先选择职业',
}],
})(
<Select style={{width:"190px",marginRight:"20px"}} onChange={this.changeJob} disabled={professionalFlag}>
<Option value="teacher">教师</Option>
<Option value="student">学生</Option>
<Option value="professional">专业人士</Option>
</Select>
)}
</Form.Item>
{
identity && identity=="student" &&
<Form.Item
label=""
className="formItemInline fl"
style={{ 'margin-top': '3px'}}
// style={{display:identity && identity=="student" ? "block":"none"}}
>
{getFieldDecorator('student_No', {
rules: [{
required: true,
message: '请先输入学号',
}],
})(
<Input type="text" placeholder="请输入学号" style={{width:"190px"}} disabled={professionalFlag}></Input>
)}
</Form.Item>
}
{
identity && identity=="teacher" &&
<Form.Item
label=""
className="formItemInline fl"
// style={{display:identity && identity=="teacher" ? "block":"none"}}
>
{getFieldDecorator('job1', {
rules: [{
initialValue:"教授",
required: true,
message: '请先选择职称',
}],
})(
<Select style={{width:"190px"}} disabled={professionalFlag}>
<Option value="教授">教授</Option>
<Option value="副教授">副教授</Option>
<Option value="讲师">讲师</Option>
<Option value="助教">助教</Option>
</Select>
)}
</Form.Item>
}
{
identity && identity=="professional" &&
<Form.Item
label=""
className="formItemInline fl mb0"
// style={{display:identity && identity=="professional" ? "block":"none"}}
>
{getFieldDecorator('job2', {
rules: [{
initialValue:"企业管理者",
required: true,
message: '请先选择职称',
}],
})(
<Select style={{width:"190px"}} disabled={professionalFlag}>
<Option value="企业管理者">企业管理者</Option>
<Option value="部门管理者">部门管理者</Option>
<Option value="高级工程师">高级工程师</Option>
<Option value="工程师">工程师</Option>
<Option value="助理工程师">助理工程师</Option>
</Select>
)}
</Form.Item>
}
</div>
<Form.Item
label="学校/单位"
className="formItemInline mb0"
>
{getFieldDecorator('org', {
rules: [{
// initialValue: this.state.cityDefaultValue,
// type: 'array',
required: true,
message: '请先选择学校/单位',
// 做不了输入时和submit时都会执行这里
// validator: (rule, value, callback) => {
// if (this.this_school_id) {
// callback();
// return;
// }
// callback('请先选择学校/单位');
// }
}],
})(
<AutoComplete width={400} showSearch onSearch={this.filterList} onChange={this.changeList} disabled={professionalFlag}>
{
filterSchoolList && filterSchoolList.map((item,key)=>{
return(<Option value={item.name} key={item.id}>{item.name}</Option>)
})
}
</AutoComplete>
)}
</Form.Item>
{!filterSchoolList || (filterSchoolList && filterSchoolList.length==0 )&& school &&
<div style={{marginLeft: '113px',height:"20px",lineHeight:"20px"}}>
<span>
<span style={{color: '#CDCDCD'}}>未找到包含{school}的高校</span>
<span style={{color: '#4CACFF', cursor: 'pointer'}} onClick={this.showApplyForAddOrgModal}>申请新增</span>
</span>
</div>
}
<Form.Item
label="院系/部门"
className="formItemInline mb0"
style={{ 'margin-top': '10px'}}
>
{getFieldDecorator('org2', {
rules: [{
// initialValue: this.state.cityDefaultValue,
// type: 'array',
required: true,
message: '请先选择院系/部门',
// validator: (rule, value, callback) => {
// if (this.this_department_id) {
// callback();
// return;
// }
// callback('请先选择院系/部门');
// }
}],
})(
<AutoComplete width={400} showSearch onSearch={this.searchDepartment} onChange={this.changeDepartment} disabled={professionalFlag}>
{
filterDepartments && filterDepartments.map((item,key)=>{
return(
<Option value={item.name} key={item.name}>{item.name}</Option>
)
})
}
</AutoComplete>
)}
</Form.Item>
{
filterDepartments != undefined && ( (filterDepartments && filterDepartments.length==0 )
|| (departmentsName == '' && !this.state.department_id
&& (!departments || departments.length == 0) )) &&
<div style={{marginLeft: '113px',height:"20px",lineHeight:"20px"}}>
<span>
<span style={{color: '#CDCDCD'}}>{departmentsName ? `未找到包含“${departmentsName}”的院系/部门` : '未找到院系'}</span>
<span style={{color: '#4CACFF', cursor: 'pointer'}} onClick={this.showApplyForAddChildOrgModal}>申请新增</span>
</span>
</div>
}
<AccountBasicEditItem
identity={identity}
getFieldDecorator = {getFieldDecorator}
professionalFlag = {professionalFlag}
basicInfo = {basicInfo}
{...this.props}
{...this.state}
{...common}
form={this.props.form}
filterSchoolList={filterSchoolList}
filterDepartments={filterDepartments}
departmentsName={departmentsName}
school={school}
department_id={this.state.department_id}
departments={departments}
></AccountBasicEditItem>
{/* htmlType="submit" */}
{/* <Form.Item>
<div className="clearfix mt30 mb30"> */}

@ -0,0 +1,199 @@
import React, { Component } from 'react';
import { SnackbarHOC, getImageUrl, City, ConditionToolTip } from 'educoder';
import { Form, Button, Input, Radio, Select, Tooltip, Icon, AutoComplete } from 'antd'
const RadioGroup = Radio.Group;
const Option = Select.Option;
class AccpimtBasicEditItem extends Component {
constructor(props){
super(props);
}
render(){
let {
professionalFlag ,
getFieldDecorator ,
identity ,
filterSchoolList ,
filterDepartments,
departmentsName,
school,
departments,
department_id
} = this.props
return(
<div>
<div className="clearfix mt10">
<Form.Item
label="职业"
className="formItemInline fl"
>
{getFieldDecorator('job', {
rules: [{
initialValue:"teacher",
required: true,
message: '请先选择职业',
}],
})(
<Select style={{width:"190px",marginRight:"20px"}} onChange={(e)=>this.props.changeJob(e)} disabled={professionalFlag}>
<Option value="teacher">教师</Option>
<Option value="student">学生</Option>
<Option value="professional">专业人士</Option>
</Select>
)}
</Form.Item>
{
identity && identity=="student" &&
<Form.Item
label=""
className="formItemInline fl"
style={{ 'margin-top': '3px'}}
// style={{display:identity && identity=="student" ? "block":"none"}}
>
{getFieldDecorator('student_No', {
rules: [{
required: true,
message: '请先输入学号',
}],
})(
<Input type="text" placeholder="请输入学号" style={{width:"190px"}} disabled={professionalFlag}></Input>
)}
</Form.Item>
}
{
identity && identity=="teacher" &&
<Form.Item
label=""
className="formItemInline fl"
// style={{display:identity && identity=="teacher" ? "block":"none"}}
>
{getFieldDecorator('job1', {
rules: [{
initialValue:"教授",
required: true,
message: '请先选择职称',
}],
})(
<Select style={{width:"190px"}} disabled={professionalFlag}>
<Option value="教授">教授</Option>
<Option value="副教授">副教授</Option>
<Option value="讲师">讲师</Option>
<Option value="助教">助教</Option>
</Select>
)}
</Form.Item>
}
{
identity && identity=="professional" &&
<Form.Item
label=""
className="formItemInline fl mb0"
// style={{display:identity && identity=="professional" ? "block":"none"}}
>
{getFieldDecorator('job2', {
rules: [{
initialValue:"企业管理者",
required: true,
message: '请先选择职称',
}],
})(
<Select style={{width:"190px"}} disabled={professionalFlag}>
<Option value="企业管理者">企业管理者</Option>
<Option value="部门管理者">部门管理者</Option>
<Option value="高级工程师">高级工程师</Option>
<Option value="工程师">工程师</Option>
<Option value="助理工程师">助理工程师</Option>
</Select>
)}
</Form.Item>
}
</div>
<Form.Item
label="学校/单位"
className="formItemInline mb0"
>
{getFieldDecorator('org', {
rules: [{
// initialValue: this.state.cityDefaultValue,
// type: 'array',
required: true,
message: '请先选择学校/单位',
// 做不了输入时和submit时都会执行这里
// validator: (rule, value, callback) => {
// if (this.this_school_id) {
// callback();
// return;
// }
// callback('请先选择学校/单位');
// }
}],
})(
<AutoComplete width={400} showSearch onSearch={this.props.filterList} onChange={this.props.changeList} disabled={professionalFlag}>
{
filterSchoolList && filterSchoolList.map((item,key)=>{
return(<Option value={item.name} key={item.id}>{item.name}</Option>)
})
}
</AutoComplete>
)}
</Form.Item>
{!filterSchoolList || (filterSchoolList && filterSchoolList.length==0 )&& school &&
<div style={{marginLeft: '113px',height:"20px",lineHeight:"20px"}}>
<span>
<span style={{color: '#CDCDCD'}}>未找到包含{school}的高校</span>
<span style={{color: '#4CACFF', cursor: 'pointer'}} onClick={this.props.showApplyForAddOrgModal}>申请新增</span>
</span>
</div>
}
<Form.Item
label="院系/部门"
className="formItemInline mb0"
style={{ 'margin-top': '10px'}}
>
{getFieldDecorator('org2', {
rules: [{
// initialValue: this.state.cityDefaultValue,
// type: 'array',
required: true,
message: '请先选择院系/部门',
// validator: (rule, value, callback) => {
// if (this.this_department_id) {
// callback();
// return;
// }
// callback('请先选择院系/部门');
// }
}],
})(
<AutoComplete width={400} showSearch onSearch={this.props.searchDepartment} onChange={this.props.changeDepartment} disabled={professionalFlag}>
{
filterDepartments && filterDepartments.map((item,key)=>{
return(
<Option value={item.name} key={item.name}>{item.name}</Option>
)
})
}
</AutoComplete>
)}
</Form.Item>
{
filterDepartments != undefined && ( (filterDepartments && filterDepartments.length==0 )
|| (departmentsName == '' && ! department_id
&& (!departments || departments.length == 0) )) &&
<div style={{marginLeft: '113px',height:"20px",lineHeight:"20px"}}>
<span>
<span style={{color: '#CDCDCD'}}>{departmentsName ? `未找到包含“${departmentsName}”的院系/部门` : '未找到院系'}</span>
<span style={{color: '#4CACFF', cursor: 'pointer'}} onClick={this.props.showApplyForAddChildOrgModal}>申请新增</span>
</span>
</div>
}
</div>
)
}
}
export default AccpimtBasicEditItem;

@ -76,7 +76,7 @@ class ApplyForAddChildOrgModal extends Component{
{...this.props }
onOk={this.onOk}
okText="保存"
className="applyForModal courseNormalForm"
className="applyForModal courseNormalForm styleForapply"
>
<style>{`
.applyForModal .ant-form-item-label {
@ -86,7 +86,7 @@ class ApplyForAddChildOrgModal extends Component{
.applyForModal .ant-form-item-label label {
color: #979797
}
.applyForModal .formItemInline .ant-form-item-control-wrapper {
.styleForapply .formItemInline .ant-form-item-control-wrapper {
width: 390px;
}
`}</style>

@ -1,15 +1,19 @@
import React, { Component } from "react";
import { message, Icon, Input, Form, Upload} from "antd";
import { message, Icon, Input, Form, Upload,Radio ,Tooltip} from "antd";
import axios from 'axios'
import ModalWrapper from "../../courses/common/ModalWrapper"
import { City, getUploadActionUrl, getImageUrl, ImageLayer2, getUploadActionUrlOfAuth } from 'educoder'
import { City, getUploadActionUrl, getImageUrl, ImageLayer2, getUploadActionUrlOfAuth ,ConditionToolTip } from 'educoder'
import '../account/common.css'
import AccountBasicEditItem from '../account/AccountBasicEditItem'
import ApplyForAddOrgModal from './ApplyForAddOrgModal'
import ApplyForAddChildOrgModal from './ApplyForAddChildOrgModal'
import authImg from '../../../images/account/auth.png'
import jobImg from '../../../images/account/job.png'
const { TextArea } = Input;
const RadioGroup = Radio.Group;
const Dragger = Upload.Dragger;
const MAX_NAME_LENGTH = 10
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
@ -26,16 +30,232 @@ function beforeUpload(file) {
}
return isJPG && isLt2M;
}
export function getHiddenName(name) {
if (!name) return ''
let len=parseInt(name.length)-1;
let str="";
for(var i = 0; i < len; i++){ str += "*"; }
const newName = name.substr(0,1)+str;
return newName
}
class RealNameCertificationModal extends Component{
constructor(props){
super(props);
this.state={
identity:"teacher",
departmentsName:undefined,
filterSchoolList:undefined,
filterDepartments :undefined,
school:undefined,
school_id:undefined,
department_id:undefined,
schoolList:undefined,
departments:undefined,
showRealName:true,
}
}
componentDidMount() {
console.log("RealNameCertificationModal");
console.log(this.props.basicInfo);
if(this.props.basicInfo){
this.setValue(this.props.basicInfo);
this.getSchoolList(this.props.basicInfo);
}
}
setValue=(basicInfo)=>{
if(basicInfo){
this.props.form.setFieldsValue({
nickname:basicInfo.nickname,
name:!basicInfo.show_realname ? this.hideRealName(basicInfo.name) : basicInfo.name,
sex:String(basicInfo.gender),
job:basicInfo.identity,
org:basicInfo.school_name,
// city:[basicInfo.location,basicInfo.location_city]
})
setTimeout(() => {
// 等显示后再set
this.props.form.setFieldsValue({
job:basicInfo.identity,
student_No:basicInfo.student_id,
org2:basicInfo.department_name,
job1:basicInfo && basicInfo.identity=="teacher" ? basicInfo.technical_title:"教授",
job2:basicInfo && basicInfo.identity=="professional" ? basicInfo.technical_title:"企业管理者",
})
}, 100)
//if(basicInfo.nickname){
this.setState({
forDisable: true,
nameLength:basicInfo.nickname?basicInfo.nickname.length:0,
showRealName:basicInfo.show_realname,
realName: basicInfo.name,
identity:basicInfo.identity,
school_id:basicInfo.school_id,
department_id:basicInfo.department_id
})
//}
}
}
getSchoolList=(basicInfo, selectedName)=>{
let url=`/schools/for_option.json`;
axios.get(url).then((result)=>{
if(result){
this.setState({
schoolList:result.data.schools
})
if (selectedName) {
let school_id
result.data.schools.reverse().some( item => {
if (item.name == selectedName) {
school_id = item.id
return true;
}
})
this.props.form.setFieldsValue({
org: selectedName
})
this.setState({
school_id,
school: selectedName
}, () => {
this.filterList(selectedName)
})
} else if(basicInfo && basicInfo.school_name){
this.setState({
school:basicInfo.school_name,
filterSchoolList:this.state.schoolList.filter(function(item){
return item.name.indexOf(basicInfo.school_name)>-1;
})
})
this.getDepartments(basicInfo.school_name,false);
}
}
}).catch((error)=>{
console.log(error);
})
}
// 将名字隐藏起来
hideRealName=(name)=>{
this.setState({ realName: name })
const newName = getHiddenName(name)
this.props.form.setFieldsValue({
name: newName
})
return newName
}
getDepartments=(e,flag)=>{
let arr=this.state.schoolList.filter(function(item){
if(item.name.indexOf(e) > -1){
return item.name;
}
});
if (!arr[0]) {
if (!e) {
this.setState({
filterSchoolList: []
})
}
// 没找到学校,清空部门
this.setState({
departments: [],
filterDepartments: [],
departmentsName: '',
school_id: '',
department_id: '',
})
this.this_school_id = ''
this.props.form.setFieldsValue({
org2: ''
})
return;
}
this.props.form.setFieldsValue({
org: arr[0].name
})
this.filterList(e)
// 保存选择的学校id
this.this_school_id = arr[0].id
this.setState({
school_id: arr[0].id,
school:e,
})
this._getDepartments(arr[0].id, flag)
}
_getDepartments = (schoolId, flag, selectedName) => {
let url=`/schools/${schoolId || this.state.school_id}/departments/for_option.json`;
axios.get(url).then((result)=>{
if(result){
this.setState({
departments:result.data.departments,
filterDepartments:result.data.departments
})
if (selectedName) {
let department_id
result.data.departments.reverse().some( item => {
if (item.name == selectedName) {
department_id = item.id
return true;
}
})
this.props.form.setFieldsValue({
org2: selectedName
})
this.setState({
department_id,
// school: selectedName
})
} else if(result.data.departments && result.data.departments.length>0 && flag==true){
// 切换学校后,部门默认选择第一个
this.props.form.setFieldsValue({
org2:result.data.departments[0].name
})
this.setState({
department_id: result.data.departments[0].id
})
}else if(result.data.departments && result.data.departments.length == 0 && flag==true){
this.props.form.setFieldsValue({
org2:''
})
}
}
}).catch((error)=>{
console.log(error);
})
}
filterList =(e)=>{
const inputVal = e.trim()
let arr=[];
if(inputVal){
arr= this.state.schoolList.filter(function(item){
return item.name.indexOf(inputVal)>-1;
});
this.props.form.setFieldsValue({
org: inputVal
})
this.setState({
school: inputVal,
filterSchoolList: arr
})
} else {
this.setState({
school: '',
})
}
// else{
// let {school}=this.state;
// arr= this.state.schoolList.filter(function(item){
// return item.name.indexOf(school)>-1;
// });
// }
}
setVisible = (visible) => {
this.refs.modalWrapper.setVisible(visible)
}
@ -43,6 +263,7 @@ class RealNameCertificationModal extends Component{
onSendOk = () => {
this.props.form.validateFieldsAndScroll((err, values) => {
console.log(values);
console.log(this.state.department_id);
if(!err){
let{imageUrl2}=this.state;
let{current_user,basicInfo}=this.props;
@ -52,30 +273,52 @@ class RealNameCertificationModal extends Component{
// 实名认证
let url = `/users/accounts/${current_user && current_user.login}/authentication_apply.json`
axios.post((url),{
name:basicInfo.name,
name:values.name,
gender:parseInt(values.sex),
id_number:values.credentials
}).then((result)=>{
if(result){
this.props.showNotification("申请已提交,请等待审核!");
try {
this.props.getBasicInfo();
} catch (e) {
}
try {
this.props.Getdata();
} catch (e) {
}
this.setVisible(false);
}
}).catch((error)=>{
console.log(error);
})
}else{
// 职业认证
// console.log(values.job == "student" ? values.student_No : values.job == "teacher" ? values.job1 : values.job2);
let url = `/users/accounts/${current_user && current_user.login}/professional_auth_apply.json`
axios.post((url),{
school_id:basicInfo && basicInfo.school_id,
department_id:basicInfo && basicInfo.department_id,
identity:basicInfo && basicInfo.identity,
extra:basicInfo && basicInfo.identity == "student" ? basicInfo.student_id:basicInfo.technical_title
school_id:this.state.school_id,
department_id:this.state.department_id,
identity:this.state.identity,
extra: values.job == "student" ? values.student_No : values.job == "teacher" ? values.job1 : values.job2
}).then((result)=>{
if(result){
this.props.showNotification("申请已提交,请等待审核!");
try {
this.props.getBasicInfo();
} catch (e) {
}
try {
this.props.Getdata();
} catch (e) {
}
this.setVisible(false);
}
}).catch((error)=>{
console.log(error);
@ -119,13 +362,120 @@ class RealNameCertificationModal extends Component{
}));
}
}
// 切换职称
changeJob=(e)=>{
this.setState({
identity:e
})
let {basicInfo}=this.props;
if(basicInfo){
this.props.form.setFieldsValue({
job1:basicInfo && basicInfo.identity=="teacher" ? basicInfo.technical_title:"教授",
job2:basicInfo && basicInfo.identity=="professional" ? basicInfo.technical_title:"企业管理者",
})
}
}
// 选择学校(获取对应学校的学院、部门)
changeList=(e)=>{
this.getDepartments(e.trim(),true);
}
showApplyForAddOrgModal = () => {
this.applyForAddOrgForm.setVisible(true)
}
showApplyForAddChildOrgModal = () => {
let{school,schoolList}=this.state;
let arr=schoolList.filter(function(item){
return item.name == school;
});
if(arr.length > 0){
this.applyForAddChildOrgForm.setVisible(true)
}else{
this.props.showNotification("请先选择正确的单位或者学校!");
}
}
addOrgSuccess = (name) => {
// const schoolList = this.state.schoolList.slice(0)
// schoolList.push({ id: schoolList.length + 2000, name: name})
// this.setState({ schoolList })
this.getSchoolList(this.props.basicInfo, name);
this.props.form.setFieldsValue({
org: name
})
}
addChildOrgSuccess = (deptName) => {
this._getDepartments(this.state.school_id, false, deptName);
}
// 隐藏或显示真实姓名
showOrHide=(flag)=>{
const name = this.props.form.getFieldsValue().name || this.props.basicInfo.name
this.setState({
showRealName:flag==true?false:true
})
if(flag==true){ // 隐藏真实姓名
this.hideRealName(name);
}else{ // 显示
this.props.form.setFieldsValue({
name: this.state.realName
})
}
}
// 选择部门、学院
changeDepartment=(e)=>{
let arr = this.state.departments && this.state.departments.filter ? this.state.departments.filter(function(item){
return item.name == e;
}) : [];
if (!arr[0]) {
this.setState({
department_id: '',
departmentsName: e,
filterDepartments: [],
})
this.this_department_id = ''
return;
}
this.this_department_id = arr[0].id
this.setState({
departmentsName:e,
department_id: arr[0].id,
})
}
render(){
const { course_lists, checkBoxValues, searchValue, loading, imageUrl, imageUrl2 } = this.state
const { course_lists, checkBoxValues, searchValue, loading, imageUrl, imageUrl2,
identity,
departmentsName ,
filterSchoolList ,
filterDepartments ,
school,
department_id,
departments,
school_id,
showRealName
} = this.state
const { moduleName } = this.props
const { getFieldDecorator } = this.props.form;
let {certification}=this.props;
// /api/users/accounts/${this.props.current_user.login}/auth_attachment.json
// 已职业认证的账户不能修改职业,学校/单位,院系/部门true为disable
const professionalFlag = basicInfo && basicInfo.professional_certification == "certified" ;
let{ basicInfo }=this.props
let common={
changeJob:this.changeJob,
filterList:this.filterList,
changeList:this.changeList,
changeDepartment:this.changeDepartment,
showApplyForAddOrgModal:this.showApplyForAddOrgModal,
showApplyForAddChildOrgModal:this.showApplyForAddChildOrgModal
}
const uploadProps2 = {
name: 'image',
data: {type: certification == 1 ? "real_name" : "professional"},
@ -136,7 +486,20 @@ class RealNameCertificationModal extends Component{
className: 'idPic-uploader',
onChange: this.handleChange2,
};
// form合并了
const propsWithoutForm = Object.assign({}, this.props)
delete propsWithoutForm.form
return(
<div>
<ApplyForAddOrgModal ref="applyForAddOrgModal" wrappedComponentRef={(form) => this.applyForAddOrgForm = form} schoolName={school}
{...propsWithoutForm} addOrgSuccess={this.addOrgSuccess}
></ApplyForAddOrgModal>
<ApplyForAddChildOrgModal ref="applyForAddChildOrgModal" schoolName={school} schoolId={school_id} departmentName={departmentsName}
{...propsWithoutForm}
wrappedComponentRef={(form) => this.applyForAddChildOrgForm = form}
addChildOrgSuccess={this.addChildOrgSuccess}
></ApplyForAddChildOrgModal>
<ModalWrapper
ref="modalWrapper"
title={
@ -145,9 +508,11 @@ class RealNameCertificationModal extends Component{
<span><i className="iconfont icon-zhiyerenzheng font-18 color-blue mr5" style={{fontWeight:"normal"}}></i></span>
}
{...this.props }
{...this.state}
onOk={this.onOk}
okText="保存"
className="applyForModal certificationModal courseNormalForm"
width="660px"
bottomRender={
certification && certification == 1?
<div className="bottomRender">
@ -202,9 +567,9 @@ class RealNameCertificationModal extends Component{
.certificationModal .ant-modal-body{
padding:20px;
}
.certificationModal .formItemInline .ant-form-item-control-wrapper {
width: 448px;
}
// .certificationModal .formItemInline .ant-form-item-control-wrapper {
// width: 448px;
// }
span.idPic-uploader {
margin-right:20px;
height:110px;
@ -255,16 +620,77 @@ class RealNameCertificationModal extends Component{
align-items: center;
display: -webkit-flex;
}
.formItemInline.ant-form-item {
display: -ms-flexbox;
display: flex;
}
.formItemInline {
display: flex;
margin-bottom: 10px;
position: relative;
}
.formItemInline .ant-form-explain{
position:absolute;
bottom:-20px;
left:0px;
width:100%;
}
.yslgraduainputedit{
width:295px;
}
`}</style>
<Form onSubmit={this.handleSubmit}>
{
certification && certification ==1 &&
{certification && certification == 1 ?
<div>
<Form.Item
label="姓名"
className="formItemInline"
>
{basicInfo && basicInfo.authentication == 'uncertified' ? <React.Fragment>{getFieldDecorator('name', {
rules: [{
// initialValue: this.state.cityDefaultValue,
required: true,
message: `请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`,
validator: this.checkNameLength
}],
})(
<Input placeholder={`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`} className="yslgraduainputedit" disabled={!showRealName && this.state.forDisable == true } addonAfter={
<i className={showRealName?"iconfont icon-xianshi font-18 color-blue":"iconfont icon-yincang font-18 color-blue"}
onClick={()=>this.showOrHide(showRealName)}></i>
}></Input>
)}
<span>{ showRealName ? '(显示:平台将显示您的真实姓名)' : '(隐藏:平台将显示你的昵称)' }</span>
</React.Fragment> :
<div className="df" style={{}}>
<Tooltip title="已完成实名认证,不能修改">
<span className="mr8" >{showRealName ? this.props.basicInfo.name : getHiddenName(this.props.basicInfo.name)}</span>
</Tooltip>
<i className={showRealName?"iconfont icon-xianshi font-18 color-blue":"iconfont icon-yincang font-18 color-blue"}
onClick={()=>this.showOrHide(showRealName)}></i>
<span>{ showRealName ? '(显示:平台将显示您的真实姓名)' : '(隐藏:平台将显示你的昵称)' }</span>
</div>
}
</Form.Item>
<Form.Item
label="性别"
className="formItemInline resetSexStyle"
>
{getFieldDecorator('sex', {
rules: [{
required: true,
message: '请选择性别',
}],
})(
<RadioGroup>
<ConditionToolTip title="已完成实名认证,不能修改" condition={basicInfo.authentication != 'uncertified'} >
<Radio value="0" disabled={basicInfo.authentication != 'uncertified'}></Radio>
<Radio value="1" disabled={basicInfo.authentication != 'uncertified'}></Radio>
</ConditionToolTip>
</RadioGroup>
)}
</Form.Item>
<Form.Item
label="证件号:"
className="formItemInline"
@ -279,14 +705,29 @@ class RealNameCertificationModal extends Component{
<Input placeholder="请输入证件号" ></Input>
)}
</Form.Item>
}
<div style={{ marginLeft: '18px' }}>
<div>
<span style={{color: '#999999'}}>{ certification && certification == 1 ? "身份证(人像面)上传":"职业证照片上传" }</span>
<span style={{color: '#FF6800'}}>png/jpg/bmp格式不超过2MB</span>
</div>
<div className="df mt20" style={{ justifyContent: 'center' }} >
:
<AccountBasicEditItem
identity={identity}
getFieldDecorator={getFieldDecorator}
professionalFlag={professionalFlag}
basicInfo={basicInfo}
{...this.props}
{...this.state}
{...common}
form={this.props.form}
filterSchoolList={filterSchoolList}
filterDepartments={filterDepartments}
departmentsName={departmentsName}
school={school}
department_id={department_id}
departments={departments}
></AccountBasicEditItem>
}
<div className="mt15" style={{ marginLeft: '18px' }}>
<div className="df">
<span style={{color: '#999999'}}>{ certification && certification == 1 ? "身份证上传:":"职业证上传:" }</span>
<div className="df ml10" style={{ justifyContent: 'center' }} >
<span className="idPic-uploader demoImg">
<img src={`${certification == 1 ? authImg : jobImg}`} alt="avatar" style={{ maxHeight: '110px'}}/>
</span>
@ -305,21 +746,25 @@ class RealNameCertificationModal extends Component{
}
</Dragger>
</div>
<div className="df mt10 color-grey-9" style={{ justifyContent: 'center' }} >
<span className="fl mr20 edu-txt-center" style={{width:"160px"}}>示例图片</span>
<span className="fl edu-txt-center mr20" style={{width:"160px"}}>
</div>
<div className="df mt10 color-grey-9">
<span className="fl edu-txt-center" style={{width:"200px",marginLeft:"65px"}}>
<p>示例图片</p>
<p className="font-12" style={{color: '#FF6800'}}>png/jpg/bmp格式不超过2MB</p>
</span>
<span className="fl edu-txt-center" style={{width:"160px"}}>
<ImageLayer2 parentSel={'#imageLayerBtn'} parentSel={'#imageLayerBtn'}
></ImageLayer2>
<a href="javascript:void(0)" id="imageLayerBtn" src={imageUrl || imageUrl2} className="color-orange" style={{borderBottom:"1px solid #ff6800"}}>查看大图</a>
</span>
</div>
</div>
</Form>
</ModalWrapper>
</div>
)
}
}

@ -287,7 +287,7 @@ class Infos extends Component{
}
></Route>
{/* 实训课程 */}
{/* 实践课程 */}
<Route exact path="/users/:username/paths"
render={
(props) => (<InfosPath {...this.props} {...props} {...this.state} {..._commonProps}/>)
@ -317,7 +317,6 @@ class Infos extends Component{
></Route>
<Route exact path="/users/:username"
render={
(props) => (<InfosCourse {...this.props} {...props} {...this.state} {..._commonProps}/>)

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { SnackbarHOC } from 'educoder';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import {Tooltip,Menu,Pagination,Spin} from 'antd';
import {Tooltip, Menu, Pagination, Spin, Dropdown} from 'antd';
import Loadable from 'react-loadable';
import Loading from '../../../Loading';
import axios from 'axios';
@ -20,7 +20,8 @@ class InfosCourse extends Component{
status:undefined,
page:1,
per_page:16,
sort_by: "updated_at",
sort_direction: "desc",
totalCount:undefined,
data:undefined,
isSpin:false
@ -31,27 +32,35 @@ class InfosCourse extends Component{
this.setState({
isSpin:true
})
let{category,status,page}=this.state;
this.getCourses(category,status,page);
let {category, status, page, sort_by, sort_direction} = this.state;
this.getCourses(category, status, page, sort_by, sort_direction);
}
getCourses=(category,status,page)=>{
getCourses = (category, status, page, sort_by, sort_direction) => {
let url=`/users/${this.props.match.params.username}/courses.json`;
axios.get((url),{params:{
category,
status,
page,
sort_by,
sort_direction,
per_page: this.props.is_current && category && page ==1?17:16
}}).then((result)=>{
if(result){
console.log("请求成功");
this.setState({
totalCount:result.data.count,
data:result.data,
sort_direction: sort_direction,
sort_by: sort_by,
isSpin:false
})
}
}).catch((error)=>{
console.log(error);
this.setState({
isSpin: false
})
})
}
@ -92,6 +101,27 @@ class InfosCourse extends Component{
}
}
updatedlist(sort_by) {
//按照什么样子排序
this.setState({
isSpin: true
});
let {category, status, page, sort_direction} = this.state;
this.getCourses(category, status, 1, sort_by, "desc");
}
updatedlists(sort_direction, i) {
// console.log("updatedlistssort_direction");
// console.log(sort_direction);
// console.log(i);
//是否是倒序
this.setState({
isSpin: true
});
let {category, status, page, sort_by} = this.state;
this.getCourses(category, status, page, sort_by, sort_direction);
}
render(){
let{
category,
@ -99,11 +129,25 @@ class InfosCourse extends Component{
page,
data,
totalCount,
isSpin
isSpin,
sort_by,
sort_direction
} = this.state;
let is_current=this.props.is_current;
// console.log(this.props.current_user&&this.props.current_user.user_identity==="学生")
const menu = (
<Menu>
<Menu.Item onClick={() => this.updatedlist("updated_at")}>
最新动态
</Menu.Item>
<Menu.Item onClick={() => this.updatedlist("created_at")}>
最新创建
</Menu.Item>
</Menu>
);
return(
<div className="educontent">
<Spin size="large" spinning={isSpin}>
@ -120,10 +164,66 @@ class InfosCourse extends Component{
<li className={status=="end" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeStatus("end")}>已结束</a></li>
</div>
}
<p className="pl25 pr25 clearfix font-12 mb20 mt20">
<p className="pl25 pr25 clearfix font-12 " style={{
lineHeight: "41px",
}}>
<span className="fl color-grey-9">共参与{totalCount}{category?category=="manage"?"发布":"学习":"课堂"}</span>
<span className="fr color-grey-9">时间最新</span>
<sapn className="relativef fr"
style={{
display: "flex",
flexDirection: "column",
height: "40px",
lineHeight: "40px",
}}
>
<span
style={{
flexDirection: "column",
textAlign: "center",
height: "10px",
lineHeight: "10px",
display: "table",
marginTop: "9px",
}}
>
<i className={sort_direction === "asc" ?
"iconfont icon-sanjiaoxing-up font-12 color-blue h10 " : "iconfont icon-sanjiaoxing-up font-12 h10"}
onClick={() => this.updatedlists("asc", 1)}></i>
</span>
<span
style={{
flexDirection: "column",
height: "10px",
lineHeight: "10px",
textAlign: "center",
display: "table",
}}
>
<i className={sort_direction === "desc" ?
"iconfont icon-sanjiaoxing-down font-12 yslbottomsj color-blue h10" : "iconfont icon-sanjiaoxing-down font-12 yslbottomsj h10"}
onClick={() => this.updatedlists("desc", 2)}></i>
</span>
</sapn>
<Dropdown overlay={menu}>
<span className="fr color-grey-9 mr10 pointer " style={{
display: "flex",
flexDirection: "initial",
}}>
<span>{sort_by === "updated_at" ? '最新动态' : sort_by === "created_at" ? '最新创建' : ""}</span>
</span>
</Dropdown>
</p>
<style>
{
`
.square-list{width: 100%;box-sizing: border-box;margin-top:10px}
`
}
</style>
<div className="square-list clearfix">
{/* 289 */}
{

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { SnackbarHOC } from 'educoder';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import {Tooltip,Menu,Pagination, Spin} from 'antd';
import {Tooltip, Menu, Pagination, Spin, Dropdown} from 'antd';
import Loadable from 'react-loadable';
import Loading from '../../../Loading';
import NoneData from '../../courses/coursesPublic/NoneData'
@ -19,11 +19,11 @@ class InfosPath extends Component{
this.state={
category:undefined,
page:1,
sort_by:'time',
status:undefined,
per_page:16,
isSpin:false,
sort_by: "updated_at",
sort_direction: "desc",
totalCount:undefined,
data:undefined
}
@ -33,28 +33,34 @@ class InfosPath extends Component{
this.setState({
isSpin:true
})
let{category,status,sort_by,page,per_page}=this.state;
this.getCourses(category,status,sort_by,page,per_page);
let {category, status, sort_by, page, per_page, sort_direction} = this.state;
this.getCourses(category, status, sort_by, page, sort_direction);
}
getCourses=(category,status,sort_by,page,per_page)=>{
getCourses = (category, status, sort_by, page, sort_direction) => {
let url=`/users/${this.props.match.params.username}/subjects.json`;
axios.get((url),{params:{
category,
status,
sort_by,
page,
sort_direction,
per_page:this.props.is_current && category && page ==1?17:16
}}).then((result)=>{
if(result){
this.setState({
totalCount:result.data.count,
data:result.data,
sort_by: sort_by,
sort_direction: sort_direction,
isSpin:false
})
}
}).catch((error)=>{
console.log(error);
this.setState({
isSpin: false
})
})
}
@ -66,18 +72,18 @@ class InfosPath extends Component{
page:1,
isSpin:true
})
let{sort_by}=this.state;
this.getCourses(cate,undefined,sort_by,1);
let {sort_by, sort_direction} = this.state;
this.getCourses(cate, undefined, sort_by, 1, sort_direction);
}
// 切换状态
changeStatus=(status)=>{
let{category,sort_by}=this.state;
let {category, sort_by, sort_direction} = this.state;
this.setState({
status,
page:1,
isSpin:true
})
this.getCourses(category,status,sort_by,1);
this.getCourses(category, status, sort_by, 1, sort_direction);
}
//切换页数
changePage=(page)=>{
@ -85,8 +91,8 @@ class InfosPath extends Component{
page,
isSpin:true
})
let{category,sort_by,status}=this.state;
this.getCourses(category,status,sort_by,page);
let {category, sort_by, status, sort_direction} = this.state;
this.getCourses(category, status, sort_by, page, sort_direction);
}
// 进入课堂
@ -101,15 +107,38 @@ class InfosPath extends Component{
sort_by:sort,
isSpin:true
})
let{category,status,page}=this.state;
this.getCourses(category,status,sort,page);
let {category, status, page, sort_direction} = this.state;
this.getCourses(category, status, sort, page, sort_direction);
}
//切换种类
updatedlist(sort_by) {
//按照什么样子排序
this.setState({
isSpin: true
});
let {category, status, page, sort_direction} = this.state;
this.getCourses(category, status, sort_by, 1, "desc");
}
//排序
updatedlists(sort_direction) {
//是否是倒序
this.setState({
isSpin: true
});
let {category, status, page, sort_by} = this.state;
this.getCourses(category, status, sort_by, page, sort_direction);
}
render(){
let{
category,
status,
sort_by,
sort_direction,
page,
data,
totalCount,
@ -117,6 +146,17 @@ class InfosPath extends Component{
} = this.state;
let isStudent = this.props.isStudent();
let is_current=this.props.is_current;
const menu = (
<Menu>
<Menu.Item onClick={() => this.updatedlist("updated_at")}>
最近更新
</Menu.Item>
<Menu.Item onClick={() => this.updatedlist("created_at")}>
最新创建
</Menu.Item>
</Menu>
);
return(
<div className="educontent">
<Spin size="large" spinning={isSpin}>
@ -142,10 +182,65 @@ class InfosPath extends Component{
<li className={status=="finished" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeStatus("finished")}>已完成</a></li>
</div>
}
<div className="pl25 pr25 clearfix font-12 mb20 mt20">
<div className="pl25 pr25 clearfix font-12 " style={{
lineHeight: "41px",
}}>
<span className="fl color-grey-9">共参与{totalCount}{category?category=="manage"?"发布":"学习":"实践课程"}</span>
<span className="fr color-grey-9">时间最新</span>
<sapn className="relativef fr"
style={{
display: "flex",
flexDirection: "column",
height: "40px",
lineHeight: "40px",
}}
>
<span
style={{
flexDirection: "column",
textAlign: "center",
height: "10px",
lineHeight: "10px",
display: "table",
marginTop: "9px",
}}
>
<i className={sort_direction === "asc" ?
"iconfont icon-sanjiaoxing-up font-12 color-blue h10 " : "iconfont icon-sanjiaoxing-up font-12 h10"}
onClick={() => this.updatedlists("asc")}></i>
</span>
<span
style={{
flexDirection: "column",
height: "10px",
lineHeight: "10px",
textAlign: "center",
display: "table",
}}
>
<i className={sort_direction === "desc" ?
"iconfont icon-sanjiaoxing-down font-12 yslbottomsj color-blue h10" : "iconfont icon-sanjiaoxing-down font-12 yslbottomsj h10"}
onClick={() => this.updatedlists("desc")}></i>
</span>
</sapn>
<Dropdown overlay={menu}>
<span className="fr color-grey-9 mr10 pointer " style={{
display: "flex",
flexDirection: "initial",
}}>
<span>{sort_by === "updated_at" ? '最近更新' : sort_by === "created_at" ? '最新创建' : ""}</span>
</span>
</Dropdown>
</div>
<style>
{
`
.square-list{width: 100%;box-sizing: border-box;margin-top:10px}
`
}
</style>
<div className="square-list clearfix">
{/* 295 */}
{

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { SnackbarHOC } from 'educoder';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import {Tooltip,Pagination,Spin} from 'antd';
import {Tooltip, Pagination, Spin, Dropdown, Menu} from 'antd';
import axios from 'axios';
import NoneData from '../../courses/coursesPublic/NoneData'
import {getImageUrl} from 'educoder';
@ -16,7 +16,8 @@ class InfosProject extends Component{
status:undefined,
page:1,
per_page:16,
sort_by: "updated_on",
sort_direction: "desc",
totalCount:undefined,
data:undefined,
isSpin:false
@ -27,16 +28,18 @@ class InfosProject extends Component{
this.setState({
isSpin:true
})
let{category,status,page}=this.state;
this.getCourses(category,status,page);
let {category, status, page, sort_by, sort_direction} = this.state;
this.getCourses(category, status, page, sort_by, sort_direction);
}
getCourses=(category,status,page)=>{
getCourses = (category, status, page, sort_by, sort_direction) => {
let url=`/users/${this.props.match.params.username}/projects.json`;
axios.get((url),{params:{
category,
status,
page,
sort_by,
sort_direction,
per_page:this.props.is_current && category && page ==1?17:16
}}).then((result)=>{
if(result){
@ -49,6 +52,8 @@ class InfosProject extends Component{
this.setState({
totalCount:result.data.count,
data:result.data,
sort_by: sort_by,
sort_direction: sort_direction,
isSpin:false
})
}
@ -56,6 +61,9 @@ class InfosProject extends Component{
}
}).catch((error)=>{
console.log(error);
this.setState({
isSpin: false
})
})
}
@ -66,8 +74,9 @@ class InfosProject extends Component{
page:1,
isSpin:true
})
let{status}=this.state;
this.getCourses(cate,status,1);
let {status, sort_by, sort_direction} = this.state;
this.getCourses(cate, status, 1, sort_by,
sort_direction);
}
//切换状态
changeStatus=(status)=>{
@ -76,8 +85,12 @@ class InfosProject extends Component{
page:1,
isSpin:true
})
let{category}=this.state;
this.getCourses(category,status,1);
let {
category, sort_by,
sort_direction
} = this.state;
this.getCourses(category, status, 1, sort_by,
sort_direction);
}
//切换页数
changePage=(page)=>{
@ -85,8 +98,12 @@ class InfosProject extends Component{
page,
isSpin:true
})
let{category,status}=this.state;
this.getCourses(category,status,page);
let {
category, status, sort_by,
sort_direction
} = this.state;
this.getCourses(category, status, page, sort_by,
sort_direction);
}
// 进入项目
@ -96,6 +113,27 @@ class InfosProject extends Component{
}
}
//切换种类
updatedlist(sort_by) {
//按照什么样子排序
this.setState({
isSpin: true
});
let {category, status, page, sort_direction} = this.state;
this.getCourses(category, status, 1, sort_by, "desc");
}
//排序
updatedlists(sort_direction) {
//是否是倒序
this.setState({
isSpin: true
});
let {category, status, page, sort_by} = this.state;
this.getCourses(category, status, page, sort_by, sort_direction);
}
render(){
let{
category,
@ -103,12 +141,24 @@ class InfosProject extends Component{
page,
data,
totalCount,
isSpin
isSpin,
sort_by,
sort_direction
} = this.state;
let isStudent = this.props.isStudent();
let is_current=this.props.is_current;
console.log(data)
const menu = (
<Menu>
<Menu.Item onClick={() => this.updatedlist("updated_on")}>
最新动态
</Menu.Item>
<Menu.Item onClick={() => this.updatedlist("created_on")}>
最新创建
</Menu.Item>
</Menu>
);
return(
<div className="educontent">
<Spin size="large" spinning={isSpin}>
@ -125,10 +175,65 @@ class InfosProject extends Component{
<li className={status=="personal" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeStatus("personal")}>私有</a></li>
</div>
}
<p className="pl25 pr25 clearfix font-12 mb20 mt20">
<p className="pl25 pr25 clearfix font-12 " style={{
lineHeight: "41px",
}}>
<span className="fl color-grey-9">共参与{totalCount}{category?category=="manage"?"发布":"学习":"项目"}</span>
<span className="fr color-grey-9">时间最新</span>
<sapn className="relativef fr"
style={{
display: "flex",
flexDirection: "column",
height: "40px",
lineHeight: "40px",
}}
>
<span
style={{
flexDirection: "column",
textAlign: "center",
height: "10px",
lineHeight: "10px",
display: "table",
marginTop: "9px",
}}
>
<i className={sort_direction === "asc" ?
"iconfont icon-sanjiaoxing-up font-12 color-blue h10 " : "iconfont icon-sanjiaoxing-up font-12 h10"}
onClick={() => this.updatedlists("asc")}></i>
</span>
<span
style={{
flexDirection: "column",
height: "10px",
lineHeight: "10px",
textAlign: "center",
display: "table",
}}
>
<i className={sort_direction === "desc" ?
"iconfont icon-sanjiaoxing-down font-12 yslbottomsj color-blue h10" : "iconfont icon-sanjiaoxing-down font-12 yslbottomsj h10"}
onClick={() => this.updatedlists("desc")}></i>
</span>
</sapn>
<Dropdown overlay={menu}>
<span className="fr color-grey-9 mr10 pointer " style={{
display: "flex",
flexDirection: "initial",
}}>
<span>{sort_by === "updated_on" ? '最近更新' : sort_by === "created_on" ? '最新创建' : ""}</span>
</span>
</Dropdown>
</p>
<style>
{
`
.square-list{width: 100%;box-sizing: border-box;margin-top:10px}
`
}
</style>
<div className="square-list clearfix">
{/* 289 */}
{

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import { Pagination , Spin } from 'antd';
import {Pagination, Spin, Dropdown, Menu} from 'antd';
import NoneData from '../../courses/coursesPublic/NoneData'
import axios from 'axios';
@ -16,11 +16,11 @@ class InfosShixun extends Component{
this.state={
category:undefined,
page:1,
sort_by:'time',
status:undefined,
per_page:16,
isSpin:false,
sort_by: "updated_at",
sort_direction: "desc",
totalCount:undefined,
data:undefined
}
@ -30,11 +30,15 @@ class InfosShixun extends Component{
this.setState({
isSpin:true
})
let{category,status,sort_by,page}=this.state;
this.getCourses(category,status,sort_by,page);
let {category, status, sort_by, page, sort_direction} = this.state;
this.getCourses(category, status, sort_by, page, sort_direction);
}
getCourses=(category,status,sort_by,page)=>{
getCourses = (category, status, sort_by, page, sort_direction) => {
// console.log("请求数据成功");
// console.log("getCourses");
// console.log(sort_by);
// console.log(sort_direction);
let url=`/users/${this.props.match.params.username}/shixuns.json`;
axios.get((url),{params:{
category,
@ -44,14 +48,21 @@ class InfosShixun extends Component{
per_page:this.props.is_current && category && page ==1?17:16
}}).then((result)=>{
if(result){
console.log("请求数据成功");
console.log(sort_by);
this.setState({
totalCount:result.data.count,
data:result.data,
sort_by: sort_by,
sort_direction: sort_direction,
isSpin:false
})
}
}).catch((error)=>{
console.log(error);
this.setState({
isSpin: false
})
})
}
@ -63,8 +74,8 @@ class InfosShixun extends Component{
page:1,
isSpin:true
})
let{sort_by}=this.state;
this.getCourses(cate,undefined,sort_by,1);
let {sort_by, sort_direction} = this.state;
this.getCourses(cate, undefined, sort_by, 1, sort_direction);
}
// 切换状态
changeStatus=(status)=>{
@ -73,8 +84,8 @@ class InfosShixun extends Component{
page:1,
isSpin:true
})
let{category,sort_by}=this.state;
this.getCourses(category,status,sort_by,1);
let {category, sort_by, sort_direction} = this.state;
this.getCourses(category, status, sort_by, 1, sort_direction);
}
//切换页数
changePage=(page)=>{
@ -82,8 +93,8 @@ class InfosShixun extends Component{
page,
isSpin:true
})
let{category,sort_by,status}=this.state;
this.getCourses(category,status,sort_by,page);
let {category, sort_by, status, sort_direction} = this.state;
this.getCourses(category, status, sort_by, page, sort_direction);
}
// 进入课堂
@ -98,8 +109,28 @@ class InfosShixun extends Component{
sort_by:sort,
isSpin:true
})
let{category,status,page}=this.state;
this.getCourses(category,status,sort,page);
let {category, status, page, sort_direction} = this.state;
this.getCourses(category, status, sort, page, sort_direction);
}
//切换种类
updatedlist(sort_by) {
//按照什么样子排序
this.setState({
isSpin: true
});
let {category, status, page, sort_direction} = this.state;
this.getCourses(category, status, sort_by, 1, "desc");
}
//排序
updatedlists(sort_direction) {
//是否是倒序
this.setState({
isSpin: true
});
let {category, status, page, sort_by} = this.state;
this.getCourses(category, status, sort_by, page, sort_direction);
}
render(){
@ -110,10 +141,22 @@ class InfosShixun extends Component{
page,
data,
totalCount,
sort_direction,
isSpin
} = this.state;
let is_current=this.props.is_current;
const menu = (
<Menu>
<Menu.Item onClick={() => this.updatedlist("updated_at")}>
最新动态
</Menu.Item>
<Menu.Item onClick={() => this.updatedlist("created_at")}>
语言类别
</Menu.Item>
</Menu>
);
return(
<div className="educontent">
<Spin size="large" spinning={isSpin}>
@ -140,17 +183,57 @@ class InfosShixun extends Component{
<li className={status=="passed" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeStatus("passed")}>已通关</a></li>
</div>
}
<div className="pl25 pr25 clearfix font-12 mb20 mt20">
<div className="pl25 pr25 clearfix font-12 " style={{
lineHeight: "41px",
}}>
<span className="fl color-grey-9">共参与{totalCount}{category?category=="manage"?"发布":"学习":"实训"}</span>
<div className="fr">
<li className="drop_down">
<span className="color-grey-9 font-12">{sort_by=="time"?"时间最新":"语言类别"}</span><i className="iconfont icon-xiajiantou font-12 ml2 color-grey-6"></i>
<ul className="drop_down_normal">
<li onClick={()=>this.changeOrder("time")}>时间最新</li>
<li onClick={()=>this.changeOrder("language")}>语言类别</li>
</ul>
</li>
</div>
<sapn className="relativef fr"
style={{
display: "flex",
flexDirection: "column",
height: "40px",
lineHeight: "40px",
}}
>
<span
style={{
flexDirection: "column",
textAlign: "center",
height: "10px",
lineHeight: "10px",
display: "table",
marginTop: "9px",
}}
>
<i className={sort_direction === "asc" ?
"iconfont icon-sanjiaoxing-up font-12 color-blue h10 " : "iconfont icon-sanjiaoxing-up font-12 h10"}
onClick={() => this.updatedlists("asc")}></i>
</span>
<span
style={{
flexDirection: "column",
height: "10px",
lineHeight: "10px",
textAlign: "center",
display: "table",
}}
>
<i className={sort_direction === "desc" ?
"iconfont icon-sanjiaoxing-down font-12 yslbottomsj color-blue h10" : "iconfont icon-sanjiaoxing-down font-12 yslbottomsj h10"}
onClick={() => this.updatedlists("desc")}></i>
</span>
</sapn>
<Dropdown overlay={menu}>
<span className="fr color-grey-9 mr10 pointer " style={{
display: "flex",
flexDirection: "initial",
}}>
<span>{sort_by === "updated_at" ? '最新动态' : sort_by === "created_at" ? '语言类别' : ""}</span>
</span>
</Dropdown>
</div>
<style>
{
@ -160,6 +243,7 @@ class InfosShixun extends Component{
left: 10px;
bottom: 100px;
}
.square-list{width: 100%;box-sizing: border-box;margin-top:10px}
`
}
</style>

@ -17,8 +17,7 @@ class publicCreateNew extends Component{
//头部获取是否已经登录了
getUser=(url)=> {
console.log(this.props)
if (!this.props.user && this.props.user.email) {
if (this.props.user&&this.props.user.email===undefined||this.props.user&&this.props.user.email===null||this.props.user&&this.props.user.email==="") {
this.props.showNotification("请先绑定邮箱,谢谢");
return
}

@ -435,3 +435,7 @@
.educontent .square-list {
min-height: 400px;
}
.h10 {
height: 10px;
}

@ -96,7 +96,7 @@ function InfoVideo (props) {
setCount(response.data.count)
}
}).catch(() => {
setLoading(false)
})
}
function fetchReviewvideos() {
@ -201,7 +201,10 @@ function InfoVideo (props) {
function getCopyText (file_url, cover_url) {
return `<video src="${file_url}" controls="true" controlslist="nodownload" width="${DEFAULT_VIDEO_WIDTH_IN_MD}" height="${DEFAULT_VIDEO_HEIGHT_IN_MD}" poster="${cover_url}">您的浏览器不支持 video 标签。</video>`
}
const _inputValue = getCopyText(videoId.file_url, videoId.cover_url)
const _inputValue = getCopyText(videoId.file_url, videoId.cover_url);
const sorts = sortKey.split('-')
return (
<div className="educontent infoVideo">
<EditVideoModal {...props} {...editModalObj}
@ -281,7 +284,9 @@ function InfoVideo (props) {
}
></InfoTab>
<div className="toolbarRow mt20 df">
<div className="toolbarRow df" style={{
lineHeight: "40px",
}}>
<span>
<span style={{color: theme.foreground_orange1}}> {count} </span>
@ -297,11 +302,48 @@ function InfoVideo (props) {
{categoryObj.category == 'all' &&<div className="fr">
<li className="drop_down">
<span className="color-grey-9 font-12">{sortKey=="published_at-desc"?"最新上传":"最早上传"}</span><i className="iconfont icon-xiajiantou font-12 ml2 color-grey-6"></i>
<ul className="drop_down_normal">
<li onClick={()=>onSortChange("published_at-desc",0)}>最新上传</li>
<li onClick={()=>onSortChange("published_at-asc",1)}>最早上传</li>
</ul>
<span className="color-grey-9 font-12" style={{
marginRight: " 5px",
}}>{"最新上传"}</span>
<sapn className="relativef fr"
style={{
display: "flex",
flexDirection: "column",
height: "40px",
lineHeight: "40px",
}}
>
<span
style={{
flexDirection: "column",
textAlign: "center",
height: "10px",
lineHeight: "10px",
display: "table",
marginTop: "9px",
}}
>
<i className={sorts[1] === "asc" ?
"iconfont icon-sanjiaoxing-up font-12 color-blue h10 " : "iconfont icon-sanjiaoxing-up font-12 h10"}
onClick={() => onSortChange("published_at-asc", 0)}></i>
</span>
<span
style={{
flexDirection: "column",
height: "10px",
lineHeight: "10px",
textAlign: "center",
display: "table",
}}
>
<i className={sorts[1] === "desc" ?
"iconfont icon-sanjiaoxing-down font-12 yslbottomsj color-blue h10" : "iconfont icon-sanjiaoxing-down font-12 yslbottomsj h10"}
onClick={() => onSortChange("published_at-desc", 0)}></i>
</span>
</sapn>
</li>
</div>}
</div>

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe GameAnswer, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save