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

sso^2
cxt 5 years ago
commit a136bdb8ca

2
.gitignore vendored

@ -43,7 +43,7 @@
/public/react/config/stats.json /public/react/config/stats.json
/public/react/stats.json /public/react/stats.json
/public/react/.idea/* /public/react/.idea/*
/public/h5build
/public/npm-debug.log /public/npm-debug.log
# avatars # avatars

@ -19,6 +19,10 @@ class MainController < ApplicationController
uid_logger("main start is #{cookies[:_educoder_session]}") uid_logger("main start is #{cookies[:_educoder_session]}")
end end
if params[:path] == "h5"
render file: 'public/h5build/index.html', :layout => false
else
render file: 'public/react/build/index.html', :layout => false render file: 'public/react/build/index.html', :layout => false
end end
end end
end

@ -265,7 +265,9 @@ class MyshixunsController < ApplicationController
uid_logger_dubug("-- game build: file update #{@sec_key}, record id is #{record.id}, time is **** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") uid_logger_dubug("-- game build: file update #{@sec_key}, record id is #{record.id}, time is **** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
end end
# 隐藏代码文件 和 VNC的都不需要走版本库 # 隐藏代码文件 和 VNC的都不需要走版本库
unless @hide_code || (@myshixun.shixun&.vnc_evaluate && params[:evaluate].present?) vnc = @myshixun.shixun&.vnc
unless @hide_code || (vnc && params[:evaluate].present?)
# 远程版本库文件内容 # 远程版本库文件内容
last_content = GitService.file_content(repo_path: @repo_path, path: path)["content"] last_content = GitService.file_content(repo_path: @repo_path, path: path)["content"]
@ -275,8 +277,8 @@ class MyshixunsController < ApplicationController
else else
params[:content] params[:content]
end end
uid_logger_dubug("###11222333####{content}") uid_logger_dubug("content_#{@myshixun.identifier}: #{content}")
uid_logger_dubug("###222333####{last_content}") uid_logger_dubug("###last_content_#{@myshixun.identifier}####{last_content}")
if content != last_content if content != last_content
@content_modified = 1 @content_modified = 1
@ -286,6 +288,7 @@ class MyshixunsController < ApplicationController
message = params[:evaluate] == 0 ? "System automatically submitted" : "User submitted" message = params[:evaluate] == 0 ? "System automatically submitted" : "User submitted"
uid_logger_dubug("112233#{author_name}") uid_logger_dubug("112233#{author_name}")
uid_logger_dubug("112233#{author_email}") uid_logger_dubug("112233#{author_email}")
uid_logger_dubug("daiao_debug_#{@myshixun.identifier}: #{@repo_path}: #{path}; #{message}; #{content}; ")
@content = GitService.update_file(repo_path: @repo_path, @content = GitService.update_file(repo_path: @repo_path,
file_path: path, file_path: path,
message: message, message: message,

@ -474,7 +474,7 @@ class ShixunsController < ApplicationController
if params[:shixun][:vnc] if params[:shixun][:vnc]
shixun_params.merge(vnc_evaluate: 1) shixun_params.merge(vnc_evaluate: 1)
else else
shixun_params shixun_params.merge(vnc_evaluate: 0)
end end
@shixun.update_attributes!(update_params) @shixun.update_attributes!(update_params)
end end

@ -72,7 +72,7 @@ class SubjectsController < ApplicationController
end end
# 排序 # 排序
order_str = reorder == "publish_time" ? "status = 2 desc, publish_time asc" : "updated_at desc" order_str = (reorder == "publish_time" ? "homepage_show desc, excellent desc, status = 2 desc, publish_time asc" : "homepage_show desc, excellent desc, updated_at desc")
@subjects = @subjects.reorder(order_str) @subjects = @subjects.reorder(order_str)
end end

@ -22,7 +22,7 @@ class Subjects::CourseUsedInfoService < ApplicationService
# choice_shixun_frequency: 选用该课程实训的次数 # choice_shixun_frequency: 选用该课程实训的次数
course_info = [] course_info = []
schools.find_in_batches do |s| schools.find_in_batches do |s|
Parallel.each(s) do |school| s.each do |school|
name = school.name name = school.name
course_count = school.course_count course_count = school.course_count
student_count = school.courses.joins(:course_members).where(course_members: {role: 4, course_id: course_ids}).size student_count = school.courses.joins(:course_members).where(course_members: {role: 4, course_id: course_ids}).size

@ -11,7 +11,7 @@ class Subjects::ShixunUsedInfoService < ApplicationService
position = stage.position position = stage.position
shixuns = stage.shixuns.includes(myshixuns: :games, homework_commons: :course) shixuns = stage.shixuns.includes(myshixuns: :games, homework_commons: :course)
shixuns.find_in_batches(batch_size: 1000) do |s| shixuns.find_in_batches(batch_size: 1000) do |s|
Parallel.each_with_index(s, in_processes: 2) do |shixun, index| s.each_with_index do |shixun, index|
stage = "#{position}-#{index+1}" stage = "#{position}-#{index+1}"
name = shixun.name name = shixun.name
myshixuns = shixun.myshixuns myshixuns = shixun.myshixuns

@ -13,7 +13,7 @@ class Subjects::UserUsedInfoService < ApplicationService
users_info = [] users_info = []
users = User.includes(myshixuns: :games).where(myshixuns: {shixun_id: shixun_ids}, games: {status: 2}, users: {is_test: false}) users = User.includes(myshixuns: :games).where(myshixuns: {shixun_id: shixun_ids}, games: {status: 2}, users: {is_test: false})
users.find_in_batches(batch_size: 500) do |u| users.find_in_batches(batch_size: 500) do |u|
Parallel.each(u, in_processes: 2) do |user| u.each do |user|
myshixuns = user.myshixuns.select{|m| shixun_ids.include?(m.shixun_id)} myshixuns = user.myshixuns.select{|m| shixun_ids.include?(m.shixun_id)}
name = "#{user.lastname}#{user.firstname}" name = "#{user.lastname}#{user.firstname}"
passed_myshixun_count = myshixuns.select{|m| m.status == 1}.size passed_myshixun_count = myshixuns.select{|m| m.status == 1}.size

@ -0,0 +1,10 @@
class ModifyVncEvaluteForShixuns < ActiveRecord::Migration[5.2]
def change
Shixun.find_each do |shixun|
if !shixun.vnc && shixun.vnc_evaluate
puts "####shixun_id: #{shixun.id}"
shixun.update_column(:vnc_evaluate, false)
end
end
end
end

@ -0,0 +1,14 @@
class AddIndexToUserIdAndShixunIdForShixuns < ActiveRecord::Migration[5.2]
def change
shixun_members = ShixunMember.select("count(*) cnt, shixun_members.*").group(:user_id, :shixun_id).having("cnt > 1")
puts "shixun_members: #{shixun_members.map{|sm| sm.id}}"
shixun_members.each do |sm|
s = ShixunMember.where.not(id: sm.id).where(user_id: sm.user_id, shixun_id: sm.shixun_id)
puts "s: #{s.map{|sm| sm.id}}"
s.delete_all
end
add_index :shixun_members, [:user_id, :shixun_id], unique: true
end
end

@ -5,12 +5,14 @@ namespace :subjects do
puts("---------------------data_statistic_begin") puts("---------------------data_statistic_begin")
Rails.logger.info("---------------------data_statistic_begin") Rails.logger.info("---------------------data_statistic_begin")
subjects = Subject.where(status: 2, hidden: 0) subjects = Subject.where(status: 2, hidden: 0)
str = "" if ENV['subject_id'].present?
buffer_size = 0 subjects = subjects.where(id:ENV['subject_id'])
end
column_value = "subject_id, study_count, course_study_count, initiative_study, passed_count, course_used_count, " + column_value = "subject_id, study_count, course_study_count, initiative_study, passed_count, course_used_count, " +
"school_used_count, created_at, updated_at" "school_used_count, created_at, updated_at"
subjects.find_in_batches(batch_size: 50) do |s| subjects.find_in_batches(batch_size: 50) do |s|
Parallel.each(s, in_processes: 4) do |subject| str = []
Parallel.each_with_index(s, in_threads: 4) do |subject, index|
puts("---------------------data_statistic: #{subject.id}") puts("---------------------data_statistic: #{subject.id}")
Rails.logger.info("---------------------data_statistic: #{subject.id}") Rails.logger.info("---------------------data_statistic: #{subject.id}")
data = Subjects::DataStatisticService.new(subject) data = Subjects::DataStatisticService.new(subject)
@ -18,26 +20,19 @@ namespace :subjects do
next if study_count == 0 next if study_count == 0
course_study_count = data.course_study_count course_study_count = data.course_study_count
initiative_study = study_count - course_study_count initiative_study = study_count - course_study_count
str += ", " unless str.empty? str << ("(#{subject.id}, #{study_count}, #{course_study_count}, #{initiative_study}, " +
str += ("(#{subject.id}, #{study_count}, #{course_study_count}, #{initiative_study}, " +
"#{data.passed_count}, #{data.course_used_count}, #{data.school_used_count}, " + "#{data.passed_count}, #{data.course_used_count}, #{data.school_used_count}, " +
"'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')") "'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')")
buffer_size += 1 puts "index: #{index}; worker_number: #{Parallel.worker_number}"
puts "buffer_size: #{buffer_size}; subject: #{subject == s.last}; index:#{index+1}" puts "####str: #{str}"
if buffer_size == 1000 || subject == s.last
sql = "REPLACE INTO subject_records(#{column_value}) VALUES #{str}"
puts sql
ActiveRecord::Base.connection.execute sql
str = ""
buffer_size = 0
end
end end
end if str.size > 0
if buffer_size > 0 sql = "REPLACE INTO subject_records(#{column_value}) VALUES #{str.uniq.join(",")}"
sql = "REPLACE INTO subject_records(#{column_value}) VALUES #{str}"
puts sql puts sql
ActiveRecord::Base.connection.execute sql ActiveRecord::Base.connection.execute sql
end end
end
puts("---------------------data_statistic_end") puts("---------------------data_statistic_end")
Rails.logger.info("---------------------data_statistic_end") Rails.logger.info("---------------------data_statistic_end")
end end
@ -46,38 +41,36 @@ namespace :subjects do
puts("---------------------course_info_statistic_begin") puts("---------------------course_info_statistic_begin")
Rails.logger.info("---------------------course_info_statistic_begin") Rails.logger.info("---------------------course_info_statistic_begin")
subjects = Subject.where(status: 2, hidden: 0) subjects = Subject.where(status: 2, hidden: 0)
str = ""
buffer_size = 0
column_value = "subject_id, school_id, school_name, course_count, student_count, choice_shixun_num, " + column_value = "subject_id, school_id, school_name, course_count, student_count, choice_shixun_num, " +
"choice_shixun_frequency, created_at, updated_at" "choice_shixun_frequency, created_at, updated_at"
if ENV['subject_id'].present?
subjects.find_in_batches(batch_size: 50) do |s| subjects = subjects.where(id:ENV['subject_id'])
Parallel.each(s, in_processes: 4) do |subject| end
subjects.find_in_batches(batch_size: 20) do |s|
Parallel.each_with_index(s, in_processes: 4) do |subject, index, str = []|
puts("---------------------course_info_statistic: #{subject.id}") puts("---------------------course_info_statistic: #{subject.id}")
Rails.logger.info("---------------------course_info_statistic: #{subject.id}") Rails.logger.info("---------------------course_info_statistic: #{subject.id}")
data = Subjects::CourseUsedInfoService.call(subject) data = Subjects::CourseUsedInfoService.call(subject)
Parallel.map_with_index(data) do |key, index| data.each do |key|
next if key[:school_id].nil? next if key[:school_id].nil?
str += ", " unless str.empty? str << ("(#{subject.id}, #{key[:school_id]}, '#{key[:school_name]}', #{key[:course_count]}, " +
str += ("(#{subject.id}, #{key[:school_id]}, '#{key[:school_name]}', #{key[:course_count]}, " +
"#{key[:student_count]}, #{key[:choice_shixun_num]}, #{key[:choice_shixun_frequency]}, " + "#{key[:student_count]}, #{key[:choice_shixun_num]}, #{key[:choice_shixun_frequency]}, " +
"'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')") "'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')")
buffer_size += 1 # if str.size == 1000
if buffer_size == 1000 || (index + 1) == data.size # sql = "REPLACE INTO subject_course_records(#{column_value}) VALUES #{str.uniq.join(",")}"
sql = "REPLACE INTO subject_course_records(#{column_value}) VALUES #{str}" # str_c = str
# puts sql
# ActiveRecord::Base.connection.execute sql
# str -= str_c
# end
end
if str.size > 0
sql = "REPLACE INTO subject_course_records(#{column_value}) VALUES #{str.uniq.join(",")}"
puts sql puts sql
ActiveRecord::Base.connection.execute sql ActiveRecord::Base.connection.execute sql
str = ""
buffer_size = 0
end
end end
end end
end end
if buffer_size > 0
sql = "REPLACE INTO subject_course_records(#{column_value}) VALUES #{str}"
puts sql
ActiveRecord::Base.connection.execute sql
end
puts("---------------------course_info_statistic_end") puts("---------------------course_info_statistic_end")
Rails.logger.info("---------------------course_info_statistic_end") Rails.logger.info("---------------------course_info_statistic_end")
end end
@ -86,38 +79,35 @@ namespace :subjects do
puts("---------------------shixun_info_statistic_begin") puts("---------------------shixun_info_statistic_begin")
Rails.logger.info("---------------------shixun_info_statistic_begin") Rails.logger.info("---------------------shixun_info_statistic_begin")
subjects = Subject.where(status: 2, hidden: 0) subjects = Subject.where(status: 2, hidden: 0)
str = "" if ENV['subject_id'].present?
buffer_size = 0 subjects = subjects.where(id:ENV['subject_id'])
end
column_value = "subject_id, shixun_id, stage, shixun_name, challenge_count, course_count, " + column_value = "subject_id, shixun_id, stage, shixun_name, challenge_count, course_count, " +
"school_count, used_count, passed_count, evaluate_count, passed_ave_time, created_at, updated_at" "school_count, used_count, passed_count, evaluate_count, passed_ave_time, created_at, updated_at"
subjects.find_in_batches(batch_size: 50) do |s| subjects.find_in_batches(batch_size: 20) do |s|
Parallel.each_with_index(s, in_processes: 4) do |subject| Parallel.each_with_index(s, in_processes: 4) do |subject, index, str = []|
puts("---------------------shixun_info_statistic: #{subject.id}") puts("---------------------shixun_info_statistic: #{subject.id}")
Rails.logger.info("---------------------shixun_info_statistic: #{subject.id}") Rails.logger.info("---------------------shixun_info_statistic: #{subject.id}")
data = Subjects::ShixunUsedInfoService.call(subject) data = Subjects::ShixunUsedInfoService.call(subject)
data.each_with_index do |key, index| data.each do |key|
next if key[:shixun_id].nil? next if key[:shixun_id].nil?
str += ", " unless str.empty? str << ("(#{subject.id}, #{key[:shixun_id]}, '#{key[:stage]}', '#{key[:name]}', #{key[:challenge_count]}, " +
str += ("(#{subject.id}, #{key[:shixun_id]}, '#{key[:stage]}', '#{key[:name]}', #{key[:challenge_count]}, " +
"#{key[:course_count]}, #{key[:school_count]}, #{key[:used_count]}, #{key[:passed_count]}, " + "#{key[:course_count]}, #{key[:school_count]}, #{key[:used_count]}, #{key[:passed_count]}, " +
"#{key[:evaluate_count]}, #{key[:passed_ave_time]}, " + "#{key[:evaluate_count]}, #{key[:passed_ave_time]}, " +
"'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')") "'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')")
buffer_size += 1 # if str.size == 1000
if buffer_size == 1000 || (index+1) == data.size # sql = "REPLACE INTO subject_shixun_infos(#{column_value}) VALUES #{str.join(",")}"
sql = "REPLACE INTO subject_shixun_infos(#{column_value}) VALUES #{str}" # puts sql
# ActiveRecord::Base.connection.execute sql
# end
end
if str.size > 0
sql = "REPLACE INTO subject_shixun_infos(#{column_value}) VALUES #{str.join(",")}"
puts sql puts sql
ActiveRecord::Base.connection.execute sql ActiveRecord::Base.connection.execute sql
str = ""
buffer_size = 0
end
end end
end end
end end
if buffer_size > 0
sql = "REPLACE INTO subject_shixun_infos(#{column_value}) VALUES #{str}"
puts sql
ActiveRecord::Base.connection.execute sql
end
puts("---------------------shixun_info_statistic_end") puts("---------------------shixun_info_statistic_end")
Rails.logger.info("---------------------shixun_info_statistic_end") Rails.logger.info("---------------------shixun_info_statistic_end")
end end
@ -126,36 +116,29 @@ namespace :subjects do
puts("---------------------user_info_statistic_begin") puts("---------------------user_info_statistic_begin")
Rails.logger.info("---------------------user_info_statistic_begin") Rails.logger.info("---------------------user_info_statistic_begin")
subjects = Subject.where(status: 2, hidden: 0) subjects = Subject.where(status: 2, hidden: 0)
str = ""
buffer_size = 0
column_value = "user_id, subject_id, username, passed_myshixun_count, passed_games_count, " + column_value = "user_id, subject_id, username, passed_myshixun_count, passed_games_count, " +
"code_line_count, evaluate_count, cost_time, created_at, updated_at" "code_line_count, evaluate_count, cost_time, created_at, updated_at"
subjects.find_in_batches(batch_size: 20) do |s|
subjects.find_in_batches(batch_size: 50) do |s| Parallel.each_with_index(s, in_processes: 4) do |subject, index, str = []|
Parallel.each_with_index(s, in_processes: 4) do |subject, index|
puts("---------------------user_info_statistic: #{subject.id}") puts("---------------------user_info_statistic: #{subject.id}")
data = Subjects::UserUsedInfoService.call(subject) data = Subjects::UserUsedInfoService.call(subject)
data.each do |key| data.each do |key|
next if key[:user_id].nil? str << ("(#{key[:user_id]}, #{subject.id}, '#{key[:name].gsub(/'/, '"')}', #{key[:passed_myshixun_count]}, " +
str += ", " unless str.empty?
str += ("(#{key[:user_id]}, #{subject.id}, '#{key[:name].gsub(/'/, '"')}', #{key[:passed_myshixun_count]}, " +
"#{key[:passed_games_count]}, #{key[:code_line_count]}, #{key[:evaluate_count]}, #{key[:cost_time]}, " + "#{key[:passed_games_count]}, #{key[:code_line_count]}, #{key[:evaluate_count]}, #{key[:cost_time]}, " +
"'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')") "'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')")
buffer_size += 1 # if str.size == 1000
if buffer_size == 1000 || (index+1 == data.size) # sql = "REPLACE INTO subject_user_infos(#{column_value}) VALUES #{str.join(",")}"
sql = "REPLACE INTO subject_user_infos(#{column_value}) VALUES #{str}" # ActiveRecord::Base.connection.execute sql
# str = []
# end
end
if str.size > 0
sql = "REPLACE INTO subject_user_infos(#{column_value}) VALUES #{str.join(",")}"
puts sql
ActiveRecord::Base.connection.execute sql ActiveRecord::Base.connection.execute sql
str = ""
buffer_size = 0
end
end end
end end
end end
if buffer_size > 0
sql = "REPLACE INTO subject_user_infos(#{column_value}) VALUES #{str}"
puts sql
ActiveRecord::Base.connection.execute sql
end
puts("---------------------user_info_statistic_end") puts("---------------------user_info_statistic_end")
Rails.logger.info("---------------------user_info_statistic_end") Rails.logger.info("---------------------user_info_statistic_end")
end end

@ -5,9 +5,9 @@
<title>EduCoder</title> <title>EduCoder</title>
<meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" type="text/css" href="/stylesheets/css/edu-common.css?1"> <link rel="stylesheet" type="text/css" href="/stylesheets/css/edu-common.css?2">
<link rel="stylesheet" type="text/css" href="/stylesheets/educoder/edu-main.css?1"> <link rel="stylesheet" type="text/css" href="/stylesheets/educoder/edu-main.css?2">
<link rel="stylesheet" type="text/css" href="/stylesheets/educoder/edu-all.css?1"> <link rel="stylesheet" type="text/css" href="/stylesheets/educoder/edu-all.css?2">
</head> </head>
<body style="" data-gr-c-s-loaded="true"> <body style="" data-gr-c-s-loaded="true">

@ -15,7 +15,7 @@
text-align: center; text-align: center;
height: 60px; height: 60px;
box-sizing: border-box; box-sizing: border-box;
min-width: 785px; min-width: 780px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;

@ -367,10 +367,10 @@ const JupyterTPI = Loadable({
loading: Loading loading: Loading
}); });
// 微信代码编辑器 // 微信代码编辑器
const WXCode = Loadable({ // const WXCode = Loadable({
loader: () => import('./modules/wxcode'), // loader: () => import('./modules/wxcode'),
loading: Loading // loading: Loading
}); // });
// //个人竞赛报名 // //个人竞赛报名
// const PersonalCompetit = Loadable({ // const PersonalCompetit = Loadable({
// loader: () => import('./modules/competition/personal/PersonalCompetit.js'), // loader: () => import('./modules/competition/personal/PersonalCompetit.js'),
@ -828,11 +828,11 @@ class App extends Component {
render={ render={
(props) => (<Headplugselection {...this.props} {...props} {...this.state} />) (props) => (<Headplugselection {...this.props} {...props} {...this.state} />)
}/> }/>
<Route path="/wxcode/:identifier?" component={WXCode} {/*<Route path="/wxcode/:identifier?" component={WXCode} */}
render={ {/* render={*/}
(props)=>(<WXCode {...this.props} {...props} {...this.state}></WXCode>) {/* (props)=>(<WXCode {...this.props} {...props} {...this.state}></WXCode>)*/}
} {/* }*/}
/> {/*/>*/}
<Route exact path="/" <Route exact path="/"
// component={ShixunsHome} // component={ShixunsHome}
render={ render={

@ -1195,6 +1195,9 @@ const options = [{
children: [{ children: [{
value: "太原", value: "太原",
label: '太原' label: '太原'
},{
value: "吕梁",
label: '吕梁'
},{ },{
value: '长治', value: '长治',
label: '长治' label: '长治'

@ -36,6 +36,12 @@ class Live extends Component{
</a> </a>
<a href="https://www.douyu.com/special/guide/anchor" target="_blank" className="color-blue ml20">(简明手册)</a> <a href="https://www.douyu.com/special/guide/anchor" target="_blank" className="color-blue ml20">(简明手册)</a>
</li> </li>
<li>
<a><img alt="" src={WeiBaiTong} className="mr8" width="28px"/>
<label className="color-grey-3 pointer">威佰通</label>
</a>
<a href="https://www.educoder.net/forums/3734" target="_blank" className="color-blue ml20">(简明手册)</a>
</li>
</ul> </ul>
{ {
lives && lives.length > 0 ? lives && lives.length > 0 ?

@ -1,11 +1,29 @@
import React,{ Component } from "react"; import React,{ Component } from "react";
import { getImageUrl } from 'educoder'; import { getImageUrl } from 'educoder';
import { Modal } from 'antd';
import { WordsBtn } from 'educoder'; import { WordsBtn } from 'educoder';
import moment from 'moment';
import axios from 'axios'; import axios from 'axios';
class LiveItem extends Component{ // 点击按钮复制功能
function jsCopy(props){
var e = document.getElementById("copy_meet_content");
e.select();
document.execCommand("Copy");
props.showNotification("复制成功!");
}
const $ = window.$;
function getRight(){
var right = parseInt($(".-task-sidebar").css("right"));
return right;
}
class LiveItem extends Component{
constructor(props) {
super(props);
this.state = {
visible:false
}
}
deleteLive=(id)=>{ deleteLive=(id)=>{
this.props.confirm({ this.props.confirm({
@ -27,12 +45,80 @@ class LiveItem extends Component{
console.log('Cancel'); console.log('Cancel');
}, },
}); });
}
alertInfo=()=>{
this.setState({
visible:true
})
getRight();
}
onDialogOkBtnClick=()=>{
this.setState({
visible:false,
})
} }
render(){ render(){
const { key, item , setLiveId } = this.props; const { key, item , setLiveId } = this.props;
const { visible } = this.state;
const wei_flag = item.platform && (item.platform === "威佰通");
console.log(wei_flag && item.url);
return( return(
<div className="liveItem" key={key}> <div className="liveItem" key={key}>
<Modal
title="提示"
visible={visible}
closable={false}
footer={null}
keyboard={false}
centered={true}
>
{
wei_flag && item.url ?
<React.Fragment>
<div className="task-popup-content edu-txt-center">
<p className="font-16">打开威佰通客户端输入会议号即可进入直播</p>
<div className="wei_meet">
<p className="wei_meet_info">
<span>会议号</span>
<input value={item.url} className="showNumber" readOnly id="copy_meet_content"/>
<a className="color-blue ml50" onClick={()=>jsCopy(this.props)}>复制会议号</a>
</p>
</div>
</div>
<div className="task-popup-submit clearfix edu-txt-center">
<a className="task-btn fl" onClick={this.onDialogOkBtnClick}>取消</a >
<a className="task-btn task-btn-orange fr" onClick={this.onDialogOkBtnClick}>完成</a >
</div>
</React.Fragment>
:
<React.Fragment>
<div className="task-popup-content">
<p className="task-popup-text-center font-16 pb20">{wei_flag ? "当前直播无会议号":"直播链接失效"}</p >
</div>
<div className="task-popup-submit clearfix edu-txt-center">
<a className="task-btn task-btn-orange mr51" onClick={this.onDialogOkBtnClick}>知道了</a >
</div>
</React.Fragment>
}
</Modal>
{
visible ?
<style>{
`
body{
width: calc(100% - 7px)!important;
overflow: hidden!important;
}
.-task-sidebar{
right:${getRight()+7}px!important;
}
`}
</style>
:
""
}
<div className="lineMiddle livesMain"> <div className="lineMiddle livesMain">
<span className="lineMiddle"> <span className="lineMiddle">
<span className="font-18 task-hide" style={{maxWidth:"759px"}}>{item.course_name}</span> <span className="font-18 task-hide" style={{maxWidth:"759px"}}>{item.course_name}</span>
@ -44,8 +130,22 @@ class LiveItem extends Component{
<p><span className="task-hide-2 break_word">{item.description}</span></p> <p><span className="task-hide-2 break_word">{item.description}</span></p>
</div> </div>
{ {
(item.on_status && item.url)? item.on_status ?
<React.Fragment>
{
item.url ?
<React.Fragment>
{
wei_flag ?
<a className="btns going" onClick={this.alertInfo}>进入</a>
:
<a className="btns going" target="_blank" href={`${item.url}`}>进入</a> <a className="btns going" target="_blank" href={`${item.url}`}>进入</a>
}
</React.Fragment>
:
<a className="btns going" onClick={this.alertInfo}>进入</a>
}
</React.Fragment>
: :
<span className="btns ect">进入</span> <span className="btns ect">进入</span>
} }
@ -56,7 +156,7 @@ class LiveItem extends Component{
<label className="mr50">{item.author_name}</label> <label className="mr50">{item.author_name}</label>
{ item.platform && <span className="mr50">直播平台{item.platform}</span> } { item.platform && <span className="mr50">直播平台{item.platform}</span> }
{ item.live_time && <span className="mr50">开播时间{item.live_time}</span>} { item.live_time && <span className="mr50">开播时间{item.live_time}</span>}
{ item.duration && <span className="mr50">直播时长{item.duration}</span> } { item.duration && <span className="mr50">直播预计时长{item.duration}分钟</span> }
</span> </span>
<span> <span>
{ {

@ -9,7 +9,7 @@ import axios from 'axios';
const { TextArea } = Input; const { TextArea } = Input;
const { Option } = Select; const { Option } = Select;
const array=['腾讯课堂','B站','斗鱼','威佰通'] const array=['腾讯课堂','B站','斗鱼','威佰通'];
function range(start, end) { function range(start, end) {
const result = []; const result = [];
@ -35,6 +35,7 @@ class LiveNew extends Component{
this.state={ this.state={
isSpining:false, isSpining:false,
beginTime:undefined, beginTime:undefined,
wei_flag:undefined
} }
} }
@ -66,7 +67,8 @@ class LiveNew extends Component{
course_name:result.data.course_name course_name:result.data.course_name
}) })
this.setState({ this.setState({
beginTime:result.data.live_time && moment(result.data.live_time,"YYYY-MM-DD HH:mm") beginTime:result.data.live_time && moment(result.data.live_time,"YYYY-MM-DD HH:mm"),
wei_flag:result.data.platform && result.data.platform === "威佰通"
}) })
} }
}) })
@ -167,7 +169,8 @@ class LiveNew extends Component{
duration:undefined duration:undefined
}) })
this.setState({ this.setState({
beginTime:undefined beginTime:undefined,
wei_flag:false
}) })
} }
@ -177,8 +180,20 @@ class LiveNew extends Component{
}) })
} }
ChangePlatform=(e)=>{
if(e === "威佰通"){
this.setState({
wei_flag:true
})
}else{
this.setState({
wei_flag:false
})
}
}
render(){ render(){
const { isSpining , beginTime } = this.state; const { isSpining , beginTime , wei_flag } = this.state;
const {getFieldDecorator} = this.props.form; const {getFieldDecorator} = this.props.form;
const { visible } = this.props; const { visible } = this.props;
@ -212,16 +227,17 @@ class LiveNew extends Component{
})( })(
<AutoComplete <AutoComplete
placeholder="请选择或输入直播平台名称" placeholder="请选择或输入直播平台名称"
onChange={this.ChangePlatform}
dataSource={dataSource} dataSource={dataSource}
> >
</AutoComplete> </AutoComplete>
)} )}
</Form.Item> </Form.Item>
<Form.Item label={`直播链接`}> <Form.Item label={wei_flag?`会议号`:`直播链接`}>
{getFieldDecorator('url', { {getFieldDecorator('url', {
rules: [], rules: [],
})( })(
<Input placeholder="请输入第三方直播链接,如:腾讯课堂播放链接等。" /> <Input placeholder={wei_flag?`请输入会议号`:"请输入第三方直播链接,如:腾讯课堂播放链接等。"} />
)} )}
</Form.Item> </Form.Item>
<div className="flex-bottom"> <div className="flex-bottom">
@ -242,7 +258,7 @@ class LiveNew extends Component{
onChange={this.onChangeTime} onChange={this.onChangeTime}
></DatePicker> ></DatePicker>
</div> </div>
<Form.Item label={`直播时长`}> <Form.Item label={`直播预计时长`}>
{getFieldDecorator('duration', { {getFieldDecorator('duration', {
rules: [], rules: [],
})( })(

@ -14,6 +14,12 @@ import '../css/Courses.css';
import '../publicNav/nav.css'; import '../publicNav/nav.css';
const PAGE_SIZE = 15; const PAGE_SIZE = 15;
const LIVE_PAGE_SIZE = 10; const LIVE_PAGE_SIZE = 10;
const $ = window.$;
function getRight(){
var right = parseInt($(".-task-sidebar").css("right"));
return right;
}
class VideoIndex extends Component{ class VideoIndex extends Component{
constructor(props){ constructor(props){
super(props); super(props);
@ -47,8 +53,17 @@ class VideoIndex extends Component{
} }
componentDidMount=()=>{ componentDidMount=()=>{
const { type ,page } = this.state; const { search } = this.props.location;
this.checkType(type,page); const { page } = this.state;
if(search && search === "?open=live"){
this.setState({
type:"live"
})
this.checkType("live",page);
}else{
this.checkType("video",page);
}
} }
// 获取直播列表 // 获取直播列表
getLiveList=(page)=>{ getLiveList=(page)=>{
@ -200,14 +215,11 @@ class VideoIndex extends Component{
overflow: hidden!important; overflow: hidden!important;
} }
.-task-sidebar{ .-task-sidebar{
right:44px!important right:${getRight()+7}px!important;
} }
`}</style>: `}</style>:
<style>{ <style>{
` `
.-task-sidebar{
right:35px
}
body{ body{
width: 100%!important; width: 100%!important;
} }

@ -162,7 +162,18 @@
margin-bottom: 10px; margin-bottom: 10px;
} }
.platform > li{ .platform > li{
margin-right: 80px; margin-right: 50px;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.showNumber{
border:none;
}
.wei_meet{
display: flex;
margin:20px auto;
align-items: center;
}
.wei_meet_info{
margin:0px auto;
}

@ -373,8 +373,8 @@ class ShixunhomeWorkItem extends Component{
{this.props.isAdmin?<span onClick={(event)=>this.stopPro(event)} className={discussMessage&&discussMessage.shixun_status>1?this.props.isAdminOrCreator()?" newhomepagePostSettingname fr":" homepagePostSettingbox fr":" newwidthSettin fr"} style={{"right":"-2px","top":"6px","display":"block"}}> {this.props.isAdmin?<span onClick={(event)=>this.stopPro(event)} className={discussMessage&&discussMessage.shixun_status>1?this.props.isAdminOrCreator()?" newhomepagePostSettingname fr":" homepagePostSettingbox fr":" newwidthSettin fr"} style={{"right":"-2px","top":"6px","display":"block"}}>
{discussMessage&&discussMessage.shixun_status>1?<Link className="btn colorblue font-16 fontweight400 mr20" to={"/shixuns/"+discussMessage.shixun_identifier+"/challenges"} target={"_blank"}>实训详情</Link>: {discussMessage&&discussMessage.shixun_status>1?<Link className="btn colorblue font-16 fontweight400 mr20" to={"/shixuns/"+discussMessage.shixun_identifier+"/challenges"} target={"_blank"}>进入学习</Link>:
<a className={"btn colorfff font-16 fontweight400 "}>实训详情</a> <a className={"btn colorfff font-16 fontweight400 "}>进入学习</a>
} }
@ -388,26 +388,27 @@ class ShixunhomeWorkItem extends Component{
discussMessage.time_status<5? discussMessage.time_status<5?
<WordsBtn style="blue" className="colorblue font-16 mr20 fr mt2 "> <WordsBtn style="blue" className="colorblue font-16 mr20 fr mt2 ">
{startbtn===false? {startbtn===false?
(discussMessage.task_operation[0] == '继续挑战' || discussMessage.task_operation[0] == '查看实战' ? (discussMessage.task_operation[0] == '进入学习' || discussMessage.task_operation[0] == '进入学习' ?
<a className="btn colorblue" href={getTaskUrlById(discussMessage.task_operation[1])}> <a className="btn colorblue" href={getTaskUrlById(discussMessage.task_operation[1])}>
{discussMessage.task_operation[0]} {/*{discussMessage.task_operation[0]}*/}
进入学习
</a> </a>
: :
<a className="btn colorblue" onClick={()=>this.taskoperationId(discussMessage.task_operation[1])}> <a className="btn colorblue" onClick={()=>this.taskoperationId(discussMessage.task_operation[1])}>
{discussMessage.task_operation[0]} 进入学习
</a>):<a className="btn colorblue" ></a>} </a>):<a className="btn colorblue" ></a>}
</WordsBtn>:"":"":"":"" </WordsBtn>:"":"":"":""
} }
{ this.props.isAdmin?<a onClick={()=>this.hrefjumpskip("/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+discussMessage.homework_id+"/list?tab=0")} className="btn colorblue font-16 fontweight400 mr20 fr">作品详情</a>:""} { this.props.isAdmin?<a onClick={()=>this.hrefjumpskip("/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+discussMessage.homework_id+"/list?tab=0")} className="btn colorblue font-16 fontweight400 mr20 fr">作品列表</a>:""}
{ {
this.props.isStudent? <a onClick={()=>this.hrefjumpskip("/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+discussMessage.homework_id+"/list?tab=0")} className="btn colorblue font-16 fontweight400 mr20 fr mt2">作品详情</a>:"" this.props.isStudent? <a onClick={()=>this.hrefjumpskip("/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+discussMessage.homework_id+"/list?tab=0")} className="btn colorblue font-16 fontweight400 mr20 fr mt2">作品列表</a>:""
} }
{ {
this.props.isNotMember===true? this.props.discussMessage.private_icon===true?"" this.props.isNotMember===true? this.props.discussMessage.private_icon===true?""
:<a onClick={()=>this.hrefjumpskip("/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+discussMessage.homework_id+"/list?tab=0")} className="btn colorblue font-16 fontweight400 mr20 fr">作品详情</a>:"" :<a onClick={()=>this.hrefjumpskip("/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+discussMessage.homework_id+"/list?tab=0")} className="btn colorblue font-16 fontweight400 mr20 fr">作品列表</a>:""
} }

@ -510,6 +510,8 @@ class MessagSub extends Component {
//分组作业 //分组作业
return window.open(`/courses/${item.belong_container_id}/group_homeworks/${item.parent_container_id}`); return window.open(`/courses/${item.belong_container_id}/group_homeworks/${item.parent_container_id}`);
} }
case 'LiveLink':
return window.open(`/courses/${item.belong_container_id}/course_videos?open=live`);
case 'Hack': case 'Hack':
if (item.extra && item.parent_container_type !== 'HackDelete') { if (item.extra && item.parent_container_type !== 'HackDelete') {
return window.open(`/problems/${item.extra}/edit`); return window.open(`/problems/${item.extra}/edit`);

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2020-01-10 09:33:45 * @Date: 2020-01-10 09:33:45
* @LastEditors : tangjiang * @LastEditors : tangjiang
* @LastEditTime : 2020-01-14 17:01:32 * @LastEditTime : 2020-02-14 14:39:40
*/ */
import './index.scss'; import './index.scss';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
@ -166,36 +166,42 @@ const App = (props) => {
{ {
title: '姓名', title: '姓名',
dataIndex: 'username', dataIndex: 'username',
align: 'center' align: 'center',
width: 200
}, },
{ {
title: '通关实训数', title: '通关实训数',
dataIndex: 'passed_myshixun_count', dataIndex: 'passed_myshixun_count',
align: 'center', align: 'center',
with: 150,
sorter: (a, b) => a.passed_myshixun_count - b.passed_myshixun_count sorter: (a, b) => a.passed_myshixun_count - b.passed_myshixun_count
}, },
{ {
title: '完成关卡', title: '完成关卡',
dataIndex: 'passed_games_count', dataIndex: 'passed_games_count',
align: 'center', align: 'center',
with: 150,
sorter: (a, b) => a.passed_games_count - b.passed_games_count sorter: (a, b) => a.passed_games_count - b.passed_games_count
}, },
{ {
title: '代码行', title: '代码行',
dataIndex: 'code_line_count', dataIndex: 'code_line_count',
align: 'center', align: 'center',
with: 150,
sorter: (a, b) => a.code_line_count - b.code_line_count sorter: (a, b) => a.code_line_count - b.code_line_count
}, },
{ {
title: '评测次数', title: '评测次数',
dataIndex: 'evaluate_count', dataIndex: 'evaluate_count',
align: 'center', align: 'center',
with: 150,
sorter: (a, b) => a.evaluate_count - b.evaluate_count sorter: (a, b) => a.evaluate_count - b.evaluate_count
}, },
{ {
title: '所用时间', title: '所用时间',
dataIndex: 'cost_time', dataIndex: 'cost_time',
align: 'center', align: 'center',
with: 150,
render: (text) => (text && moment(text).format('HH:mm:ss')) || '-', render: (text) => (text && moment(text).format('HH:mm:ss')) || '-',
sorter: (a, b) => a.cost_time - b.cost_time sorter: (a, b) => a.cost_time - b.cost_time
} }

@ -35,14 +35,14 @@ if (!window['indexHOCLoaded']) {
// $('head').append($('<link rel="stylesheet" type="text/css" />') // $('head').append($('<link rel="stylesheet" type="text/css" />')
// .attr('href', `${_url_origin}/stylesheets/educoder/antd.min.css?1525440977`)); // .attr('href', `${_url_origin}/stylesheets/educoder/antd.min.css?1525440977`));
$('head').append($('<link rel="stylesheet" type="text/css" />') $('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?1`)); .attr('href', `${_url_origin}/stylesheets/css/edu-common.css?3`));
$('head').append($('<link rel="stylesheet" type="text/css" />') $('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?1`)); .attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?3`));
// index.html有加载 // index.html有加载
$('head').append($('<link rel="stylesheet" type="text/css" />') $('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?1`)); .attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?3`));
// $('head').append($('<link rel="stylesheet" type="text/css" />') // $('head').append($('<link rel="stylesheet" type="text/css" />')

@ -15,7 +15,7 @@
text-align: center; text-align: center;
height: 60px; height: 60px;
box-sizing: border-box; box-sizing: border-box;
min-width: 785px; min-width: 780px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;

Loading…
Cancel
Save