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

competitions
杨树林 5 years ago
commit ee2890aed1

@ -1,5 +1,6 @@
# README
https://www.trustie.net/issues/24719
[云上实验室] Logo、导航、底部备案信息定制化
This README would normally document whatever steps are necessary to get the
application up and running.

@ -0,0 +1,15 @@
class Admins::CompetitionsController < Admins::BaseController
def index
params[:sort_by] = params[:sort_by].presence || 'created_on'
params[:sort_direction] = params[:sort_direction].presence || 'desc'
@competitions = custom_sort Competition.all, params[:sort_by], params[:sort_direction]
@params_page = params[:page] || 1
@competitions = paginate @competitions
respond_to do |format|
format.js
format.html
end
end
end

@ -2,7 +2,7 @@ class BoardsController < ApplicationController
before_action :require_login, :check_auth
before_action :find_course, only: [:create]
before_action :set_board, except: [:create]
before_action :teacher_or_admin_allowed
before_action :teacher_allowed
def index
@boards = @course.boards.includes(messages: [:last_reply, :author])

@ -2,7 +2,7 @@ class CourseGroupsController < ApplicationController
before_action :require_login, :check_auth
before_action :set_group, except: [:create]
before_action :find_course, only: [:create]
before_action :teacher_or_admin_allowed
before_action :teacher_allowed
def create
tip_exception("分班名称不能为空") if params[:name].blank?

@ -2,7 +2,8 @@ class CourseModulesController < ApplicationController
before_action :require_login, :check_auth
before_action :set_module, except: [:unhidden_modules]
before_action :find_course, only: [:unhidden_modules]
before_action :teacher_or_admin_allowed
before_action :teacher_or_admin_allowed, except: [:add_second_category]
before_action :teacher_allowed, only: [:add_second_category]
# 模块置顶
def sticky_module
@ -48,9 +49,9 @@ class CourseModulesController < ApplicationController
tip_exception("已存在同名子目录") if @course_module.course_second_categories.exists?(name: params[:name].strip)
ActiveRecord::Base.transaction do
begin
@course_module.course_second_categories.create!(name: params[:name].strip, category_type: @course_module.module_type,
category = @course_module.course_second_categories.create!(name: params[:name].strip, category_type: @course_module.module_type,
course_id: @course.id, position: @course_module.course_second_categories.count + 1)
normal_status(0, "添加成功")
render :json => {category_id: category.id, status: 0, message: "添加成功"}
rescue Exception => e
uid_logger_error(e.message)
tip_exception("添加子目录失败")

@ -1,7 +1,7 @@
class CourseSecondCategoriesController < ApplicationController
before_action :require_login, :check_auth
before_action :set_category
before_action :teacher_or_admin_allowed
before_action :teacher_allowed
# 目录重命名
def rename_category

@ -35,7 +35,7 @@ class CoursesController < ApplicationController
:transfer_to_course_group, :delete_from_course, :export_member_scores_excel,
:search_users, :add_students_by_search, :get_historical_courses, :add_teacher_popup,
:add_teacher, :export_couser_info, :export_member_act_score,
:update_informs, :new_informs, :delete_informs]
:update_informs, :new_informs, :delete_informs, :switch_to_student]
before_action :admin_allowed, only: [:set_invite_code_halt, :set_public_or_private, :change_course_admin,
:set_course_group, :create_group_by_importing_file,
:update_task_position, :tasks_list]
@ -681,13 +681,19 @@ class CoursesController < ApplicationController
course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1)
tip_exception("切换失败") if course_member.STUDENT?
course_student = CourseMember.find_by!(user_id: current_user.id, role: %i[STUDENT], course_id: @course.id)
course_member.update_attributes(is_active: 0)
course_student.update_attributes(is_active: 1)
course_student = CourseMember.find_by(user_id: current_user.id, role: %i[STUDENT], course_id: @course.id)
course_member.update_attributes!(is_active: 0)
if course_student
course_student.update_attributes!(is_active: 1)
else
# 学生身份不存在则创建
CourseMember.create!(user_id: current_user.id, role: 4, course_id: @course.id)
CourseAddStudentCreateWorksJob.perform_later(@course.id, [current_user.id])
end
normal_status(0, "切换成功")
rescue => e
uid_logger_error("switch_to_student error: #{e.message}")
tip_exception("切换失败")
tip_exception(e.message)
raise ActiveRecord::Rollback
end
end
@ -1127,7 +1133,7 @@ class CoursesController < ApplicationController
def top_banner
@user = current_user
@is_teacher = @user_course_identity < Course::STUDENT
@switch_student = Course::BUSINESS < @user_course_identity && @user_course_identity < Course::STUDENT
@is_student = @user_course_identity == Course::STUDENT
@course.increment!(:visits)
end

@ -9,19 +9,20 @@ class FilesController < ApplicationController
before_action :set_pagination, only: %i[index public_with_course_and_project mine_with_course_and_project]
before_action :validate_upload_params, only: %i[upload import]
before_action :find_file, only: %i[show setting update]
before_action :publish_params, only: %i[upload import update]
SORT_TYPE = %w[created_on downloads quotes]
def index
sort = params[:sort] || 0 # 0: 降序1: 升序
sort_type = params[:sort_type] || 'created_on' # created_on时间排序 downloads下载次数排序; quotes: 引用次数排序
course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id
@course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id
@user = current_user
@attachments = course_second_category_id.to_i == 0 ? @course.attachments : @course.attachments.by_course_second_category_id(course_second_category_id)
@attachments = @attachments.includes(attachment_group_settings: :course_group, author: [:user_extension, :course_members])
@attachments = @course_second_category_id.to_i == 0 ? @course.attachments.includes(:course_second_category) : @course.attachments.by_course_second_category_id(@course_second_category_id)
@attachments = @attachments.includes(author: [:user_extension, :course_members])
.ordered(sort: sort.to_i, sort_type: sort_type.strip)
get_category(@course, course_second_category_id)
get_category(@course, @course_second_category_id)
@total_count = @attachments.size
@publish_count = @attachments.published.size
@unpublish_count = @total_count - @publish_count
@ -137,9 +138,9 @@ class FilesController < ApplicationController
def upload
attachment_ids = params[:attachment_ids]
course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id
is_unified_setting = params.has_key?(:is_unified_setting) ? params[:is_unified_setting] : true
publish_time = params[:publish_time]
course_group_publish_times = params[:course_group_publish_times] || []
# is_unified_setting = params.has_key?(:is_unified_setting) ? params[:is_unified_setting] : true
# publish_time = params[:publish_time]
# course_group_publish_times = params[:course_group_publish_times] || []
begin
attachment_ids.each do |attchment_id|
@ -148,9 +149,12 @@ class FilesController < ApplicationController
attachment.container = @course
attachment.course_second_category_id = course_second_category_id
attachment.description = params[:description]
attachment.is_public = params[:is_public] ? 1 : 0
attachment.set_publish_time(publish_time) if is_unified_setting
attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank?
attachment.is_public = params[:is_public] && @course.is_public == 1 ? 1 : 0
attachment.is_publish = @atta_is_publish
attachment.delay_publish = @atta_delay_publish
attachment.publish_time = @atta_publish_time
# attachment.set_publish_time(publish_time) if is_unified_setting
# attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank?
attachment.save!
end
end
@ -188,8 +192,9 @@ class FilesController < ApplicationController
attach_copied_obj.created_on = Time.now
attach_copied_obj.author = current_user
attach_copied_obj.is_public = 0
attach_copied_obj.is_publish = 1
attach_copied_obj.publish_time = Time.now
attach_copied_obj.is_publish = @atta_is_publish
attach_copied_obj.delay_publish = @atta_delay_publish
attach_copied_obj.publish_time = @atta_publish_time
attach_copied_obj.course_second_category_id = course_second_category_id
attach_copied_obj.copy_from = ori.copy_from.nil? ? ori.id : ori.copy_from
if attach_copied_obj.attachtype == nil
@ -209,11 +214,7 @@ class FilesController < ApplicationController
def update
return normal_status(403, "您没有权限进行该操作") if current_user.course_identity(@course) >= 5 && @file.author != current_user
is_unified_setting = params[:is_unified_setting]
publish_time = params[:publish_time]
publish_time = format_time(Time.parse(publish_time)) unless publish_time.blank?
is_public = params[:is_public]
course_group_publish_times = params[:course_group_publish_times] || []
@old_attachment = @file
@new_attachment = Attachment.find_by_id params[:new_attachment_id]
@ -225,25 +226,29 @@ class FilesController < ApplicationController
old_course_second_category_id = @old_attachment.course_second_category_id
@old_attachment.copy_attributes_from_new_attachment(@new_attachment)
@old_attachment.is_public = is_public == true ? 1 : 0 if is_public
@old_attachment.course_second_category_id = old_course_second_category_id
@old_attachment.save!
@new_attachment.delete
end
@old_attachment.is_public = is_public == true && @course.is_public == 1 ? 1 : 0
@old_attachment.is_publish = @atta_is_publish
@old_attachment.delay_publish = @atta_delay_publish
@old_attachment.publish_time = @atta_publish_time
if params[:description] && !params[:description].strip.blank? && params[:description] != @old_attachment.description
@old_attachment.description = params[:description]
end
@old_attachment.set_public(is_public)
# @old_attachment.set_public(is_public)
if is_unified_setting
@old_attachment.set_publish_time(publish_time)
@old_attachment.attachment_group_settings.destroy_all
end
# if is_unified_setting
# @old_attachment.set_publish_time(publish_time)
# @old_attachment.attachment_group_settings.destroy_all
# end
if publish_time.blank? && @course.course_groups.size > 0 && !is_unified_setting
@old_attachment.set_course_group_publish_time(@course, course_group_publish_times)
end
# if publish_time.blank? && @course.course_groups.size > 0 && !is_unified_setting
# @old_attachment.set_course_group_publish_time(@course, course_group_publish_times)
# end
@old_attachment.save!
rescue Exception => e
@ -304,11 +309,19 @@ class FilesController < ApplicationController
end
def file_validate_sort_type
normal_status(-2, "参数sort_tyope暂时只支持 'created_on', 'quotes', 'downloads'") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
normal_status(-2, "参数sort_type暂时只支持 'created_on', 'quotes', 'downloads'") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
end
def validate_upload_params
find_attachment_ids
find_course_second_category_id
end
def publish_params
tip_exception("缺少发布参数") if params[:delay_publish].blank?
tip_exception("缺少延期发布的时间参数") if params[:delay_publish].to_i == 1 && params[:publish_time].blank?
@atta_is_publish = params[:delay_publish].to_i == 1 && params[:publish_time].to_time > Time.now ? 0 : 1
@atta_delay_publish = params[:delay_publish].to_i
@atta_publish_time = params[:delay_publish].to_i == 1 && params[:publish_time] ? params[:publish_time] : Time.now
end
end

@ -9,6 +9,8 @@ class Attachment < ApplicationRecord
belongs_to :course, foreign_key: :container_id, optional: true
has_many :attachment_group_settings, :dependent => :destroy
has_many :attachment_histories, -> { order(version: :desc) }, :dependent => :destroy
# 二级目录
belongs_to :course_second_category, optional: true
scope :by_filename_or_user_name, -> (keywords) { joins(:author).where("filename like :search or LOWER(concat(users.lastname, users.firstname)) LIKE :search",
:search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank? }
@ -96,7 +98,7 @@ class Attachment < ApplicationRecord
def become_history
history = self.attachment_histories.first
new_attachment_history = AttachmentHistory.new(self.attributes.except("id", "resource_bank_id", "unified_setting", "course_second_category_id").merge(
new_attachment_history = AttachmentHistory.new(self.attributes.except("id", "resource_bank_id", "unified_setting", "course_second_category_id", "delay_publish").merge(
attachment_id: self.id,
version: history.nil? ? 1 : history.version + 1,
))
@ -104,7 +106,7 @@ class Attachment < ApplicationRecord
end
def copy_attributes_from_new_attachment(new_attachment)
self.attributes = new_attachment.attributes.dup.except("id","container_id","container_type","is_public","downloads", "quotes",'is_publish','publish_time')
self.attributes = new_attachment.attributes.dup.except("id","container_id","container_type","is_public","downloads", "quotes",'is_publish','publish_time', "delay_publish")
end
def set_public(is_public)

@ -0,0 +1,3 @@
class CompetitionModeSetting < ApplicationRecord
belongs_to :course
end

@ -19,7 +19,7 @@ class Laboratory < ApplicationRecord
return if subdomain.blank?
rails_env = EduSetting.get('rails_env')
subdomain = subdomain.slice(0, subdomain.size - rails_env.size - 1) if subdomain.end_with?(rails_env) # winse.dev => winse
subdomain = subdomain.slice(0, subdomain.size - rails_env.size - 1) if rails_env && subdomain.end_with?(rails_env) # winse.dev => winse
find_by_identifier(subdomain)
end

@ -30,7 +30,7 @@ class Admins::SaveLaboratorySettingService < ApplicationService
hash = {}
hash[:name] = strip nav[:name]
hash[:link] = strip nav[:link]
hash[:hidden] = nav[:hidden].to_s == 0
hash[:hidden] = nav[:hidden].to_s != '0'
hash
end
end

@ -0,0 +1,7 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('竞赛列表', admins_competitions_path) %>
<% end %>
<div class="box competitions-list-container">
<%= render partial: 'admins/shixuns/shared/list', locals: { shixuns: @shixuns } %>
</div>

@ -66,6 +66,8 @@
<% end %>
</li>
<li><%= sidebar_item(admins_competitions_path, '竞赛', icon: 'trophy', controller: 'admins-competitions') %></li>
<li>
<%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %>
<li><%= sidebar_item(admins_carousels_path, '轮播图', icon: 'image', controller: 'admins-carousels') %></li>

@ -4,10 +4,11 @@ json.is_public attachment.publiced?
# json.is_lock attachment.locked?(@is_member)
json.is_lock !attachment.publiced?
json.is_publish attachment.published?
json.delay_publish attachment.delay_publish
json.publish_time attachment.publish_time
json.unified_setting attachment.unified_setting
json.filesize number_to_human_size(attachment.filesize)
json.quotes attachment.quotes_count
# json.quotes attachment.quotes_count
json.description attachment.description
json.downloads_count attachment.downloads_count
json.created_on attachment.created_on

@ -20,7 +20,7 @@ json.competitions do
if section
json.current_stage do
json.name = section.competition_stage.name
json.name section.competition_stage.name
json.start_time section.display_start_time
json.end_time section.display_end_time
end

@ -11,7 +11,7 @@ json.course_modules @course_modules.each do |mod|
case mod.module_type
when "course_group"
# json.none_group_count @course.none_group_count
json.second_category left_group_info @course
# json.second_category left_group_info @course
when "board"
course_board = @course.course_board
if course_board.present?

@ -1,5 +1,6 @@
json.partial! "commons/success"
json.data do
json.array! @courses, :id, :name, :updated_at
json.data @courses do |course|
json.(course, :id, :name, :updated_at, :end_date)
json.created_at course.created_at.strftime("%Y-%m-%d")
end

@ -15,7 +15,7 @@ json.is_admin @user_course_identity < Course::PROFESSOR
json.is_public @course.is_public == 1
json.code_halt @course.invite_code_halt == 1
json.invite_code @course.invite_code_halt == 0 ? @course.generate_invite_code : ""
json.switch_to_student switch_student_role(@is_teacher, @course, @user)
json.switch_to_student @switch_student
json.switch_to_teacher switch_teacher_role(@is_student, @course, @user)
json.switch_to_assistant switch_assistant_role(@is_student, @course, @user)
#json.join_course !@user.member_of_course?(@course)

@ -13,7 +13,10 @@ json.data do
json.author do
json.partial! "users/user_simple", user: attachment.author
end
json.partial! "files/course_groups", attachment_group_settings: attachment.attachment_group_settings
# json.partial! "files/course_groups", attachment_group_settings: attachment.attachment_group_settings
if @course_second_category_id.to_i == 0
json.category_name attachment.course_second_category&.name
end
end
end
end

@ -1,3 +1,3 @@
json.partial! 'attachments/attachment', attachment: @file
json.partial! "files/course_groups", attachment_group_settings: @file.attachment_group_settings
# json.partial! "files/course_groups", attachment_group_settings: @file.attachment_group_settings
json.partial! "attachment_histories/list", attachment_histories: @attachment_histories

@ -5,10 +5,11 @@ json.partial! "homework_btn_check", locals: {identity: @user_course_identity, ho
json.partial! "student_btn_check", locals: {identity: @user_course_identity, homework: @homework, work: @work}
json.description @homework.description
# 实训作业才有说明
if @homework.homework_type == "practice"
json.explanation @homework.explanation
# else
# json.description @homework.description
end
# 附件

@ -980,6 +980,8 @@ Rails.application.routes.draw do
resource :laboratory_setting, only: [:show, :update]
resource :laboratory_user, only: [:create, :destroy]
end
resources :competitions, only: [:index, :destroy]
end
resources :colleges, only: [] do

@ -0,0 +1,7 @@
class MigrateCourseAtta < ActiveRecord::Migration[5.2]
def change
add_column :attachments, :delay_publish, :boolean, default: 0
Attachment.where(container_type: "Course").where(is_publish: 0).where("publish_time > '#{(Time.now).strftime("%Y-%m-%d %H:%M:%S")}'").update_all(delay_publish: 1)
end
end

@ -0,0 +1,6 @@
class AddNewColumnToCompetitions < ActiveRecord::Migration[5.2]
def change
add_column :competitions, :bonus, :integer, default: 0
add_column :competitions, :mode, :integer, default: 0
end
end

@ -0,0 +1,11 @@
class CreateCompetitionModeSettings < ActiveRecord::Migration[5.2]
def change
create_table :competition_mode_settings do |t|
t.references :course
t.datetime :start_time
t.datetime :end_time
t.timestamps
end
end
end

@ -13,7 +13,7 @@
<meta http-equiv="Expires" content="0" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!-- <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">-->
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
@ -23,7 +23,8 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>EduCoder</title>
<!-- <title>EduCoder</title>-->
<!--react-ssr-head-->
<script type="text/javascript">
window.__isR = true;

@ -10,7 +10,7 @@
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!-- <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">-->
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
@ -20,7 +20,8 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Educoder</title>
<!-- <title>Educoder</title>-->
<!--react-ssr-head-->
<script type="text/javascript">
window.__isR = true;
</script>

@ -9,7 +9,7 @@ import {
Route,
Switch
} from 'react-router-dom';
import axios from 'axios';
import '@icedesign/base/dist/ICEDesignBase.css';
import '@icedesign/base/index.scss';
@ -287,6 +287,7 @@ class App extends Component {
Addcoursestypes:false,
mydisplay:false,
occupation:0,
mygetHelmetapi:undefined,
}
}
@ -327,7 +328,6 @@ class App extends Component {
}
componentDidMount() {
this.disableVideoContextMenu();
// force an update if the URL changes
history.listen(() => {
this.forceUpdate()
@ -336,7 +336,8 @@ class App extends Component {
$("html").animate({ scrollTop: $('html').scrollTop() - 0 })
});
initAxiosInterceptors(this.props)
initAxiosInterceptors(this.props);
this.getAppdata();
//
// axios.interceptors.response.use((response) => {
// // console.log("response"+response);
@ -362,15 +363,78 @@ class App extends Component {
this.setState({
isRender:false,
})
};
//获取当前定制信息
getAppdata=()=>{
let url = "/setting.json";
axios.get(url).then((response) => {
// console.log("app.js开始请求/setting.json");
// console.log("获取当前定制信息");
if(response){
if(response.data){
this.setState({
mygetHelmetapi:response.data.setting
});
document.title = response.data.setting.name;
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = '/'+response.data.setting.tab_logo_url;
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}else {
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
render() {
}else{
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
}).catch((error) => {
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
});
};
render() {
let{mygetHelmetapi}=this.state;
// console.log("appappapp");
// console.log(mygetHelmetapi);
return (
<LocaleProvider locale={zhCN}>
<MuiThemeProvider theme={theme}>
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={()=>this.Modifyloginvalue()}></LoginDialog>
<Notcompletedysl {...this.props} {...this.state}></Notcompletedysl>
@ -413,10 +477,22 @@ class App extends Component {
<Route path="/compatibility" component={CompatibilityPageLoadable}/>
<Route
path="/login" component={EducoderLogin}
path="/login"
render={
(props) => {
return (<EducoderLogin {...this.props} {...props} {...this.state} />)
}
}
/>
<Route
path="/register" component={EducoderLogin}
path="/register"
render={
(props) => {
return (<EducoderLogin {...this.props} {...props} {...this.state} />)
}
}
/>
<Route
path="/otherloginstart" component={Otherloginstart}
@ -440,7 +516,13 @@ class App extends Component {
}></Route>
<Route
path="/changepassword" component={EducoderLogin}
path="/changepassword"
render={
(props) => {
return (<EducoderLogin {...this.props} {...props} {...this.state} />)
}
}
/>
<Route
path="/interesse" component={Interestpage}
@ -468,7 +550,7 @@ class App extends Component {
></Route>
{/*课堂*/}
<Route path="/courses" component={CoursesIndex} {...this.props}></Route>
<Route path="/courses" component={CoursesIndex} {...this.props} {...this.state}></Route>
{/* <Route path="/forums" component={ForumsIndexComponent}>
</Route> */}
@ -502,7 +584,12 @@ class App extends Component {
render={
(props)=>(<Ecs {...this.props} {...props} {...this.state}></Ecs>)
}/>
<Route exact path="/" component={ShixunsHome}/>
<Route exact path="/"
// component={ShixunsHome}
render={
(props)=>(<ShixunsHome {...this.props} {...props} {...this.state}></ShixunsHome>)
}
/>
<Route component={Shixunnopage}/>

@ -94,9 +94,15 @@ export function initAxiosInterceptors(props) {
}
}
if (requestMap[config.url] === true) { // 避免重复的请求
if (config.method === "post") {
if (requestMap[config.url] === true) { // 避免重复的请求 导致页面f5刷新 也会被阻止 显示这个方法会影响到定制信息定制信息是get 请求
// console.log(config);
// console.log(JSON.parse(config));
// console.log(config.url);
// console.log("被阻止了是重复请求=================================");
return false;
}
}
// 非file_update请求
if (config.url.indexOf('update_file') === -1) {
requestMap[config.url] = true;

@ -209,6 +209,9 @@ class Fileslistitem extends Component{
text-overflow:ellipsis;
white-space:nowrap
}
.mt2{
margin-top:2px;
}
`}</style>
<div className="clearfix ds pr contentSection" style={{cursor : this.props.isAdmin ? "pointer" : "default"}} onClick={() => window.$(`.sourceitem${index} input`).click() }>
<h6 onClick={(event)=>this.eventStop(event)}>
@ -248,6 +251,29 @@ class Fileslistitem extends Component{
:""
}
{discussMessage.is_publish===false?<CoursesListType typelist={["未发布"]} typesylename={""}/>:""}
{this.props.isAdmin?
<span className={"fr mr10 mt2"} onClick={(event)=>this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<a className="btn colorblue"
onClick={()=>this.settingList()}>设置</a>
</WordsBtn>
</span>:""}
{this.props.isStudent===true&&this.props.current_user.login===discussMessage.author.login?
<span className={"fr mr10 mt2"} onClick={(event)=>this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<a className="btn colorblue"
onClick={()=>this.settingList()}>设置</a>
</WordsBtn>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<a className="btn colorblue"
onClick={()=>this.onDelete(discussMessage.id)}>删除</a>
</WordsBtn>
</span>:""}
</h6>
<style>
{
@ -303,33 +329,14 @@ class Fileslistitem extends Component{
{ discussMessage.publish_time===null?"":discussMessage.is_publish===true?moment(discussMessage.publish_time).fromNow():moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm')}
</span>
</span>
{this.props.isAdmin?
<span className={"fr mrf2 mr10"} onClick={(event)=>this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<a className="btn colorblue"
onClick={()=>this.settingList()}>设置</a>
</WordsBtn>
</span>:""}
{this.props.isStudent===true&&this.props.current_user.login===discussMessage.author.login?
<span className={"fr mrf2 mr10"} onClick={(event)=>this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<a className="btn colorblue"
onClick={()=>this.settingList()}>设置</a>
</WordsBtn>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<a className="btn colorblue"
onClick={()=>this.onDelete(discussMessage.id)}>删除</a>
</WordsBtn>
</span>:""}
{discussMessage&&discussMessage.category_name===null?"":this.props.child===false?<div className="color-grey9 task-hide fr mr60" title={discussMessage&&discussMessage.category_name}
style={{"max-width":"268px"}}>所属目录{discussMessage&&discussMessage.category_name}
</div>:""}
</p>
<p className={this.props.isAdmin===true?"color-grey panel-lightgrey mt8 fl ml30":"color-grey panel-lightgrey mt8 fl ml13"} style={{width:'100%'}}>
<p className={this.props.isAdmin===true?"color-grey panel-lightgrey mt8 fl ml30":"color-grey panel-lightgrey mt8 fl ml13"} style={{width:'94%'}}>
<style>
{
`

@ -745,6 +745,7 @@ class Fileslists extends Component{
{/*选择资源*/}
{shixunmodal&&shixunmodal===true?<Selectresource
{...this.props}
{...this.state}
visible={this.state.shixunmodal}
shixunmodallist={this.state.shixunmodallist}
newshixunmodallist={this.state.newshixunmodallist}
@ -760,6 +761,7 @@ class Fileslists extends Component{
{/*上传资源*/}
{Accessoryvisible&&Accessoryvisible===true?<Sendresource
{...this.props}
{...this.state}
modalname={"上传资源"}
visible={Accessoryvisible}
Cancelname={"取消"}
@ -770,9 +772,10 @@ class Fileslists extends Component{
has_course_groups={this.state.has_course_groups}
attachmentId={this.state.coursesecondcategoryid}
/>:""}
{/*设置资源*/}
{Settingtype&&Settingtype===true?<Selectsetting
{...this.props}
{...this.state}
Settingtype={Settingtype}
discussMessageid={discussMessageid}
course_id={this.props.match.params.coursesId}
@ -781,7 +784,18 @@ class Fileslists extends Component{
has_course_groups={this.state.has_course_groups}
attachmentId={this.state.coursesecondcategoryid}
/>:""}
{child===false?"":<style>
{
`
.filesnameslist{
max-width: 486px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
`
}
</style>}
<Titlesearchsection
title={child===false?"全部资源":name}
searchValue={ searchValue }
@ -923,6 +937,7 @@ class Fileslists extends Component{
<div key={index}>
<Fileslistitem
{...this.props}
{...this.state}
discussMessage={item}
isAdmin={this.props.isAdmin()}
isStudent={this.props.isStudent()}

@ -61,7 +61,7 @@ class Titlesearchsection extends Component{
<p className="clearfix padding30 bor-bottom-greyE">
<p style={{height: '20px'}}>
<span className="font-18 fl color-dark-21">{title}</span>
<span className="font-18 fl color-dark-21 filesnameslist" title={title}>{title}</span>
<li className="fr font-16">
{ firstRowRight }
</li>

@ -1,17 +1,34 @@
import React,{ Component } from "react";
import { Modal,Checkbox,Select,Input,Spin,Icon} from "antd";
import { Modal,Checkbox,Select,Input,Spin,Icon,Radio,DatePicker} from "antd";
import locale from 'antd/lib/date-picker/locale/zh_CN';
import axios from'axios';
import {handleDateString} from 'educoder';
import NoneData from "../coursesPublic/NoneData";
import Modals from '../../modals/Modals';
import moment from 'moment';
const Option = Select.Option;
const Search = Input.Search;
const dateFormat ="YYYY-MM-DD HH:mm"
function formatDate(date) {
var dateee = new Date(date).toJSON();
return new Date(+new Date(dateee) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '')
}
function range(start, end) {
const result = [];
for (let i = start; i < end; i++) {
result.push(i);
}
return result;
}
function disabledDateTime() {
return {
disabledMinutes: () => range(1, 30).concat(range(31, 60)),
// disabledSeconds: () => range(1,60)
}
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class Selectresource extends Component{
constructor(props){
super(props);
@ -23,7 +40,9 @@ class Selectresource extends Component{
Resourcelist:undefined,
hometypepvisible:true,
getallfiles:false,
searchtype:'getallfiles'
searchtype:'getallfiles',
Radiovalue:0,
datatime:undefined
}
}
componentDidMount() {
@ -32,11 +51,7 @@ class Selectresource extends Component{
componentDidUpdate = (prevProps) => {
let {getallfiles}=this.state;
if ( prevProps.visible != this.props.visible ) {
}
}
@ -197,7 +212,7 @@ class Selectresource extends Component{
savecouseShixunModal=()=>{
let {patheditarry}=this.state;
let {patheditarry,datatime,Radiovalue}=this.state;
let {coursesId,attachmentId}=this.props;
let url="/files/import.json";
@ -212,19 +227,28 @@ class Selectresource extends Component{
})
}
if(this.state.Radiovalue===1){
if(datatime===undefined||datatime===null||datatime=== ""){
this.setState({
Radiovaluetype:true
})
return
}else{
this.setState({
Radiovaluetype:false
})
}
}
axios.post(url, {
course_id:coursesId,
attachment_ids:patheditarry,
course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId,
delay_publish:Radiovalue,
publish_time:Radiovalue===1?datatime:undefined
}
).then((response) => {
if(response.data.status===0){
// this.setState({
// Modalstype:true,
// Modalstopval:response.data.message,
// ModalSave:this.ModalCancelModalCancel,
// loadtype:true
// })
this.ModalCancelModalCancel();
this.props.updataleftNavfun();
this.props.showNotification("选用资源成功");
@ -236,15 +260,33 @@ class Selectresource extends Component{
}
selectCloseList=(value)=>{
RadioonChange=(e)=>{
if(e.target.value===0){
this.setState({
datatime:undefined
})
}
this.setState({
Radiovalue: e.target.value,
});
}
onChangeTimepublish= (date, dateString) => {
this.setState({
category_id:value
datatime:handleDateString(dateString),
})
}
render(){
let {Searchvalue,type,category_id,Resourcelist,hometypepvisible,patheditarry}=this.state;
let {visible,shixunmodallist}=this.props;
let {Searchvalue,type,Resourcelist,hometypepvisible,patheditarry,datatime}=this.state;
let {visible}=this.props;
const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;
const radioStyle = {
display: 'block',
height: '30px',
lineHeight: '30px',
};
return(
<div>
{/*提示*/}
@ -373,10 +415,36 @@ class Selectresource extends Component{
}
</div>
<div className={"mt10"}>
<span className={"color-ooo fl mt6 ml20"}>发布设置</span>
<Radio.Group onChange={this.RadioonChange} value={this.state.Radiovalue} style={{'width': '460px'}}>
<Radio style={radioStyle} value={0}>
立即发布
</Radio>
<Radio style={radioStyle} value={1} className={"fl"}>
<span className={"mr5"}>延迟发布</span>
<DatePicker
dropdownClassName="hideDisable"
showTime={{ format: 'HH:mm' }}
locale={locale}
format={dateFormat}
placeholder="请选择发布时间"
id={"startime"}
showToday={false}
width={"210px"}
value={this.state.Radiovalue===1?datatime===undefined||datatime===""?undefined:moment(datatime, dateFormat):undefined}
onChange={(e,index)=>this.onChangeTimepublish(e,index,undefined,1)}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={this.state.Radiovalue===1?false:true}
/>
</Radio>
<span className={"fl mt5 color-grey-c"}>(按照设置的时间定时发布)</span>
</Radio.Group>
</div>
{this.state.patheditarrytype===true?<p className={"color-red ml20"}>请选择资源</p>:""}
{this.state.Radiovaluetype===true?<p className={"color-red ml20"}>发布时间不能为空</p>:""}
<div className="mt20 marginauto clearfix edu-txt-center">
<a className="pop_close task-btn mr30 margin-tp26" onClick={this.hidecouseShixunModal}>取消</a>
<a className="task-btn task-btn-orange margin-tp26" id="submit_send_shixun" onClick={this.savecouseShixunModal}>确定</a>

@ -1,5 +1,5 @@
import React,{ Component } from "react";
import { Modal,Checkbox,Select,Input,Upload,Button,Icon,message,DatePicker,Tooltip} from "antd";
import { Modal,Checkbox,Select,Input,Upload,Button,Icon,message,DatePicker,Tooltip,Radio} from "antd";
import axios from'axios';
import {getUrl,handleDateString,appendFileSizeToUploadFileAll} from 'educoder';
import locale from 'antd/lib/date-picker/locale/zh_CN';
@ -36,9 +36,10 @@ class Selectsetting extends Component{
course_groups:undefined,
attachment_histories:undefined,
datatime:undefined,
unified_setting:true,
fileList:[],
fileListtype:false
fileListtype:false,
is_public:false,
Radiovaluetype:false
}
}
@ -54,53 +55,13 @@ class Selectsetting extends Component{
})
.then((response) => {
if(response.status===200){
let newcourse_groups=[];
let list =response.data.course_groups;
// let list=[
// {
// "course_group_id": 820,
// "course_group_name": "示例A班",
// "course_group_publish_time": "2019-04-18T17:00:00.000+08:00"
// },
// {
// "course_group_id": 821,
// "course_group_name": "示例B班",
// "course_group_publish_time": "2019-04-19T19:00:00.000+08:00"
// },
// {
// "course_group_id": 822,
// "course_group_name": "示例C班",
// "course_group_publish_time": "2019-04-10T19:00:00.000+08:00"
// }
// ]
if(list.length!=0){
list.forEach((item,key)=>{
newcourse_groups.push ({
course_group_id:item.course_group_id,
course_group_name:item.course_group_id,
publish_time:moment(item.course_group_publish_time).format(dateFormat)
})
})
}else{
newcourse_groups.push ({
course_group_id:undefined,
course_group_name:undefined,
publish_time:""
})
}
this.setState({
datalist:response.data,
description: response.data.description,
is_public:response.data.is_public,
unified_setting: response.data.unified_setting,
datatime:response.data.publish_time,
// is_public:response.data.course_groups,
Radiovalue:response.data.delay_publish==false?0:1,
//attachment_histories:response.data.attachment_histories
course_groups:newcourse_groups
})
}
@ -110,23 +71,6 @@ class Selectsetting extends Component{
});
let coursesId=this.props.match.params.coursesId;
if(this.props.isAdmin()){
let url = `/courses/${coursesId}/all_course_groups.json`
axios.get(url, {
})
.then((response) => {
this.setState({
course_groupss: response.data.course_groups,
})
})
.catch(function (error) {
console.log(error);
});
}
}
@ -145,21 +89,6 @@ class Selectsetting extends Component{
this.getalldata()
}
}
onChangepublics=(e)=>{
console.log(e.target.checked)
this.setState({
is_public:e.target.checked
})
}
onChangesettings=(e)=>{
console.log(e.target.checked)
this.setState({
unified_setting:e.target.checked
})
}
settextarea=(e)=>{
@ -180,13 +109,26 @@ class Selectsetting extends Component{
}
savecouseShixunModal=()=>{
let {fileList,is_public,unified_setting,description,datatime,course_groups}=this.state;
let {fileList,is_public,description,datatime,Radiovalue}=this.state;
let newfileList=[];
for(var list of fileList){
newfileList.push(list.response.id)
}
if(this.state.Radiovalue===1){
if(datatime===undefined||datatime===null||datatime=== ""){
this.setState({
Radiovaluetype:true
})
return
}else{
this.setState({
Radiovaluetype:false
})
}
}
if(description===undefined||description===null){
}else if(description.length>100){
@ -196,29 +138,6 @@ class Selectsetting extends Component{
return
}
// course_groups.forEach((item,key)=>{
// if(item.course_group_id===undefined||item.publish_time===undefined){
// this.setState({
// course_group_publish_timestype:true
// })
// return
// }
// })
// if(unified_setting===false){
//
// course_groups.forEach((item,key)=>{
// if(item.course_group_id===undefined){
// this.setState({
// course_group_idtypes:true
// })
// return
// }
// })
//
// }
let coursesId=this.props.match.params.coursesId;
let attachmentId=this.props.attachmentId;
let url="/files/"+this.props.discussMessageid+".json";
@ -228,12 +147,10 @@ class Selectsetting extends Component{
new_attachment_id:newfileList.length===0?undefined:newfileList,
course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId,
is_public:is_public,
is_unified_setting:unified_setting,
publish_time:unified_setting===true?datatime===undefined?moment(new Date()).format('YYYY-MM-DD HH'):datatime:undefined,
publish_time:Radiovalue===0?undefined:datatime===undefined?moment(new Date(),dateFormat):datatime,
description:description,
course_group_publish_times:unified_setting===false?course_groups:undefined
delay_publish:Radiovalue
}).then((result)=>{
if(result.data.status===0){
this.props.setupdate(attachmentId)
this.props.showNotification("设置资源成功");
@ -244,7 +161,6 @@ class Selectsetting extends Component{
}
onChangeTimepublish= (date, dateString) => {
// console.log('startValue', dateString);
this.setState({
datatime:handleDateString(dateString),
})
@ -268,31 +184,6 @@ class Selectsetting extends Component{
}
}
// onAttachmentRemove = (file) => {
// // confirm({
// // title: '确定要删除这个附件吗?',
// // okText: '确定',
// // cancelText: '取消',
// // // content: 'Some descriptions',
// // onOk: () => {
// // this.deleteAttachment(file)
// // },
// // onCancel() {
// // console.log('Cancel');
// // },
// // });
// // return false;
//
// // this.setState({
// // Modalstype:true,
// // Modalstopval:'确定要删除这个附件吗?',
// // ModalSave: ()=>this.deleteAttachment(file),
// // ModalCancel:this.cancelAttachment
// // })
// // return false;
//
// this.deleteAttachment(file);
// }
onAttachmentRemove = (file) => {
@ -309,14 +200,7 @@ class Selectsetting extends Component{
fileListtype:false,
fileList:[]
})
// this.setState((state) => {
// const index = state.fileList.indexOf(file);
// const newFileList = state.fileList.slice();
// newFileList.splice(index, 1);
// return {
// fileList: newFileList,
// };
// });
}
}
})
@ -332,63 +216,28 @@ class Selectsetting extends Component{
fileList:[]
})
}
// const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
}
onChangeTimepublishs= (date, dateString,key) => {
let {course_groups}=this.state;
let newgroup_publish=course_groups;
for(var i=0; i<newgroup_publish.length; i++){
if(i===parseInt(key)){
newgroup_publish[i].publish_time=handleDateString(dateString);
}
}
onChangepublic=(e)=>{
this.setState({
course_groups:newgroup_publish,
})
}
selectassigngroups=(e,index,key)=>{
let {course_groups}=this.state;
let newgroup_publish=course_groups;
for(var i=0; i<newgroup_publish.length; i++){
if(i===parseInt(key)){
newgroup_publish[i].course_group_id=index.props.value;
}
}
this.setState({
course_groups:newgroup_publish,
is_public:e.target.checked
})
}
deletegrouppublish=(key)=>{
let newlist=this.state.course_groups;
newlist.splice(key,1);
RadioonChange=(e)=>{
if(e.target.value===0){
this.setState({
course_groups:newlist
datatime:undefined
})
}
addgrouppublish=()=>{
let newlist=this.state.course_groups;
newlist.push( {
course_group_id : undefined,
publish_time :""
// moment(new Date()).format('YYYY-MM-DD HH:mm')
})
this.setState({
course_groups:newlist
})
Radiovalue: e.target.value,
});
}
render(){
let {is_public,unified_setting,course_groups,datatime,description,datalist,course_group_publish_timestype}=this.state;
let {datatime,description,datalist}=this.state;
const uploadProps = {
width: 600,
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUrl()}/api/attachments.json`,
onChange: this.handleChange,
onRemove: this.onAttachmentRemove,
@ -401,9 +250,13 @@ class Selectsetting extends Component{
return isLt150M;
},
};
const radioStyle = {
display: 'block',
height: '30px',
lineHeight: '30px',
};
// console.log(this.props.has_course_groups)
console.log(this.state.Radiovalue)
return(
<div>
<style>
@ -461,9 +314,9 @@ class Selectsetting extends Component{
.fontlefts{text-align: left; text-align: center;}
`}</style>
<ul className="clearfix greybackHead edu-txt-center">
<li className="fl paddingleft22 fontlefts" style={{width:'220px'}}>资源名称</li>
<li className="fl paddingleft22 fontlefts" style={{width:'330px'}}>资源名称</li>
<li className="fl edu-txt-left" style={{width:'80px'}}>下载</li>
<li className="fl" style={{width:'100px'}}>引用</li>
{/*<li className="fl" style={{width:'100px'}}>引用</li>*/}
<li className="fl" style={{width:'130px'}}>版本号</li>
</ul>
@ -490,7 +343,7 @@ class Selectsetting extends Component{
`}</style>
<div className="pl20 pr20 settingbox">
<div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE">
<li className="fl" style={{width: '241px'}}>
<li className="fl" style={{width: '350px'}}>
<span className={"isabox"} title={datalist&&datalist.title}> {datalist&&datalist.title} </span>
{datalist&&datalist.attachment_histories.length===0?"":<span className={"newcolor-orange fl"}>当前版本</span>}
</li>
@ -505,13 +358,13 @@ class Selectsetting extends Component{
{datalist&&datalist.attachment_histories.map((item,key)=>{
return(
<div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" key={key}>
<li className="fl" style={{width: '241px'}}>
<li className="fl" style={{width: '350px'}}>
<span className={"isabox"} title={item.title}> {item.title} </span>
{/*<span className={"newcolor-orange fl"}>当前版本</span>*/}
</li>
<li className="fl edu-txt-left task-hide paddingl5 "
style={{width: '76px'}}> {item.downloads_count} </li>
<li className="fl paddingl10 " style={{width: '100px'}}> {item.quotes} </li>
{/*<li className="fl paddingl10 " style={{width: '100px'}}> {item.quotes} </li>*/}
<li className="fl paddingl10 datastyle">
{moment(item.created_on).format('YYYY-MM-DD HH:mm')==="Invalid date"?"":moment(item.created_on).format('YYYY-MM-DD HH:mm')}
</li>
@ -607,61 +460,15 @@ class Selectsetting extends Component{
</Upload>
</p>
{/*<style>*/}
{/*{*/}
{/*`*/}
{/*.maxwidth400{*/}
{/*max-width: 400px;*/}
{/*overflow: hidden;*/}
{/*text-overflow: ellipsis;*/}
{/*white-space: nowrap;*/}
{/*}*/}
{/*`*/}
{/*}*/}
{/*</style>*/}
{/*{this.state.fileList.length===0?"":this.state.fileList.map((item,key)=>{*/}
{/*return(*/}
{/*<p className="color-grey mt10" key={key} >*/}
{/*<a className="color-grey fl">*/}
{/*<i className="font-14 color-green iconfont icon-fujian mr8" aria-hidden="true"></i>*/}
{/*</a>*/}
{/*<span className="mr12 color9B9B maxwidth400 fl" length="58">*/}
{/*{item.name}*/}
{/*</span>*/}
{/*<span className="color656565 mt2 color-grey-6 font-12 mr8">*/}
{/*{item.response===undefined?"":isNaN(bytesToSize(item.filesize))?"123":bytesToSize(item.filesize)}*/}
{/*</span>*/}
{/*<i className="font-14 iconfont icon-guanbi "*/}
{/*id={item.response===undefined?"":item.response.id}*/}
{/*aria-hidden="true" onClick={()=>this.onAttachmentRemove(item.response===undefined?"":item.response.id&&item.response.id)}></i>*/}
{/*</p>*/}
{/*)*/}
{/*})}*/}
{this.state.newfileListtypes===true?<p className={"color-red"}>请先上传资源</p>:""}
<p className={this.state.fileListtype===true?"mt15":""}>
<p className={this.state.fileListtype===true?"mt15 selecboxfilas":"selecboxfilas"}>
<style>{`
.ant-checkbox-wrapper{
.selecboxfilas .ant-checkbox-wrapper{
margin-left:0px !important;
margin-top:10px;
}
`}</style>
{/*<div className={this.state.fileListtype===true?"mt30":""}>*/}
{/*<Checkbox*/}
{/*checked={is_public}*/}
{/*onChange={this.onChangepublics}>*/}
{/*<span className={"font-14"}>勾选后所有用户可见,否则仅课堂成员可见</span>*/}
{/*</Checkbox>*/}
{/*</div>*/}
{/*{this.props.has_course_groups&&this.props.has_course_groups===true?:""}*/}
{this.state.course_groupss&&this.state.course_groupss.length>0?<Checkbox
checked={unified_setting}
onChange={this.onChangesettings}>
<span>统一设置</span><span className={"font-14 color-grey-9"}>(使)</span>
</Checkbox>:""}
<style>
{`
.Selectleft20{
@ -675,53 +482,11 @@ class Selectsetting extends Component{
}
`}
</style>
{/*this.props.has_course_groups&&this.props.has_course_groups===true?:""*/}
<div className={"resourcebox"}>
{unified_setting===false?
this.state.course_groups&&this.state.course_groups.map((item,key)=>{
return(
<div className={"mt10 "} key={key}>
<Select placeholder="请选择分班名称"
value={item.course_group_id}
style={{ width: 200 }}
onChange={(e,index)=>this.selectassigngroups(e,index,key)}
>
{ this.state.course_groupss&&this.state.course_groupss.map((item,key)=>{
return(
<Option value={item.id} key={key}>{item.name}</Option>
)
})}
</Select>
<DatePicker
showToday={false}
dropdownClassName="hideDisable"
showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm"
locale={locale}
placeholder="请选择发布时间"
id={"startimes"}
className={"Selectleft20"}
width={"200px"}
value={item.publish_time===undefined||item.publish_time===""?"":item.publish_time===null?"":moment(item.publish_time, dateFormat)}
onChange={(e,index)=>this.onChangeTimepublishs(e,index,key)}
// onChange={ this.onChangeTimepublish }
disabledTime={disabledDateTime}
disabledDate={disabledDate}
/>
{key!=0?<i className="iconfont icon-shanchu color-grey-c font-14 font-n ml20" onClick={()=>this.deletegrouppublish(key)}></i>:""}
{key===course_groups.length-1?<i className="iconfont icon-tianjiafangda color-green ml15" onClick={this.addgrouppublish}></i>:""}
</div>
)
}):""}
</div>
{this.props.course_is_public===true?<div>
<span className={"color-ooo"}>公开</span><Checkbox checked={this.state.is_public} onChange={(e)=>this.onChangepublic(e)}>
<span className={"font-14 color-ooo"}>选中所有用户可见否则课堂成员可见</span>
</Checkbox>
</div>:""}
</p>
<style>
{`
@ -730,10 +495,17 @@ class Selectsetting extends Component{
}
`}
</style>
{unified_setting===true?
<p className={"mt10"}>
<span>
<div className={this.props.course_is_public===true?"mt10":""}>
<span className={"color-ooo fl mt6"}>发布设置</span>
<Radio.Group onChange={(e)=>this.RadioonChange(e)} value={this.state.Radiovalue} style={{'width': '460px'}}>
<Radio style={radioStyle} value={0}>
立即发布
</Radio>
<Radio style={radioStyle} value={1} className={"fl"}>
<span className={"mr5"}>延迟发布</span>
<DatePicker
showToday={false}
dropdownClassName="hideDisable"
showTime={{ format: 'HH:mm' }}
@ -746,12 +518,13 @@ class Selectsetting extends Component{
onChange={this.onChangeTimepublish}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={this.state.Radiovalue===1?false:true}
/>
</span>
</p>:""}
{/*{this.state.course_group_idtypes===true?<p className={"color-red"}>请选择分班</p>:""}*/}
</Radio>
<span className={"fl mt5 color-grey-c"}>(按照设置的时间定时发布)</span>
</Radio.Group>
</div>
{/*{course_group_publish_timestype===true?<p className={"color-red mt10"}>请填写完整</p>:""}*/}
<textarea placeholder="请输入资源描述最大限制100个字符" className={"mt10"} value={description} onInput={this.settextarea} style={{
width: '100%',
@ -760,6 +533,7 @@ class Selectsetting extends Component{
padding: '10px'
}}></textarea>
{this.state.descriptiontypes===true?<p className={"color-red"}>描述不能超过最大限制100个字符</p>:""}
{this.state.Radiovaluetype===true?<p className={"color-red"}>发布时间不能为空</p>:""}
</div>
<div className="mt20 marginauto clearfix edu-txt-center">

@ -1,9 +1,11 @@
import React, { Component } from "react";
import { Modal, Checkbox, Input, Spin} from "antd";
import axios from 'axios'
import axios from 'axios';
import moment from 'moment';
import ModalWrapper from "../common/ModalWrapper";
import InfiniteScroll from 'react-infinite-scroller';
const dateFormat ="YYYY-MM-DD HH:mm"
const Search = Input.Search
const pageCount = 15;
class Sendtofilesmodal extends Component{
@ -170,7 +172,12 @@ class Sendtofilesmodal extends Component{
bottom: 93px;
width: 82%;
text-align: center;
}`}
}
.ModalWrappertitle{
background: #D0E8FC;
padding: 10px;
}
`}
</style>
<p className="color-grey-6 mb20 edu-txt-center" style={{ fontWeight: "bold" }} >选择的{moduleName}发送到<span className="color-orange-tip">指定课堂</span></p>
@ -183,7 +190,12 @@ class Sendtofilesmodal extends Component{
></Search>
<div>
{/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */}
<p className="clearfix ModalWrappertitle">
<div className="task-hide fl pagemancenter" style={{"width":'215px'}}>课堂名称</div>
<div className="task-hide fl pagemancenter" style={{"width":'140px'}}>创建时间</div>
<div className="task-hide fl pagemancenter" style={{"width":'110px'}}>结束时间</div>
</p>
<div className="edu-back-skyblue padding15" style={{"height":"300px", overflowY: "scroll", overflowAnchor: 'none' }}>
<InfiniteScroll
threshold={10}
@ -199,20 +211,14 @@ class Sendtofilesmodal extends Component{
return (
<p className="clearfix mb7" key={course.id}>
<Checkbox className="fl" value={course.id} key={course.id} ></Checkbox>
<span className="fl with45"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{course.name}</label></span>
<div className="task-hide fl" style={{"width":'224px'}} title={course.name}>{course.name}</div>
<div className="task-hide fl" style={{"width":'130px'}}>{moment(course.created_at).format('YYYY-MM-DD')}</div>
<div className="task-hide fl" style={{"width":'110px'}}>{course.end_date}</div>
</p>
)
}) }
</Checkbox.Group>
{loading && hasMore && (
<div className="demo-loading-container">
<Spin />
</div>
)}
{/* TODO */}
{/* {
!hasMore && <div>没有更多了</div>
} */}
</InfiniteScroll>
</div>

@ -1,5 +1,5 @@
import React,{ Component } from "react";
import { Modal,Checkbox,Upload,Button,Icon,message,DatePicker,Select,Tooltip} from "antd";
import { Modal,Checkbox,Upload,Button,Icon,message,DatePicker,Select,Tooltip,Radio} from "antd";
import axios from 'axios';
import Modals from '../../modals/Modals';
import {getUrl,handleDateString,bytesToSize,appendFileSizeToUploadFileAll} from 'educoder';
@ -40,7 +40,6 @@ class Sendresource extends Component{
ModalSave:"",
fileListtype:false,
loadtype:false,
is_unified_setting:true,
is_public:false,
datatime:undefined,
// moment(new Date()).format('YYYY-MM-DD HH:mm:ss'),
@ -50,30 +49,15 @@ class Sendresource extends Component{
publish_time :""
}],
course_groups:undefined,
course_groups_count:undefined
course_groups_count:undefined,
Radiovalue:0,
Radiovaluetype:false
}
}
componentDidMount() {
let coursesId=this.props.match.params.coursesId;
if(this.props.isAdmin()){
let url = `/courses/${coursesId}/all_course_groups.json`
axios.get(url, {
})
.then((response) => {
this.setState({
course_groups: response.data.course_groups,
course_groups_count:response.data.course_groups_count
})
})
.catch(function (error) {
console.log(error);
});
}
}
//勾选实训
@ -101,37 +85,6 @@ class Sendresource extends Component{
}
}
// onAttachmentRemove = (file) => {
//
// this.setState({
// fileListtype:false,
// })
// // confirm({
// // title: '确定要删除这个附件吗?',
// // okText: '确定',
// // cancelText: '取消',
// // // content: 'Some descriptions',
// // onOk: () => {
// // this.deleteAttachment(file)
// // },
// // onCancel() {
// // console.log('Cancel');
// // },
// // });
// // return false;
//
// // this.setState({
// // Modalstype:true,
// // Modalstopval:'确定要删除这个附件吗?',
// // ModalSave: ()=>this.deleteAttachment(file),
// // ModalCancel:this.cancelAttachment
// // })
// // return false;
//
// this.deleteAttachment(file);
// }
onAttachmentRemove = (file) => {
if(!file.percent || file.percent == 100){
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
@ -174,8 +127,7 @@ class Sendresource extends Component{
}
Saves=()=>{
let id=this.props.categoryid;
let {fileList,description,is_public,is_unified_setting,datatime,course_group_publish_times} =this.state;
let {fileList,description,is_public,datatime,Radiovalue} =this.state;
let newfileList=[];
for(var list of fileList){
@ -188,17 +140,19 @@ class Sendresource extends Component{
})
return
}
// if(is_unified_setting===false){
// course_group_publish_times.forEach((item,key)=>{
// if(item.course_group_id===undefined||item.publish_time===undefined){
// this.setState({
// course_group_publish_timestype:true
// })
// return
// }
// })
//
// }
if(this.state.Radiovalue===1){
if(datatime===undefined||datatime===null||datatime=== ""){
this.setState({
Radiovaluetype:true
})
return
}else{
this.setState({
Radiovaluetype:false
})
}
}
@ -222,22 +176,14 @@ class Sendresource extends Component{
course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId,
attachment_ids:newfileList,
is_public:is_public,
is_unified_setting:is_unified_setting,
publish_time:is_unified_setting===true?datatime===undefined? moment(new Date()).format('YYYY-MM-DD HH:mm'):datatime:undefined,
publish_time:Radiovalue===1?datatime===undefined? undefined:datatime:undefined,
description:description,
course_group_publish_times:is_unified_setting===false?course_group_publish_times:undefined
delay_publish:Radiovalue,
}).then((result)=>{
if(result.data.status===0){
// this.setState({
// Modalstype:true,
// Modalstopval:result.data.message,
// ModalSave:this.ModalCancelModalCancel,
// loadtype:true
// })
this.ModalCancelModalCancel();
this.props.updataleftNavfun();
// this.props.showNotification(result.data.message);
this.props.showNotification("上传资源成功");
this.props.setupdate(this.props.attachmentId)
}
@ -253,14 +199,6 @@ class Sendresource extends Component{
})
}
onChangesetting=(e)=>{
this.setState({
is_unified_setting:e.target.checked
})
}
onChangepublic=(e)=>{
this.setState({
@ -289,50 +227,20 @@ class Sendresource extends Component{
}
selectassigngroups=(e,index,key)=>{
let {course_group_publish_times}=this.state;
let newgroup_publish=course_group_publish_times;
for(var i=0; i<newgroup_publish.length; i++){
if(i===parseInt(key)){
newgroup_publish[i].course_group_id=index.props.value;
}
}
RadioonChange=(e)=>{
if(e.target.value===0){
this.setState({
course_group_publish_times:newgroup_publish,
datatime:undefined
})
}
deletegrouppublish=(key)=>{
let newlist=this.state.course_group_publish_times;
newlist.splice(key,1);
this.setState({
course_group_publish_times:newlist
})
}
addgrouppublish=()=>{
let newlist=this.state.course_group_publish_times;
newlist.push( {
course_group_id : undefined,
publish_time :undefined
})
this.setState({
course_group_publish_times:newlist
})
Radiovalue: e.target.value,
});
}
render(){
let {settextarea,newfileListtype,descriptiontype,
course_group_publish_timestype,
Modalstopval,
ModalCancel,
ModalSave,
loadtype,
is_unified_setting,
let { newfileListtype,descriptiontype,
is_public,
datatime,
course_group_publish_times,
course_groups
}=this.state;
const uploadProps = {
@ -350,7 +258,11 @@ class Sendresource extends Component{
return isLt150M;
},
};
const radioStyle = {
display: 'block',
height: '30px',
lineHeight: '30px',
};
return(
<div>
{/*提示*/}
@ -389,6 +301,7 @@ class Sendresource extends Component{
margin-right: 5px;
}
.ant-upload-list-item:hover .ant-upload-list-item-info{
padding: 0 12px 0 0px;
background-color:#fff;
}
.upload_1 .ant-upload-list {
@ -437,42 +350,12 @@ class Sendresource extends Component{
<Button className="uploadBtn">
<Icon type="upload" /> 选择文件
</Button>
<span className={"ml10"}>(单个文件最大150M)</span>
<span className={"ml10 color-ooo"}>(单个文件最大150M)</span>
</span>:""}
</Upload>
</p>
{/*<style>*/}
{/*{*/}
{/*`*/}
{/*.maxwidth400{*/}
{/*max-width: 400px;*/}
{/*overflow: hidden;*/}
{/*text-overflow: ellipsis;*/}
{/*white-space: nowrap;*/}
{/*}*/}
{/*`*/}
{/*}*/}
{/*</style>*/}
{/*{this.state.fileList.length===0?"":this.state.fileList.map((item,key)=>{*/}
{/*debugger*/}
{/*return(*/}
{/*<p className="color-grey mt10" key={key} >*/}
{/*<a className="color-grey fl">*/}
{/*<i className="font-14 color-green iconfont icon-fujian mr8" aria-hidden="true"></i>*/}
{/*</a>*/}
{/*<span className="mr12 color9B9B maxwidth400 fl" length="58">*/}
{/*{item.name}*/}
{/*</span>*/}
{/*<span className="color656565 mt2 color-grey-6 font-12 mr8">*/}
{/*{item.response===undefined?"":isNaN(bytesToSize(item.filesize))?"":bytesToSize(item.filesize)}*/}
{/*</span>*/}
{/*<i className="font-14 iconfont icon-guanbi "*/}
{/*id={item.response===undefined?"":item.response.id}*/}
{/*aria-hidden="true" onClick={()=>this.onAttachmentRemove(item.response===undefined?"":item.response.id&&item.response.id)}></i>*/}
{/*</p>*/}
{/*)*/}
{/*})}*/}
{newfileListtype===true&&this.state.fileListtype===false?<p className={"color-red"}>请先上传资源</p>:""}
@ -484,13 +367,12 @@ class Sendresource extends Component{
}
`}</style>
{/*<div className={this.state.fileListtype===true?"mt30":""}></div><Checkbox checked={is_public} onChange={this.onChangepublic}>*/}
{/*<span className={"font-14"}>勾选后所有用户可见,否则仅课堂成员可见</span>*/}
{/*</Checkbox>*/}
{this.props.course_is_public===true?<div>
<span className={"color-ooo"}>公开</span><Checkbox checked={is_public} onChange={this.onChangepublic}>
<span className={"font-14 color-ooo"}>选中所有用户可见否则课堂成员可见</span>
</Checkbox>
</div>:""}
{this.state.course_groups_count&&this.state.course_groups_count>0?<Checkbox checked={is_unified_setting} onChange={this.onChangesetting}>
<span>统一设置</span><span className={"font-14 color-grey-9"}>(使)</span>
</Checkbox>:""}
<style>{`
.Selectleft20{
margin-left: 20px !important;
@ -505,54 +387,19 @@ class Sendresource extends Component{
overflow: auto;
}
`}</style>
<div className={"resourcebox"}>
{is_unified_setting===false?
course_group_publish_times.map((item,key)=>{
return(
<div className={"mt10"} key={key}>
</p>
<Select placeholder="请选择分班名称"
value={item.course_group_id}
style={{ width: 200 }}
onChange={(e,index)=>this.selectassigngroups(e,index,key)}
>
{course_groups&&course_groups.map((item,key)=>{
return(
<Option value={item.id} key={key}>{item.name}</Option>
)
})}
</Select>
<div className={this.props.course_is_public===true?"mt10":""}>
<span className={"color-ooo fl mt6"}>发布设置</span>
<Radio.Group onChange={this.RadioonChange} value={this.state.Radiovalue} style={{'width': '460px'}}>
<Radio style={radioStyle} value={0}>
立即发布
</Radio>
<Radio style={radioStyle} value={1} className={"fl"}>
<span className={"mr5"}>延迟发布</span>
<DatePicker
dropdownClassName="hideDisable"
showTime={{ format: 'HH:mm' }}
locale={locale}
showToday={false}
format={dateFormat}
placeholder="请选择发布时间"
id={"startimes"}
className={"Selectleft20 "}
width={"200px"}
value={item.publish_time===undefined||item.publish_time===""?undefined:moment(item.publish_time, dateFormat)}
onChange={(e,index)=>this.onChangeTimepublish(e,index,key,2)}
// onChange={ this.onChangeTimepublish }
disabledTime={disabledDateTime}
disabledDate={disabledDate}
/>
{key!=0?<i className="iconfont icon-shanchu color-grey-c font-14 font-n ml20" onClick={()=>this.deletegrouppublish(key)}></i>:""}
{key===course_group_publish_times.length-1&&key<this.state.course_groups_count-1?<i className="iconfont icon-tianjiafangda color-green ml15" onClick={this.addgrouppublish}></i>:""}
</div>
)
})
:""}
</div>
</p>
{is_unified_setting===true?<p className={"mt10"}>
<span>
<DatePicker
dropdownClassName="hideDisable"
showTime={{ format: 'HH:mm' }}
locale={locale}
@ -561,13 +408,17 @@ class Sendresource extends Component{
id={"startime"}
showToday={false}
width={"210px"}
value={datatime===undefined||datatime===""?undefined:moment(datatime, dateFormat)}
value={this.state.Radiovalue===1?datatime===undefined||datatime===""?undefined:moment(datatime, dateFormat):undefined}
onChange={(e,index)=>this.onChangeTimepublish(e,index,undefined,1)}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={this.state.Radiovalue===1?false:true}
/>
</span>
</p>:""}
</Radio>
<span className={"fl mt5 color-grey-c"}>(按照设置的时间定时发布)</span>
</Radio.Group>
</div>
{/*{course_group_publish_timestype===true?<p className={"color-red mt10"}>请填写完整</p>:""}*/}
<textarea placeholder="请在此输入资源描述最大限制100个字符" className={"mt10"} value={this.state.description} onInput={this.settextarea} style={{
@ -577,6 +428,7 @@ class Sendresource extends Component{
padding: '10px'
}}></textarea>
{descriptiontype===true?<p className={"color-red"}>请输入资源描述最大限制100个字符</p>:""}
{this.state.Radiovaluetype===true?<p className={"color-red"}>发布时间不能为空</p>:""}
<div className="clearfix mt30 edu-txt-center mb10">
<a className="task-btn color-white mr70" onClick={this.props.Cancel}>{this.props.Cancelname}</a>
<a className="task-btn task-btn-orange" onClick={()=>this.Saves()}>{this.props.Savesname}</a>

@ -2666,8 +2666,11 @@ class Studentshavecompletedthelist extends Component {
.ysltableows2 .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 9px;
}
mysjysltable1 .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 9px;
}
`}</style>
<div className="edu-table edu-back-white">
<div className="edu-table edu-back-white ysltableows2">
{data === undefined ? "" : <Table
dataSource={data}
columns={columnsys}
@ -2773,6 +2776,9 @@ class Studentshavecompletedthelist extends Component {
.ysltableows2 .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 9px;
}
mysjysltable2 .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 9px;
}
`}</style>
<div className="edu-table edu-back-white minH-560 ysltableows2">
{datas === undefined ? "" : <Table
@ -2826,6 +2832,9 @@ class Studentshavecompletedthelist extends Component {
.ysltableows .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 9px;
}
mysjysltable3 .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 9px;
}
`
}
</style>
@ -2917,6 +2926,9 @@ class Studentshavecompletedthelist extends Component {
.ysltableowss .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 9px;
}
mysjysltable4 .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 9px;
}
`}</style>
<div className="edu-table edu-back-white minH-560 ysltableowss">
{datas === undefined ? "" : <Table

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'
import React, { useState, useEffect, memo } from 'react'
import { trigger, WordsBtn } from 'educoder'
import { Input, Checkbox, Popconfirm } from "antd";
import axios from 'axios'
@ -6,11 +6,13 @@ import axios from 'axios'
/**
角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生
*/
function ChangeRolePop({ member_roles = [], record, courseId, onChangeRoleSuccess, showNotification, getUserId, fetchUser }) {
function ChangeRolePop({ member_roles = [], record, courseId, onChangeRoleSuccess, showNotification, getUserId, fetchUser, style }) {
const [checkBoxRoles, setCheckBoxRoles] = useState(member_roles)
useEffect(() => {
setCheckBoxRoles(member_roles)
}, [member_roles])
// useEffect(() => {
// if (checkBoxRoles.length != member_roles.length) { // 死循环
// setCheckBoxRoles(member_roles)
// }
// }, [member_roles])
function onCheckBoxChange(val) {
console.log(val)
@ -73,8 +75,8 @@ function ChangeRolePop({ member_roles = [], record, courseId, onChangeRoleSucces
</Checkbox.Group>
}
>
<WordsBtn style={'blue'}>修改角色</WordsBtn>
<WordsBtn style={'blue'} style2={style}>修改角色</WordsBtn>
</Popconfirm>
)
}
export default ChangeRolePop
export default memo(ChangeRolePop)

@ -89,7 +89,7 @@ function CourseGroupChooser({ course_groups, isAdminOrCreator = true, item, inde
<p className="drop_down_btn">
<a href="javascript:void(0)" className="color-grey-6"
onClick={() => trigger('groupAdd')}
>添加分班</a>
>新建分班</a>
</p>
</ul>
)

@ -152,7 +152,7 @@ function CourseGroupList(props) {
</React.Fragment> }
{
// pageType !== TYPE_STUDENTS &&
!isCourseEnd && isAdmin && isParent && <WordsBtn style="blue" className="mr30" onClick={()=>addDir()}>新建分班</WordsBtn> }
!isCourseEnd && isAdmin && <WordsBtn style="blue" className="mr30" onClick={()=>addDir()}>新建分班</WordsBtn> }
{/* {
isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>deleteDir()}>删除分班</WordsBtn> } */}
{/* {
@ -210,13 +210,13 @@ function CourseGroupList(props) {
onPressEnter={onPressEnter}
></Titlesearchsection>
<div className="mt20 edu-back-white padding20-30 ">
{!!none_group_member_count && <div className="mt20 edu-back-white padding20-30 ">
<span>未分班</span>
<span style={{color: '#999999'}}>{none_group_member_count}个学生</span>
<WordsBtn style="blue" className="fr "
onClick={() => {props.history.push(`/courses/${courseId}/course_groups/0`)}}>查看</WordsBtn>
</div>
</div>}
<Spin size="large" spinning={isSpin}>
{course_groups && !!course_groups.length ?

@ -28,7 +28,6 @@ function CourseGroupListTable(props) {
}
course_groups.forEach((record) => {
const id = record.id
debugger;
let _clipboard = new ClipboardJS(`.copyBtn_${id}`);
_clipboard.on('success', (e) => {
props.showNotification('复制成功')
@ -135,14 +134,14 @@ function CourseGroupListTable(props) {
{isAdmin && <WordsBtn style2={{ marginRight: '12px' }} data-clipboard-text={record.invite_code}
className={`copyBtn_${record.id}`} style={''}>复制邀请码</WordsBtn> }
{isStudent && <WordsBtn style2={{ marginRight: '12px' }} onClick={() => addToDir(record)} style={''}>加入分班</WordsBtn>}
<WordsBtn style2={{ marginRight: '12px' }} onClick={() => onGoDetail(record)} style={''}>查看</WordsBtn>
<WordsBtn onClick={() => onGoDetail(record)} style={''}>查看</WordsBtn>
</React.Fragment>
}
})
return columns
}
const addToDir = async (record) => {
const doAddToDir = async (record) => {
const courseId = props.match.params.coursesId
const url = `/courses/${courseId}/join_course_group.json`
const course_group_id = record.id
@ -151,11 +150,27 @@ function CourseGroupListTable(props) {
course_group_id
})
if (response && response.data.status == 0) {
props.showNotification('加入成功')
props.showNotification(`已加入分班:${record.name}`)
props.updataleftNavfun()
props.onOperationSuccess && props.onOperationSuccess()
}
}
const addToDir = (record) => {
props.confirm({
content: `是否确认加入分班: ${record.name}?`,
okText: '确认',
cancelText: '取消',
onOk: () => {
doAddToDir(record)
},
onCancel() {
console.log('Cancel');
},
});
}
function onDelete(record) {
props.confirm({

@ -107,7 +107,7 @@ const buildColumns = (that,isParent) => {
}
];
if (course_groups && course_groups.length) {
columns.push({
this.isStudentPage && columns.push({
title: '分班',
dataIndex: 'course_group_name',
key: 'course_group_name',
@ -130,7 +130,7 @@ const buildColumns = (that,isParent) => {
}
const isAdmin = that.props.isAdmin()
if (isAdmin) {
columns.unshift({
!that.isStudentPage && columns.unshift({
title: '',
dataIndex: 'check',
key: 'check',
@ -148,8 +148,9 @@ const buildColumns = (that,isParent) => {
render: (text, record) => {
return (
<React.Fragment>
<WordsBtn style2={{ marginRight: '12px' }} onClick={() => that.onDelete(record)} style={'grey'}>删除学生</WordsBtn>
<ChangeRolePop
<WordsBtn onClick={() => that.onDelete(record)} style={'grey'}>删除学生</WordsBtn>
{record.member_roles && record.member_roles.length && <ChangeRolePop
style={{ marginLeft: '12px' }}
courseId={courseId}
record={record}
member_roles={record.member_roles}
@ -157,7 +158,7 @@ const buildColumns = (that,isParent) => {
showNotification={that.props.showNotification}
getUserId={that.props.isUserid}
fetchUser={that.props.fetchUser}
></ChangeRolePop>
></ChangeRolePop>}
</React.Fragment>
)
},
@ -319,6 +320,9 @@ class studentsList extends Component{
isAdmin && on('updateNavSuccess', this.updateNavSuccess)
}
componentWillUnmount() {
if (this.clipboard) {
this.clipboard.destroy()
}
const isAdmin = this.props.isAdmin()
if (isAdmin) {
off('addStudentSuccess', this.addStudentSuccessListener)
@ -330,6 +334,7 @@ class studentsList extends Component{
}
updateNavSuccess = () => {
this.fetchCourseGroups()
this.fetchAll()
}
addStudentSuccessListener=(e, data)=>{
@ -418,6 +423,7 @@ class studentsList extends Component{
invite_code: result.data.invite_code,
isSpin:false
}, () => {
if (course_group_id) {
if (!this.clipboard) {
const clipboard = new ClipboardJS('.copybtn');
clipboard.on('success', (e) => {
@ -425,6 +431,7 @@ class studentsList extends Component{
});
this.clipboard = clipboard
}
}
})
}
}).catch((error)=>{
@ -547,7 +554,7 @@ class studentsList extends Component{
addDir = () => {
trigger('groupAdd', this.props.coursesids)
}
addToDir = async () => {
doAddToDir = async () => {
const courseId = this.props.match.params.coursesId
const url = `/courses/${courseId}/join_course_group.json`
const course_group_id = this.props.match.params.course_group_id
@ -556,11 +563,27 @@ class studentsList extends Component{
course_group_id
})
if (response && response.data.status == 0) {
this.props.showNotification('加入成功')
this.props.showNotification(`已加入分班:${this.state.course_group_name}`)
this.props.updataleftNavfun()
this.fetchAll()
}
}
addToDir = (record) => {
this.props.confirm({
content: `是否确认加入分班: ${this.state.course_group_name}?`,
okText: '确认',
cancelText: '取消',
onOk: () => {
this.doAddToDir()
},
onCancel() {
console.log('Cancel');
},
});
}
renameDir = () => {
const course_group_id = this.props.match.params.course_group_id
trigger('groupRename', { id: parseInt(course_group_id), name: this.state.course_group_name})
@ -572,15 +595,15 @@ class studentsList extends Component{
<div>是否确认删除?</div>
</div>,
onOk: () => {
// const cid = this.props.match.params.coursesId
const course_group_id = this.props.match.params.course_group_id
const courseId = this.props.match.params.coursesId
const url = `/course_groups/${course_group_id}.json`
axios.delete(url)
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('删除成功')
this.props.history.push(response.data.right_url)
this.props.history.push(`/courses/${courseId}/course_groups`)
}
})
.catch(function (error) {
@ -666,11 +689,14 @@ class studentsList extends Component{
if (this.props.match.path.endsWith('students')) {
} else if (course_group_id) {
pageType = TYPE_COURSE_GOURP_PARENT
} else {
pageType = TYPE_COURSE_GOURP_CHILD
} else {
pageType = TYPE_COURSE_GOURP_PARENT
}
// 本页面有2个状态学生列表、具体分班
const isStudentPage = pageType == TYPE_STUDENTS
this.isStudentPage = isStudentPage
const isGroupChildPage = pageType == TYPE_COURSE_GOURP_CHILD
return(
<React.Fragment >
@ -683,7 +709,12 @@ class studentsList extends Component{
<Titlesearchsection
title={isParent ? (pageType == TYPE_STUDENTS ? "全部学生" : "学生列表"):
<React.Fragment>
<span>{course_group_name || '未分班'}</span>
<span>
<Tooltip title="返回">
<i className="icon-zuojiantou iconfont font-14" onClick={() => { this.props.history.push(`/courses/${courseId}/course_groups`)}}
style={{color: '#212121', verticalAlign: 'initial', marginRight: '14px' }}
></i>
</Tooltip>{course_group_name || ''}</span>
{isAdmin && invite_code && <React.Fragment>
<span className="color-grey-9 font-16 ml10">邀请码</span>
<span className="color-orange font-16">
@ -708,23 +739,24 @@ class studentsList extends Component{
searchPlaceholder={ '请输入姓名、学号进行搜索' }
firstRowRight={
<React.Fragment>
{
{/* {
// pageType !== TYPE_STUDENTS &&
isSuperAdmin && <React.Fragment>
!isStudentPage && isSuperAdmin && <React.Fragment>
<CreateGroupByImportModal ref="createGroupByImportModal" {...this.props}
createGroupImportSuccess={this.createGroupImportSuccess}
></CreateGroupByImportModal>
<WordsBtn style="blue" className="mr30" onClick={()=> this.refs['createGroupByImportModal'].setVisible(true)}>导入创建分班</WordsBtn>
</React.Fragment> }
</React.Fragment> } */}
{
// pageType !== TYPE_STUDENTS &&
!isCourseEnd && isAdmin && isParent && <WordsBtn style="blue" className="mr30" onClick={()=>this.addDir()}>添加分班</WordsBtn> }
!isStudentPage && isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>this.deleteDir()}>删除分班</WordsBtn> }
{
isStudent && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>this.addToDir()}>加入分班</WordsBtn> }
!isStudentPage && isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>this.renameDir()}>分班重命名</WordsBtn> }
{
isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>this.deleteDir()}>删除分班</WordsBtn> }
!isStudentPage && !isCourseEnd && isAdmin && <WordsBtn style="blue" className="mr30" onClick={()=>this.addDir()}>新建分班</WordsBtn> }
{
isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>this.renameDir()}>分班重命名</WordsBtn> }
!isStudentPage && isStudent && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="" onClick={()=>this.addToDir()}>加入分班</WordsBtn> }
<style>{`
.drop_down_menu li a {
padding: 0px;
@ -779,11 +811,11 @@ class studentsList extends Component{
{
total_count > 0 || this.state.isSpin == true ?
<div className="mt20 edu-back-white padding20">
<div className="clearfix stu_head" style={{paddingLeft: '15px'}}>
{isAdmin && <Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue} >已选 {checkBoxValues.length} </Checkbox>}
<div className="clearfix stu_head" style={{paddingLeft: '5px'}}>
{isAdmin && !isStudentPage && <Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue} >已选 {checkBoxValues.length} </Checkbox>}
<div className="studentList_operation_ul">
{/* {isAdmin && <li className="li_line"><a href="javascript:void(0)" className="color-grey-9" onClick={this.onDelete}>删除</a></li>} */}
{isAdmin && <li className="drop_down">
{isAdmin && !isStudentPage && <li className="drop_down">
移动到...<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu" style={{"right":"0px","left":"unset", width: '200px', maxHeight: '324px', overflowY: 'auto'}}>
{
@ -810,7 +842,7 @@ class studentsList extends Component{
<p className="drop_down_btn">
<a href="javascript:void(0)" className="color-grey-6"
onClick={()=>this.addDir()}
>添加分班...</a>
>新建分班...</a>
</p>
}

@ -200,7 +200,8 @@ function buildColumns(that) {
},
})
}
if(isAdminOrTeacher && hasGraduationModule) {
// 待审批不需要
if(filterKey == '1' && isAdminOrTeacher && hasGraduationModule) {
columns.unshift({
title: '',
dataIndex: 'course_member_id',

@ -1725,7 +1725,7 @@ class Trainingjobsetting extends Component {
flagPageEditstwo:releasetime,
flagPageEditsthrees:deadline,
flagPageEditsfor:endtime,
completionefficiencyscore:true,
completionefficiencyscore:false,
work_efficiencys:this.state.work_efficiencys,
unifiedsetting:this.state.unifiedsetting,
latedeductiontwo:this.state.latedeductiontwo,
@ -1841,7 +1841,7 @@ class Trainingjobsetting extends Component {
flagPageEditstwo:releasetime,
flagPageEditsthrees:deadline,
flagPageEditsfor:endtime,
completionefficiencyscore:true,
completionefficiencyscore:datas.data.work_efficiency===true?true:false,
work_efficiencys:datas.data.work_efficiency,
unifiedsetting:datas.data.unified_setting,
latedeductiontwo:datas.data.eff_score,

@ -1142,11 +1142,38 @@ class ShixunHomework extends Component{
addsave={addsave}
/>
{
datas&&datas.category_name===undefined||datas&&datas.category_name===null?"":
<style>
{
`
.category_namehome{
max-width: 558px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
margin-right: 5px;
}
.category_namehomelist{
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
`
}
</style>
}
<div className="edu-back-white">
<p className="clearfix padding30 bor-bottom-greyE">
<p style={{height: '20px'}}>
<span className="font-18 fl color-dark-21">{datas&&datas.category_name===undefined||datas&&datas.category_name===null?datas&&datas.main_category_name:datas&&datas.category_name+" 作业列表"}</span>
<span className="font-18 fl color-dark-21">
{datas&&datas.category_name===undefined||datas&&datas.category_name===null?datas&&datas.main_category_name:<span>
<span className={"category_namehome"}>{datas&&datas.category_name} </span>
<span className={"category_namehomelist"}> 作业列表</span>
</span>}
</span>
<li className="fr">
{datas===undefined?"":datas.homeworks && datas.homeworks.length>1?this.props.isAdminOrCreator()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null?
<span>

@ -60,7 +60,7 @@ class MemoTechShare extends Component {
(oldParsed.order && newParsed.order && oldParsed.order != newParsed.order)) {
this.props.fetchMemos();
}
console.log('componentWillReceiveProps...')
// console.log('componentWillReceiveProps...')
}
}

@ -19,6 +19,8 @@ import {
notification
} from "antd";
import {Link, Switch, Route, Redirect} from 'react-router-dom';
import { SnackbarHOC,getImageUrl } from 'educoder';
import { TPMIndexHOC } from '../tpm/TPMIndexHOC';
import '../courses/css/members.css';
import "../courses/common/formCommon.css"
import '../courses/css/Courses.css';
@ -108,7 +110,8 @@ class EducoderLogin extends Component {
}
componentDidMount() {
// console.log("EducoderLogin");
// console.log(this.props);
}
Setlogins=(i)=>{
@ -137,6 +140,9 @@ class EducoderLogin extends Component {
render() {
let {showbool,loginstatus,logini} = this.state;
console.log("EducoderLogingetHelmetapi");
console.log(this.props);
// console.log(this.props.mygetHelmetapi);
return (
<div style={newContainer} className=" clearfix" >
@ -148,7 +154,13 @@ class EducoderLogin extends Component {
"width": "100%"
}}>
<div style={{cursor:"pointer"}}>
{
this.props.mygetHelmetapi===undefined||this.props.mygetHelmetapi.login_logo_url===null|| this.props.mygetHelmetapi.login_logo_url===undefined?
<img style={{cursor:"pointer"}} onClick={()=>this.gohome()} src={educodernet}/>
:
<img style={{cursor:"pointer"}} onClick={()=>this.gohome()} src={getImageUrl(this.props.mygetHelmetapi.login_logo_url)}/>
}
</div>
@ -196,7 +208,6 @@ class EducoderLogin extends Component {
}
}
export default EducoderLogin ;
// showbool === 2 ?
// <div style={{

@ -103,8 +103,13 @@
}
#closeIcon{
position: absolute;
top: -30px;
right: -27px;
z-index: 100000;
}
#logincloseIcon{
position: absolute;
top: -100px;
right: -27px;

@ -568,7 +568,7 @@ class LoginDialog extends Component {
</style>:""}
{isRender===true?
<div className={dialogBox}>
<div id="closeIcon" onClick={()=>{this.handleDialogClose()}}>
<div id="closeIcon" className={"logincloseIcon"} onClick={()=>{this.handleDialogClose()}}>
<i className="iconfont icon-shanchudiao"></i>
</div>

@ -39,6 +39,8 @@ class NewFooter extends Component {
</ul>
</div>
<div>
{
this.props.mygetHelmetapi===undefined|| this.props.mygetHelmetapi.footer===null||this.props.mygetHelmetapi.footer===undefined?
<p className="footer_con-p inline lineh-30 font-14">
<span className="font-18 fl">©</span>&nbsp;2019&nbsp;EduCoder
<a style={{"color":"#888"}} target="_blank" href="http://beian.miit.gov.cn/" className="ml15 mr15">湘ICP备17009477号</a>
@ -49,6 +51,11 @@ class NewFooter extends Component {
target="_blank">Trustie</a>&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;IntelliDE inside. <span
className="mr15">版权所有 湖南智擎科技有限公司</span>
</p>
:
<div dangerouslySetInnerHTML={{__html: this.props.mygetHelmetapi.footer}}></div>
}
</div>
<div className="cl"></div>
</div>

@ -65,13 +65,26 @@ class NewHeader extends Component {
showTrial:false,
setevaluatinghides:false,
occupation:0,
mydisplay:false
mydisplay:false,
headtypesonClickbool:false,
headtypess:"/",
mygetHelmetapi2:undefined,
}
// console.log("176")
console.log("176")
// console.log(props);
// console.log("NewHeader1234567890");
// console.log(this.props);
}
componentDidUpdate = (prevProps) => {
// console.log("componentDidMount2");
// console.log(this.state.mygetHelmetapi2);
if(this.state.mygetHelmetapi2===undefined){
this.getAppdata();
}
}
componentDidMount() {
console.log("componentDidMount1");
this.getAppdata();
window._header_componentHandler = this;
//下拉框的显示隐藏
@ -633,8 +646,77 @@ submittojoinclass=(value)=>{
this.setState({
AccountProfiletype:false
})
};
headtypesonClick=(url,bool)=>{
this.setState({
headtypess:url,
headtypesonClickbool:bool,
})
}
getAppdata=()=>{
// console.log("开始刷新数据了")
let url = "/setting.json";
axios.get(url).then((response) => {
// console.log("axios.get");
// console.log(response);
if(response){
if(response.data){
this.setState({
mygetHelmetapi2:response.data.setting
});
document.title = response.data.setting.name;
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = '/'+response.data.setting.tab_logo_url;
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}else {
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
}else{
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
}).catch((error) => {
console.log("开始刷新定制数据了但报错了");
console.log(error);
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
});
};
render() {
const isLogin = true; // 这里不会出现未登录的情况,服务端在服务端路由时发现如果是未登录,则跳转到登录页了。
const {match,} = this.props;
@ -655,6 +737,9 @@ submittojoinclass=(value)=>{
user,
isRender,
showSearchOpentype,
headtypesonClickbool,
headtypess,
mygetHelmetapi2,
}=this.state;
/*
用户名称 用户头像url
@ -684,6 +769,95 @@ submittojoinclass=(value)=>{
activeIndex = true;
}
let headtypes='/';
// console.log("mygetHelmetapi2");
// console.log(mygetHelmetapi2);
if(mygetHelmetapi2){
if(mygetHelmetapi2.navbar){
if(mygetHelmetapi2.navbar.length>0){
// console.log("mygetHelmetapi2.navbar.length>0====-=-=--=-=-=-=");
//
// console.log(match.path);
if(match.path==='/'){
if(headtypesonClickbool===false){
headtypes=undefined;
}else{
headtypes=headtypess;
}
}else {
for(var i=0;i<mygetHelmetapi2.navbar.length;i++){
if(match.path===mygetHelmetapi2.navbar[i].link){
headtypes=mygetHelmetapi2.navbar[i].link;
break;
}
}
}
}else{
if (match.path === '/forums') {
headtypes = '/forums';
} else if (match.path.startsWith('/shixuns')) {
headtypes = '/shixuns';
}else if (match.path.startsWith('/paths')) {
headtypes = '/paths';
} else if (match.path.startsWith('/courses')) {
headtypes = '/courses';
}else if (match.path.startsWith('/competitions')) {
headtypes = '/competitions';
}else if (match.path.startsWith('/crowdsourcing')) {
headtypes = '/crowdsourcing';
}else if(match.path.startsWith('/moop_cases')){
headtypes = '/moop_cases';
}else {
headtypes = '/';
}
}
}else{
if (match.path === '/forums') {
headtypes = '/forums';
} else if (match.path.startsWith('/shixuns')) {
headtypes = '/shixuns';
}else if (match.path.startsWith('/paths')) {
headtypes = '/paths';
} else if (match.path.startsWith('/courses')) {
headtypes = '/courses';
}else if (match.path.startsWith('/competitions')) {
headtypes = '/competitions';
}else if (match.path.startsWith('/crowdsourcing')) {
headtypes = '/crowdsourcing';
}else if(match.path.startsWith('/moop_cases')){
headtypes = '/moop_cases';
}else {
headtypes = '/';
}
}
}else{
if (match.path === '/forums') {
headtypes = '/forums';
} else if (match.path.startsWith('/shixuns')) {
headtypes = '/shixuns';
}else if (match.path.startsWith('/paths')) {
headtypes = '/paths';
} else if (match.path.startsWith('/courses')) {
headtypes = '/courses';
}else if (match.path.startsWith('/competitions')) {
headtypes = '/competitions';
}else if (match.path.startsWith('/crowdsourcing')) {
headtypes = '/crowdsourcing';
}else if(match.path.startsWith('/moop_cases')){
headtypes = '/moop_cases';
}else {
headtypes = '/';
}
}
// console.log("NewHeadergetHelmetapi432423423423");
// console.log(mygetHelmetapi2);
// console.log("NewHeadermygetHelmetapi123123123123");
// console.log(mygetHelmetapi2);
// console.log(this.props);
return (
<div className="newHeaders" id="nHeader" >
@ -699,9 +873,14 @@ submittojoinclass=(value)=>{
{...this.props}
{...this.state}
/>:""}
<Link to="/" className={"fl mr30 ml25 mt10"}>
<img alt="高校智能化教学与实训平台" className="logoimg" src={getImageUrl("images/educoder/headNavLogo.png?1526520218")}></img>
</Link>
<a href={"/"} onClick={()=>this.headtypesonClick("/",false)} className={"fl mr30 ml25 mt10"}>
{
mygetHelmetapi2===undefined||mygetHelmetapi2.nav_logo_url===null||mygetHelmetapi2.nav_logo_url===undefined?
<img alt="高校智能化教学与实训平台" className="logoimg" style={{heigth:"40px"}} src={getImageUrl("images/educoder/headNavLogo.png?1526520218")}></img>
:
<img alt="高校智能化教学与实训平台" className="logoimg" style={{heigth:"40px"}} src={getImageUrl(mygetHelmetapi2.nav_logo_url)}></img>
}
</a>
<style>
{
@ -714,10 +893,156 @@ submittojoinclass=(value)=>{
`
}
</style>
<div className="educontents fl">
{/*<%= link_to image_tag("/images/educoder/logo.png", alt:"高校智能化教学与实训平台", className:"logoimg"), home_path %>*/}
{
mygetHelmetapi2!==undefined&&mygetHelmetapi2.navbar!==null&&mygetHelmetapi2.navbar!==undefined&&mygetHelmetapi2.navbar.length>0?
<div className="head-nav pr" id={"head-navpre1"}>
<ul id="header-nav">
{/*<li className={`${activeIndex === true ? 'active' : ''}`}><a href="/">首页</a></li>*/}
{/*<li><a href={this.props.Headertop===undefined?"":this.props.Headertop.shixun_paths_url}>实训路径</a></li>*/}
{
mygetHelmetapi2.navbar && mygetHelmetapi2.navbar.map((item,key)=>{
// console.log("headtypes");
// console.log(headtypes);hidden
var str=new RegExp("http");
var strbool=false;
//test方法返回值为(true或者false)
if(item.link){
if(str.test(item.link)===true){
strbool=true
}else{
strbool=false
}
}
console.log(item.hidden);
return(
<li key={key} onClick={()=>this.headtypesonClick(item.link,true)} className={`${headtypes===undefined?'pr':headtypes===item.link?'pr active':'pr'}`} style={item.hidden==false?{display: 'block'}:{display: 'none'}}>
{
strbool===true?
<a href={item.link}>{item.name}</a>
:
<Link to={item.link}>{item.name}</Link>
}
</li>
)
})
}
{/*<li className={`${activePaths === true ? 'pr active' : 'pr'}`}>*/}
{/* <Link to={this.props.Headertop===undefined?"":'/paths'}>实践课程</Link>*/}
{/*</li>*/}
{/*<li><a href={this.props.Headertop===undefined?"":'/courses'}>课堂</a></li>*/}
{/*<li className={`${coursestype === true ? 'pr active' : 'pr'}`}>*/}
{/* /!*<a href={this.props.Headertop===undefined?"":this.props.Headertop.course_url}>课堂</a>*!/*/}
{/* <Link to={this.props.Headertop===undefined?"":'/courses'}>翻转课堂</Link>*/}
{/*</li>*/}
{/*<li className={`${activeShixuns === true ? 'pr active' : 'pr'}`}>*/}
{/* <Link to="/shixuns">实训项目</Link>*/}
{/* <img src={getImageUrl("images/educoder/hot-h.png")} className="nav-img">*/}
{/* </img>*/}
{/*</li>*/}
<div className="head-nav pr">
{/*<li className=""><a href={"/libraries"}>教学案例</a></li>*/}
{/*<li className="">*/}
{/* <a href={this.props.Headertop===undefined?"":this.props.Headertop.competitions_url}>在线竞赛</a>*/}
{/* <img className="roundedRectangles"*/}
{/* src={require('./roundedRectangle.png')}*/}
{/* />*/}
{/*</li>*/}
{/*<li className={`${activeMoopCases === true ? 'pr active' : 'pr'}`}> <Link to={`/moop_cases`}>教学案例</Link></li>*/}
{/*<li className={`${activePackages === true ? 'pr active' : 'pr'}`}>*/}
{/*<Link to={'/crowdsourcing'}>众包创新</Link>*/}
{/*</li>*/}
{/*<li className={`${activeForums === true ? 'active' : ''}`}> <Link to={this.props.Headertop===undefined?"":this.props.Headertop.topic_url}>交流问答</Link></li>*/}
{/*<li*/}
{/* style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.auth===null? 'none' : 'block'}}*/}
{/*><a href={this.props.Headertop===undefined?"":this.props.Headertop.auth}>工程认证</a></li>*/}
<li className="fl edu-menu-panel careershover "
style={{display: this.props.Headertop === undefined ?'none' : this.props.Headertop.career_url.length > 0 ? 'block' : 'none'}}>
<a>职业路径</a>
<div
style={{display: this.props.Headertop === undefined ?'none' : this.props.Headertop.career_url.length > 0 ? 'block' : 'none'}}>
<ul className="edu-menu-list edu-menu-listnew " style={{top:'60px'}}>
{this.props.Headertop === undefined ? "" : this.props.Headertop.career_url.map((item, key) => {
return(
<li key={key}><i className="iconfont icon-java left careersiconfont"
style={{color: '#000 important'}}
></i><a style={{width: '83%'}}
href={item.url}>{item.name}</a></li>
)
})
}
</ul>
</div>
</li>
</ul>
</div>
// :mygetHelmetapi2===undefined||mygetHelmetapi2.navbar===null||mygetHelmetapi2.navbar===undefined||mygetHelmetapi2.navbar.length===0?
// <div className="head-nav pr" id={"head-navpre2"}>
//
// <ul id="header-nav">
// {/*<li className={`${activeIndex === true ? 'active' : ''}`}><a href="/">首页</a></li>*/}
//
// {/*<li><a href={this.props.Headertop===undefined?"":this.props.Headertop.shixun_paths_url}>实训路径</a></li>*/}
// <li className={`${activePaths === true ? 'pr active' : 'pr'}`}>
// <Link to={this.props.Headertop===undefined?"":'/paths'}>实践课程</Link>
// </li>
//
// {/*<li><a href={this.props.Headertop===undefined?"":'/courses'}>课堂</a></li>*/}
// <li className={`${coursestype === true ? 'pr active' : 'pr'}`}>
// {/*<a href={this.props.Headertop===undefined?"":this.props.Headertop.course_url}>课堂</a>*/}
// <Link to={this.props.Headertop===undefined?"":'/courses'}>翻转课堂</Link>
// </li>
//
// <li className={`${activeShixuns === true ? 'pr active' : 'pr'}`}>
// <Link to="/shixuns">实训项目</Link>
// {/*<img src={getImageUrl("images/educoder/hot-h.png")} className="nav-img">*/}
// {/*</img>*/}
// </li>
//
// <li className="fl edu-menu-panel careershover "
// style={{display: this.props.Headertop === undefined ?'none' : this.props.Headertop.career_url.length > 0 ? 'block' : 'none'}}>
// <a>职业路径</a>
// <div
// style={{display: this.props.Headertop === undefined ?'none' : this.props.Headertop.career_url.length > 0 ? 'block' : 'none'}}>
// <ul className="edu-menu-list edu-menu-listnew " style={{top:'60px'}}>
// {this.props.Headertop === undefined ? "" : this.props.Headertop.career_url.map((item, key) => {
// return(
// <li key={key}><i className="iconfont icon-java left careersiconfont"
// style={{color: '#000 important'}}
// ></i><a style={{width: '83%'}}
// href={item.url}>{item.name}</a></li>
// )
// })
// }
// </ul>
// </div>
// </li>
//
// {/*<li className=""><a href={"/libraries"}>教学案例</a></li>*/}
// <li className="">
// <a href={this.props.Headertop===undefined?"":this.props.Headertop.competitions_url}>在线竞赛</a>
// {/*<img className="roundedRectangles"*/}
// {/* src={require('./roundedRectangle.png')}*/}
// {/*/>*/}
// </li>
// <li className={`${activeMoopCases === true ? 'pr active' : 'pr'}`}> <Link to={`/moop_cases`}>教学案例</Link></li>
// {/*<li className={`${activePackages === true ? 'pr active' : 'pr'}`}>*/}
// {/*<Link to={'/crowdsourcing'}>众包创新</Link>*/}
// {/*</li>*/}
// <li className={`${activeForums === true ? 'active' : ''}`}> <Link to={this.props.Headertop===undefined?"":this.props.Headertop.topic_url}>交流问答</Link></li>
// <li
// style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.auth===null? 'none' : 'block'}}
// ><a href={this.props.Headertop===undefined?"":this.props.Headertop.auth}>工程认证</a></li>
// </ul>
// </div>
:
<div className="head-nav pr" id={"head-navpre3"}>
<ul id="header-nav">
{/*<li className={`${activeIndex === true ? 'active' : ''}`}><a href="/">首页</a></li>*/}
@ -735,8 +1060,8 @@ submittojoinclass=(value)=>{
<li className={`${activeShixuns === true ? 'pr active' : 'pr'}`}>
<Link to="/shixuns">实训项目</Link>
<img src={getImageUrl("images/educoder/hot-h.png")} className="nav-img">
</img>
{/*<img src={getImageUrl("images/educoder/hot-h.png")} className="nav-img">*/}
{/*</img>*/}
</li>
<li className="fl edu-menu-panel careershover "
@ -761,9 +1086,9 @@ submittojoinclass=(value)=>{
{/*<li className=""><a href={"/libraries"}>教学案例</a></li>*/}
<li className="">
<a href={this.props.Headertop===undefined?"":this.props.Headertop.competitions_url}>在线竞赛</a>
<img className="roundedRectangles"
src={require('./roundedRectangle.png')}
/>
{/*<img className="roundedRectangles"*/}
{/* src={require('./roundedRectangle.png')}*/}
{/*/>*/}
</li>
<li className={`${activeMoopCases === true ? 'pr active' : 'pr'}`}> <Link to={`/moop_cases`}>教学案例</Link></li>
{/*<li className={`${activePackages === true ? 'pr active' : 'pr'}`}>*/}
@ -774,10 +1099,13 @@ submittojoinclass=(value)=>{
style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.auth===null? 'none' : 'block'}}
><a href={this.props.Headertop===undefined?"":this.props.Headertop.auth}>工程认证</a></li>
</ul>
</div>
}
</div>
</div>
<style>
{

@ -7,8 +7,8 @@ import NewFooter from './NewFooter'
import SiderBar from './SiderBar'
import { getUrl, downloadFile } from 'educoder'
import axios from 'axios';
import { Spin } from 'antd'
import './TPMIndex.css'
import { Spin } from 'antd';
import './TPMIndex.css';
import LoginDialog from '../login/LoginDialog';
import AccountProfile from '../user/AccountProfile';
@ -83,7 +83,8 @@ export function TPMIndexHOC(WrappedComponent) {
globalLoading: false,
dataquerys:{},
isloginCancel:undefined
isloginCancel:undefined,
mygetHelmetapi:undefined,
}
}
@ -147,6 +148,8 @@ export function TPMIndexHOC(WrappedComponent) {
}
componentDidMount() {
// console.log("TPMIndexHOC========");
// console.log(this.props);
window.addEventListener('keyup', this.keyupListener)
if(this.props.match.path==="/"){
@ -198,6 +201,8 @@ export function TPMIndexHOC(WrappedComponent) {
axios.get(url, {
}).then((response) => {
// console.log("开始请求/get_navigation_info.json");
// console.log(response);
if(response!=undefined){
if(response.status===200){
this.setState({
@ -207,7 +212,8 @@ export function TPMIndexHOC(WrappedComponent) {
}
}
});
///请求定制化的信息
this.getAppdata();
}
/**
课堂权限相关方法暂时写这里了 ----------------------------------------START
@ -277,7 +283,67 @@ export function TPMIndexHOC(WrappedComponent) {
//
// }
//获取当前定制信息
//获取当前定制信息
getAppdata=()=>{
let url = "/setting.json";
axios.get(url).then((response) => {
// console.log("app.js开始请求/setting.json");
// console.log("获取当前定制信息");
if(response){
if(response.data){
this.setState({
mygetHelmetapi:response.data.setting
});
document.title = response.data.setting.name;
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = '/'+response.data.setting.tab_logo_url;
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}else {
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
}else{
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
}).catch((error) => {
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
});
};
/**
课堂权限相关方法暂时写这里了 ----------------------------------------END
*/
@ -535,7 +601,7 @@ export function TPMIndexHOC(WrappedComponent) {
this.setState({ globalLoading: false })
}
render() {
let{Headertop,Footerdown, isRender, AccountProfiletype}=this.state;
let{Headertop,Footerdown, isRender, AccountProfiletype,mygetHelmetapi}=this.state;
const common = {
isSuperAdmin:this.isSuperAdmin,
isAdminOrCreator:this.isAdminOrCreator,
@ -569,7 +635,9 @@ export function TPMIndexHOC(WrappedComponent) {
yslslowCheckresults:this.yslslowCheckresults,
yslslowCheckresultsNo:this.yslslowCheckresultsNo,
}
};
// console.log("this.props.mygetHelmetapi");
// console.log(this.props.mygetHelmetapi);
return (
<div className="indexHOC">
{isRender===true ? <LoginDialog
@ -644,6 +712,7 @@ export function TPMIndexHOC(WrappedComponent) {
</Spin>
<NewFooter
{...this.state} {...this.props}
Footerdown={Footerdown}
/>

@ -17,7 +17,7 @@ class LoginRegisterPage extends Component {
// newMain clearfix
return (
<div className="">
login
<LoginRegisterComponent {...this.props} {...this.state}></LoginRegisterComponent>
<br></br>
<br></br>

@ -197,6 +197,7 @@ input::-ms-clear{display:none;}
.color-white{color: #ffffff!important;}
/*黑色*/
.color-dark{color: #05101a!important;}
.color-ooo{color: #000!important;}
/*灰色*/
.color-grey-name{color: #1A0B00!important;}
.color-grey-fa{color: #FAFAFA!important;}

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