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

dev_newshixunModel
杨树林 5 years ago
commit d5a52ca114

@ -13,6 +13,7 @@
//= require bootstrap-datepicker
//= require bootstrap.viewer
//= require jquery.mloading
//= require jquery-confirm.min
//= require common
//= require echarts

@ -0,0 +1,12 @@
$(document).on('turbolinks:load', function(){
$(document).on('click', '.batch-all-check-box', function(){
var $checkAll = $(this);
$('.batch-check-box').prop('checked', $checkAll.is(':checked'));
})
$(document).on('click', '.batch-check-box', function(){
var allChecked = $('.batch-check-box:checked').length === $('.batch-check-box').length
$('.batch-all-check-box').prop('checked', allChecked);
})
});

@ -10,11 +10,41 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('select[name="status"]').val('processed');
if($link.data('value') === 'processed'){
$('.batch-action-container').hide();
$searchFrom.find('.status-filter').show();
} else {
$('.batch-action-container').show();
$searchFrom.find('.status-filter').hide();
$searchFrom.find('select[name="status"]').val('pending');
}
});
$('.batch-agree-btn').on('click', function(){
if($('.batch-check-box:checked').length === 0){
$.notify({ message: '请先选择数据' }, { type: 'info' });
return;
}
customConfirm({
content: '确认审核通过?',
ok: function(){
var ids = $('.batch-check-box:checked').map(function(_, e){ return $(e).val() }).get();
$.ajax({
url: '/admins/identity_authentications/batch_agree',
method: 'POST',
dataType: 'json',
data: { ids: ids },
success: function(data){
$.notify({ message: '操作成功' });
window.location.reload();
},
error: function(res){
$.notify({ message: res.responseJSON.message }, { type: 'danger' });
}
})
}
})
})
}
})

@ -10,11 +10,41 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('select[name="status"]').val('processed');
if($link.data('value') === 'processed'){
$('.batch-action-container').hide();
$searchFrom.find('.status-filter').show();
} else {
$('.batch-action-container').show();
$searchFrom.find('.status-filter').hide();
$searchFrom.find('select[name="status"]').val('pending');
}
});
$('.batch-agree-btn').on('click', function(){
if($('.batch-check-box:checked').length === 0){
$.notify({ message: '请先选择数据' }, { type: 'info' });
return;
}
customConfirm({
content: '确认审核通过?',
ok: function(){
var ids = $('.batch-check-box:checked').map(function(_, e){ return $(e).val() }).get();
$.ajax({
url: '/admins/professional_authentications/batch_agree',
method: 'POST',
dataType: 'json',
data: { ids: ids },
success: function(data){
$.notify({ message: '操作成功' });
window.location.reload();
},
error: function(res){
$.notify({ message: res.responseJSON.message }, { type: 'danger' });
}
})
}
})
})
}
})

@ -42,4 +42,26 @@ function ajaxErrorNotifyHandler(res) {
function resetFileInputFunc(file){
file.after(file.clone().val(""));
file.remove();
}
function customConfirm(opts){
var okCallback = opts.ok;
var cancelCallback = opts.cancel;
var defaultOpts = {
title: '提示',
buttons: {
ok: {
text: '确认',
btnClass: 'btn btn-primary',
action: okCallback
},
cancel: {
text: '取消',
btnClass: 'btn btn-secondary',
action: cancelCallback
},
}
}
return $.confirm($.extend({}, defaultOpts, opts))
}

File diff suppressed because one or more lines are too long

@ -6,6 +6,7 @@
@import "bootstrap-datepicker";
@import "bootstrap-datepicker.standalone";
@import "jquery.mloading";
@import "jquery-confirm.min";
@import "codemirror/lib/codemirror";
@import "editormd/css/editormd.min";

@ -110,5 +110,11 @@
.CodeMirror {
border: 1px solid #ced4da;
}
.batch-action-container {
margin-bottom: -15px;
padding: 10px 20px 0;
background: #fff;
}
}

File diff suppressed because one or more lines are too long

@ -1,6 +1,7 @@
class Admins::IdentityAuthenticationsController < Admins::BaseController
def index
params[:status] ||= 'pending'
params[:sort_direction] = params[:status] == 'pending' ? 'asc' : 'desc'
applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 1))
@ -18,6 +19,24 @@ class Admins::IdentityAuthenticationsController < Admins::BaseController
render_success_js
end
def batch_agree
ApplyUserAuthentication.real_name_auth.where(id: params[:ids]).each do |apply|
begin
Admins::IdentityAuths::AgreeApplyService.call(apply)
rescue => e
Util.logger_error(e)
end
end
render_ok
end
def revoke
Admins::IdentityAuths::RevokeApplyService.call(current_apply)
render_success_js
end
private
def current_apply

@ -1,6 +1,7 @@
class Admins::ProfessionalAuthenticationsController < Admins::BaseController
def index
params[:status] ||= 'pending'
params[:sort_direction] = params[:status] == 'pending' ? 'asc' : 'desc'
applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 2))
@ -18,6 +19,23 @@ class Admins::ProfessionalAuthenticationsController < Admins::BaseController
render_success_js
end
def batch_agree
ApplyUserAuthentication.professional_auth.where(id: params[:ids]).each do |apply|
begin
Admins::ProfessionalAuths::AgreeApplyService.call(apply)
rescue => e
Util.logger_error(e)
end
end
render_ok
end
def revoke
Admins::ProfessionalAuths::RevokeApplyService.call(current_apply)
render_success_js
end
private
def current_apply

@ -51,7 +51,8 @@ class CommonsController < ApplicationController
200
end
when 'journals_for_message'
if current_user.course_identity(@object.jour.course) >= Course::STUDENT && @object.user != current_user
course = @object.jour&.course || @object.jour&.student_work&.homework_common&.course
if current_user.course_identity(course) >= Course::STUDENT && @object.user != current_user
403
else
200

@ -559,7 +559,7 @@ class GamesController < ApplicationController
secret_rep = @shixun.shixun_secret_repository
logger.info("############secret_rep: #{secret_rep}")
if secret_rep&.repo_name
secretGitUrl = repo_url secret_rep.repo_path
secretGitUrl = repo_ip_url secret_rep.repo_path
br_params.merge!({secretGitUrl: Base64.urlsafe_encode64(secretGitUrl), secretDir: secret_rep.secret_dir_path})
logger.info("#######br_params:#{br_params}")
end

@ -415,6 +415,20 @@ class SubjectsController < ApplicationController
order by ue_count desc limit 10")
end
# 预约报名
def appointment
tip_exception("还存在未结束的课堂") unless @subject.max_course_end_date.nil? || @subject.max_course_end_date < Date.today
tip_exception("无需重复报名") if @subject.subject_appointments.exists?(user_id: current_user.id)
ActiveRecord::Base.transaction do
@subject.subject_appointments << SubjectAppointment.new(user_id: current_user.id)
@subject.increment!(:participant_count)
if @subject.participant_count == @subject.student_count
@subject.start_course_notify
end
normal_status("预约成功")
end
end
private
def subject_params
tip_exception("实训路径名称不能为空") if params[:name].blank?

@ -384,4 +384,8 @@ module TidingDecorator
def public_course_start_content
I18n.t(locale_format) % [belong_container&.name, belong_container&.start_date&.strftime("%Y-%m-%d")]
end
def subject_start_course_content
I18n.t(locale_format) % belong_container&.name
end
end

@ -18,6 +18,10 @@ class ApplyUserAuthentication < ApplicationRecord
nil
end
def revoke!
update!(status: 3)
end
private
def send_tiding

@ -1,6 +1,6 @@
class StudentWorksScore < ApplicationRecord
#appeal_status: 0正常1申诉中2撤销申诉3申诉成功4申诉被拒绝5申诉失效
belongs_to :student_work
belongs_to :student_work
belongs_to :user
has_many :journals_for_messages, -> { order('created_on desc') }, as: :jour, dependent: :destroy
has_one :student_works_scores_appeal, dependent: :destroy

@ -13,6 +13,8 @@ class Subject < ApplicationRecord
has_many :stage_shixuns, dependent: :destroy
has_many :shixuns, through: :stage_shixuns
has_many :subject_appointments, dependent: :destroy
has_many :subject_members, ->{ order("subject_members.position asc")}, dependent: :destroy
has_many :users, through: :subject_members
has_many :tidings, as: :container, dependent: :destroy
@ -44,6 +46,10 @@ class Subject < ApplicationRecord
courses.where("start_date <= '#{Date.today}' and end_date >= '#{Date.today}'").count > 0
end
def has_participate?
subject_appointments.exists?(user_id: User.current.id)
end
# 挑战过路径的成员数(金课统计去重后的报名人数)
def member_count
excellent ? CourseMember.where(role: 4, course_id: courses.pluck(:id)).pluck(:user_id).length : shixuns.pluck(:myshixuns_count).sum
@ -109,4 +115,10 @@ class Subject < ApplicationRecord
def learning? user_id
Myshixun.where(user_id: user_id, shixun_id: shixuns).exists?
end
def start_course_notify
Tiding.create(user_id: user_id, trigger_user_id: 0, container_id: id,
container_type: 'SubjectStartCourse', belong_container_id: id,
belong_container_type: 'Subject', tiding_type: 'System')
end
end

@ -0,0 +1,4 @@
class SubjectAppointment < ApplicationRecord
belongs_to :subject
belongs_to :user
end

@ -346,7 +346,7 @@ class User < ApplicationRecord
elsif business?
Course::BUSINESS
else
role = course.course_members.find_by(user_id: id, is_active: 1)&.role
role = course&.course_members&.find_by(user_id: id, is_active: 1)&.role
case role
when nil then Course::NORMAL
when 'CREATOR' then Course::CREATOR

@ -0,0 +1,26 @@
class Admins::IdentityAuths::RevokeApplyService < ApplicationService
attr_reader :apply, :user
def initialize(apply)
@apply = apply
@user = apply.user
end
def call
ActiveRecord::Base.transaction do
apply.revoke!
user.update!(authentication: false)
deal_tiding!
end
end
private
def deal_tiding!
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
container_id: apply.id, container_type: 'CancelUserAuthentication',
belong_container_id: apply.user_id, belong_container_type: 'User',
status: 1, tiding_type: 'System')
end
end

@ -0,0 +1,26 @@
class Admins::ProfessionalAuths::RevokeApplyService < ApplicationService
attr_reader :apply, :user
def initialize(apply)
@apply = apply
@user = apply.user
end
def call
ActiveRecord::Base.transaction do
apply.revoke!
user.update!(professional_certification: false)
deal_tiding!
end
end
private
def deal_tiding!
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
container_id: apply.id, container_type: 'CancelUserProCertification',
belong_container_id: apply.user_id, belong_container_type: 'User',
status: 1, tiding_type: 'System')
end
end

@ -25,6 +25,10 @@
<% end %>
</div>
<div class="batch-action-container">
<%= javascript_void_link '批量同意', class: 'btn btn-outline-primary btn-sm batch-agree-btn' %>
</div>
<div class="box identity-authentication-list-container">
<%= render(partial: 'admins/identity_authentications/shared/list', locals: { applies: @applies }) %>
</div>

@ -3,6 +3,12 @@
<table class="table table-hover text-center identity-authentication-list-table">
<thead class="thead-light">
<tr>
<% unless is_processed %>
<th width="4%">
<%= check_box_tag('all-check', 1, false, id: nil, class: 'batch-all-check-box',
data: { toggle: 'tooltip', title: '全选' }) %>
</th>
<% end %>
<th width="8%">头像</th>
<th width="10%">姓名</th>
<th width="14%">身份证号</th>
@ -14,12 +20,14 @@
<i class="fa fa-question-circle" data-toggle="tooltip" data-html="true" data-placement="top" title="审核完成后自动删除图片"></i>
</th>
<% end %>
<th width="16%">时间</th>
<% if is_processed %>
<th width="14%">拒绝原因</th>
<th width="10%">时间</th>
<th width="12%">拒绝原因</th>
<th width="8%">状态</th>
<th width="8%">操作</th>
<% else %>
<th width="20%">操作</th>
<th width="16%">时间</th>
<th width="16%">操作</th>
<% end %>
</tr>
</thead>
@ -28,6 +36,9 @@
<% applies.each do |apply| %>
<% user = apply.user %>
<tr class="identity-authentication-item identity-authentication-<%= apply.id %>">
<% unless is_processed %>
<td><%= check_box_tag('ids[]', apply.id, false, id: nil, class: 'batch-check-box') %></td>
<% end %>
<td>
<%= link_to "/users/#{user.login}", class: 'identity-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
@ -53,6 +64,11 @@
<% if is_processed %>
<td class="text-secondary"><%= overflow_hidden_span apply.remarks, width: 140 %></td>
<td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
<td>
<% if apply.status == 1 %>
<%= agree_link '撤销', revoke_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}"), 'data-confirm': '是否确认撤销认证??' %>
<% end %>
</td>
<% else %>
<td class="action-container">
<%= agree_link '同意', agree_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %>

@ -25,6 +25,10 @@
<% end %>
</div>
<div class="batch-action-container">
<%= javascript_void_link '批量同意', class: 'btn btn-outline-primary btn-sm batch-agree-btn' %>
</div>
<div class="box professional-authentication-list-container">
<%= render(partial: 'admins/professional_authentications/shared/list', locals: { applies: @applies }) %>
</div>

@ -3,12 +3,18 @@
<table class="table table-hover text-center professional-authentication-list-table">
<thead class="thead-light">
<tr>
<% unless is_processed %>
<th width="4%">
<%= check_box_tag('all-check', 1, false, id: nil, class: 'batch-all-check-box',
data: { toggle: 'tooltip', title: '全选' }) %>
</th>
<% end %>
<th width="8%">头像</th>
<th width="14%">姓名</th>
<th width="28%">学校/单位</th>
<th width="20%">学校/单位</th>
<th width="12%">职称</th>
<% unless is_processed %>
<th width="10%">
<th width="14%">
照片
<i class="fa fa-question-circle" data-toggle="tooltip" data-html="true" data-placement="top" title="审核完成后自动删除图片"></i>
</th>
@ -17,8 +23,9 @@
<% if is_processed %>
<th width="14%">拒绝原因</th>
<th width="8%">状态</th>
<th width="8%">操作</th>
<% else %>
<th width="18%">操作</th>
<th width="22%">操作</th>
<% end %>
</tr>
</thead>
@ -27,6 +34,9 @@
<% applies.each do |apply| %>
<% user = apply.user %>
<tr class="professional-authentication-item professional-authentication-<%= apply.id %>">
<% unless is_processed %>
<td><%= check_box_tag('ids[]', apply.id, false, id: nil, class: 'batch-check-box') %></td>
<% end %>
<td>
<%= link_to "/users/#{user.login}", class: 'professional-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
@ -51,6 +61,11 @@
<% if is_processed %>
<td class="text-secondary"><%= overflow_hidden_span apply.remarks, width: 140 %></td>
<td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
<td>
<% if apply.status == 1 %>
<%= agree_link '撤销', revoke_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '是否确认撤销认证??' %>
<% end %>
</td>
<% else %>
<td class="action-container">
<%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?', 'data-disable-with': "提交中..." %>

@ -9,13 +9,13 @@ wb = xlsx_package.workbook
wb.styles do |style|
title_style = style.add_style(sz: 16, height: 20, b: true)
ec_year_style = style.add_style(sz: 10, height: 14)
label_style = style.add_style(sz: 11, b: true, bg_color: '90EE90', alignment: { horizontal: :center }, border: { style: :thin, color: '000000' })
label_style = style.add_style(sz: 11, b: true, bg_color: '90EE90', alignment: { horizontal: :center, vertical: :center }, border: { style: :thin, color: '000000' })
content_style = style.add_style(sz: 11, height: 16, border: { style: :thin, color: '000000' })
tip_style = style.add_style(sz: 11, height: 16, color: 'FFA07A')
tip_style = style.add_style(sz: 11, height: 16, color: Axlsx::Color.new(rgb: 'FFFFA07A'))
wb.add_worksheet(:name => '课程体系对毕业要求的支撑') do |sheet|
sheet.add_row ['课程体系VS毕业要求'], style: title_style
sheet.merge_cells wb.rows.first.cells[(1..(3 + max_support_length - 1))]
sheet.merge_cells sheet.rows.first.cells[(1..(3 + max_support_length - 1))]
sheet.add_row []
@ -25,8 +25,8 @@ wb.styles do |style|
sheet.add_row ['注:有对应关系的课程名称下方为其权重系数,一个指标点的权重系数之和必须等于1'], style: tip_style
sheet.add_row ['注:“★” 表示关联度高']
sheet.merge_cells wb.rows[5].cells[(1..(3 + max_support_length - 1))]
sheet.merge_cells wb.rows[6].cells[(1..(3 + max_support_length - 1))]
sheet.merge_cells sheet.rows[5].cells[(1..(3 + max_support_length - 1))]
sheet.merge_cells sheet.rows[6].cells[(1..(3 + max_support_length - 1))]
sheet.add_row []
@ -34,9 +34,9 @@ wb.styles do |style|
data[last_column_index] = '课程数量'
sheet.add_row data, style: label_style
course_columns = max_support_length.times.map { |i| "课程#{i + 1}" }
sheet.add_row %w('一级 二级') + course_columns + ['∑目标值'], style: label_style
sheet.add_row %w(一级 二级) + course_columns + ['∑目标值'], style: label_style
sheet.merge_cells("A9:B9")
sheet.merge_cells wb.rows[8].cells[(3..(3 + max_support_length - 1))]
# sheet.merge_cells sheet.rows[8].cells[(3..(3 + max_support_length - 1))]
current_row = 11
graduation_subitems.group_by(&:ec_graduation_requirement).each do |requirement, items|
@ -61,11 +61,11 @@ wb.styles do |style|
sheet.add_row course_data, style: styles
sheet.add_row weight_data, style: styles
sheet.merge_cells("B#{current_row - 1}:B#{current_row}")
sheet.merge_cells("B#{current_row}:B#{current_row + 1}")
current_row += 2
end
sheet.merge_cells("A#{start_row - 1}:B#{current_row - 1}")
sheet.merge_cells("A#{start_row}:A#{current_row - 1}")
end
end
end

@ -9,8 +9,10 @@ json.results do
# 去除开头标点符号
reg = /^[,。?:;‘’!“”—……、]/
highlights[:description]&.first&.sub!(reg, '')
highlights[:content]&.first&.sub!(reg, '')
# 附件的替换
atta_reg = /!\[\]\(\/api\/attachments\/\d+\)/
highlights[:description]&.first&.sub!(reg, '').sub!(atta_reg, '')
highlights[:content]&.first&.sub!(reg, '').sub!(atta_reg, '')
json.content highlights
end

@ -7,11 +7,13 @@ json.shixun_list do
# 去除开头标点符号
reg = /^[,。?:;‘’!“”—……、]/
highlights[:description]&.first&.sub!(reg, '')
highlights[:content]&.first&.sub!(reg, '')
# 附件的替换
atta_reg = /!\[\]\(\/api\/attachments\/\d+\)/
highlights[:description]&.first&.sub!(reg, '')&.sub!(atta_reg, '')
highlights[:content]&.first&.sub!(reg, '')&.sub!(atta_reg, '')
json.title highlights.delete(:name)&.join('...') || obj.searchable_title
json.description highlights[:description]&.join('...') || Util.extract_content(obj.description)[0..300]
json.description highlights[:description]&.join('...') || Util.extract_content(obj.description)[0..300]&.sub!(atta_reg, '')
json.content highlights
json.level level_to_s(obj.trainee)

@ -24,4 +24,10 @@ if @subject.excellent
json.course_identity @user.course_identity(course)
json.course_status subject_course_status course
end
if @subject.max_course_end_date.nil? || @subject.max_course_end_date < Date.today
json.student_count @subject.student_count
json.participant_count @subject.participant_count
json.has_participate @subject.has_participate?
end
end

@ -10,7 +10,7 @@
"2_1_end": "你提交的职业认证申请,审核已通过"
"2_2_end": "你提交的职业认证申请,审核未通过<br/><span>原因:%{reason}</span>"
CancelUserAuthentication_end: "取消了你的实名认证:%s %s"
CancelUserProCertification_end: "取消了你的实名认证:%s %s"
CancelUserProCertification_end: "取消了你的职业认证:%s %s"
JoinCourse:
"9_end": "申请加入课堂:%s教师"
"7_end": "申请加入课堂:%s助教"
@ -227,3 +227,4 @@
1_end: "你提交的发布视频申请:%s审核已通过"
2_end: "你提交的发布视频申请:%s审核未通过<br/><span>原因:%{reason}</span>"
PublicCourseStart_end: "你报名参与的开放课程:%s将于%s正式开课"
SubjectStartCourse_end: "您创建的开放课程:%s 已达到开课人数要求。您可以在24小时内自主开设新一期课程。如果超过24小时未开课平台将自动开课并复制您上一期的课程内容。"

@ -284,6 +284,7 @@ Rails.application.routes.draw do
post :up_member_position
post :down_member_position
get :right_banner
post :appointment
end
collection do
@ -879,12 +880,22 @@ Rails.application.routes.draw do
member do
post :agree
post :refuse
post :revoke
end
collection do
post :batch_agree
end
end
resources :professional_authentications, only: [:index] do
member do
post :agree
post :refuse
post :revoke
end
collection do
post :batch_agree
end
end
resources :shixun_authorizations, only: [:index] do

@ -0,0 +1,6 @@
class AddCourseMemberToSubjects < ActiveRecord::Migration[5.2]
def change
add_column :subjects, :student_count, :integer, :default => 0
add_column :subjects, :participant_count, :integer, :default => 0
end
end

@ -0,0 +1,10 @@
class CreateSubjectAppointments < ActiveRecord::Migration[5.2]
def change
create_table :subject_appointments do |t|
t.references :subject, index: true
t.references :user, index: true
t.timestamps
end
end
end

File diff suppressed because one or more lines are too long

@ -65,8 +65,8 @@
"<label>" + imageLang.alt + "</label>" +
"<input type=\"text\" value=\"" + selection + "\" data-alt />" +
"<br/>" +
"<label>" + imageLang.link + "</label>" +
"<input type=\"text\" value=\"http://\" data-link />" +
"<label class=\"image-link\">" + imageLang.link + "</label>" +
"<input class=\"image-link\" type=\"text\" value=\"http://\" data-link />" +
"<br/>" +
( (settings.imageUpload) ? "</form>" : "</div>");

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@icedesign/base": "^0.2.8",
"@icedesign/base": "^0.2.5",
"@novnc/novnc": "^1.1.0",
"antd": "^3.23.2",
"array-flatten": "^2.1.2",

@ -3048,7 +3048,7 @@ a.singlepublishtwo{
/*工程认证*/
/*首页*/
.authMainImg{width: 100%;height: 240px;background:url("/images/educoder/auth/banner1.jpg") no-repeat top center;background-size: 100% 100%;justify-content: center;align-items: center;display: -webkit-flex;}
.ListTableLine>p,.ListTableLine>.ListTableTitle{padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;}
.ListTableLine>p,.ListTableLine>.ListTableTitle{margin-bottom: 0px;padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;}
.ListTableLine>p span,.ListTableTitle span{float: left;color: #666;box-sizing: border-box}
.ListTableLine li{min-height: 48px;padding: 10px 0px;box-sizing: border-box;margin:0px 30px;border-bottom: 1px solid #eaeaea;}
.ListTableLine li>span{float: left;box-sizing: border-box;}

@ -72,6 +72,13 @@ html, body {
/* 某些情况下被cm盖住了 */
z-index: 99;
}
/* 图片点击放大的场景,隐藏图片链接 */
.editormd-image-click-expand .editormd-image-dialog {
height: 234px !important;
}
.editormd-image-click-expand .editormd-image-dialog .image-link {
display: none;
}
/* 解决鼠标框选时,左边第一列没高亮的问题 */
.CodeMirror .CodeMirror-lines pre.CodeMirror-line, .CodeMirror .CodeMirror-lines pre.CodeMirror-line-like {
padding: 0 12px ;

@ -2,7 +2,7 @@ import React,{Component} from "React";
import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal, Table, Divider, Tag,DatePicker,Radio,Tooltip,Spin, Pagination} from "antd";
import {Link} from 'react-router-dom';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import { WordsBtn, ConditionToolTip, queryString,getImageUrl, on, off} from 'educoder';
import { WordsBtn, ConditionToolTip, queryString,getImageUrl, on, off, NoneData} from 'educoder';
import axios from 'axios';
import Modals from '../../modals/Modals';
import CoursesListType from '../coursesPublic/CoursesListType';
@ -817,10 +817,8 @@ class CommonWorkList extends Component{
<Spin size="large" spinning={this.state.isSpin}>
<div id="forum_list" className="forum_table">
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
<NoneData></NoneData>
</div>
</div>
</Spin>

@ -86,7 +86,7 @@ class WorkDetailPageHeader extends Component{
background: #fff;
}
.workDetailPageHeader .summaryname {
line-height:30px
line-height:28px
}
`}</style>
<CBreadcrumb items={[

@ -250,7 +250,7 @@ class CommonReply extends Component{
}
`}</style>
<MemoDetailMDEditor ref="editor" memo={memo} usingMockInput={true} placeholder="说点什么"
height={160} showError={true}
height={160} showError={true} imageExpand={true}
replyComment={this.replyComment}
commentsLength={comments ? comments.length : 0}
></MemoDetailMDEditor>

@ -80,7 +80,10 @@ class AddStudentModal extends Component{
}
setVisible = (visible) => {
if (visible) {
this.setState({school_name: this.props.user.user_school},()=>{
this.setState({
school_name: this.props.user.user_school,
name: undefined
},()=>{
this.fetchMemberList();
})
this.fetchOptions()
@ -88,7 +91,7 @@ class AddStudentModal extends Component{
this.refs.modalWrapper.setVisible(visible)
if (visible == false) {
this.setState({
checkBoxValues: []
checkBoxValues: [],
})
}
}

@ -349,7 +349,7 @@ class ShixunWorkReport extends Component {
<span className={"color-grey-9"}> {data&&data.course_name}</span>
</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<a className="btn colorgrey fl hovercolorblue " to={"/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+category_id}>
<a className="btn colorgrey fl hovercolorblue " href={"/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+category_id}>
<span className={"color-grey-9"}>{data===undefined?"":data.category===null?"":data.category.category_name}</span>
</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>

@ -579,7 +579,7 @@ class CourseSupports extends Component {
let ismidbox={width:123.82*max_support_count+"px",margin:'0px 0px'};
console.log(this.props.year&&this.props.year.can_manager)
// console.log(this.props.year&&this.props.year.can_manager)
return (
<div className="newMain clearfix">
<Modal
@ -623,8 +623,8 @@ class CourseSupports extends Component {
</div>
<div className="padding20-30" id="training_objective_contents">
<span className="fl SystemParameters" >毕业要求指标点<a href={data.subitems_url}><span className="Systemnum">{data.count}</span></a></span>
<span className="fl ml20 SystemParameters">课程体系<a href={data.course_url}><span className="Systemnum">{data.course_count}</span></a></span>
<span className="fl SystemParameters" >毕业要求指标点<Link to={`/ecs/major_schools/${this.props.match.params.major_school_id}/years/${this.props.match.params.ec_year_id}/graduation_requirement`}><span className="Systemnum">{data.count}</span></Link></span>
<span className="fl ml20 SystemParameters">课程体系<Link to={`/ecs/major_schools/${this.props.match.params.major_school_id}/years/${this.props.match.params.ec_year_id}/courses/ec_course_support_setting/1`}><span className="Systemnum">{data.course_count}</span></Link></span>
</div>
</div>
@ -633,7 +633,7 @@ class CourseSupports extends Component {
<p className="clearfix" style={toptiebox}>
<span className="color-666 finishtarget">毕业要求指标点</span>
{list(max_support_count<5||max_support_count===undefined?5:max_support_count)}
{data.graduation_subitems===undefined?"":list(max_support_count<5||max_support_count===undefined?5:max_support_count)}
<span className="column-1 operationright color-666"
style={{
paddingLeft: '28px'

@ -130,7 +130,7 @@ class MemoDetailMDEditor extends Component {
}
}
render() {
const { match, history, memo, placeholder, className } = this.props
const { match, history, memo, placeholder, className, imageExpand } = this.props
const { isInited, errorMsg } = this.state
if (!memo) {
return <div></div>
@ -185,7 +185,8 @@ class MemoDetailMDEditor extends Component {
`
} */}
</style>
<div nhname={`new_message_${memo.id}`} className={`commentInput commentInputs ${className}`}
<div nhname={`new_message_${memo.id}`}
className={`commentInput commentInputs ${className} ${imageExpand && 'editormd-image-click-expand' }`}
style={{ padding: '30px',boxSizing:"border-box", display: isInited ? '' : 'none', paddingBottom: '40px' }} >
<div id="memo_comment_editorMd" className="editorMD" style={{ marginBottom: '0px'
, border: errorMsg ? '1px solid red' : '1px solid #ddd'}}>

@ -109,7 +109,15 @@ class ShixunsHome extends Component {
homedatalistreps.push(homedatalist.reps[homedatalist.reps.length-i-1])
}
}
const MyRate = ({ defaultValue, ...rest }) => {
let myValue = defaultValue;
console.log(myValue-Math.floor(myValue))
// if (myValue < Math.ceil(myValue)) {
// myValue = Math.floor(myValue) + 0.5;
// }
return <Rating {...rest} value={myValue} />;
};
return (
<div className="newMain clearfix backFAFAFA shixunsHome">
{this.state.updata===undefined?"":<UpgradeModals
@ -343,7 +351,7 @@ class ShixunsHome extends Component {
<p className="clearfix mt8 ml-3">
<span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
<Rating key={key} value={item.score_info===null?5:item.score_info} disabled allowHalf />
<MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/>
</span>
<span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span>
</p>

@ -1,47 +1,56 @@
import React, { Component } from 'react';
import {getImageUrl} from 'educoder';
import { Spin, Icon , Modal} from 'antd';
class Modals extends Component {
constructor(props) {
super(props);
this.state = {
funmodalsType:false,
istype:false
}
}
render() {
const antIcons = <Icon type="loading" style={{ fontSize: 24 }} spin />
return(
<Modal
className={this.props.className}
keyboard={false}
title="提示"
visible={this.props.modalsType===undefined?false:this.props.modalsType}
closable={false}
footer={null}
destroyOnClose={true}
centered={true}
width="530px"
>
<Spin indicator={antIcons} spinning={this.props.antIcon===undefined?false:this.props.antIcon} >
<div className="task-popup-content">
<p className="task-popup-text-center font-16">{this.props.modalsTopval}</p>
<p className="task-popup-text-center font-16 mt5">{this.props.modalsBottomval}</p>
{this.props.loadtype===true?
<div className="clearfix edu-txt-center mt20">
<a className="task-btn task-btn-orange pop_close" onClick={this.props.modalSave}>知道啦</a>
</div>
:
<div className="clearfix mt30 edu-txt-center">
<a className="task-btn mr30" onClick={this.props.modalCancel}>取消</a>
<a className="task-btn task-btn-orange" onClick={this.props.modalSave}>{this.props.okText || '确定'}</a>
</div>
}
</div>
</Spin>
</Modal>
)
}
}
import React, { Component } from 'react';
import {getImageUrl} from 'educoder';
import { Spin, Icon , Modal} from 'antd';
class Modals extends Component {
constructor(props) {
super(props);
this.state = {
funmodalsType:false,
istype:false
}
}
render() {
const antIcons = <Icon type="loading" style={{ fontSize: 24 }} spin />
return(
<Modal
className={this.props.className}
keyboard={false}
title="提示"
visible={this.props.modalsType===undefined?false:this.props.modalsType}
closable={false}
footer={null}
destroyOnClose={true}
centered={true}
width="530px"
>
{this.props.modalsType===true?<style>
{
`
body{
overflow: hidden !important;
}
`
}
</style>:""}
<Spin indicator={antIcons} spinning={this.props.antIcon===undefined?false:this.props.antIcon} >
<div className="task-popup-content">
<p className="task-popup-text-center font-16">{this.props.modalsTopval}</p>
<p className="task-popup-text-center font-16 mt5">{this.props.modalsBottomval}</p>
{this.props.loadtype===true?
<div className="clearfix edu-txt-center mt20">
<a className="task-btn task-btn-orange pop_close" onClick={this.props.modalSave}>知道啦</a>
</div>
:
<div className="clearfix mt30 edu-txt-center">
<a className="task-btn mr30" onClick={this.props.modalCancel}>取消</a>
<a className="task-btn task-btn-orange" onClick={this.props.modalSave}>{this.props.okText || '确定'}</a>
</div>
}
</div>
</Spin>
</Modal>
)
}
}
export default Modals;

@ -40,8 +40,9 @@ class CodeRepositoryView extends Component {
constructor(props) {
super(props);
this.treeExpanded = false;
this.state = {
autoExpandParent: true,
autoExpandParent: false,
expandedKeys: [],
addtionalSSHArray: [],
@ -52,24 +53,28 @@ class CodeRepositoryView extends Component {
const { game, challenge, hide_code, tabIndex, } = this.props
if ( // 初始化 或者 game切换
challenge.path && challenge.path.length && this.state.expandedKeys.length === 0 ||
!this.treeExpanded && challenge.path && challenge.path.length && this.state.expandedKeys.length === 0 ||
game && (!prevProps.game
|| prevProps.game.identifier !== this.props.game.identifier) ) {
const _path = challenge.multiPath ? challenge.path[0] : challenge.path;
let _ar = [];
const expandedKeys = [];
if (_path) {
_ar = _path.split('/')
_ar.length = _ar.length - 1
_ar.forEach( (item, index) => {
expandedKeys.push( index === 0 ? item : expandedKeys[index - 1] + '/' + item)
if (!this.treeExpanded) {
this.treeExpanded = true
const _path = challenge.multiPath ? challenge.path[0] : challenge.path;
let _ar = [];
const expandedKeys = [];
if (_path) {
_ar = _path.split('/')
_ar.length = _ar.length - 1
_ar.forEach( (item, index) => {
expandedKeys.push( index === 0 ? item : expandedKeys[index - 1] + '/' + item)
})
}
expandedKeys.length = 1 // 没办法做到多级初始化,而且会引起点击其他子目录,加载当前文件目录的问题
// 初始化时无法展开到根节点 https://github.com/fis-components/rc-tree/issues/3
expandedKeys.length && this.setState({
expandedKeys,
})
}
expandedKeys.length = 1 // 没办法做到多级初始化
// 初始化时无法展开到根节点 https://github.com/fis-components/rc-tree/issues/3
expandedKeys.length && this.setState({
expandedKeys,
})
if (game && (!prevProps.game
|| prevProps.game.identifier !== this.props.game.identifier)) {

@ -191,6 +191,10 @@ class CodeRepositoryViewContainer extends Component {
// withCredentials: true,
})
.then((response) => {
// if (!response) {
// resolve && resolve();
// return;
// }
const repoFilesData = this.map2OldData(response.data.trees)
if (!this.state.fileTreeData || this.state.fileTreeData.length === 0) { // 还没树节点,没加载过

@ -495,7 +495,7 @@ class DetailCards extends Component{
:
<li className={showparagraph===false?"none":"fr status_li"}>
{
showparagraphkey===key&&showparagraphindex===index?<div>
showparagraphkey===key&&showparagraphindex===index?this.props.detailInfoList&&this.props.detailInfoList.allow_statistics===false&&this.props.MenuItemsindextype===2?"":<div>
<Link to={'/shixuns/'+line.identifier+'/challenges'} className="mr30 color-blue_4C shixun_detail pointer fl" target="_blank">查看详情</Link>
{line.shixun_status==="暂未公开"?"":<a onClick={()=>this.startgameid(line.identifier)} className="btn_auto user_bluebg_btn fl" id="shixun_operation" >开始实战</a>}
</div>:""

@ -26,7 +26,9 @@ class DetailTop extends Component{
MenuItemskey:1,
courseslist:[],
Pathcourseid:undefined,
OpenCourseTypes:false
OpenCourseTypes:false,
putappointmenttype:false,
getappointmenttype:false
}
}
componentDidMount(){
@ -74,7 +76,9 @@ class DetailTop extends Component{
})
}
this.props.getMenuItemsindex(keys,courseslist[0].course_status.status)
}
this.setState({
courseslist:courseslist,
MenuItemskey:keys,
@ -156,7 +160,8 @@ class DetailTop extends Component{
Modalstype:false,
Modalsbottomval:'',
loadtype:false,
deletepathtype:false
deletepathtype:false,
putappointmenttype:false
})
}
@ -219,6 +224,8 @@ class DetailTop extends Component{
)
}
})
this.props.getMenuItemsindex(keys,courseslist[0].course_status.status)
this.setState({
MenuItemskey:keys,
courseslist:courseslist,
@ -245,6 +252,20 @@ class DetailTop extends Component{
pathcousestypeid:typeid
})
}
putappointment=()=>{
this.setState({
Modalstype:true,
Modalstopval:"是否确认立即预约?",
Modalsbottomval:"",
cardsModalcancel:()=>this.cardsModalcancel(),
putappointmenttype:true,
loadtype:false
})
}
ysljoinmodalCancel=()=>{
this.setState({
yslJointhe:false
@ -267,9 +288,34 @@ class DetailTop extends Component{
OpenCourseTypes:false
})
}
getappointment=()=>{
let pathid=this.props.match.params.pathId;
let url=`/paths/${pathid}/appointment.json`
axios.post(url).then((response) => {
if (response.status === 200) {
if(response.data.status===0){
this.setState({
getappointmenttype:true
})
this.cardsModalcancel()
// this.props.getlistdatas()
this.props.showNotification(response.data.message)
}else{
this.props.showNotification(response.data.message)
}
}
}).catch((error) => {
console.log(error)
this.cardsModalcancel()
})
}
render(){
let{detailInfoList}=this.props;
let{Modalstype,Modalstopval,cardsModalcancel,OpenCourseTypes,Modalsbottomval,cardsModalsavetype,loadtype}=this.state;
let{Modalstype,Modalstopval,cardsModalcancel,putappointmenttype,Modalsbottomval,cardsModalsavetype,loadtype,getappointmenttype}=this.state;
const radioStyle = {
display: 'block',
height: '30px',
@ -292,6 +338,9 @@ class DetailTop extends Component{
let applypath=this.props.detailInfoList&&this.props.detailInfoList.participant_count!=undefined&&this.props.detailInfoList&&this.props.detailInfoList.allow_statistics===false;
// console.log(this.props.courses)
return(
<div className={this.props.courses===undefined||this.props.courses.length===0?"subhead":"subhead mb70"}>
@ -300,7 +349,7 @@ class DetailTop extends Component{
modalsTopval={Modalstopval}
modalsBottomval={Modalsbottomval}
modalCancel={cardsModalcancel}
modalSave={cardsModalsavetype===true?this.reovkissuePaths:this.cardsModalsave}
modalSave={cardsModalsavetype===true?()=>this.reovkissuePaths():putappointmenttype===true?()=>this.getappointment():()=>this.cardsModalsave()}
loadtype={loadtype}
>
</Modals>
@ -428,12 +477,12 @@ class DetailTop extends Component{
</div>
{this.props.courses===undefined||this.props.courses.length===0?"":<div className="userNavs mt20">
{this.props.courses===undefined||this.props.courses.length===0?"":<div className="userNavs mt20" style={applypath===false?{}:this.state.MenuItemskey===this.props.courses.length?{height:'158px'}:{}}>
<li className={"fl pd4020"}>
<style>
{
`
<li className={"fl pd4020"}>
<style>
{
`
.anticon-down{
font-size:14px !important;
transform:none !important;
@ -451,34 +500,34 @@ class DetailTop extends Component{
color:#CDCDCD;
}
`
}
</style>
{this.props.courses===undefined?"":this.state.courseslist.map((item,key)=>{
if(item.course_identity<4){
return(
<Tooltip placement="bottom" title={"编辑课堂"} key={key}>
<a href={`/courses/${item.course_id}/newgolds/settings`} target={"_blank"}>
<i className="iconfont icon-bianji1 newbianji1"></i>
</a>
</Tooltip>
)}})
}
}
</style>
<Dropdown
overlay={menu}
onVisibleChange={this.onVisibleChanges}
>
<a className={"alist"}>
<span className={"color-orange"}> {this.state.MenuItemskey} </span>次开课 <Icon className="aIcons" type={!this.state.onVisibleChangestype?"down":"up"} />
</a>
</Dropdown>
</li>
<style>
{
`
{this.props.courses===undefined?"":this.state.courseslist.map((item,key)=>{
if(item.course_identity<4){
return(
<Tooltip placement="bottom" title={"编辑课堂"} key={key}>
<a href={`/courses/${item.course_id}/newgolds/settings`} target={"_blank"}>
<i className="iconfont icon-bianji1 newbianji1"></i>
</a>
</Tooltip>
)}})
}
<Dropdown
overlay={menu}
onVisibleChange={this.onVisibleChanges}
>
<a className={"alist"}>
<span className={"color-orange"}> {this.state.MenuItemskey} </span>次开课 <Icon className="aIcons" type={!this.state.onVisibleChangestype?"down":"up"} />
</a>
</Dropdown>
</li>
<style>
{
`
.pdt28{
padding-top: 28px;
}
@ -494,12 +543,12 @@ class DetailTop extends Component{
font-size: 14px;
}
`
}
</style>
<li className={"ml20"}>
{this.state.courseslist.map((item,key)=>{
return(
<div className={"ant-breadcrumb pdt28"} key={key}>
}
</style>
<li className={"ml20"}>
{this.state.courseslist.map((item,key)=>{
return(
<div className={"ant-breadcrumb pdt28"} key={key}>
<span>
<div className="ant-breadcrumb-link fl mr23">
<div className={"pathtime"}>
@ -512,7 +561,7 @@ class DetailTop extends Component{
<div className="fl solidright"></div>
</span>
<span>
<span>
<div className="ant-breadcrumb-link fl mr23 ml23">
<div className={"pathtime"}>
结课时间
@ -524,7 +573,7 @@ class DetailTop extends Component{
<div className="fl solidright"></div>
</span>
<span>
<span>
<div className="ant-breadcrumb-link fl mr23 ml23">
<div className={"pathtime"}>
报名人数
@ -534,17 +583,17 @@ class DetailTop extends Component{
</div>
</div>
</span>
</div>
)
})
}
</div>
)
})
}
</li>
</li>
<li className={"fr mr25"}>
<style>
{
`
<li className={"fr mr25"}>
<style>
{
`
.user-colorgrey-9b{color:#9B9B9B}
.user-colorgrey-green{color:#7ED321}
.background191{
@ -565,40 +614,81 @@ class DetailTop extends Component{
.courseslistsa{
color:#fff !important;
}
.pathbtensbox{
width: 188px !important;
height: 46px !important;
background: rgba(76,172,255,1);
border-radius: 4px;
line-height: 46px !important;
}
.lineHeight0{
line-height: 0px;
}
.font153{
font-size: 14px;
font-weight: 400;
color: rgba(153,153,153,1);
line-height: 14px;
margin-left: 30px;
}
.absolutewidth{
position: absolute;
top: -21px;
right: 71px;
}
.relativewidth{
position: relative;
width: 100%;
}
`
}
</style>
{this.state.courseslist.map((item,key)=>{
}
</style>
{/*
height: 158px;
}*/}
{this.state.courseslist.map((item,key)=>{
return(
<div key={key}>
{/*{item.course_status.status===0?<div className="mr51 shixun_detail pointer fl user-colorgrey-green pathdefault">即将开课</div>:""}*/}
{item.course_status.status===1?<div className="mr51 shixun_detail pointer fl color-orange pathdefault">{item.course_status.time}</div>:""}
{item.course_status.status===2&&item.course_identity<6?<div className="mr51 shixun_detail pointer fl user-colorgrey-9b pathdefault">已结束</div>:""}
{item.course_status.status===0?
item.course_identity<5?<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens courseslistsa" href={item.first_category_url} target="_blank">
进入课堂
</a>:item.course_identity<6?<div className="fr user_default_btn background191 font-18 mt28 pathbtens pathdefault"></div>
:<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens" onClick={()=>this.JoinnowCourse(item.course_id)}>立即报名</a>:""}
{item.course_status.status===1?
item.course_identity<5?<a className="courseslistsa fr user_default_btn task-btn-orange font-18 mt28 pathbtens" href={item.first_category_url} target="_blank">
进入课堂
</a>:item.course_identity<6?<a className="courseslistsa fr user_default_btn task-btn-orange font-18 mt28 pathbtens" href={item.first_category_url} target="_blank">
立即学习
</a>:<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens" onClick={()=>this.JoinnowCourse(item.course_id,item.course_status.status)}></a>:""}
{item.course_status.status===2?
item.course_identity<6?<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens courseslistsa" href={item.first_category_url} target="_blank">
进入课堂
</a>:<div className="fr user_default_btn background191 font-18 mt28 pathbtens pathdefault"></div>:""}
</div>
)})}
</li>
{applypath===false?"":this.state.MenuItemskey===this.props.courses.length?<div className={"clear"}></div>:""}
{applypath===false?"":this.state.MenuItemskey===this.props.courses.length?<span className={"fl ml20 lineHeight0 relativewidth"}>
<span>当前预约报名人数<span className={"color-red mr5"}>{getappointmenttype===true?this.props.detailInfoList&&this.props.detailInfoList.participant_count+1:this.props.detailInfoList&&this.props.detailInfoList.participant_count}</span></span>
<span className={"font153"}>当预约报名人数达到 {this.props.detailInfoList&&this.props.detailInfoList.student_count} 人时即将开课</span>
{this.props.detailInfoList&&this.props.detailInfoList.has_participate===false?
getappointmenttype===true?<a className="fr user_default_btn background191 font-18 pathbtensbox absolutewidth">预约报名成功</a>:<a className="fr user_default_btn task-btn-orange font-18 pathbtensbox absolutewidth" onClick={()=>this.putappointment()}></a>:
<a className="fr user_default_btn background191 font-18 pathbtensbox absolutewidth">预约报名成功</a>}
</span>:""}
return(
<div key={key}>
{item.course_status.status===0?<div className="mr51 shixun_detail pointer fl user-colorgrey-green pathdefault">即将开课</div>:""}
{item.course_status.status===1?<div className="mr51 shixun_detail pointer fl color-orange pathdefault">{item.course_status.time}</div>:""}
{item.course_status.status===2&&item.course_identity<6?<div className="mr51 shixun_detail pointer fl user-colorgrey-9b pathdefault">已结束</div>:""}
{item.course_status.status===0?
item.course_identity<5?<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens courseslistsa" href={item.first_category_url} target="_blank">
进入课堂
</a>:item.course_identity<6?<div className="fr user_default_btn background191 font-18 mt28 pathbtens pathdefault"></div>
:<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens" onClick={()=>this.JoinnowCourse(item.course_id)}>立即报名</a>:""}
{item.course_status.status===1?
item.course_identity<5?<a className="courseslistsa fr user_default_btn task-btn-orange font-18 mt28 pathbtens" href={item.first_category_url} target="_blank">
进入课堂
</a>:item.course_identity<6?<a className="courseslistsa fr user_default_btn task-btn-orange font-18 mt28 pathbtens" href={item.first_category_url} target="_blank">
立即学习
</a>:<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens" onClick={()=>this.JoinnowCourse(item.course_id,item.course_status.status)}></a>:""}
{item.course_status.status===2?
item.course_identity<6?<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens courseslistsa" href={item.first_category_url} target="_blank">
进入课堂
</a>:<div className="fr user_default_btn background191 font-18 mt28 pathbtens pathdefault"></div>:""}
</div>
)})}
</li>
</div>}
</div>

@ -85,6 +85,8 @@ class PathDetailIndex extends Component{
items: getItems(10),
pathtopskey:1,
dataquerys:{},
MenuItemsindex:1,
MenuItemsindextype:2
}
this.onDragEnd = this.onDragEnd.bind(this);
@ -147,7 +149,10 @@ class PathDetailIndex extends Component{
}
componentDidMount(){
this.getlistdatas()
}
getlistdatas=()=>{
const query = this.props.location.search;
// const type = query.split('?chinaoocTimestamp=');
// console.log("Eduinforms12345");
@ -254,7 +259,13 @@ class PathDetailIndex extends Component{
console.log(error);
})
};
getMenuItemsindex=(key,status)=>{
this.setState({
MenuItemsindex:key,
MenuItemsindextype:status
})
}
getdatasindex=(key)=>{
// yslwebobject 后端需要的接口
let pathid=this.props.match.params.pathId;
@ -460,9 +471,13 @@ class PathDetailIndex extends Component{
members,
tags,
courses,
MenuItemsindex,
MenuItemsindextype
} = this.state
// console.log(MenuItemsindex)
// console.log(MenuItemsindextype===2&&detailInfoList&&detailInfoList.allow_statistics===false)
return(
<div className="newContainer">
<style>
@ -487,7 +502,7 @@ class PathDetailIndex extends Component{
>
</Modals>
<div className="newMain clearfix">
<DetailTop {...this.state} {...this.props} getdatasindex={(key)=>this.getdatasindex(key)}></DetailTop>
<DetailTop {...this.state} {...this.props} getdatasindex={(key)=>this.getdatasindex(key)} getMenuItemsindex={(key,status)=>this.getMenuItemsindex(key,status)} getlistdatas={()=>this.getlistdatas()}></DetailTop>
<div className="educontent clearfix mb80">
<div className="with65 fl">
<div className="produce-content mb10">

@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
import { Rating ,Progress} from "@icedesign/base";
import {Modal,Input,Radio,Pagination,message,Spin,Icon,Tooltip} from 'antd';
import {Modal,Input,Radio,Pagination,message,Spin,Icon,Tooltip,Rate} from 'antd';
import AccountProfile from"../user/AccountProfile";
@ -569,6 +569,15 @@ class TPMBanner extends Component {
};
const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;
const MyRate = ({ defaultValue, ...rest }) => {
let myValue = defaultValue;
console.log(myValue-Math.floor(myValue))
// if (myValue < Math.ceil(myValue)) {
// myValue = Math.floor(myValue) + 0.5;
// }
return <Rating {...rest} value={myValue} />;
};
return (
shixunsDetails===undefined?"":
@ -607,7 +616,22 @@ class TPMBanner extends Component {
</p>
<div className="clearfix mt50">
<ul className="fl color-grey-c pathInfo">
{/*<style>*/}
{/*{*/}
{/*`*/}
{/*.anticon-star{*/}
{/*font-size:14px;*/}
{/*}*/}
{/*.pathInfo{*/}
{/*margin-right:-5px;*/}
{/*}*/}
{/*.ant-rate{*/}
{/*color: #FFA800;*/}
{/*}*/}
{/*`*/}
{/*}*/}
{/*</style>*/}
<ul className="fl color-grey-c pathInfo" >
<li>
<span>学习人数</span>
<span className="mt10">{shixunsDetails.stu_num}</span>
@ -624,11 +648,11 @@ class TPMBanner extends Component {
</ul>
<div className="pr fl" id="commentsStar" onMouseOver={()=>this.showonMouseOver()} onMouseOut={()=>this.hideonMouseOut()}>
<div className={"color-grey-c mb7"} style={{color: "#Fff",textAlign: "center"}}>学员评分</div>
<div className={"color-grey-c ml15"} style={{color: "#Fff",textAlign: "center"}}>学员评分</div>
<div className="rateYo">
<Rating value={star_info[0]} disabled allowHalf/>
<MyRate allowHalf defaultValue={star_info[0]} disabled/>
</div>
<div id="ratePanel" className="showratePanel" style={{"width":"512px"}} onMouseOut={()=>this.hideonMouseOut()}>
<div id="ratePanel" className="showratePanel" style={{"width":"530px"}} onMouseOut={()=>this.hideonMouseOut()}>
<div className="pr">
<span className="rateTrangle"></span>
<div className="pr clearfix ratePanelContent" style={{height: '177px'}}>
@ -639,16 +663,16 @@ class TPMBanner extends Component {
<span className="displayblock">总评分</span>
<div className="rateYo">
{showradios === true ?
<Rating value={star_info[0]} allowHalf/>
<MyRate allowHalf defaultValue={star_info[0]} disabled/>
: ""}
</div>
</div>
</div>
<div className="fr width360">
<div className="fr">
<div className="clearfix">
<div className="rateYo fl mt3">
{showradios === true ?
<Rating value={5} disabled allowHalf/>
<MyRate allowHalf defaultValue={5} disabled/>
: ""}
</div>
<Progress percent={star_infos[1]} showInfo={false}></Progress>
@ -657,7 +681,7 @@ class TPMBanner extends Component {
<div className="clearfix">
<div className="rateYo fl mt3">
{showradios === true ?
<Rating value={4} disabled allowHalf/>
<MyRate allowHalf defaultValue={4} disabled/>
: ""}
</div>
<Progress percent={star_infos[2]} showInfo={false}></Progress>
@ -666,7 +690,7 @@ class TPMBanner extends Component {
<div className="clearfix">
<div className="rateYo fl mt3">
{showradios === true ?
<Rating value={3} disabled allowHalf/>
<MyRate allowHalf defaultValue={3} disabled/>
: ""}
</div>
<Progress percent={star_infos[3]} showInfo={false}></Progress>
@ -675,7 +699,7 @@ class TPMBanner extends Component {
<div className="clearfix">
<div className="rateYo fl mt3">
{showradios === true ?
<Rating value={2} disabled allowHalf/>
<MyRate allowHalf defaultValue={2} disabled/>
: ""}
</div>
<Progress percent={star_infos[4]} showInfo={false}></Progress>
@ -684,7 +708,7 @@ class TPMBanner extends Component {
<div className="clearfix">
<div className="rateYo fl mt3">
{showradios === true ?
<Rating value={1} disabled allowHalf/>
<MyRate allowHalf defaultValue={1} disabled/>
: ""}
</div>
<Progress percent={star_infos[5]} showInfo={false}></Progress>

@ -88,7 +88,15 @@ export default class TPMFork_listComponent extends Component {
let {shixuns, total_count, shixunsID, Forkvisible, Forkcurrent} = this.state;
const MyRate = ({ defaultValue, ...rest }) => {
let myValue = defaultValue;
console.log(myValue-Math.floor(myValue))
// if (myValue < Math.ceil(myValue)) {
// myValue = Math.floor(myValue) + 0.5;
// }
return <Rating {...rest} value={myValue} />;
};
return (
<React.Fragment>
<div className="educontent mb20">
@ -141,9 +149,9 @@ export default class TPMFork_listComponent extends Component {
</p>
<p className="clearfix mt8 ml-3">
<span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
<Rating key={key} value={item.score_info===null?5:item.score_info} disabled allowHalf />
</span>
<span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
<MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/>
</span>
<span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span>
</p>

@ -1,47 +1,47 @@
.tpmComment .-fit {
position: inherit;
}
.tpmComment .rc-pagination {
margin-left: auto;
margin-right: auto;
margin-top: 12px;
margin-bottom: 20px;
}
.tpmComment .paginationSection {
background: #FAFAFA;
}
.tpmComment .comment_item_cont.df.clearfix:nth-last-child(1) {
border-bottom: none;
}
/*.tpmComment .fl.edu-back-white {*/
/*min-height: 600px;*/
/*}*/
.user_watch_btn {
cursor: pointer;
}
/*md编辑器*/
.tpmComment .commentItemMDEditor a.task-btn {
background: #4cacff!important;
margin-right: 16px;
margin-top: 16px;
}
/* md编辑器 resizeBar*/
.tpmComment .commentItemMDEditor .editor__resize {
transform: translateX(-176%)
}
#ratePanel > div > div > div.fr div.rateYo.fl.mt3 {
height: 20px;
line-height: 20px;
cursor: default;
width: 90px;
}
.tpmComment .icon-jiangli {
/* margin-top: 2px; */
.tpmComment .-fit {
position: inherit;
}
.tpmComment .rc-pagination {
margin-left: auto;
margin-right: auto;
margin-top: 12px;
margin-bottom: 20px;
}
.tpmComment .paginationSection {
background: #FAFAFA;
}
.tpmComment .comment_item_cont.df.clearfix:nth-last-child(1) {
border-bottom: none;
}
/*.tpmComment .fl.edu-back-white {*/
/*min-height: 600px;*/
/*}*/
.user_watch_btn {
cursor: pointer;
}
/*md编辑器*/
.tpmComment .commentItemMDEditor a.task-btn {
background: #4cacff!important;
margin-right: 16px;
margin-top: 16px;
}
/* md编辑器 resizeBar*/
.tpmComment .commentItemMDEditor .editor__resize {
transform: translateX(-176%)
}
#ratePanel > div > div > div.fr div.rateYo.fl.mt3 {
height: 20px;
line-height: 20px;
cursor: default;
width: 110px;
}
.tpmComment .icon-jiangli {
/* margin-top: 2px; */
}

@ -317,14 +317,14 @@ export default class TPMMDEditor extends Component {
let {
showError
} = this.state;
let { mdID, className, noStorage } = this.props;
let { mdID, className, noStorage, imageExpand } = this.props;
let _style = {}
if (showError) {
_style.border = '1px solid red'
}
return (
<React.Fragment>
<div className={`df ${className}`} >
<div className={`df ${className} ${imageExpand && 'editormd-image-click-expand' }`} >
{/* padding10-20 */}
<div className="edu-back-greyf5 radius4" id={`mdEditor_${mdID}`} style={{..._style}}>
<textarea style={{display: 'none'}} id={`mdEditors_${mdID}`} name="content"></textarea>

@ -11,7 +11,7 @@ import { Rating ,Pagination} from "@icedesign/base";
import {getImageUrl,setImagesUrl, toPath} from 'educoder';
import { Spin,Icon,Tooltip } from 'antd';
import { Spin,Icon,Tooltip ,Rate} from 'antd';
import './shixunCss/shixunCard.css';
@ -46,6 +46,15 @@ class ShixunCard extends Component {
render() {
let {middleshixundata, pagination, typepvisible, pages, totalcount} = this.props;
const MyRate = ({ defaultValue, ...rest }) => {
let myValue = defaultValue;
console.log(myValue-Math.floor(myValue))
// if (myValue < Math.ceil(myValue)) {
// myValue = Math.floor(myValue) + 0.5;
// }
return <Rating {...rest} value={myValue} />;
};
return (
<div className="educontent mb80">
@ -69,10 +78,11 @@ class ShixunCard extends Component {
</div>
<div className="mt10 mb20 clearfix"
style={{display: middleshixundata === undefined || middleshixundata.length === 0 ? "none" : "block"}}>
// style={{display: middleshixundata === undefined || middleshixundata.length === 0 ? "none" : "block"}}
>
<div className="shixun_list_content">
<div className="square-list clearfix">
{ middleshixundata===undefined?" ":middleshixundata.map((item,key)=>{
{middleshixundata === undefined || middleshixundata.length === 0?" ":middleshixundata.map((item,key)=>{
return(
<div className="square-Item" key={key} id={item.id}>
<style>
@ -113,12 +123,27 @@ class ShixunCard extends Component {
</p>
{/*target="_blank"*/}
{/*<style>*/}
{/*{*/}
{/*`*/}
{/*.anticon-star{*/}
{/*font-size:16px;*/}
{/*}*/}
{/*.pathInfo{*/}
{/*margin-right:-5px;*/}
{/*}*/}
{/*.ant-rate{*/}
{/*color: #FFA800;*/}
{/*}*/}
{/*`*/}
{/*}*/}
{/*</style>*/}
<p className="clearfix mt8 ml-3">
<span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
<Rating key={key} value={item.score_info===null?5:item.score_info} disabled allowHalf />
{/*<Rate allowHalf value={item.score_info===null?5:item.score_info} disabled key={key} />*/}
<MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/>
</span>
<span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span>
<span className="fl ml25 font-12 color-grey-9 lineh-12 mt5">{item.score_info===null?"5分":item.score_info+"分"}</span>
</p>
<p className="clearfix mt8 font-12 color-grey-B4">

@ -8,7 +8,7 @@
.rateYo{
text-align: center;
cursor: default;
width: 90px;
width: 111px;
}
a:link, a:visited {

@ -3051,7 +3051,7 @@ a.singlepublishtwo{
/*工程认证*/
/*首页*/
.authMainImg{width: 100%;height: 240px;background:url("/images/educoder/auth/banner1.jpg") no-repeat top center;background-size: 100% 100%;justify-content: center;align-items: center;display: -webkit-flex;}
.ListTableLine>p,.ListTableLine>.ListTableTitle{padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;}
.ListTableLine>p,.ListTableLine>.ListTableTitle{margin-bottom: 0px;padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;}
.ListTableLine>p span,.ListTableTitle span{float: left;color: #666;box-sizing: border-box}
.ListTableLine li{min-height: 48px;padding: 10px 0px;box-sizing: border-box;margin:0px 30px;border-bottom: 1px solid #eaeaea;}
.ListTableLine li>span{float: left;box-sizing: border-box;}

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