Merge branch 'dev_aliyun' into dev_Cs

# Conflicts:
#	public/react/src/App.js
dev_hjm
caishi 6 years ago
commit 8ea3901027

@ -1,2 +0,0 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.

@ -1,3 +0,0 @@
// Place all the styles related to the forums controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -160,7 +160,7 @@ class AccountsController < ApplicationController
# 发送验证码
# params[:login] 手机号或者邮箱号
# params[:type]为事件通知类型 1用户注册注册 2忘记密码 3: 绑定手机 4: 绑定邮箱 # 如果有新的继续后面加
# params[:type]为事件通知类型 1用户注册注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
# 发送验证码send_type 1注册手机验证码 2找回密码手机验证码 3找回密码邮箱验证码 4绑定手机 5绑定邮箱
# 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码 9: 验收手机号有效
def get_verification_code
@ -200,7 +200,7 @@ class AccountsController < ApplicationController
session[:user_id] = nil
end
# type 事件类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱 # 如果有新的继续后面加
# type 事件类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
# login_type 1手机类型 2邮箱类型
def verify_type login_type, type
case type
@ -212,6 +212,8 @@ class AccountsController < ApplicationController
login_type == 1 ? 4 : tip_exception('请填写正确的手机号')
when 4
login_type == 1 ? tip_exception('请填写正确的邮箱') : 5
when 5
login_type == 1 ? 9 : tip_exception('请填写正确的手机号')
end
end

@ -64,10 +64,10 @@ class ApplicationController < ActionController::Base
# 发送及记录激活码
# 发送验证码type 1注册手机验证码 2找回密码手机验证码 3找回密码邮箱验证码 4绑定手机 5绑定邮箱
# 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码
# 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码 9验证手机号有效
def check_verification_code(code, send_type, value)
case send_type
when 1, 2, 4
when 1, 2, 4, 9
# 手机类型的发送
sigle_para = {phone: value}
status = Educoder::Sms.send(mobile: value, code: code)
@ -241,14 +241,17 @@ class ApplicationController < ActionController::Base
User.current = User.find 57703
end
if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
User.current = User.find 81403
elsif params[:debug] == 'student'
User.current = User.find 8686
elsif params[:debug] == 'admin'
User.current = User.find 1
end
# 测试版前端需求
if request.host == "47.96.87.25"
if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
User.current = User.find 81403
elsif params[:debug] == 'student'
User.current = User.find 8686
elsif params[:debug] == 'admin'
User.current = User.find 1
end
end
# User.current = User.find 81403
end

@ -1,7 +1,7 @@
class DiscussesController < ApplicationController
LIMIT = 10
before_action :find_container, only: [:index, :hidden]
before_action :find_discuss, except: [:create, :index, :new_message, :reward_code]
before_action :find_discuss, except: [:create, :index, :new_message, :reward_code, :forum_discusses]
def index
page = params[:page].to_i
@ -28,6 +28,48 @@ class DiscussesController < ApplicationController
@current_user = current_user
end
def forum_discusses
page = params[:page] || 1
limit = params[:limit] || 15
offset = (page.to_i-1) * limit
search = params[:search]
tag = params[:tag_repertoire_id]
sql, sql1, sql2 = '', '', ''
sql1 =
unless search.blank?
"and d.content like '%#{search}%'"
end
sql2 =
if tag
shixun_ids = ShixunTagRepertoire.where(:tag_repertoire_id => tag).pluck(:shixun_id)
"and d.dis_id in(#{shixun_ids.join(",")})"
end
sql = "select d.id from discusses d join shixuns s on d.dis_id = s.id where s.status = 2 and s.hidden = false and d.root_id is null
and d.hidden = false #{sql1} #{sql2} order by d.created_at desc"
memo_ids = Discuss.find_by_sql(sql).pluck(:id)
@memo_count = memo_ids.size
memo_ids = memo_ids[offset, limit]
order_ids = memo_ids.size > 0 ? memo_ids.join(',') : -1
@memos = Discuss.where(id: memo_ids).order("field(id,#{order_ids})").includes(:praise_treads, dis: :tag_repertoires, user: :user_extension)
# @memos = memos.includes(:praise_treads, user: :user_extension).page(page).per(limit)
# 实训标签使用最多的9个
# @hot_tags = TagRepertoire.find_by_sql("select distinct(a.name), a.id from
# (select tr.id, tr.name, count(d.dis_id) cnt
# from tag_repertoires tr join (shixun_tag_repertoires str
# left join (shixuns s join discusses d on d.dis_id = s.id)
# on s.id = str.shixun_id) on tr.id = str.tag_repertoire_id
# group by d.dis_id order by cnt desc) a limit 9").map{|ht| ht.attributes.dup}
tag_id = ShixunTagRepertoire.joins(:shixun).order("myshixuns_count desc").pluck(:tag_repertoire_id).uniq.first(9)
@hot_tags = TagRepertoire.select([:id, :name]).where(id: tag_id).order("FIELD(id, #{tag_id.join(",")})").map{|ht| ht.attributes.dup} if tag_id
@memos = DiscussesService.new.memo_list @memos
@hot_memos = Memo.field_for_recommend.posts.hot.includes(:tag_repertoires).limit(4)
@recommend_shixuns = DiscussesService.new.recommends
end
def new_message
onclick_time = Myshixun.find(params[:myshixun_id]).try(:onclick_time)
ids = Discuss.where(user_id: User.current.id, dis_id: params[:container_id], dis_type: params[:container_type]).

@ -1,2 +0,0 @@
class ForumsController < ApplicationController
end

@ -336,7 +336,7 @@ class HomeworkCommonsController < ApplicationController
@messages = @messages.parent_comment
end
@messages = @messages.page(@page).per(@limit).order("created_on desc")
@messages = @messages.includes(:praise_treads).page(@page).per(@limit).order("created_on desc")
end
def reference_answer

@ -1,5 +1,9 @@
class MemosController < ApplicationController
before_action :set_memo, only: [:show, :edit, :update, :destroy]
before_action :require_login, except: [:show, :index]
before_action :set_memo, only: [:show, :edit, :update, :destroy, :sticky_or_cancel, :hidden, :more_reply]
before_action :validate_memo_params, only: [:create, :update]
before_action :owner_or_admin, only: [:edit, :update, :destroy]
before_action :is_admin, only: [:sticky_or_cancel, :hidden]
include ApplicationHelper
# GET /memos
@ -8,27 +12,21 @@ class MemosController < ApplicationController
@user = current_user
@memos = Memo.all
s_order = (params[:order] == "replies_count" ? "all_replies_count" : params[:order]) || "updated_at"
#@tidding_count = unviewed_tiddings(current_user) if current_user.present?
page = params[:page].to_i
# @tidding_count = unviewed_tiddings(current_user) if current_user.present?
page = params[:page] || 1
limit = params[:limit] || 15
search = params[:search]
offset = page * 15
forum_id = params[:forum]
user_id = params[:user_id]
if user_id == -1
user_id = current_user.try(:id)
end
tag_repertoire_id = params[:tag_repertoire_id]
sql =
if forum_id
search ? "forum_id = #{forum_id} and root_id is null and subject like '%#{search}%'" :
!search.blank? ? "forum_id = #{forum_id} and root_id is null and subject like '%#{search}%'" :
"forum_id = #{forum_id} and root_id is null"
elsif search
user_id ? "author_id = #{user_id.to_i} and forum_id in(3, 5) and root_id is null and subject like '%#{search}%'" :
"forum_id in(3, 5) and root_id is null and subject like '%#{search}%'"
elsif !search.blank?
"forum_id in(3, 5) and root_id is null and subject like '%#{search}%'"
else
user_id ? "author_id = #{user_id.to_i} and forum_id in(3, 5) and root_id is null" :
"forum_id in(3, 5) and root_id is null"
"forum_id in(3, 5) and root_id is null"
end
if tag_repertoire_id
@ -41,27 +39,27 @@ class MemosController < ApplicationController
sql += " and all_replies_count != 0"
end
memos = Memo.field_for_list.includes(:praise_tread, :author).where("#{sql}")
memos = Memo.field_for_list.where("#{sql}")
@memos_count = memos.length
@memos = memos.order("sticky = 1 desc, #{Memo.table_name}.#{s_order} desc").offset(offset).limit(15)
@my_memos_count = Memo.user_posts(current_user.try(:id)).count
@memos = memos.order("sticky = 1 desc, #{Memo.table_name}.#{s_order} desc").page(page).per(limit)
@memos = @memos.includes(:praise_treads, :tag_repertoires, author: :user_extension)
# @my_memos_count = Memo.user_posts(current_user.try(:id)).count
@tags_info = MemoTagRepertoire.find_by_sql("SELECT tag_repertoire_id, tr.name, count(*) cnt
FROM memo_tag_repertoires mtr join tag_repertoires tr on
tr.id = mtr.tag_repertoire_id group by tag_repertoire_id order by cnt desc,
tag_repertoire_id desc limit 9")
@hot_memos = Memo.field_for_recommend.posts.hot.limit(4)
@hot_memos = Memo.field_for_recommend.posts.hot.includes(:tag_repertoires).limit(4)
@recommend_shixuns = DiscussesService.new.recommends
end
# GET /memos/1
# GET /memos/1.json
def show
# tidding_count = unviewed_tiddings(current_user) if current_user
@user = current_user
# TODO 附件最后再做
# attachments_list =
@memo.update_column(:viewed_count, @memo.viewed_count+1)
@memos = @memo.reply_for_memo.includes(:praise_tread, :author).order("created_at desc").limit(10)
@memos = @memo.reply_for_memo.includes(:praise_treads, author: :user_extension).order("created_at desc").limit(10)
@attachments = @memo.attachments
@recommend_shixuns = DiscussesService.new.recommends
end
# GET /memos/new
@ -71,43 +69,44 @@ class MemosController < ApplicationController
# GET /memos/1/edit
def edit
@tag_list = TagRepertoire.field_for_list.order("name asc")
@memo_tags = @memo.tag_repertoires.field_for_list
@attachments = @memo.attachments
end
# POST /memos
# POST /memos.json
def create
ActiveRecord::Base.transaction do
begin
@memo = Memo.new(memo_params)
@memo.author = current_user
# TODO 保存附件
# @memo.save_attachments(params[:attachments]) if params[:attachments]
@memo.save!
Attachment.associate_container(params[:attachment_ids], @memo.id, @memo.class.name)
params[:tags].each do |tag|
MemoTagRepertoire.create(:memo_id => @memo.id, :tag_repertoire_id => tag)
MemoTagRepertoire.create!(memo_id: @memo.id, tag_repertoire_id: tag)
end
@status = 0
@message = "帖子创建成功!"
normal_status("帖子创建成功")
rescue Exception => e
@status = -1
@message = "帖子创建失败,原因:#{e}"
tip_exception("帖子创建失败,原因:#{e}")
raise ActiveRecord::Rollback
end
end
end
# PATCH/PUT /memos/1
# PATCH/PUT /memos/1.json
def update
respond_to do |format|
if @memo.update(memo_params)
format.html { redirect_to @memo, notice: 'Memo was successfully updated.' }
format.json { render :show, status: :ok, location: @memo }
else
format.html { render :edit }
format.json { render json: @memo.errors, status: :unprocessable_entity }
ActiveRecord::Base.transaction do
begin
@memo.update_attributes!(memo_params)
Attachment.associate_container(params[:attachment_ids], @memo.id, @memo.class.name)
@memo.memo_tag_repertoires.destroy_all
params[:tags].each do |tag|
MemoTagRepertoire.create!(memo_id: @memo.id, tag_repertoire_id: tag)
end
normal_status("帖子更新成功")
rescue Exception => e
tip_exception("帖子更新失败,原因:#{e}")
raise ActiveRecord::Rollback
end
end
end
@ -116,21 +115,88 @@ class MemosController < ApplicationController
# DELETE /memos/1.json
def destroy
@memo.destroy
respond_to do |format|
format.html { redirect_to memos_url, notice: 'Memo was successfully destroyed.' }
format.json { head :no_content }
normal_status("删除成功")
end
def sticky_or_cancel
tip_exception("只能对主贴进行置顶操作") unless @memo.parent_id.nil?
begin
@memo.update_attributes!(sticky: !@memo.sticky)
normal_status("更新成功")
rescue Exception => e
tip_exception("更新失败,原因:#{e}")
raise ActiveRecord::Rollback
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_memo
@memo = Memo.find(params[:id])
def hidden
tip_exception("不能对主贴进行隐藏操作") if @memo.parent_id.nil?
begin
@memo.update_attributes!(hidden: !@memo.hidden)
normal_status("更新成功")
rescue Exception => e
tip_exception("更新失败,原因:#{e}")
raise ActiveRecord::Rollback
end
end
def reply
tip_exception("parent_id不能为空") if params[:parent_id].blank?
tip_exception("content不能为空") if params[:content].blank?
# Never trust parameters from the scary internet, only allow the white list through.
def memo_params
params.fetch(:memo, {})
ActiveRecord::Base.transaction do
begin
memo = Memo.find_by!(id: params[:parent_id])
reply = Memo.new
reply.content = params[:content]
reply.author = current_user
reply.forum_id = memo.forum_id
reply.subject = memo.subject
reply.root_id = memo.root_id || memo.id
memo.children << reply
m = Memo.find_by!(id: reply.root_id)
m.increment!(:all_replies_count)
normal_status("回复成功")
rescue Exception => e
tip_exception("回复失败,原因:#{e}")
raise ActiveRecord::Rollback
end
end
end
def more_reply
@user = current_user
page = params[:page] || 2
limit = params[:limit] || 10
offset = (page.to_i - 1) * limit
@memos_count = Memo.where(parent_id: @memo.id).count
@memos = Memo.limit(limit).where(parent_id: @memo.id).includes(:author, :praise_treads).order("created_at desc").offset(offset)
end
private
# Use callbacks to share common setup or constraints between actions.
def set_memo
@memo = Memo.find(params[:id])
end
def owner_or_admin
tip_exception(403, "无权限操作") unless @memo.author == current_user || current_user.admin? || current_user.business?
end
def is_admin
tip_exception(403, "无权限操作") unless current_user.admin? || current_user.business?
end
# Never trust parameters from the scary internet, only allow the white list through.
def memo_params
params.require(:memo).permit(:subject, :content, :forum_id)
end
def validate_memo_params
tip_exception("话题名称不能为空") if params[:subject].blank?
tip_exception("话题内容不能为空") if params[:content].blank?
tip_exception("话题类型不能为空") if params[:forum_id].blank?
tip_exception("技术标签不能为空") if params[:tags].blank?
end
end

@ -1,10 +1,2 @@
class ProjectsController < ApplicationController
def search
query_params = { keyword: params[:keyword], category: 'manage' }
projects = Users::ProjectService.new(current_user, query_params).call
params[:limit] = params[:per_page].to_i.zero? ? 20 : params[:per_page].to_i
@count = projects.count
@projects = paginate projects
end
end

@ -408,18 +408,16 @@ class ShixunsController < ApplicationController
@shixun.update_attributes(shixun_params)
@shixun.shixun_info.update_attributes(shixun_info_params)
@shixun.shixun_schools.delete_all
if params[:scope_partment].present? && params[:user_scope].to_i == 1
logger.info("##########scope_partment:###{params[:scope_partment]}")
# scope_partment: 高校的名称
if params[:scope_partment].present?
arr = []
ids = School.where(:name => params[:scope_partment]).pluck(:id).uniq
ids.each do |id|
arr << { :school_id => id, :shixun_id => @shixun.id }
end
ShixunSchool.create!(arr)
use_scope = 1
else
use_scope = 0
end
@shixun.update_attributes!(:use_scope => use_scope)
# 超级管理员和运营人员才能保存 中间层服务器pod信息的配置
if current_user.admin? || current_user.business?
@shixun.shixun_service_configs.destroy_all

@ -222,7 +222,7 @@ class SubjectsController < ApplicationController
@subject.update_attributes(status: 1)
ApplyAction.create(container_type: "ApplySubject", container_id: @subject.id, user_id: current_user.id, status: 0)
begin
status = Trustie::Sms.send(mobile: '18711011226', send_type:'publish_subject' , name: '管理员')
status = Educoder::Sms.send(mobile: '18711011226', send_type:'publish_subject' , name: '管理员')
rescue => e
uid_logger_error("发送验证码出错: #{e}")
end

@ -43,7 +43,7 @@ class Users::BaseController < ApplicationController
page = page_value
per_page = per_page_value
return Kaminari.paginate_array(objs).page(page).per(per_page) unless observed_logged_user? && opts[:special]
return Kaminari.paginate_array(objs).page(page).per(per_page) unless opts[:special] && observed_logged_user?
# note: 为实现第一页少一条记录,让前端放置新建入口
if page == 1

@ -3,11 +3,13 @@ class Users::PrivateMessageDetailsController < Users::BaseController
after_action :update_message_status, only: [:show]
helper_method :target_user
def show
messages = observed_user.private_messages.without_deleted.where(target: target_user)
@count = messages.count
@messages = messages.order(send_time: :asc).includes(sender: :user_extension)
@messages = paginate messages.order(send_time: :desc).includes(sender: :user_extension)
end
private

@ -1,4 +1,6 @@
class Users::ProjectsController < Users::BaseController
skip_before_action :check_observed_user_exists!, only: [:search]
def index
projects = Users::ProjectService.new(observed_user, query_params).call
@ -6,6 +8,15 @@ class Users::ProjectsController < Users::BaseController
@projects = paginate(projects.includes(:project_score, owner: { user_extension: :school }), special: true)
end
def search
query_params = { keyword: params[:keyword], category: 'manage' }
projects = Users::ProjectService.new(current_user, query_params).call
params[:limit] = params[:per_page].to_i.zero? ? 20 : params[:per_page].to_i
@count = projects.count
@projects = paginate projects
end
private
def query_params

@ -329,6 +329,23 @@ module ApplicationHelper
content
end
def strip_html(text, len=0, endss="...")
ss = ""
if !text.nil? && text.length>0
ss=text.gsub(/<\/?.*?>/, '').strip
ss = ss.gsub(/&nbsp;*/, '')
ss = ss.gsub(/\r\n/,'') #新增
ss = ss.gsub(/\n/,'') #新增
if len > 0 && ss.length > len
ss = ss[0, len] + endss
elsif len > 0 && ss.length <= len
ss = ss
#ss = truncate(ss, :length => len)
end
end
ss
end
def strip_export_title(content)
con_ = ""
if content.length > 0

@ -1,2 +0,0 @@
module ForumsHelper
end

@ -8,6 +8,7 @@ class Discuss < ApplicationRecord
has_many :praise_treads, as: :praise_tread_object, dependent: :destroy
has_many :tidings, as: :container, dependent: :destroy
has_one :praise_tread_cache, as: :object, dependent: :destroy
belongs_to :dis, polymorphic: true
belongs_to :challenge
after_create :send_tiding
@ -44,6 +45,10 @@ class Discuss < ApplicationRecord
Discuss.where(parent_id: self.id).includes(:user).reorder(created_at: :asc)
end
def child_discuss_count
Discuss.where(root_id: id).count
end
private
def send_tiding

@ -6,7 +6,7 @@ class Memo < ApplicationRecord
has_many :memo_tag_repertoires, dependent: :destroy
has_many :tag_repertoires, :through => :memo_tag_repertoires
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
has_many :praise_treads, as: :praise_tread_object, dependent: :destroy
has_one :praise_tread_cache, as: :object, dependent: :destroy
belongs_to :author, class_name: 'User', foreign_key: 'author_id'
@ -14,6 +14,8 @@ class Memo < ApplicationRecord
has_many :descendants, foreign_key: :root_id, class_name: 'Memo'
has_many :children, foreign_key: :parent_id, class_name: 'Memo'
has_many :attachments, as: :container, dependent: :destroy
has_many :tidings, as: :container, dependent: :destroy
scope :field_for_list, lambda{
select([:id, :subject, :author_id, :sticky, :updated_at, :language, :reward, :all_replies_count, :viewed_count, :forum_id])

@ -440,7 +440,7 @@ class User < ApplicationRecord
end
def manager_of_memo?(memo)
id == memo.author_id || admin?
id == memo.author_id || admin? || business?
end
# 是否是项目管理者

@ -58,7 +58,7 @@ class DiscussesService
praise_count: 0, position: params[:position], challenge_id: params[:challenge_id], hidden: !current_user.admin?
)
# 发送手机通知
Trustie::Sms.send(mobile:'18173242757', send_type:'discuss', name:'管理员')
Educoder::Sms.send(mobile:'18173242757', send_type:'discuss', name:'管理员')
rescue Exception => e
raise(e.message)
end
@ -148,30 +148,6 @@ class DiscussesService
@discuss = Discuss.select([:id, :hidden, :reward, :dis_type, :dis_id, :position, :challenge_id, :root_id]).find(id)
end
protected
def memo_list memos
memos.map do |m|
user = User.find(m.user_id)
praise_count = m.praise_tread.where(:praise_or_tread => 1).count
replies_count = Discuss.where(:root_id => m.id).count
shixun_tag = m.dis.tag_repertoires.map(&:name)
m.attributes.dup.except("user_id", "dis_id", "dis_type", "root_id").merge({
subject: (message_content m.content),
username: user.show_name,
login: user.login,
praise_count: praise_count,
replies_count: replies_count,
image_url: url_to_avatar(user),
shixun_tag: shixun_tag,
tpm_url: "/shixuns/#{m.dis.identifier}/shixun_discuss"
})
end
end
def format_for_current_user current_user
{username: current_user.show_name, login: current_user.login, user_id: current_user.id, image_url: url_to_avatar(current_user), admin: current_user.admin?}
end
def recommends
hot_shixuns = Shixun.field_for_recommend.published.order("myshixuns_count desc").limit(2)
newest_shixuns = Shixun.field_for_recommend.published.order("created_at desc").limit(2)
@ -185,6 +161,30 @@ class DiscussesService
return recommend_shixuns
end
def memo_list memos
memos.map do |m|
user = m.user
# praise_count = m.praise_treads.select{|pt| pt.praise_or_tread == 1}.count
replies_count = m.child_discuss_count
shixun_tag = m.dis.tag_repertoires.map(&:name)
m.attributes.dup.except("user_id", "dis_id", "dis_type", "root_id", "praise_count", "content").merge({
subject: (message_content m.content),
username: user.full_name,
login: user.login,
replies_count: replies_count,
image_url: url_to_avatar(user),
shixun_tag: shixun_tag,
tpm_url: "/shixuns/#{m.dis.identifier}/shixun_discuss"
})
end
end
protected
def format_for_current_user current_user
{username: current_user.show_name, login: current_user.login, user_id: current_user.id, image_url: url_to_avatar(current_user), admin: current_user.admin?}
end
# 将数据库对象转换成哈希对象
def object_to_hash objects
objects.map{|o| o.attributes.dup}

@ -3,7 +3,7 @@ class PrivateMessages::CreateService < ApplicationService
attr_reader :sender, :receiver, :params
def initialize(sender, receiver, **params)
def initialize(sender, receiver, params)
@sender = sender
@receiver = receiver
@params = params

@ -22,7 +22,7 @@ class Projects::ApplyJoinService < ApplicationService
apply.forge_activities.find_or_create_by!(user: user, project: project)
notify_project_manager!
notify_project_manager!(apply)
end
# notify_project_owner
@ -47,10 +47,13 @@ class Projects::ApplyJoinService < ApplicationService
end
end
def notify_project_manager!
def notify_project_manager!(apply)
columns = %i[user_id applied_id applied_type status viewed applied_user_id role project_id created_at updated_at]
AppliedMessage.bulk_insert(*columns) do |worker|
base_attr = { status: false, viewed: false, applied_user_id: user.id, role: role_value, project_id: project.id }
base_attr = {
applied_id: apply.id, applied_type: 'AppliedProject', status: false, viewed: false,
applied_user_id: user.id, role: role_value, project_id: project.id
}
project.manager_members.each do |manager|
worker.add(base_attr.merge(user_id: manager.user_id))

@ -1,96 +0,0 @@
class SearchShixunService < ApplicationService
include ElasticsearchAble
attr_reader :user, :params
def initialize(user, params)
@user = user
@params = params
end
def call
Shixun.search(keyword,
fields: search_fields,
where: where_clauses,
order: order_clauses,
includes: includes_clauses,
page: page,
per_page: per_page)
end
private
def tag_filter_shixun_ids
return [] if params[:tag_level].to_i == 0 || params[:tag_id].blank?
case params[:tag_level].to_i
when 1 then
Repertoire.find(params[:tag_id]).tag_repertoires.joins(:shixun_tag_repertoires)
.pluck('shixun_tag_repertoires.shixun_id')
when 2 then
SubRepertoire.find(params[:tag_id]).tag_repertoires.joins(:shixun_tag_repertoires)
.pluck('shixun_tag_repertoires.shixun_id')
when 3 then
TagRepertoire.find(params[:tag_id]).shixun_tag_repertoires.pluck(:shixun_id)
else
[]
end
end
def user_filter_shixun_ids
return [] if params[:order_by] != 'mine'
user.shixun_members.pluck(:shixun_id) + user.myshixuns.pluck(:shixun_id)
end
def keyword
params[:keyword].to_s.strip.presence || '*'
end
def search_fields
%w(name^10 author_name challenge_names description challenge_tag_names)
end
def where_clauses
hash = {}
ids = user_filter_shixun_ids + tag_filter_shixun_ids
hash[:id] = ids if ids.present?
if params[:order_by] == 'mine'
hash[:status] = { not: -1 }
else
hash.merge!(hidden: false, status: 2)
end
unless params[:status].to_i.zero?
params[:status] = [0, 1] if params[:status].to_i == 1
hash[:status] = params[:status]
end
hash[:trainee] = params[:diff].to_i unless params[:diff].to_i.zero?
hash
end
def includes_clauses
[]
end
def order_clauses
hash = { _score: :desc }
publish_order = { type: 'number', order: :desc, script: 'doc["status"].value=="2" ? 1 : 0' }
sort = params[:sort].to_s.strip == 'asc' ? 'asc' : 'desc'
clauses =
case params[:order_by].presence
when 'new' then { _script: publish_order, created_at: sort }
when 'hot' then { _script: publish_order, myshixuns_count: sort }
when 'mine' then { created_at: sort }
else { _script: publish_order, publish_time: sort }
end
hash.merge!(clauses)
hash
end
end

@ -51,6 +51,8 @@ class Users::UpdateAccountService < ApplicationService
if first_full_reward
RewardGradeService.call(user, container_id: user.id, container_type: 'Account', score: 500)
sms_notify_admin(user.lastname) if user.user_extension.teacher?
end
user
@ -65,4 +67,10 @@ class Users::UpdateAccountService < ApplicationService
def user_extension_attributes
params.slice(*%i[location location_city identity student_id technical_title school_id department_id])
end
def sms_notify_admin name
Educoder::Sms.send(mobile:'17680641960', send_type:'teacher_register', name: name, user_name:'管理员')
rescue => ex
Util.logger_error(ex)
end
end

@ -0,0 +1,27 @@
json.memo_list @memos
# do |memo|
# json.(memo, :id, :updated_at, :reward)
# json.subject message_content(memo.content)
# json.praise_count memo.praises_count
# json.replies_count memo.child_discuss_count
# json.shixun_tag memo.dis.tag_repertoires.map(&:name)
# json.username memo.user.full_name
# json.login memo.user.login
# json.image_url url_to_avatar(memo.user)
# json.tpm_url "/shixuns/#{memo.dis.identifier}/shixun_discuss"
# end
json.memo_count @memo_count
json.hot_memos do
json.array! @hot_memos do |hm|
json.(hm, :id, :subject, :language, :forum_id)
json.replies_count hm.all_replies_count
# json.praise_count hm.praise_tread.praise_count
json.tag hm.tag_repertoires.map(&:name)
end
end
json.hot_tags @hot_tags
json.recommend_shixuns @recommend_shixuns

@ -1 +1,2 @@
json.status 0
json.code @code

@ -25,29 +25,28 @@ elsif @type == "txt"
elsif @type =="qrcode"
json.qrcode_str @qrcode_str
elsif @type == "mp3" || @type == "mp4"
if @type == "mp4"
json.orignal_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378171/123.mp4"}]
json.user_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378172/456.mp4"}]
json.answer_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378173/789.mp4"}]
else
json.orignal_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378174/58099.mp3"}]
json.user_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378175/654058514.mp3"}]
json.answer_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378175/654058514.mp3"}]
end
# json.orignal_file do
# json.array! @orignal_picture do |file|
# json.file_url attachment_show_users_path(:file_name => file, :path => @original_path)
# end
# end
# json.user_file do
# json.array! @user_picture do |file|
# json.file_url attachment_show_users_path(:file_name => file, :path => @user_path, :time => Time.now.to_i)
# end
# end
# json.answer_file do
# json.array! @answer_picture do |file|
# json.file_url attachment_show_users_path(:file_name => file, :path => @answer_path)
# end
# if @type == "mp4"
# json.orignal_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378171/123.mp4"}]
# json.user_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378172/456.mp4"}]
# json.answer_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378173/789.mp4"}]
# else
# json.orignal_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378174/58099.mp3"}]
# json.user_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378175/654058514.mp3"}]
# json.answer_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378175/654058514.mp3"}]
# end
json.orignal_file do
json.array! @orignal_picture do |file|
json.file_url attachment_show_users_path(:file_name => file, :path => @original_path)
end
end
json.user_file do
json.array! @user_picture do |file|
json.file_url attachment_show_users_path(:file_name => file, :path => @user_path, :time => Time.now.to_i)
end
end
json.answer_file do
json.array! @answer_picture do |file|
json.file_url attachment_show_users_path(:file_name => file, :path => @answer_path)
end
end
end

@ -10,7 +10,7 @@ json.hidden message.hidden
if message.m_parent_id
json.can_delete message.can_delete(identity)
else
json.praise_count message.praise_treads.liker.count
json.user_praise message.praise_treads.user_liker(current_user).count
json.praise_count message.praise_treads.select{|pt| pt.praise_or_tread == 1}.count
json.user_praise message.praise_treads.select{|pt| pt.praise_or_tread == 1 && user_id == current_user.id}.count
json.child_message_count message.m_reply_count
end

@ -1,8 +1,14 @@
json.(memo, :id, :subject, :is_md, :content, :sticky, :reward, :viewed_count)
json.tag memo.tag_repertoires.map(&:name)
json.time memo.created_at
json.replies_count memo.all_replies_count
json.attachments_list []
json.user_praise memo.praise_tread.user_liker(@user.try(:id)) ? true : false
json.memo_praise_count = memo.praise_tread.liker.count
json.memo do
json.id memo.id
json.subject memo.subject
json.is_md memo.is_md
json.content memo.content
json.sticky memo.sticky
json.reward memo.reward
json.viewed_count memo.viewed_count
json.tag memo.tag_repertoires.map(&:name)
json.time memo.created_at
json.replies_count memo.all_replies_count
json.user_praise memo.praise_treads.user_liker(@user.try(:id)) ? true : false
json.memo_praise_count memo.praise_treads.liker.count
end

@ -1,7 +1,7 @@
json.(memo, :id, :subject, :author_id, :sticky,
:updated_at, :language, :reward, :all_replies_count,
:viewed_count, :forum_id)
json.praise_count memo.praise_tread.praise_count
json.praise_count memo.praise_treads.liker.count
json.replies_count memo.all_replies_count
json.tag memo.tag_repertoires.map(&:name)
json.user_name memo.author.full_name

@ -7,10 +7,10 @@ json.username memo.author.full_name
json.reward memo.reward
json.hidden memo.hidden
json.permission @user.manager_of_memo?(memo)
json.praise_count memo.praise_tread.liker.count
json.user_praise memo.praise_tread.select{|pt| pt.user_id == @user.id}.length > 0
json.praise_count memo.praise_treads.select{|pt| pt.praise_or_tread == 1}.count
json.user_praise memo.praise_treads.select{|pt| pt.praise_or_tread == 1 && pt.user_id == @user.id}.length > 0
json.user_login memo.author.login
json.admin @user.admin
json.admin @user.admin? || @user.business?
json.children do
json.array! memo.children_of_reply do |child|

@ -0,0 +1,7 @@
json.(@memo, :subject, :content, :forum_id)
json.memo_tags @memo_tags
json.attachments @attachments do |attachment|
json.partial! "attachments/attachment_simple", locals: {attachment: attachment}
end
json.tag_list @tag_list
json.forums forum_list

@ -8,22 +8,30 @@
# tidding_count: 消息数
# #
json.memo_list do
json.array! @memos do |memo|
json.partial! "memos/memo_list", locals: {memo: memo}
end
json.memo_list @memos do |memo|
json.(memo, :id, :subject, :sticky,
:updated_at, :language, :reward,
:viewed_count, :forum_id)
json.praise_count memo.praise_treads.select{|pt| pt.praise_or_tread == 1}.count
json.replies_count memo.all_replies_count
json.tag memo.tag_repertoires.map(&:name)
json.user_name memo.author.full_name
json.login memo.author.login
json.image_url url_to_avatar(memo.author)
end
json.memo_count @memos_count
json.hot_memos do
json.array! @hot_memos do |hm|
json.(hm, :id, :subject, :language, :forum_id, :all_replies_count)
json.(hm, :id, :subject, :language, :forum_id)
json.replies_count hm.all_replies_count
json.praise_count hm.praise_tread.praise_count
# json.praise_count hm.praise_tread.praise_count
json.tag hm.tag_repertoires.map(&:name)
end
end
json.hot_tags @tags_info.map{|o| o.attributes.dup.except("cnt", "id")}
json.recommend_shixuns @recommend_shixuns

@ -0,0 +1,7 @@
json.memo_replies do
json.array! @memos do |memo|
json.partial! "memos/replies_list", memo: memo
end
end
json.memos_count @memos_count

@ -1,3 +1,2 @@
json.tag_list @tag_list
json.forums @csrf_token
json.forums forum_list

@ -1,5 +1,9 @@
json.partial! "memos/memo", memo: @memo
json.attachments_list @attachments do |attachment|
json.partial! "attachments/attachment_simple", locals: {attachment: attachment}
end
json.memo_replies do
json.array! @memos do |memo|
json.partial! "memos/replies_list", memo: memo
@ -9,10 +13,11 @@ end
json.author_info do
json.username @memo.author.full_name
# TODO watched_by 插件没法用,等把lib文件载入后在打开代码
#json.watched @memo.author.watched_by?(@user)
json.watched @user.watched?(@memo.author)
json.image_url url_to_avatar(@memo.author)
json.identity @memo.author.identity
json.login @memo.author.login
json.user_id @memo.author.id
end
json.recommend_shixuns @recommend_shixuns

@ -1,4 +1,5 @@
json.username @user.full_name
json.real_name @user.real_name
json.login @user.login
json.user_id @user.id
json.image_url url_to_avatar(@user)

@ -1,9 +1,13 @@
json.count @count
json.target do
json.partial! 'users/user_simple', user: target_user
end
json.messages do
json.array! @messages.each do |message|
json.extract! message, :id, :user_id, :receiver_id, :sender_id, :content
json.send_time message.display_send_time
json.send_day message.send_time.strftime('%Y-%m-%d')
json.sender do
json.partial! 'users/user_simple', user: message.sender
end

@ -20,7 +20,18 @@ Rails.application.routes.draw do
put 'commons/unhidden', to: 'commons#unhidden'
delete 'commons/delete', to: 'commons#delete'
resources :memos
resources :memos do
member do
post :sticky_or_cancel
post :hidden
get :more_reply
end
collection do
post :reply
end
end
resources :tem_tests
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
#
@ -75,7 +86,7 @@ Rails.application.routes.draw do
get :system_update
resource :trial_apply, only: [:create]
resources :projects, only: [] do
resources :projects, module: :users, only: [] do
get :search, on: :collection
end
@ -222,6 +233,7 @@ Rails.application.routes.draw do
resources :discusses do
collection do
get :new_message
get :forum_discusses
end
member do
@ -703,7 +715,7 @@ Rails.application.routes.draw do
resources :libraries, only: [:index, :show, :create, :update, :destroy]
scope module: :projects do
resources :applied_projects, only: [:create]
resources :project_applies, only: [:create]
end
end

@ -21,7 +21,7 @@ module Educoder
def self.notify_admin(opt)
opt[:name] = '管理员'
opt[:mobile] = ENV['NOTIFY_ADMIN_PHONE'] || EduSetting.get('notify_admin_phone') || '17680641960'
opt[:mobile] = ENV['NOTIFY_ADMIN_PHONE'] || EduSetting.get('notify_admin_phone') || '18711085785'
send(opt)
end
@ -39,25 +39,22 @@ module Educoder
params['text'] = "【Edu实训】" + code + "手机验证码有效期为10分钟。如非本人操作请忽略。"
elsif send_type == 'competition_start'
params['text'] = "【Edu实训】亲爱的#{user_name},你参与的#{name}将于#{result}开始,请及时参赛"
Rails.logger.info "#{params['text']}"
elsif send_type == "teacher_register"
params['mobile'] = EduSetting.get('teacher_register_phone') || '17680641960'
params['text'] = "【Edu实训】亲爱的#{user_name},有新的老师#{name}注册啦,请尽快处理"
elsif send_type == 'subject_authorization' || send_type == 'shixun_authorization'
params['text'] = "【Edu实训】亲爱的#{user_name},您提交的#{name}#{send_type=='subject_authorization'?'':''}发布申请#{result},请登录平台查看详情"
Rails.logger.info "#{params['text']}"
elsif send_type == 'authentication_pro' || send_type == 'authentication'|| send_type == 'trial_authorization' || send_type == 'project_info'
params['text'] = "【Edu实训】亲爱的#{user_name},您提交的#{send_type == 'authentication_pro'?'':(send_type == 'authentication'? '' : (send_type == 'project_info'?'':'' ))}#{result},请登录平台查看详情"
Rails.logger.info "#{params['text']}"
elsif send_type == "apply_pro_certification" || send_type == "apply_auth"
params['text'] = "【Edu实训】亲爱的#{name},有新的#{send_type == 'apply_pro_certification'?'':''}认证申请,请尽快处理"
Rails.logger.info "#{params['text']}"
elsif send_type == "publish_subject" ||send_type == "publish_shixun"|| send_type == "user_apply_auth" || send_type == "discuss"
params['mobile'] = EduSetting.get('subject_shixun_notify_phone') || '18711011226' if send_type == "publish_subject" || send_type == "publish_shixun"
params['text'] = "【Edu实训】亲爱的#{name},有新的#{send_type == 'publish_subject'?'':(send_type == 'publish_shixun' ? '' : (send_type == 'discuss' ? '':''))}申请发布,请尽快处理"
Rails.logger.info "#{params['text']}"
elsif send_type == 'join_course_multi_role'
params['text'] = "【Edu实训】亲爱的#{user_name},您的课堂#{name}有助教或者教师申请加入,请尽快审核"
Rails.logger.info "#{params['text']}"
elsif send_type == 'applied_project_info'
params['text'] = "【Edu实训】亲爱的#{user_name},您的项目#{name}有成员申请加入,请尽快审核"
Rails.logger.info "#{params['text']}"
end
http = Net::HTTP.new(send_tpl_sms_uri.host, send_tpl_sms_uri.port)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 53 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -332,8 +332,12 @@ label.infolabel{display: block;float: left;width: 56px;text-align: right;margin-
}
.shixunDes{font-family: 'panmen-webfont';display: block;position: absolute;height: 100%;width: 100%;text-align: center;line-height: 220px;color: #fff;top: 0px;font-size: 24px;background-color: rgba(5,16,26,0.4);border-radius: 6px 6px 0px 0px;}
/*TPM*/
.shixunDetail_top{width: 100%;background-image: url("/images/educoder/shixun-detail.jpg");background-size: 100% 100%;height: 240px;
justify-content: center;align-items: center;display: -webkit-flex;}
.shixunDetail_top{width: 100%;background-image: url("/images/educoder/shixun-detail.jpg"); height: 240px;
justify-content: center;align-items: center;display: -webkit-flex;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.task-item{margin-top: 30px;padding-bottom: 30px;border-bottom: 1px solid #eee}
.task-item:last-child{border-bottom: none;}
.challengeNav a.active{color: #4CACFF;}
@ -420,14 +424,23 @@ table.text-file{}
/*-------------------------------实训路径-------------------------------*/
.path-head{width: 100%;height: 300px;background-image: url("/images/educoder/path.png");background-color: #081C4B;background-size: 100% 100%;}
.path-head{width: 100%;height: 300px;background-image: url("/images/educoder/path.png");
background-color: #081C4B;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.pathNavLine{position: absolute;bottom: -8px;width: 100%;}
.path-nav li{float: left;padding: 0px 30px;height: 42px;}
.path-nav li a{color:#fff;font-size: 16px;display: block; height: 40px;}
.path-nav li.active a{border-bottom: 3px solid #4CACFF;color:#4CACFF;}
/*---实训路径详情----*/
.subhead{width: 100%;margin-bottom:40px;background-size: 100% 100%;background-image: url("/images/educoder/path-detail.jpg");height: 240px;
justify-content: center;align-items: center;display: -webkit-flex;}
justify-content: center;align-items: center;display: -webkit-flex;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.subhead_content{width: 1200px;margin: 0px auto;}
.pathInfo li{text-align: center;float: left;margin-right: 38px;}
.pathInfo li span{display: block;}
@ -467,7 +480,11 @@ li.li-width7{width: 7%;text-align: left}
/*-----------------------------在线课堂动态----------------------------------*/
.courseHead{width: 100%;margin-bottom:40px;background-size: 100% 100%;background-image: url("/images/educoder/course-detail.jpg");height: 240px;
justify-content: center;align-items: center;display: -webkit-flex;}
justify-content: center;align-items: center;display: -webkit-flex;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.invite-tip{position: absolute;top: -5px;right: 140px;color: #fff; box-sizing: border-box;width: 170px;text-align: center;border-radius: 2px;background-color: rgba(5,16,26,0.6)}
.inviteTipbtn a{font-size:14px;width: 100%;height: 30px;line-height: 30px;display: block;color: #747A7F;background-color: rgba(5,16,26,0.4)}
.inviteTipbtn a:hover{color: #4cacff!important;}
@ -3048,3 +3065,358 @@ a.singlepublishtwo{
/*课程目标VS毕业要求指标点*/
.CourseTargetPoint thead th{vertical-align: baseline;}
.CourseTargetPoint tbody tr td{vertical-align: top;}
/*众包*/
.packinput .ant-input{
height: 50px;
width:749px;
border-color: #E1EDF8 !important;
}
.packinput{
width:749px;
}
.packinput .ant-input-group-addon .ant-btn{
width:140px !important;
font-size: 18px;
height: 50px;
background:rgba(76,172,255,1);
}
.setissues{
width:280px;
height:50px;
background:rgba(76,172,255,1);
border-radius:4px;
margin-left: 15px;
}
.pagetype li{
color:#8F8F8F !important;
}
.maxwidth700{
max-width: 700px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.mbf10{
margin-bottom:-10px;
}
.PackageIndexNEIBanner{
width:1200px;
height:110px;
background:rgba(255,255,255,1);
box-shadow:0px 2px 6px 0px rgba(125,125,125,0.26);
border-radius:8px;
}
.padding110{
padding: 39px 110px 0px;
box-sizing: border-box;
}
.borderccc{
border: 1px solid #ccc;
}
.input-100-40s{
width: 100%;
padding: 5px;
box-sizing: border-box;
}
.fafafas{
background-color: #fafafa!important;
height: 40px;
}
.fafafas:focus{
background-color: #fff!important;
}
.fafas .ant-input{
background-color: #fafafa!important;
height: 40px;
}
.fafas .ant-input:focus{
background-color: #fff!important;
}
.fafas .ant-input-group-addon .ant-btn{
width:140px !important;
font-size: 14px;
height: 40px;
background:rgba(76,172,255,1);
}
.newFormbox .upload_filename{
line-height: 32px;
}
.newFormbox .attachment span{
line-height: 23px;
}
.newFormbox .attachment .remove-upload{
line-height: 28px;
}
.pd26a0{
padding: 26px 26px 16px 26px;
}
.newFormbox .attachment .icon-fujian{
font-size: 14px !important;
line-height: 14px;
margin-top: 9px;
}
.newFormbox{
height:20px
}
.ml24{
margin-left:24px;
}
.defalutCancelbtns{
display: block;
border: 1px solid #4CACFF !important;
background-color: #fff;
color: #4CACFF !important;
width:130px;
height:40px;
text-align: center;
line-height: 40px;
border-radius: 4px;
}
.defalutSubmitbtns{
background-color: #4CACFF;
height:40px;
}
.defalutSubmitbtnmodels{
width:127px;
height:30px;
background-color: #4CACFF;
}
.ant-steps-item-process .ant-steps-item-icon{
background-color: #4CACFF !important;
}
.ant-steps-item-process .ant-steps-item-icon{
background-color: #4CACFF !important;
}
.padding200{
padding: 115px 200px 215px 200px;
}
.fontcircle{
font-size: 80px;
display: inherit;
}
.sumbtongs{
font-size: 24px;
display: inherit;
text-align: center;
}
.terraces{
font-size: 16px;
display: inherit;
text-align: center;
color:#999;
}
.padding251{
padding: 0px 245px;
}
.ant-modal-title{
text-align: center;
}
.ml17{
margin-left: 17px;
}
.project-package-items{
display: -webkit-flex;
display: flex;
flex-direction: row;
margin:0px !important;
padding: 20px;
background: white;
margin-bottom:0px !important;
box-shadow: none !important;
}
.mtf7{
margin-top:-7px;
}
.publicpart.orangeGreen {
border-left: 80px solid #29BD8B;
}
.publicwords{
left: 3px;
top: 18px;
}
.project-packages-list .project-package-items .item-image{
width:100px !important;
}
.height185{
height: 185px;
}
.ContacttheTA{
width: 80px;
height: 26px;
font-size: 14px;
line-height: 26px;
display: block;
border: 1px solid #4CACFF !important;
background-color: #fff;
color: #4CACFF !important;
text-align: center;
border-radius: 4px;
}
.ContacttheTAs{
width: 80px;
height: 26px;
font-size: 14px;
line-height: 24px;
/*display: block;*/
border: 1px solid #fff !important;
background-color: #4CACFF;
color: #fff !important;
text-align: center;
border-radius: 4px;
}
.ml28{
margin-left: 28px;
}
.longboxs{
font-size: 16px;
font-family: MicrosoftYaHei-Bold;
font-weight: bold;
color: rgba(5,16,26,1);
border-left: 4px solid rgba(76,172,255,1);
padding-left: 10px;
margin-bottom: 20px;
}
.padding020{
padding: 0px 20px 20px;
}
.mtf3{
margin-top:-3px;
}
.task-btn-nebules{
background: #fff!important;
color: #4CACFF!important;
border: 1px solid #4CACFF!important;
margin-left: 20px;
cursor: pointer;
display: inline-block;
padding: 0 12px;
letter-spacing: 1px;
text-align: center;
font-size: 14px;
height: 30px;
line-height: 30px;
border-radius: 2px;
}
.packageabsolute{
position: absolute;
right: -16px;
top: -7px;
}
.relativef{
position: relative;
}
.homehove:hover .ptext{
color: #4CACFF!important;
}
.homehove:hover .ContacttheTAs{
display: block;
}
.topsj{
position: absolute;
top: -6px;
}
.bottomsj{
position: absolute;
bottom: -6px;
}
.touchSelect .ant-spin-dot-spin{
margin-top: 30% !important;
}
.pagenoedits{
margin-left: 20px;
color: #ccc;
}
.pagemancenter{
text-align: center;
}
.ml0{
margin-left: 0px;
}
.tabelcli{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 850px;
display: table-cell;
}
.mtf10{
margin-top:-10px;
}
.padding26{
padding: 26px;
box-sizing: border-box;
}
.pd26{
padding: 26px;
}
.pd30a0{
padding: 30px 30px 16px 30px;
}
.shaiContent li.shaiItem:hover span{
color: #fff !important;
}
.shaiContent li.shaiItem:hover i.iconfont{
color: #4CACFF!important
}
.detail_for_paragraph p{
white-space: pre-wrap;
}

@ -50,4 +50,8 @@ html, body {
}
.ant-progress-textno{
color: #f5222d;
}
/* md多空格 */
.markdown-body p {
white-space: pre-wrap;
}

@ -123,12 +123,6 @@ const SearchPage = Loadable({
loading: Loading,
})
//教学案例
const MoopCases = Loadable({
loader: () => import('./modules/moop_cases/index'),
loading: Loading,
})
// 课堂讨论
// const BoardIndex = Loadable({
// loader: () => import('./modules/courses/boards/BoardIndex'),
@ -226,6 +220,12 @@ const UsersInfo = Loadable({
loading: Loading,
})
// 教学案例
const MoopCases = Loadable({
loader: () => import('./modules/moop_cases/index'),
loading: Loading,
})
// 兴趣页面
const Interestpage = Loadable({
loader: () => import('./modules/login/EducoderInteresse'),
@ -294,23 +294,12 @@ class App extends Component {
<Trialapplicationreview {...this.props} {...this.state}></Trialapplicationreview>
<Addcourses {...this.props} {...this.state}/>
<AccountProfile {...this.props} {...this.state}/>
{/*{*/}
{/* isRender === true?*/}
{/* <LoginDialog></LoginDialog> : ""*/}
{/*}*/}
{/*{*/}
{/* isRenders === true?*/}
{/*<Trialapplication></Trialapplication>*/}
{/*:""*/}
{/*}*/}
<Router>
<Switch>
{/*<Route path="/login" component={LoginRegisterPage}/>*/}
{/*众包创新*/}
<Route path={"/crowdsourcings"} component={ProjectPackages}/>
<Route path={"/crowdsourcing"} component={ProjectPackages}/>
{/*认证*/}
<Route path="/account" component={AccountPage}/>
@ -333,9 +322,7 @@ class App extends Component {
render={
(props) => (<UsersInfo {...this.props} {...props} {...this.state} />)
}></Route>
{/*<Route*/}
{/* path="/trialapplication" component={Trialapplication}*/}
{/*/>*/}
<Route
path="/changepassword" component={EducoderLogin}
/>
@ -355,14 +342,6 @@ class App extends Component {
{/*列表页*/}
<Route path="/shixuns" component={TPMShixunsIndexComponent}/>
{/* <Route path="/shixunchild" component={TPMShixunchildIndexComponent}>
</Route>
<Route path="/fork_list" component={TPMshixunfork_listIndexComponent}>
</Route> */}
{/*<Route path="/forums" component={ForumsIndexComponent}>*/}
{/*</Route>*/}
{/*实训课程(原实训路径)*/}
<Route path="/paths" component={ShixunPaths}></Route>
@ -376,16 +355,12 @@ class App extends Component {
{/*课堂*/}
<Route path="/courses" component={CoursesIndex} {...this.props}></Route>
{/* 课堂讨论 */}
{/* <Route path="/board" component = {BoardIndex} {...this.props}></Route> */}
{/* <Route path="/tpforums" component={TPForumsIndexComponent}>
</Route> */}
{/* <Route path="/myshixuns/:shixunId/stages/:stageId" component={Index}/> */}
{/* 兴趣页面*/}
{/*<Route path="/interest" component={Interestpage}/>*/}
{/* <Route path="/forums" component={ForumsIndexComponent}>
</Route> */}
{/* 教学案例 */}
<Route path="/moop_cases"render={
(props) => (<MoopCases {...this.props} {...props} {...this.state} />)
}/>
<Route path="/comment" component={CommentComponent}/>
<Route path="/testMaterial" component={TestMaterialDesignComponent}/>
<Route path="/test" component={TestIndex}/>
@ -393,19 +368,9 @@ class App extends Component {
<Route path="/testRCComponent" component={TestComponent}/>
<Route path="/testUrlQuery" component={TestUrlQueryComponent}/>
{/* 教学案例 */}
<Route path="/moop_cases"render={
(props) => (<MoopCases {...this.props} {...props} {...this.state} />)
}/>
{/* <Route component={NotFoundPage}/> */}
{/*列表页*/}
{/*<Route component={TPMShixunsIndexComponent}/>*/}
{/*首页*/}
<Route exact path="/" component={ShixunsHome}/>
<Route component={Shixunnopage}/>
{/*<Route component={ShixunsHome}/>*/}
</Switch>
</Router>

@ -9,7 +9,7 @@ export function markdownToHTML(oldContent, selector) {
window.$('#md_div').html('')
// markdown to html
if (selector && oldContent && oldContent.startsWith('<p')) { // 普通html处理
window.$(selector).html(oldContent)
window.$('#' + selector).html(oldContent)
} else {
try {
// selector ||

@ -0,0 +1,79 @@
import React,{ Component } from "react";
import { getUrl2 } from "educoder";
const $ = window.$
let _url_origin = getUrl2()
class Clappr extends Component{
constructor(props){
super(props);
this.state={
}
}
componentDidMount() {
const source = this.props.source || "http://your.video/here.mp4"
const { id } = this.props
const _id = `#_player${id}`
if (window['Clappr']) {
const player = new window.Clappr.Player({
source: source, parentId: _id,
plugins: {
'core': [window.Clappr.MediaControl, window.Clappr.Playback]
}
});
} else {
$.getScript(
`${_url_origin}/javascripts/media/clappr.min.js`,
(data, textStatus, jqxhr) => {
window.clappr = window.Clappr
$.getScript(
`${_url_origin}/javascripts/media/clappr-playback-rate-plugin.min.js`,
(data, textStatus, jqxhr) => {
const player = new window.Clappr.Player({
source: source, parentId: _id,
plugins: {
'core': [window.Clappr.MediaControl, window['clappr-playback-rate-plugin'].default]
}
});
})
});
//
// $.when(
// $.getScript( `${_url_origin}/javascripts/media/clappr.min.js` ),
// // $.getScript( `${_url_origin}/javascripts/media/clappr-thumbnails-plugin.js` ),
// $.getScript( `${_url_origin}/javascripts/media/clappr-playback-rate-plugin.min.js` ),
// $.Deferred(function( deferred ){
// $( deferred.resolve );
// })
// ).done(function(){
// //place your code here, the scripts are all loaded
// const player = new window.Clappr.Player({
// source: source, parentId: _id,
// plugins: {
// 'core': [window.Clappr.MediaControl, window.Clappr.Playback]
// }
// });
// });
}
}
render(){
let { source, id, className } = this.props;
const _id = `_player${id}`
return(
<React.Fragment>
<style>{`
.playback_rate {
margin-right: 16px;
}
`}</style>
<div id={_id} className={className}></div>
</React.Fragment>
)
}
}
export default Clappr;

@ -53,6 +53,8 @@ export { default as MarkdownToHtml } from './components/markdown/MarkdownToHtml'
export { default as DMDEditor } from './components/markdown/DMDEditor'
export { default as Clappr } from './components/media/Clappr'
export { default as ImageLayerHook } from './hooks/ImageLayerHook'

@ -0,0 +1,50 @@
import React, { Component } from 'react';
class EffectDisplayContent extends Component {
constructor(props) {
super(props)
this.state = {
}
}
render() {
const { typeName, content1, content2, content3 } = this.props;
return (
<div className="task-popup-content effectDisplay">
<style>{`
.effectDisplay .content_title {
flex: 1 1 0
}
.effectDisplay .content>div {
flex: 1
}
.effectDisplay .clappr {
display: flex;
justify-content: center;
}
.effectDisplay .clappr>div {
width: 400px !important;
}
`}</style>
<div className="clearfix df">
{content1 && <p className="content_title edu-txt-center fl mr03precent font-18">原始{typeName}</p>}
{content2 && <p className="content_title edu-txt-center fl font-18 mr03precent">实际输出{typeName}</p>}
{content3 && <p className="content_title edu-txt-center fl font-18 mr03precent">预期输出{typeName}</p>}
</div>
<div className="clearfix df content" >
{content1 && <div className="fl mr03precent pt10 mb50">
{content1}
</div>}
{content2 && <div className="fl mr03precent pt10 mb50">
{content2}
</div>}
{content3 && <div className="fl mr03precent pt10 mb50">
{content3}
</div>}
</div>
</div>
);
}
}
export default EffectDisplayContent;

@ -2,9 +2,9 @@ import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import { Clappr } from 'educoder'
import axios from 'axios';
import EffectDisplayContent from './EffectDisplayContent'
class EvaluateSuccessEffectDisplay extends Component {
constructor(props) {
super(props)
@ -35,7 +35,8 @@ class EvaluateSuccessEffectDisplay extends Component {
// qrcode
// const type = 'image' // 'qrcode'
const { type, qrcode_str,
answer_picture, orignal_picture, user_picture, contents } = this.props;
answer_picture, orignal_picture, user_picture, contents,
user_file, answer_file, orignal_file } = this.props;
if (type == 'qrcode') {
// 单张图片比如安卓评测完显示qrcode
return (
@ -54,22 +55,35 @@ class EvaluateSuccessEffectDisplay extends Component {
return (
<div className="task-popup-content">
<div className="clearfix">
<p className="edu-txt-center fl with33 mr03precent font-18">原始图片</p>
{orignal_picture[0] && <p className="edu-txt-center fl with33 mr03precent font-18">原始图片</p>}
<p className="edu-txt-center fl font-18 with33 mr03precent">实际输出图片</p>
<p className="edu-txt-center fl font-18 with33 mr03precent">预期输出图片</p>
</div>
<div className="clearfix" id="picture-content">
{orignal_picture[0] && <div className="fl with33 mr03precent pt10 mb50">
{orignal_picture.map(item => {
return (
<img alt="Icon"
src={ item.pic_url}/> )
})}
{/* {orignal_picture[0] && <img alt="Icon"
src={ orignal_picture[0].pic_url}/>} */}
</div>}
<div className="fl with33 mr03precent pt10 mb50">
{orignal_picture[0] && <img alt="Icon"
src={ orignal_picture[0].pic_url}/>}
</div>
<div className="fl with33 mr03precent pt10 mb50">
{user_picture[0] && <img alt="Icon"
src={ user_picture[0].pic_url }/>}
</div>
{user_picture.map(item => {
return (
<img alt="Icon"
src={ item.pic_url}/> )
})}
</div>
<div className="fl with33 mr03precent pt10 mb50">
{ answer_picture[0] && <img alt="Icon"
src={ answer_picture[0].pic_url}/> }
{answer_picture.map(item => {
return (
<img alt="Icon"
src={ item.pic_url}/> )
})}
{/* { answer_picture[0] && <img alt="Icon"
src={ answer_picture[0].pic_url}/> } */}
</div>
</div>
</div>
@ -88,7 +102,31 @@ class EvaluateSuccessEffectDisplay extends Component {
return (
<iframe id="_displayIframe"></iframe>
)
}
} else if (type == 'mp3') {
return (
<EffectDisplayContent
typeName="音频"
content1={ orignal_file[0] && orignal_file[0].file_url
? <Clappr source={orignal_file[0].file_url} id="1" className="clappr"></Clappr> : null }
content2={ user_file[0] && user_file[0].file_url
? <Clappr source={user_file[0].file_url} id="2" className="clappr"></Clappr> : null }
content3={ answer_file[0] && answer_file[0].file_url
? <Clappr source={answer_file[0].file_url} id="3" className="clappr"></Clappr> : null }
></EffectDisplayContent>
)
} else if (type == 'mp4') {
return (
<EffectDisplayContent
typeName="视频"
content1={ orignal_file[0] && orignal_file[0].file_url
? <Clappr source={orignal_file[0].file_url} id="1" className="clappr"></Clappr> : null }
content2={ user_file[0] && user_file[0].file_url
? <Clappr source={user_file[0].file_url} id="2" className="clappr"></Clappr> : null }
content3={ answer_file[0] && answer_file[0].file_url
? <Clappr source={answer_file[0].file_url} id="3" className="clappr"></Clappr> : null }
></EffectDisplayContent>
)
}
/* <div className="with49 fr">
<p className="font-18 mb20 edu-txt-center">预期输出</p>

@ -75,14 +75,15 @@ class CommonWorkDetailIndex extends Component{
})
}
goback = () => {
let workId=this.props.match.params.workId;
if ( window.location.pathname.indexOf('appraise') == -1) {
let category_id= this.state.category.category_id;
this.props.toListPage(this.props.match.params, category_id)
} else {
this.props.toWorkListPage(this.props.match.params, workId)
}
// let workId=this.props.match.params.workId;
//
// if ( window.location.pathname.indexOf('appraise') == -1) {
// let category_id= this.state.category.category_id;
// this.props.toListPage(this.props.match.params, category_id)
// } else {
// this.props.toWorkListPage(this.props.match.params, workId)
// }
this.props.history.goBack()
}
// 补交附件

@ -262,8 +262,9 @@ class CommonWorkPost extends Component{
}
goback=()=>{
this.props.toListPage(this.props.match.params, this.state.category ? this.state.category.category_id : '')
}
// this.props.toListPage(this.props.match.params, this.state.category ? this.state.category.category_id : '')
this.props.history.goBack()
}
// 输入title
@ -469,7 +470,7 @@ class CommonWorkPost extends Component{
}
gocannel=()=>{
window.history.go(-1)
this.props.history.goBack()
}
render(){

@ -31,14 +31,15 @@ class WorkDetailPageHeader extends Component{
}
goback = () => {
let workId=this.props.match.params.workId;
if ( window.location.pathname.indexOf('appraise') == -1) {
let category_id= this.props.category.category_id;
this.props.toListPage(this.props.match.params, category_id)
} else {
this.props.toWorkListPage(this.props.match.params, this.props.match.params.category_id)
}
// let workId=this.props.match.params.workId;
//
// if ( window.location.pathname.indexOf('appraise') == -1) {
// let category_id= this.props.category.category_id;
// this.props.toListPage(this.props.match.params, category_id)
// } else {
// this.props.toWorkListPage(this.props.match.params, this.props.match.params.category_id)
// }
this.props.history.goBack()
}
// 补交附件
Cancelvisible=()=>{

@ -1,33 +1,35 @@
.courses-head{
width: 100%;
height: 300px;
background-image: url(./courses.jpg);
background-color: #081C4B;
background-size: 100% 100%;
}
a{
text-decoration: none;
color: #05101a;
}
.ant-input-affix-wrapper .ant-input:not(:last-child) {
padding-right: 24px;
}
.memberscount{
font-size: 55px !important;
background: #fff;
color: #dfdfdf;
display: inline-block;
padding-right: 15px;
}
.biaoqiancours{
overflow: hidden;
position: relative;
}
.coursesover{
position: absolute;
color: #fff;
left: 17px;
background: #dfdfdf;
width: 200px;
.courses-head{
width: 100%;
height: 300px;
background-image: url(./courses.jpg);
background-color: #081C4B;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
a{
text-decoration: none;
color: #05101a;
}
.ant-input-affix-wrapper .ant-input:not(:last-child) {
padding-right: 24px;
}
.memberscount{
font-size: 55px !important;
background: #fff;
color: #dfdfdf;
display: inline-block;
padding-right: 15px;
}
.biaoqiancours{
overflow: hidden;
position: relative;
}
.coursesover{
position: absolute;
color: #fff;
left: 17px;
background: #dfdfdf;
width: 200px;
}

@ -20,6 +20,14 @@ function disabledDateTime() {
// disabledSeconds: () => [55, 56],
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class HomeworkModal extends Component{
constructor(props){
super(props);
@ -81,7 +89,7 @@ class HomeworkModal extends Component{
// console.log('startValue',dateString);
this.setState({
endtime: handleDateString(dateString),
endtime: date===null?"":handleDateString(dateString),
})
}
@ -188,6 +196,7 @@ class HomeworkModal extends Component{
dropdownClassName="hideDisable"
showTime={{ format: 'HH:mm' }}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
showToday={false}
locale={locale}
format={dateFormat}

@ -16,12 +16,17 @@ function range(start, end) {
}
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 Selectsetting extends Component{
constructor(props){
super(props);
@ -698,6 +703,7 @@ class Selectsetting extends Component{
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>:""}
@ -730,7 +736,7 @@ class Selectsetting extends Component{
value={datatime===undefined||datatime===""?"":moment(datatime, dateFormat)}
onChange={this.onChangeTimepublish}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
/>
</span>
</p>:""}

@ -22,6 +22,11 @@ function disabledDateTime() {
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
const dateFormat="YYYY-MM-DD HH:mm";
class Sendresource extends Component{
constructor(props){
@ -525,6 +530,7 @@ class Sendresource extends Component{
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>:""}
@ -551,7 +557,7 @@ class Sendresource extends Component{
value={datatime===undefined||datatime===""?undefined:moment(datatime, dateFormat)}
onChange={(e,index)=>this.onChangeTimepublish(e,index,undefined,1)}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
/>
</span>
</p>:""}

@ -1,247 +1,247 @@
import React,{Component} from "React";
import { Form, Select, Input, Button,Checkbox,DatePicker} from "antd";
import locale from 'antd/lib/date-picker/locale/zh_CN';
import "../css/Courses.css";
import CoursesListType from '../coursesPublic/CoursesListType';
const { Option } = Select;
const CheckboxGroup = Checkbox.Group;
class Ecercisemount extends Component{
constructor(props){
super(props)
this.state={
}
}
componentDidMount(){
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
}
handleSelectChange = (value) => {
console.log(value);
this.props.form.setFieldsValue({
note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,
});
}
render(){
const { getFieldDecorator } = this.props.form;
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
return(
<React.Fragment>
<div>
<div className="newMain clearfix">
<div className={"educontent mb20"}>
<div style={{ width:'100%',height:'70px'}} >
<p className="ml15 fl color-black mt30 summaryname">Java语言之控制语句</p>
<CoursesListType
typelist={["已开启补交"]}
typesylename={"mt28"}
/>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml20 mt18 mr20">返回</a>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml30 mt18 " target={"_blank"}>实训详情</a>
</div>
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
<a className="active">答题列表</a>
<a>统计结果</a>
<a>问卷预览</a>
<a>配置</a>
<a className={"fr color-blue font-16"}>导出成绩</a>
<a className={"fr color-blue font-16"}>导出空白试卷</a>
</div>
</div>
<Form onSubmit={this.handleSubmit} className={"edu-back-white newcourses exercise"}>
{/*内容*/}
<div className="stud-class-set bor-bottom-greyE pd20 exerciselist">
<Form.Item label="发布设置" hasFeedback>
{getFieldDecorator("TestingProfile")(
<Checkbox id="TestingProfile" value={""} className="fl ml40">统一设置</Checkbox>
)}
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>发布时间</span>
<span className="fl mt5">
{getFieldDecorator("startTime")(
<DatePicker
showTime
showToday={false}
locale={locale}
format={dateFormat}
placeholder="请选择发布时间"
id={"startTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>发布之前学生不会收到问卷</span>
</span>
</div>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>截止时间</span>
<span className="fl mt5">
{getFieldDecorator("endTime")(
<DatePicker
showTime
showToday={false}
locale={locale}
format={dateFormat}
placeholder="请选择截止时间"
id={"endTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>截止时间点系统将自动提交所有学生的答题学生将不能继续答题</span>
</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set bor-bottom-greyE pd20 exercisetime">
<Form.Item label="答题设置" hasFeedback>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40 font-16" style={{minWidth: '70px'}}>答题时长</span>
{getFieldDecorator("TestingProfile"
, {
rules: [{
pattern: /^[1-9]\d*$/,
message: '答题时长必须为正整数',
}],
})(
<Input id="TestingProfile" className={"greyInput mt10 mr10"} style={{width:'108px',marginLeft:'0px'}} />
)}
<span className={"mr10"}>分钟</span>
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
</div>
</Form.Item>
<Form.Item hasFeedback>
<div className={"clearfix pd60"}>
{getFieldDecorator("subject", {
valuePropName: 'checked',
})(
<Checkbox id="subject" className="fl">题目顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时题目顺序按照题型随机显示</span>
</div>
<div className={"clearfix pd60"}>
{getFieldDecorator("options", {
valuePropName: 'checked',
})(
<Checkbox id="options" className="fl">选项顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时选项顺序随机显示</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set pd20 coursenavbox">
<Form.Item
label="公开设置"
hasFeedback
>
<div className={"clearfix pd28"}>
{getFieldDecorator("opergrdee", {
valuePropName: 'checked',
})(
<Checkbox id="opergrdee" className="fl">公开成绩</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开所有成绩否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openanswer", {
valuePropName: 'checked',
})(
<Checkbox id="openanswer" className="fl">公开答案</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开试卷题目的答案否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openstatisticss", {
valuePropName: 'checked',
})(
<Checkbox id="openstatisticss" className="fl">公开统计</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开答题统计否则不公开</span>
</div>
</Form.Item>
</div>
<Form.Item wrapperCol={{ span: 12, offset: 5 }} >
<div className="clearfix mt30 mb30">
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">
提交
</Button>
{/*<a className="defalutSubmitbtn fl mr20">提交</a>*/}
<a className="defalutCancelbtn fl">取消</a>
</div>
</Form.Item>
</Form>
</div>
</div>
</div>
</React.Fragment>
)
}
}
const EcercisemountApp = Form.create({ name: 'coursesNew' })(Ecercisemount);
import React,{Component} from "React";
import { Form, Select, Input, Button,Checkbox,DatePicker} from "antd";
import locale from 'antd/lib/date-picker/locale/zh_CN';
import "../css/Courses.css";
import CoursesListType from '../coursesPublic/CoursesListType';
const { Option } = Select;
const CheckboxGroup = Checkbox.Group;
class Ecercisemount extends Component{
constructor(props){
super(props)
this.state={
}
}
componentDidMount(){
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
}
handleSelectChange = (value) => {
console.log(value);
this.props.form.setFieldsValue({
note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,
});
}
render(){
const { getFieldDecorator } = this.props.form;
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
return(
<React.Fragment>
<div>
<div className="newMain clearfix">
<div className={"educontent mb20"}>
<div style={{ width:'100%',height:'70px'}} >
<p className="ml15 fl color-black mt30 summaryname">Java语言之控制语句</p>
<CoursesListType
typelist={["已开启补交"]}
typesylename={"mt28"}
/>
<a onClick={()=>this.props.history.goBack()} className="color-grey-6 fr font-16 ml20 mt18 mr20">返回</a>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml30 mt18 " target={"_blank"}>实训详情</a>
</div>
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
<a className="active">答题列表</a>
<a>统计结果</a>
<a>问卷预览</a>
<a>配置</a>
<a className={"fr color-blue font-16"}>导出成绩</a>
<a className={"fr color-blue font-16"}>导出空白试卷</a>
</div>
</div>
<Form onSubmit={this.handleSubmit} className={"edu-back-white newcourses exercise"}>
{/*内容*/}
<div className="stud-class-set bor-bottom-greyE pd20 exerciselist">
<Form.Item label="发布设置" hasFeedback>
{getFieldDecorator("TestingProfile")(
<Checkbox id="TestingProfile" value={""} className="fl ml40">统一设置</Checkbox>
)}
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>发布时间</span>
<span className="fl mt5">
{getFieldDecorator("startTime")(
<DatePicker
showTime
showToday={false}
locale={locale}
format={dateFormat}
placeholder="请选择发布时间"
id={"startTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>发布之前学生不会收到问卷</span>
</span>
</div>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>截止时间</span>
<span className="fl mt5">
{getFieldDecorator("endTime")(
<DatePicker
showTime
showToday={false}
locale={locale}
format={dateFormat}
placeholder="请选择截止时间"
id={"endTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>截止时间点系统将自动提交所有学生的答题学生将不能继续答题</span>
</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set bor-bottom-greyE pd20 exercisetime">
<Form.Item label="答题设置" hasFeedback>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40 font-16" style={{minWidth: '70px'}}>答题时长</span>
{getFieldDecorator("TestingProfile"
, {
rules: [{
pattern: /^[1-9]\d*$/,
message: '答题时长必须为正整数',
}],
})(
<Input id="TestingProfile" className={"greyInput mt10 mr10"} style={{width:'108px',marginLeft:'0px'}} />
)}
<span className={"mr10"}>分钟</span>
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
</div>
</Form.Item>
<Form.Item hasFeedback>
<div className={"clearfix pd60"}>
{getFieldDecorator("subject", {
valuePropName: 'checked',
})(
<Checkbox id="subject" className="fl">题目顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时题目顺序按照题型随机显示</span>
</div>
<div className={"clearfix pd60"}>
{getFieldDecorator("options", {
valuePropName: 'checked',
})(
<Checkbox id="options" className="fl">选项顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时选项顺序随机显示</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set pd20 coursenavbox">
<Form.Item
label="公开设置"
hasFeedback
>
<div className={"clearfix pd28"}>
{getFieldDecorator("opergrdee", {
valuePropName: 'checked',
})(
<Checkbox id="opergrdee" className="fl">公开成绩</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开所有成绩否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openanswer", {
valuePropName: 'checked',
})(
<Checkbox id="openanswer" className="fl">公开答案</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开试卷题目的答案否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openstatisticss", {
valuePropName: 'checked',
})(
<Checkbox id="openstatisticss" className="fl">公开统计</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开答题统计否则不公开</span>
</div>
</Form.Item>
</div>
<Form.Item wrapperCol={{ span: 12, offset: 5 }} >
<div className="clearfix mt30 mb30">
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">
提交
</Button>
{/*<a className="defalutSubmitbtn fl mr20">提交</a>*/}
<a className="defalutCancelbtn fl">取消</a>
</div>
</Form.Item>
</Form>
</div>
</div>
</div>
</React.Fragment>
)
}
}
const EcercisemountApp = Form.create({ name: 'coursesNew' })(Ecercisemount);
export default EcercisemountApp;

@ -23,6 +23,7 @@ function range(start, end) {
}
return result;
}
function disabledDateTime() {
return {
// disabledHours: () => range(0, 24).splice(4, 20),
@ -30,6 +31,11 @@ function disabledDateTime() {
// disabledSeconds: () => [0, 60],
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
const dataformat="YYYY-MM-DD HH:mm";
class Exercisesetting extends Component{
@ -636,6 +642,7 @@ class Exercisesetting extends Component{
format="YYYY-MM-DD HH:mm"
showToday={false}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimepublish}
value={publish_time && moment(publish_time,"YYYY-MM-DD HH:mm")}
disabled={ publish_timetype===true?true:!flagPageEdit }
@ -661,6 +668,7 @@ class Exercisesetting extends Component{
width={"240px"}
format="YYYY-MM-DD HH:mm"
disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimeEnd}
value={end_time && moment(end_time,"YYYY-MM-DD HH:mm")}
disabled={ end_timetype===true?true:!flagPageEdit}

@ -2312,11 +2312,13 @@ class Studentshavecompletedthelist extends Component {
};
_getRequestParams() {
const { order, checkedValuesineinfo,searchtext, page ,limit} = this.state
const { order, checkedValuesineinfo,course_groupyslstwo ,searchtext, page ,limit,course_groupyslsthree} = this.state
return {
page,
review:course_groupyslsthree,
commit_status:course_groupyslstwo,
search:searchtext,
group_id:checkedValuesineinfo,
exercise_group_id:checkedValuesineinfo,
limit: limit,
order,
}

@ -1,7 +1,7 @@
import React,{ Component } from "react";
import {Checkbox,Input,Table, Pagination,Menu} from "antd";
import {Checkbox,Input,Table, Pagination,Menu,Spin} from "antd";
import {Link,NavLink} from 'react-router-dom';
import { WordsBtn ,ActionBtn,queryString} from 'educoder';
import { WordsBtn ,ActionBtn,queryString,downloadFile} from 'educoder';
import CoursesListType from '../coursesPublic/CoursesListType';
import '../css/members.css';
import '../css/busyWork.css';
@ -33,6 +33,7 @@ class Testpapersettinghomepage extends Component{
current_status:undefined,
DownloadType:false,
DownloadMessageval:undefined,
donwloading:false,
}
}
//切换tab
@ -170,7 +171,7 @@ class Testpapersettinghomepage extends Component{
}
console.log("170");
console.log(params);
axios.get(url+`?${queryString.stringify(params)}`+ '&export=true' ).then((response) => {
axios.get(url+`?${queryString.stringify(params)}`+ '&export=true').then((response) => {
if(response===undefined){
return
}
@ -192,8 +193,21 @@ class Testpapersettinghomepage extends Component{
})
}
}else {
this.props.showNotification(`正在下载中`);
window.open("/api"+url+`?${queryString.stringify(params)}`, '_blank');
this.setState({ donwloading: true })
downloadFile({
url: url+`?${queryString.stringify(params)}`,
successCallback: (url) => {
this.setState({ donwloading: false });
console.log('successCallback')
},
failCallback: (responseHtml, url) => {
this.setState({ donwloading: false });
console.log('failCallback')
}
})
this.props.showNotification(`正在下载中`);
// window.open("/api"+url+`?${queryString.stringify(params)}`+ '&export=true', '_blank');
}
}).catch((error) => {
console.log(error)
@ -234,13 +248,13 @@ class Testpapersettinghomepage extends Component{
// let category_id=this.props.match.params.category_id;
//
// window.location.href="/courses/"+courseId+"/graduation_tasks/"+datalist.graduation_id;
let courseId=this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
render(){
let {tab,visible,Commonheadofthetestpaper}=this.state;
@ -353,14 +367,14 @@ class Testpapersettinghomepage extends Component{
`}
</style>
<div className={"studentList_operation_ul mt23"}>
{isAdmin === true? <li className="li_line drop_down fr color-blue font-15" style={{"paddingLeft":"0px"}}>
{isAdmin === true? <Spin spinning={this.state.donwloading} style={{ }}><li className="li_line drop_down fr color-blue font-15" style={{"paddingLeft":"0px"}}>
导出<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu" style={{"right":"-34px","left":"unset","height":"auto"}}>
<li><a onClick={()=>this.confirmysl(`/exercises/${this.props.match.params.Id}/exercise_lists.xlsx`,this.child)}>学生成绩</a></li>
{/*<li><a onClick={()=>this.confirmysl(`/exercises/${this.props.match.params.Id}/export_exercise`)} >空白试卷</a></li>*/}
<li><a onClick={()=>this.confirmysl(`/exercises/${this.props.match.params.Id}/export_exercise`,this.child)} >空白试卷</a></li>
{/*<li><a onClick={()=>this.confirmysl(`/zip/export_exercises?exercise_id=${this.props.match.params.Id}${this.state.groupyslsval===null||this.state.groupyslsval===undefined?null:this.state.groupyslsval}`)}>学生答题试卷</a></li>*/}
</ul>
</li>:""}
</li></Spin>:""}
</div>
{

@ -97,13 +97,13 @@ class GraduationTasksSubmitedit extends Component{
goback=()=>{
let courseId=this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
@ -362,7 +362,7 @@ class GraduationTasksSubmitedit extends Component{
}
gocannel=()=>{
window.history.go(-1)
this.props.history.goBack()
}
handleSubmit=(e) => {

@ -99,14 +99,14 @@ class GraduationTasksSubmitnew extends Component{
}
goback=()=>{
let courseId=this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
}
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
// 输入title
@ -362,7 +362,7 @@ class GraduationTasksSubmitnew extends Component{
}
}
gocannel=()=>{
window.history.go(-1)
this.props.history.goBack()
}
//公用数据

@ -70,13 +70,13 @@ class GraduationTasksappraise extends Component{
// let category_id=this.props.match.params.category_id;
//
// window.location.href="/courses/"+courseId+"/graduation_tasks/"+datalist.graduation_id;
let courseId=this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
Cancelvisible=()=>{

@ -82,13 +82,13 @@ class GraduationTasksedit extends Component{
goback=()=>{
let courseId = this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// let courseId = this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}

@ -107,12 +107,13 @@ class GraduationTasksnew extends Component {
goback = () => {
let courseId = this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// let courseId = this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}

@ -27,6 +27,11 @@ function disabledDateTime() {
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class GraduationTaskssettingapp extends Component{
constructor(props){
@ -760,12 +765,13 @@ class GraduationTaskssettingapp extends Component{
}
goback=()=>{
let courseId=this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
isgoback=()=>{
@ -1181,6 +1187,7 @@ class GraduationTaskssettingapp extends Component{
value={publish_time===null||publish_time===""?"":moment(publish_time, dateFormat)}
onChange={this.onChangeTimepublish}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={this.props.isAdmin()===true?starttimetype===true?true:flagPageEdit===true?false:true:true}
className={ this.state.publishTimetypes===true?"noticeTip":""}
/>
@ -1218,6 +1225,7 @@ class GraduationTaskssettingapp extends Component{
value={end_time===null||end_time===""?"":moment(end_time, dateFormat)}
onChange={this.onChangeTimeend}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
// disabled={this.props.isSuperAdmin()===true?flagPageEdit===true?false:true:this.props.isAdmin()===true?endtimetype===true?true:flagPageEdit===true?false:true:true}
disabled={this.props.isAdmin()===true?endtimetype===true?true:flagPageEdit===true?false:true:true}
className={this.state.endTimetypes===true||end_timetype===true?"noticeTip":""}
@ -1269,6 +1277,7 @@ class GraduationTaskssettingapp extends Component{
width={"210px"}
value={latetime===null||latetime===""?"":moment(latetime, dateFormat)}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimelatetime}
disabled={this.props.isAdmin()===true?allowlate===true||allowlate===1?flagPageEdit===true?false:true:true:true}
className={ latetimetype===true?"noticeTip":""}
@ -1319,6 +1328,7 @@ class GraduationTaskssettingapp extends Component{
width={"210px"}
value={commenttime===null||commenttime=== ""?"":moment(commenttime, dateFormat)}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimecommenttime}
disabled={this.props.isAdmin()===true?flagPageEdit===true?false:true:true}
className={ commenttimetype===true?"noticeTip":""}

@ -60,13 +60,13 @@ class GraduationTaskssettinglist extends Component{
goback=()=>{
// window.history.back(-1)
let courseId=this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
seacthdata=(teacher_comment,task_status,course_group,cross_comment,order,b_order,search,pages)=>{

@ -55,12 +55,14 @@ class GraduationTasksquestions extends Component{
// let courseId=this.props.match.params.coursesId;
// let category_id=this.props.match.params.category_id;
// window.location.href="/courses/"+courseId+"/graduation_tasks/"+category_id;
let courseId = this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// let courseId = this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
end=()=>{

@ -265,7 +265,7 @@ class GraduateTopicPostWorksNew extends Component{
<div style={{ width:'100%',height:'70px'}} >
<p className="ml15 fl color-black mt30 summaryname">提交作品</p>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml30 mt18 mr20">返回</a>
<a onClick={()=>this.props.history.goBack()} className="color-grey-6 fr font-16 ml30 mt18 mr20">返回</a>
</div>
<Form {...formItemLayout} onSubmit={this.handleSubmit}>

@ -28,6 +28,9 @@ function disabledDateTime() {
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class CoursesNew extends Component {
@ -254,12 +257,13 @@ class CoursesNew extends Component {
goback = () => {
if(this.props.match.params.coursesId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// if(this.props.match.params.coursesId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
// window.history.go(-1)
this.props.history.goBack()
}
onCheckAllChange = (e) => {
@ -572,6 +576,7 @@ class CoursesNew extends Component {
width={"210px"}
value={datatime === undefined ? "" :datatime === null ? "" : moment(datatime, dateFormat)}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
dropdownClassName="hideDisable"
onChange={this.onChangeTimepublishs}
/>

@ -26,6 +26,12 @@ function disabledDateTime() {
// disabledSeconds: () => range(1,60)
}
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class PollDetailTabForthRules extends Component{
constructor(props){
super(props);
@ -404,6 +410,7 @@ class PollDetailTabForthRules extends Component{
showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm"
disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={ rule.e_timeflag ===undefined?rule.publish_time===null?false:!flagPageEdit:rule.p_timeflag == true ? true : !flagPageEdit}
style={{"height":"42px",width:'100%'}}
></DatePicker>
@ -429,6 +436,7 @@ class PollDetailTabForthRules extends Component{
showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm"
disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={ rule.e_timeflag ===undefined?rule.publish_time===null?false:!flagPageEdit:rule.e_timeflag == true ? true : !flagPageEdit}
style={{"height":"42px"}}
></DatePicker>

@ -2337,11 +2337,11 @@ class PollNew extends Component {
}
gotohome=()=>{
const { current_user} = this.props
this.props.history.push(current_user && current_user.first_category_url);
// const { current_user} = this.props
// this.props.history.push(current_user && current_user.first_category_url);
//
this.props.history.goBack()
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");

@ -1,157 +1,157 @@
import React, { Component } from 'react';
import { SnackbarHOC } from 'educoder';
import { TPMIndexHOC } from '../../tpm/TPMIndexHOC';
import { Checkbox,Input,DatePicker } from 'antd';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import "../css/Courses.css";
import CoursesListType from '../coursesPublic/CoursesListType';
//引入对应跳转的组件
class Polldepoly extends Component{
constructor(props) {
super(props)
this.state = {
contents: [{val:"",id:1}],
}
}
componentDidMount() {
}
submitCommitSummary=()=> {
const mdContnet = this.refs[`md${1}`].getValue().trim();;
console.log(mdContnet)
}
asdasdsad=()=>{
this.setState({
contents:""
})
}
render() {
let {contents}=this.state;
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
return (
<React.Fragment>
<div>
<div className="newMain clearfix">
<div className={"educontent mb20"}>
<div style={{
width:'100%',
height:'70px'
}} >
<p className="ml15 fl color-black mt30 summaryname" onClick={this.asdasdsad}>Java语言之控制语句</p>
<CoursesListType
typelist={["已开启补交"]}
typesylename={"mt28"}
/>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml30 mt18 mr20">返回</a>
</div>
{/*<div className={"edu-con-bg01 user_bg_shadow bor-grey-e educontentbox"}>*/}
{/*<span className={"commitcontents"}>*/}
{/*<span className={"color-red"}>*</span>*/}
{/*内容</span>*/}
{/*<div className={"ml30 mr30 mt10"}>*/}
{/*</div>*/}
{/*</div>*/}
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
<a className="active">答题列表</a>
<a>统计结果</a>
<a>问卷预览</a>
<a>配置</a>
<a className={"fr color-blue font-16"}>导出统计</a>
</div>
</div>
<div className="stud-class-set edu-back-white pt30 pb30 pr10 pl20">
<div className="clearfix">
<p className="ml22 fl font-16 mt5 color-grey-6">发布设置</p>
{/*<a href="javascript:void(0);" className="white-btn orange-btn fr mr15 mt15" title="编辑"*/}
{/*onClick="show_poll_edit_setting();">编辑</a>*/}
</div>
<div className="clearfix pl60 pt20">
<Checkbox className={"color-grey-6"}>统一设置 </Checkbox> <span className={"color-grey-9"}>(使)</span>
</div>
<div className="clearfix pl60 pt20">
{/*<span className={"color-grey-6"}>发布时间:</span> <Input size="large" placeholder="请选择发布时间" /><span className={"color-grey-9"}>(发布之前,学生不会收到问卷)</span>*/}
<span className="color-grey-6 mt5 fl" style={{minWidth: '70px'}}>发布时间</span>
<span className="fl mt5">
<DatePicker
showTime
showToday={false}
locale={locale}
format={dateFormat}
placeholder="请选择发布时间"
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
<label style={{top:'6px'}} className="color-grey-9 ml10" >发布之前学生不会收到问卷</label>
</span>
</div>
<div className="clearfix pl60 pt20">
{/*<span className={"color-grey-6"}>发布时间:</span> <Input size="large" placeholder="请选择发布时间" /><span className={"color-grey-9"}>(发布之前,学生不会收到问卷)</span>*/}
<span className="color-grey-6 mt5 fl" style={{minWidth: '70px'}}>截止时间</span>
<span className="fl mt5">
<DatePicker
showToday={false}
showTime
locale={locale}
format={dateFormat}
placeholder="请选择截止时间"
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
<label style={{top:'6px'}} className="color-grey-9 ml10" >截止时间点系统将自动提交所有学生的答题学生将不能继续答题</label>
</span>
</div>
<div className="stud-class-set edu-back-white pt30 pb30 pr10 pl20">
<div className="clearfix">
<p className="ml22 fl font-16 mt5 color-grey-6">公开设置</p>
{/*<a href="javascript:void(0);" className="white-btn orange-btn fr mr15 mt15" title="编辑"*/}
{/*onClick="show_poll_edit_setting();">编辑</a>*/}
</div>
<div className="clearfix pl40 pt20">
<Checkbox className={"color-grey-6"}>公开统计 </Checkbox> <span className={"color-grey-9"}></span>
</div>
<div className="clearfix pl40 pt10">
<Checkbox className={"color-grey-6"}>实名问卷 </Checkbox> <span className={"color-grey-9"}></span>
</div>
</div>
</div>
<div className="clearfix mt30 mb30">
<a className="defalutSubmitbtn fl mr20"
onClick={this.submitCommitSummary}>提交</a>
<a className="defalutCancelbtn fl">取消</a>
</div>
</div>
</div>
</div>
</React.Fragment>
)
}
}
export default SnackbarHOC() ( TPMIndexHOC(Polldepoly) );
import React, { Component } from 'react';
import { SnackbarHOC } from 'educoder';
import { TPMIndexHOC } from '../../tpm/TPMIndexHOC';
import { Checkbox,Input,DatePicker } from 'antd';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import "../css/Courses.css";
import CoursesListType from '../coursesPublic/CoursesListType';
//引入对应跳转的组件
class Polldepoly extends Component{
constructor(props) {
super(props)
this.state = {
contents: [{val:"",id:1}],
}
}
componentDidMount() {
}
submitCommitSummary=()=> {
const mdContnet = this.refs[`md${1}`].getValue().trim();;
console.log(mdContnet)
}
asdasdsad=()=>{
this.setState({
contents:""
})
}
render() {
let {contents}=this.state;
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
return (
<React.Fragment>
<div>
<div className="newMain clearfix">
<div className={"educontent mb20"}>
<div style={{
width:'100%',
height:'70px'
}} >
<p className="ml15 fl color-black mt30 summaryname" onClick={this.asdasdsad}>Java语言之控制语句</p>
<CoursesListType
typelist={["已开启补交"]}
typesylename={"mt28"}
/>
<a onClick={()=>this.props.history.goBack()} className="color-grey-6 fr font-16 ml30 mt18 mr20">返回</a>
</div>
{/*<div className={"edu-con-bg01 user_bg_shadow bor-grey-e educontentbox"}>*/}
{/*<span className={"commitcontents"}>*/}
{/*<span className={"color-red"}>*</span>*/}
{/*内容</span>*/}
{/*<div className={"ml30 mr30 mt10"}>*/}
{/*</div>*/}
{/*</div>*/}
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
<a className="active">答题列表</a>
<a>统计结果</a>
<a>问卷预览</a>
<a>配置</a>
<a className={"fr color-blue font-16"}>导出统计</a>
</div>
</div>
<div className="stud-class-set edu-back-white pt30 pb30 pr10 pl20">
<div className="clearfix">
<p className="ml22 fl font-16 mt5 color-grey-6">发布设置</p>
{/*<a href="javascript:void(0);" className="white-btn orange-btn fr mr15 mt15" title="编辑"*/}
{/*onClick="show_poll_edit_setting();">编辑</a>*/}
</div>
<div className="clearfix pl60 pt20">
<Checkbox className={"color-grey-6"}>统一设置 </Checkbox> <span className={"color-grey-9"}>(使)</span>
</div>
<div className="clearfix pl60 pt20">
{/*<span className={"color-grey-6"}>发布时间:</span> <Input size="large" placeholder="请选择发布时间" /><span className={"color-grey-9"}>(发布之前,学生不会收到问卷)</span>*/}
<span className="color-grey-6 mt5 fl" style={{minWidth: '70px'}}>发布时间</span>
<span className="fl mt5">
<DatePicker
showTime
showToday={false}
locale={locale}
format={dateFormat}
placeholder="请选择发布时间"
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
<label style={{top:'6px'}} className="color-grey-9 ml10" >发布之前学生不会收到问卷</label>
</span>
</div>
<div className="clearfix pl60 pt20">
{/*<span className={"color-grey-6"}>发布时间:</span> <Input size="large" placeholder="请选择发布时间" /><span className={"color-grey-9"}>(发布之前,学生不会收到问卷)</span>*/}
<span className="color-grey-6 mt5 fl" style={{minWidth: '70px'}}>截止时间</span>
<span className="fl mt5">
<DatePicker
showToday={false}
showTime
locale={locale}
format={dateFormat}
placeholder="请选择截止时间"
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
<label style={{top:'6px'}} className="color-grey-9 ml10" >截止时间点系统将自动提交所有学生的答题学生将不能继续答题</label>
</span>
</div>
<div className="stud-class-set edu-back-white pt30 pb30 pr10 pl20">
<div className="clearfix">
<p className="ml22 fl font-16 mt5 color-grey-6">公开设置</p>
{/*<a href="javascript:void(0);" className="white-btn orange-btn fr mr15 mt15" title="编辑"*/}
{/*onClick="show_poll_edit_setting();">编辑</a>*/}
</div>
<div className="clearfix pl40 pt20">
<Checkbox className={"color-grey-6"}>公开统计 </Checkbox> <span className={"color-grey-9"}></span>
</div>
<div className="clearfix pl40 pt10">
<Checkbox className={"color-grey-6"}>实名问卷 </Checkbox> <span className={"color-grey-9"}></span>
</div>
</div>
</div>
<div className="clearfix mt30 mb30">
<a className="defalutSubmitbtn fl mr20"
onClick={this.submitCommitSummary}>提交</a>
<a className="defalutCancelbtn fl">取消</a>
</div>
</div>
</div>
</div>
</React.Fragment>
)
}
}
export default SnackbarHOC() ( TPMIndexHOC(Polldepoly) );

@ -71,13 +71,14 @@ class CommitSummary extends Component{
console.log(mdContnet)
}
gotohome=()=>{
let courseId=this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
}
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
asdasdsad=()=>{
this.setState({
contents:""

@ -113,12 +113,13 @@ class ShixunHomeworkPage extends Component {
bindRef = ref => { this.child = ref }
///////////////教师截止
gotohome=()=>{
let courseId=this.props.match.params.coursesId;
if(courseId===undefined){
this.props.history.push("/courses");
}else{
this.props.history.push(this.props.current_user.first_category_url);
}
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
render() {
let {tab, teacherdatapage, jobsettingsdatapage} = this.state;

@ -52,13 +52,13 @@ class ShixunWorkDetails extends Component {
}
goback=(sum)=>{
let{data}=this.state
if(sum===1){
window.location.href = "/courses/"+data.course_id+"/students";
}else{
window.history.go(-1)
}
// let{data}=this.state
// if(sum===1){
// window.location.href = "/courses/"+data.course_id+"/students";
// }else{
// window.history.go(-1)
// }
this.props.history.goBack()
}
render() {
let{data}=this.state;

@ -47,6 +47,9 @@ function disabledDateTime() {
}
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class Trainingjobsetting extends Component {
//unifiedsetting 统一设置
@ -1935,6 +1938,7 @@ class Trainingjobsetting extends Component {
id={"publishtimeid"}
disabledDate={this.disabledStartDatestart}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
className={borreds}
showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm"
@ -1967,6 +1971,7 @@ class Trainingjobsetting extends Component {
showToday={false}
id={"end_timeid"}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
showTime={{ format: 'HH:mm' }}
className={borredss}
format="YYYY-MM-DD HH:mm"
@ -2049,6 +2054,7 @@ class Trainingjobsetting extends Component {
showToday={false}
id={"late_timeid"}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
format="YYYY-MM-DD HH:mm"
value={late_time && moment(late_time, dataformat)}
onChange={this.onEndChangeys}

@ -1,246 +1,246 @@
import React,{Component} from "React";
import { Form, Select, Input, Button,Checkbox,DatePicker} from "antd";
import locale from 'antd/lib/date-picker/locale/zh_CN';
import "../css/Courses.css";
import CoursesListType from '../coursesPublic/CoursesListType';
const { Option } = Select;
const CheckboxGroup = Checkbox.Group;
class StudentHomework extends Component{
constructor(props){
super(props)
this.state={
}
}
componentDidMount(){
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
}
handleSelectChange = (value) => {
console.log(value);
this.props.form.setFieldsValue({
note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,
});
}
render(){
const { getFieldDecorator } = this.props.form;
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
return(
<React.Fragment>
<div>
<div className="newMain clearfix">
<div className={"educontent mb20"}>
<div style={{ width:'100%',height:'70px'}} >
<p className="ml15 fl color-black mt30 summaryname">Java语言之控制语句</p>
<CoursesListType
typelist={["已开启补交"]}
typesylename={"mt28"}
/>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml20 mt18 mr20">返回</a>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml30 mt18 " target={"_blank"}>实训详情</a>
</div>
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
<a className="active">作业列表</a>
<a>作业问答</a>
<a>配置</a>
<a className={"fr color-blue font-16"}>立即发布</a>
<a className={"fr color-blue font-16"}>导出成绩</a>
</div>
</div>
<Form onSubmit={this.handleSubmit} className={"edu-back-white newcourses exercise"}>
{/*内容*/}
<div className="stud-class-set bor-bottom-greyE pd20 exerciselist">
<Form.Item label="发布设置" hasFeedback>
{getFieldDecorator("TestingProfile")(
<Checkbox id="TestingProfile" value={""} className="fl ml40">统一设置</Checkbox>
)}
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>发布时间</span>
<span className="fl mt5">
{getFieldDecorator("startTime")(
<DatePicker
showToday={false}
showTime
locale={locale}
format={dateFormat}
placeholder="请选择发布时间"
id={"startTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>发布之前学生不会收到问卷</span>
</span>
</div>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>截止时间</span>
<span className="fl mt5">
{getFieldDecorator("endTime")(
<DatePicker
showToday={false}
showTime
locale={locale}
format={dateFormat}
placeholder="请选择截止时间"
id={"endTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>截止时间点系统将自动提交所有学生的答题学生将不能继续答题</span>
</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set bor-bottom-greyE pd20 exercisetime">
<Form.Item label="补交设置" hasFeedback>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40 font-16" style={{minWidth: '70px'}}>答题时长</span>
{getFieldDecorator("TestingProfile"
, {
rules: [{
pattern: /^[1-9]\d*$/,
message: '答题时长必须为正整数',
}],
})(
<Input id="TestingProfile" className={"greyInput mt10 mr10"} style={{width:'108px',marginLeft:'0px'}} />
)}
<span className={"mr10"}>分钟</span>
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
</div>
</Form.Item>
<Form.Item hasFeedback>
<div className={"clearfix pd60"}>
{getFieldDecorator("subject", {
valuePropName: 'checked',
})(
<Checkbox id="subject" className="fl">题目顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时题目顺序按照题型随机显示</span>
</div>
<div className={"clearfix pd60"}>
{getFieldDecorator("options", {
valuePropName: 'checked',
})(
<Checkbox id="options" className="fl">选项顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时选项顺序随机显示</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set pd20 coursenavbox">
<Form.Item
label="公开设置"
hasFeedback
>
<div className={"clearfix pd28"}>
{getFieldDecorator("opergrdee", {
valuePropName: 'checked',
})(
<Checkbox id="opergrdee" className="fl">公开成绩</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开所有成绩否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openanswer", {
valuePropName: 'checked',
})(
<Checkbox id="openanswer" className="fl">公开答案</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开试卷题目的答案否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openstatisticss", {
valuePropName: 'checked',
})(
<Checkbox id="openstatisticss" className="fl">公开统计</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开答题统计否则不公开</span>
</div>
</Form.Item>
</div>
<Form.Item wrapperCol={{ span: 12, offset: 5 }} >
<div className="clearfix mt30 mb30">
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">
提交
</Button>
{/*<a className="defalutSubmitbtn fl mr20">提交</a>*/}
<a className="defalutCancelbtn fl">取消</a>
</div>
</Form.Item>
</Form>
</div>
</div>
</div>
</React.Fragment>
)
}
}
const StudentHomeworkApp = Form.create({ name: 'coursesNew' })(StudentHomework);
import React,{Component} from "React";
import { Form, Select, Input, Button,Checkbox,DatePicker} from "antd";
import locale from 'antd/lib/date-picker/locale/zh_CN';
import "../css/Courses.css";
import CoursesListType from '../coursesPublic/CoursesListType';
const { Option } = Select;
const CheckboxGroup = Checkbox.Group;
class StudentHomework extends Component{
constructor(props){
super(props)
this.state={
}
}
componentDidMount(){
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
}
handleSelectChange = (value) => {
console.log(value);
this.props.form.setFieldsValue({
note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,
});
}
render(){
const { getFieldDecorator } = this.props.form;
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
return(
<React.Fragment>
<div>
<div className="newMain clearfix">
<div className={"educontent mb20"}>
<div style={{ width:'100%',height:'70px'}} >
<p className="ml15 fl color-black mt30 summaryname">Java语言之控制语句</p>
<CoursesListType
typelist={["已开启补交"]}
typesylename={"mt28"}
/>
<a onClick={()=>this.props.history.goBack()} className="color-grey-6 fr font-16 ml20 mt18 mr20">返回</a>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml30 mt18 " target={"_blank"}>实训详情</a>
</div>
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
<a className="active">作业列表</a>
<a>作业问答</a>
<a>配置</a>
<a className={"fr color-blue font-16"}>立即发布</a>
<a className={"fr color-blue font-16"}>导出成绩</a>
</div>
</div>
<Form onSubmit={this.handleSubmit} className={"edu-back-white newcourses exercise"}>
{/*内容*/}
<div className="stud-class-set bor-bottom-greyE pd20 exerciselist">
<Form.Item label="发布设置" hasFeedback>
{getFieldDecorator("TestingProfile")(
<Checkbox id="TestingProfile" value={""} className="fl ml40">统一设置</Checkbox>
)}
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>发布时间</span>
<span className="fl mt5">
{getFieldDecorator("startTime")(
<DatePicker
showToday={false}
showTime
locale={locale}
format={dateFormat}
placeholder="请选择发布时间"
id={"startTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>发布之前学生不会收到问卷</span>
</span>
</div>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>截止时间</span>
<span className="fl mt5">
{getFieldDecorator("endTime")(
<DatePicker
showToday={false}
showTime
locale={locale}
format={dateFormat}
placeholder="请选择截止时间"
id={"endTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>截止时间点系统将自动提交所有学生的答题学生将不能继续答题</span>
</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set bor-bottom-greyE pd20 exercisetime">
<Form.Item label="补交设置" hasFeedback>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40 font-16" style={{minWidth: '70px'}}>答题时长</span>
{getFieldDecorator("TestingProfile"
, {
rules: [{
pattern: /^[1-9]\d*$/,
message: '答题时长必须为正整数',
}],
})(
<Input id="TestingProfile" className={"greyInput mt10 mr10"} style={{width:'108px',marginLeft:'0px'}} />
)}
<span className={"mr10"}>分钟</span>
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
</div>
</Form.Item>
<Form.Item hasFeedback>
<div className={"clearfix pd60"}>
{getFieldDecorator("subject", {
valuePropName: 'checked',
})(
<Checkbox id="subject" className="fl">题目顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时题目顺序按照题型随机显示</span>
</div>
<div className={"clearfix pd60"}>
{getFieldDecorator("options", {
valuePropName: 'checked',
})(
<Checkbox id="options" className="fl">选项顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时选项顺序随机显示</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set pd20 coursenavbox">
<Form.Item
label="公开设置"
hasFeedback
>
<div className={"clearfix pd28"}>
{getFieldDecorator("opergrdee", {
valuePropName: 'checked',
})(
<Checkbox id="opergrdee" className="fl">公开成绩</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开所有成绩否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openanswer", {
valuePropName: 'checked',
})(
<Checkbox id="openanswer" className="fl">公开答案</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开试卷题目的答案否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openstatisticss", {
valuePropName: 'checked',
})(
<Checkbox id="openstatisticss" className="fl">公开统计</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开答题统计否则不公开</span>
</div>
</Form.Item>
</div>
<Form.Item wrapperCol={{ span: 12, offset: 5 }} >
<div className="clearfix mt30 mb30">
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">
提交
</Button>
{/*<a className="defalutSubmitbtn fl mr20">提交</a>*/}
<a className="defalutCancelbtn fl">取消</a>
</div>
</Form.Item>
</Form>
</div>
</div>
</div>
</React.Fragment>
)
}
}
const StudentHomeworkApp = Form.create({ name: 'coursesNew' })(StudentHomework);
export default StudentHomeworkApp;

@ -125,7 +125,16 @@ class ShixunsHome extends Component {
{/*<SiderBar/>*/}
<div className="clearfix">
<div className="clearfix edu-back-white pb40 pt30 mb20" id="index-top" onMouseMove={this.bannaronmousemove} onMouseOut={this.bannaronmouseout}>
<style>
{
`
.banners{
overflow: hidden;
}
`
}
</style>
<div className="clearfix edu-back-white pb40 pt30 mb20 banners" id="index-top" onMouseMove={this.bannaronmousemove} onMouseOut={this.bannaronmouseout}>
<div className="educontent pr educontentSlider">
{homedatalist===undefined?"":
<Slider

@ -112,14 +112,14 @@ class PathDetailIndex extends Component{
this.setState({
Modalstype:false,
})
window.history.go(-1)
this.props.history.goBack()
}
cardsModalsave=()=>{
this.setState({
Modalstype:false,
})
window.history.go(-1)
this.props.history.goBack()
}
// 加载markdown
updatamakedown=(id)=>{

@ -15,7 +15,6 @@ class sendPanel extends Component{
openSearch:false,
sendToCourseId:undefined,
sendToShixunArray:[],
shixunNum:0,
Modalstype:false,
cardsModalcancel:this.cardsModalcancel,
cardsModalsave:this.cardsModalsave,
@ -35,7 +34,9 @@ class sendPanel extends Component{
//隐藏发送至弹框
hideSenttothevalue =()=>{
this.setState({
sentShixunPath:false
sentShixunPath:false,
sendToShixunArray:[],
sendToCourseId:undefined,
})
}
//打开课堂列表下拉框
@ -63,7 +64,7 @@ class sendPanel extends Component{
changeCheckBoxs=(list)=>{
this.setState({
sendToShixunArray:list,
shixunNum:list.length
// shixunNum:list.length
})
}
@ -86,7 +87,9 @@ class sendPanel extends Component{
Modalstype:true,
sentShixunPath:false,
Modalstopval:result.data.message,
courseurl:result.data.url
courseurl:result.data.url,
sendToShixunArray:[],
sendToCourseId:undefined,
})
}
}).catch((error)=>{
@ -118,8 +121,33 @@ class sendPanel extends Component{
let {courseurl}=this.state;
window.location.href =courseurl;
}
allChange = (e) => {
if(e.target.checked===false){
this.setState({
sendToShixunArray: [],
})
}else{
let { sendToCourseList} = this.state;
let newlist = [];
sendToCourseList.stages.map((item,key)=>{
item.shixuns.map((items,keys)=>{
newlist.push(items.shixun_id)
})
})
this.setState({
sendToShixunArray: newlist,
})
}
}
render(){
let{sentShixunPath,sendToCourseList,openSearch,shixunNum,Modalstype,Modalstopval,Modalsbottomval,cardsModalcancel,cardsModalsave}= this.state;
let{sentShixunPath,sendToCourseList,Modalstype,Modalstopval,Modalsbottomval,cardsModalcancel,cardsModalsave}= this.state;
return(
<div>
@ -178,7 +206,7 @@ class sendPanel extends Component{
</Select>
</div>
<div className="edu-back-skyblue pl15 pr15 clearfix over280 pt5">
<CheckboxGroup onChange={this.changeCheckBoxs}>
<CheckboxGroup onChange={this.changeCheckBoxs} value={this.state.sendToShixunArray}>
{
sendToCourseList && sendToCourseList.stages.map((item,key)=>{
@ -197,7 +225,16 @@ class sendPanel extends Component{
</CheckboxGroup>
</div>
<p className="color-grey-9 pl15 font-12 mt10">已选择 {shixunNum} 个实训</p>
<div className="mt10 clearfix">
<span className="fl ml15">
<Checkbox className="fl"
onChange={(e)=>this.allChange(e)}
>全选</Checkbox>
</span>
</div>
<p className="color-grey-9 pl15 font-12 mt10">已选择 {this.state.sendToShixunArray.length} 个实训</p>
<div className="mt20 clearfix edu-txt-center">
<a onClick={this.hideSenttothevalue} className="pop_close task-btn mr30">取消</a>
<a className="task-btn task-btn-orange" onClick={this.submitInfo}>确定</a>

@ -222,7 +222,7 @@ export default class MDEditors extends Component {
const _placeholder = placeholder || "";
// amp;
// 编辑时要传memoId
const imageUrl = `/upload_with_markdown?container_id=&container_type=Memo`;
const imageUrl = `/api/attachments.json`;
// 创建editorMd
let react_id = `react_${_id}`;

@ -1,9 +1,12 @@
import React, {Component} from 'react';
import {Link} from "react-router-dom";
import axios from 'axios';
import { Input ,Icon,Button,Pagination} from 'antd';
import { Input ,Icon,Button,Pagination,Spin} from 'antd';
import moment from 'moment';
import '../packageconcnet.css';
import AccountProfile from"../../user/AccountProfile";
import LoginDialog from '../../login/LoginDialog';
const { Search } = Input;
let categorylist=[
@ -45,7 +48,10 @@ class PackageConcent extends Component {
sort_direction:"desc",
page:1,
per_page:20,
categories:[]
categories:[],
isRender:false,
AccountProfiletype:false,
isSpin:false
}
}
//desc, desc, asc
@ -69,7 +75,9 @@ class PackageConcent extends Component {
}
setdatas=(category,keyword,sort_by,sort_direction,page)=>{
this.setState({
isSpin:true
})
let Url = `/project_packages.json`;
axios.get(Url,{params:{
category_id:category,
@ -82,6 +90,7 @@ class PackageConcent extends Component {
).then((response) => {
this.setState({
data:response.data,
isSpin:false,
project_packages:response.data.project_packages
})
}).catch((error) => {
@ -134,12 +143,66 @@ class PackageConcent extends Component {
this.setdatas(category,keyword,value,sort_directionvalue,page)
}
onReleaseRequirements=(url)=>{
let{current_user} =this.props;
if(current_user===undefined){
this.setState({
isRender:true
})
return
}
if(current_user&&current_user.login===""){
this.setState({
isRender:true
})
return;
}
if(current_user&&current_user.profile_completed===false){
this.setState({
AccountProfiletype:true
})
return;
}
if(url !== undefined || url!==""){
window.location.href = url;
}
}
// 登录
Modifyloginvalue=()=>{
this.setState({
isRender:false,
})
}
hideAccountProfile=()=>{
this.setState({
AccountProfiletype:false
})
}
render() {
let {data,page,category,sort_by,sort_direction,project_packages}=this.state;
let {data,page,category,sort_by,sort_direction,project_packages,
isRender,AccountProfiletype
}=this.state;
return (
<div className="educontent clearfix mtf10" style={{flex: "1 0 auto"}}>
{isRender===true?<LoginDialog
Modifyloginvalue={()=>this.Modifyloginvalue()}
{...this.state}
{...this.props}
/>:""}
{AccountProfiletype===true?<AccountProfile
hideAccountProfile={()=>this.hideAccountProfile()}
{...this.state}
{...this.props}
/>:""}
<div className="stud-class-set">
<div className="news">
<div className="edu-class-inner container clearfix">
@ -153,12 +216,12 @@ class PackageConcent extends Component {
<p className="clearfix" >
<p style={{height: '50px'}}>
<Search placeholder="输入标题名称进行检索"
style={{ width: 749}}
className="packinput"
enterButton={<span><Icon type="search" className="mr5"/> 搜索</span>}
onSearch={ (value)=>this.setdatafuns(value)} />
<Button type="primary" className="setissues fr" size={"large"}>
<a href="/crowdsourcings/new" >发布需求</a>
<a onClick={()=>this.onReleaseRequirements("/crowdsourcing/new")}>发布需求</a>
</Button>
</p>
</p>
@ -207,7 +270,7 @@ class PackageConcent extends Component {
</p>
</div>
<Spin size="large" spinning={this.state.isSpin}>
{project_packages&&project_packages.map((item,key)=>{
return(
<div className="educontent project-packages-list mb30" key={key}>
@ -224,7 +287,7 @@ class PackageConcent extends Component {
<div className=" item-head-title">
<a className={"fl mt3 font-20 font-bd color-dark maxwidth700 "}
href={"/crowdsourcings/"+item.id}
onClick={()=>this.onReleaseRequirements("/crowdsourcing/"+item.id)}
title={item.title}
>{item.title}</a>
</div>
@ -252,16 +315,16 @@ class PackageConcent extends Component {
<div className=" item-group item-other-deadline">
<span className=" item-group-icon mr10"><i className="fa fa-clock-o"></i></span>
<span className=" item-group-text">{moment(item.deadline_at).endOf('day').fromNow()}竞标截止</span>
<span className=" item-group-text">{moment(item.deadline_at).format("YYYY-MM-DD HH:mm")}竞标截止</span>
</div>
<div className=" item-group item-other-bidding ml0">
<div className=" item-group item-other-bidding ml0 pagemancenter">
<span className=" item-group-icon mr10"><i className="fa fa-user" ></i></span>
<span className=" item-group-text">{item.bidding_users_count}人竞标</span>
</div>
<div className=" item-other-blank"></div>
{/*<div className=" item-other-blank"></div>*/}
<div className=" item-group item-other-publish-at">
{item.published_at===null?<span className="item-group-text">更新于{moment(item.updated_at).format("YYYY-MM-DD HH:mm")} </span>:
<span className=" item-group-text">发布于{moment(item.published_at).format("YYYY-MM-DD HH:mm")} </span>}
@ -274,6 +337,7 @@ class PackageConcent extends Component {
</div>
)
})}
</Spin>
{project_packages&&project_packages.length===0?<div className="edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src="https://www.educoder.net/images/educoder/nodata.png" />

@ -230,7 +230,8 @@ class PackageIndexNEITaskDetails extends Component {
}
goback = () => {
// window.history.go(-1)
window.location.href="/crowdsourcings";
// window.location.href="/crowdsourcing";
this.props.history.goBack()
}
render() {
@ -252,7 +253,7 @@ class PackageIndexNEITaskDetails extends Component {
<Breadcrumb separator={'>'} className={"fl"}>
{/*<Breadcrumb.Item>{this.props.current_user.username}</Breadcrumb.Item>*/}
<Breadcrumb.Item>
<a href="/crowdsourcings">众包创新</a>
<a href="/crowdsourcing">众包创新</a>
</Breadcrumb.Item>
<Breadcrumb.Item><span className={"tabelcli"} title={data&&data.title}>{data&&data.title}</span></Breadcrumb.Item>
@ -353,7 +354,7 @@ class PackageIndexNEITaskDetails extends Component {
需求详情
{data&&data.status==="pending"&&data&&data.operation.can_select_bidding_user===true?<div className="fr">
<a className="task-btn-nebules fr" href={`/crowdsourcings/${this.props.match.params.id}/edit`}>编辑</a>
<a className="task-btn-nebules fr" href={`/crowdsourcing/${this.props.match.params.id}/edit`}>编辑</a>
<a className="task-btn-nebules fr" onClick={this.deletePackages}>删除</a>
</div>:""}

@ -43,6 +43,12 @@ function disabledDateTime() {
disabledMinutes: () => range(1, 30).concat(range(31, 60)),
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class PackageIndexNEIBannerConcent extends Component {
constructor(props) {
super(props)
@ -50,7 +56,7 @@ class PackageIndexNEIBannerConcent extends Component {
this.state = {
modalCancel:false,
getverificationcodes:true,
seconds:35,
seconds:60,
springtype:false,
category:undefined,
title:undefined,
@ -83,7 +89,7 @@ class PackageIndexNEIBannerConcent extends Component {
deadline_at:moment(data.deadline_at),
min_price:data.min_price,
max_price:data.max_price,
contact_name:data.contact_name==null||data.contact_name==undefined?this.props.current_user.username:data.contact_name,
contact_name:data.contact_name==null||data.contact_name==undefined?this.props.current_user.real_name:data.contact_name,
phones:data.contact_phone,
attachments:data.attachments,
@ -93,7 +99,7 @@ class PackageIndexNEIBannerConcent extends Component {
})
}else{
console.log(this.props.current_user&&this.props.current_user.username)
console.log(this.props.current_user&&this.props.current_user.real_name)
}
let Url = `/project_package_categories.json`;
@ -112,7 +118,7 @@ class PackageIndexNEIBannerConcent extends Component {
})
this.setState({
contact_name:this.props.current_user&&this.props.current_user.username
contact_name:this.props.current_user&&this.props.current_user.real_name
})
// this.contentMdRef.current.setValue("测试赋值")
@ -123,7 +129,7 @@ class PackageIndexNEIBannerConcent extends Component {
if(prevProps.current_user!=this.props.current_user){
if(this.props.current_user!=undefined){
this.setState({
contact_name:this.props.current_user.username
contact_name:this.props.current_user.real_name
})
}
}
@ -151,7 +157,7 @@ class PackageIndexNEIBannerConcent extends Component {
clearInterval(timer);
this.setState({
getverificationcodes: false,
seconds: 35,
seconds: 60,
})
}
});
@ -170,7 +176,7 @@ class PackageIndexNEIBannerConcent extends Component {
clearInterval(timer);
this.setState({
getverificationcodes: false,
seconds: 35,
seconds: 60,
})
}
@ -187,7 +193,7 @@ class PackageIndexNEIBannerConcent extends Component {
axios.get((url), {
params: {
value: contact_phone,
type: 9,
type: 5,
}
}).then((result) => {
//验证有问题{"status":1,"message":"success"}
@ -452,7 +458,7 @@ class PackageIndexNEIBannerConcent extends Component {
deadline_at:deadline_at._i,
min_price:parseInt(min_price),
max_price:parseInt(max_price),
contact_name: contact_name===null||contact_name===undefined?this.props.current_user.username:contact_name,
contact_name: contact_name===null||contact_name===undefined?this.props.current_user.real_name:contact_name,
contact_phone: contact_phone===undefined?this.props.current_user&&this.props.current_user.phone:contact_phone,
code:code,
publish:types
@ -462,7 +468,7 @@ class PackageIndexNEIBannerConcent extends Component {
if(type===true){
this.props.setPublicationfun(response.data.id)
}else{
window.location.href="/crowdsourcings/"+response.data.id
window.location.href="/crowdsourcing/"+response.data.id
}
this.setState({
springtype:false
@ -500,7 +506,7 @@ class PackageIndexNEIBannerConcent extends Component {
deadline_at:deadline_at._i,
min_price:parseInt(min_price),
max_price:parseInt(max_price),
contact_name: contact_name===null||contact_name===undefined?this.props.current_user.username:contact_name,
contact_name: contact_name===null||contact_name===undefined?this.props.current_user.real_name:contact_name,
contact_phone: contact_phone===undefined?this.props.current_user&&this.props.current_user.phone:contact_phone,
code:code,
publish:types
@ -510,7 +516,7 @@ class PackageIndexNEIBannerConcent extends Component {
if(type===true){
this.props.setPublicationfun(response.data.id)
}else{
window.location.href="/crowdsourcings/"+response.data.id
window.location.href="/crowdsourcing/"+response.data.id
}
this.setState({
springtype:false
@ -714,9 +720,9 @@ class PackageIndexNEIBannerConcent extends Component {
<Spin size="large" spinning={this.state.springtype} >
<p className="clearfix" id={"publishtimestart"}>
<div className={"stud-class-set pd30a0 coursenavbox edu-back-white pb20"}>
<div className={"stud-class-set pd30a0 edu-back-white pb20"}>
<div className={"ant-row contentbox mdInForm mb20"}>
<div className="ant-form-item-label mb10">
<div className="ant-form-item-label mb20">
<label htmlFor="coursesNew_description" className="ant-form-item-requireds font-16">请选择需求类型</label>
</div>
@ -729,9 +735,10 @@ class PackageIndexNEIBannerConcent extends Component {
})}
</div>
</p>
{this.state.categorytypes===true?<div className={"color-red"}>请选择类型</div>:""}
<div className="ant-form-item-label mb10">
{this.state.categorytypes===true?<div className={"color-red mb10"}>请选择类型</div>:""}
<div className="ant-form-item-label mb15">
<label htmlFor="coursesNew_description" className="ant-form-item-requireds font-16" >需求标题和详情</label>
</div>
@ -805,6 +812,8 @@ class PackageIndexNEIBannerConcent extends Component {
placeholder="请选择任务的竞标截止日期"
className={"fafas"}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
dropdownClassName="hideDisable"
value={this.state.deadline_at}
onChange={this.onChangeTimePicker}
/>
@ -848,7 +857,7 @@ class PackageIndexNEIBannerConcent extends Component {
<Input
className={"fafafas"}
style={{"width": "260px"}}
value={this.state.contact_name===null||this.state.contact_name===undefined?this.props.current_user&&this.props.current_user.username:this.state.contact_name}
value={this.state.contact_name===null||this.state.contact_name===undefined?this.props.current_user&&this.props.current_user.real_name:this.state.contact_name}
placeholder="请输入姓名"
onInput={(e)=>this.onChangeContact_name(e)}
/>

@ -14,10 +14,10 @@ class PackageIndexNEISubmit extends Component {
}
setageload=(sum)=>{
if(sum===undefined){
window.location.href="/crowdsourcings/new"
window.location.href="/crowdsourcing/new"
}else{
// this.props.history.push("/project_packages/"+sum)
window.location.href="/crowdsourcings/"+sum
window.location.href="/crowdsourcing/"+sum
}
}

@ -30,7 +30,8 @@ class PackageIndexNewandEditIndex extends Component{
goback = () => {
// window.history.go(-1)
window.location.href="/crowdsourcings";
// window.location.href="/crowdsourcing";
this.props.history.goBack()
}
render() {

@ -43,25 +43,25 @@ class ProjectPackageIndex extends Component {
<Switch>
{/*众包首页*/}
<Route path="/crowdsourcings/:id/edit"
<Route path="/crowdsourcing/:id/edit"
render={
(props) => (<PackageIndexNewandEdit {...this.props} {...props} {...this.state} />)
}
></Route>
<Route path="/crowdsourcings/new"
<Route path="/crowdsourcing/new"
render={
(props) => (<PackageIndexNewandEdit {...this.props} {...props} {...this.state} />)
}
></Route>
<Route path="/crowdsourcings/:id"
<Route path="/crowdsourcing/:id"
render={
(props) => (<PackageIndexNEITaskDetails {...this.props} {...props} {...this.state} />)
}
></Route>
<Route path="/crowdsourcings"
<Route path="/crowdsourcing"
render={
(props) => (<PackageIndex {...this.props} {...props} {...this.state} />)
}

@ -7,6 +7,11 @@
border-color: #E1EDF8 !important;
}
.packinput{
width:749px;
}
.packinput .ant-input-group-addon .ant-btn{
width:140px !important;
font-size: 18px;

@ -114,16 +114,15 @@ class NewHeader extends Component {
//
// }
}
openNotification = (messge) => {
notification.open({
message: "提示",
description:
messge,
onClick: () => {
console.log('Notification Clicked!');
},
});
};
componentWillReceiveProps(newProps, oldProps) {
this.setState({
user:newProps.user
@ -408,59 +407,62 @@ submittojoinclass=(value)=>{
return
}
if(value===0){
let url="/courses/join_course_multi_role.json"
const form = new FormData();
form.append('invite_code', tojoinclasstitle);
form.append('role', pamst);
form.append('type', 1);
axios.post(url,form,[true]
).then((response) => {
if( response.data.state===0){
this.submitstatevalue(0,"加入成功",response.data.course_id)
}else if( response.data.state===1){
}else if( response.data.state===2){
this.submitstatevalue( 0,"课堂已过期! 请联系课堂管理员重启课堂。(在配置课堂处)")
}else if( response.data.state===3){
this.submitstatevalue( 0,"您已是课堂成员)",response.data.course_id)
}else if( response.data.state===4){
this.submitstatevalue( 0,"您输入的邀请码错误)")
}else if( response.data.state===5){
this.submitstatevalue( 0,"您还未登录")
}else if( response.data.state===6){
this.submitstatevalue( 0,"申请已提交,请等待审核")
}else if( response.data.state===7){
this.submitstatevalue( 0," 您已经发送过申请了,请耐心等待")
}else if( response.data.state===8){
this.submitstatevalue( 0,"您已经是该课堂的教师了",response.data.course_id)
}else if( response.data.state==9){
this.submitstatevalue( 0,"您已经是该课堂的教辅了",response.data.course_id)
}else if( response.data.state==10){
this.submitstatevalue(0,"您已经是该课堂的管理员了",response.data.course_id)
}else if( response.data.state==11){
this.submitstatevalue(0," 该课堂已归档,请联系老师")
}else if( response.data.state==12){
this.submitstatevalue(0,"您已经发送过申请了,请耐心等待师")
}else if( response.data.state==13){
this.submitstatevalue(0,"您申请已提交,请等待审核")
}else if( response.data.state==14){
this.submitstatevalue("此邀请码已停用,请与老师联系")
}else if( response.data.state==15){
this.submitstatevalue(0,"您已是课堂成员! 加入分班请在课堂具体分班页面进行")
}else {
this.submitstatevalue(0," 未知错误,请稍后再试")
}
})
}
// if(value===0){
// let url="/courses/join_course_multi_role.json"
// const form = new FormData();
// form.append('invite_code', tojoinclasstitle);
// form.append('role', pamst);
// form.append('type', 1);
// axios.post(url,form,[true]
// ).then((response) => {
// if( response.data.state===0){
// this.submitstatevalue(0,"加入成功",response.data.course_id)
// }else if( response.data.state===1){
// }else if( response.data.state===2){
// this.submitstatevalue( 0,"课堂已过期! 请联系课堂管理员重启课堂。(在配置课堂处)")
// }else if( response.data.state===3){
// this.submitstatevalue( 0,"您已是课堂成员)",response.data.course_id)
// }else if( response.data.state===4){
// this.submitstatevalue( 0,"您输入的邀请码错误)")
// }else if( response.data.state===5){
// this.submitstatevalue( 0,"您还未登录")
// }else if( response.data.state===6){
// this.submitstatevalue( 0,"申请已提交,请等待审核")
// }else if( response.data.state===7){
// this.submitstatevalue( 0," 您已经发送过申请了,请耐心等待")
// }else if( response.data.state===8){
// this.submitstatevalue( 0,"您已经是该课堂的教师了",response.data.course_id)
// }else if( response.data.state==9){
// this.submitstatevalue( 0,"您已经是该课堂的教辅了",response.data.course_id)
// }else if( response.data.state==10){
// this.submitstatevalue(0,"您已经是该课堂的管理员了",response.data.course_id)
// }else if( response.data.state==11){
// this.submitstatevalue(0," 该课堂已归档,请联系老师")
// }else if( response.data.state==12){
// this.submitstatevalue(0,"您已经发送过申请了,请耐心等待师")
// }else if( response.data.state==13){
// this.submitstatevalue(0,"您申请已提交,请等待审核")
// }else if( response.data.state==14){
// this.submitstatevalue("此邀请码已停用,请与老师联系")
// }else if( response.data.state==15){
// this.submitstatevalue(0,"您已是课堂成员! 加入分班请在课堂具体分班页面进行")
// }else {
// this.submitstatevalue(0," 未知错误,请稍后再试")
// }
// })
//
// }
if(value===1){
let url="/api/applied_project/applied_project_info.json"
const form = new FormData();
form.append('invite_code', tojoinclasstitle);
form.append('member', RadioGroupvalue);
form.append('type', 1);
axios.post(url,form,[true]
let url="/project_applies.json"
// const form = new FormData();
// form.append('code', tojoinclasstitle);
// form.append('role', RadioGroupvalue);
// form.append('type', 1);
axios.post(url,{
code:tojoinclasstitle,
role:RadioGroupvalue
}
).then((response) => {
if( response.data.status===1){
this.submitstatevalue(1,"您输入的邀请码错误")
@ -474,9 +476,17 @@ submittojoinclass=(value)=>{
this.submitstatevalue( 1,"您已经申请加入该项目了,请耐心等待")
}else if( response.data.status===6){
this.submitstatevalue( 1,"您已成功加入项目",response.data.project)
}
}else if( response.data.status===0){
if(RadioGroupvalue==="reporter"){
this.openNotification("您加入项目成功!");
window.location.href=`/projects/${response.data.project_id}`;
}else{
this.openNotification("您的申请已提交,请等待项目管理员审批!");
}
}
})
}
this.hidetojoinclass()
}
// trialapplications =()=>{
@ -617,8 +627,10 @@ submittojoinclass=(value)=>{
let activeShixuns = false;
let activePaths = false;
let coursestype=false;
let activePackages=false;
if (match.path === '/forums') {
if (match.path === '/forums') {
activeForums = true;
} else if (match.path.startsWith('/shixuns')) {
activeShixuns = true;
@ -626,14 +638,12 @@ submittojoinclass=(value)=>{
activePaths = true;
} else if (match.path.startsWith('/courses')) {
coursestype = true;
}else {
}else if (match.path.startsWith('/crowdsourcing')) {
activePackages = true;
}else {
activeIndex = true;
}
// join_course_url: "https://www.educoder.net/courses/join_course_multi_role"
// join_project_url: "https://www.educoder.net/applied_project/applied_project_info"
// rolearr:["",""],
// console.log("618");
// console.log(user_phone_binded);
return (
<div className="newHeader" id="nHeader" >
@ -716,10 +726,9 @@ submittojoinclass=(value)=>{
/>
</li>
<li className=""><a href={this.props.Headertop===undefined?"":this.props.Headertop.moop_cases_url}>教学案例</a></li>
<li className=""><a
// href={this.props.Headertop===undefined?"":this.props.Headertop.crowdsourcing_url}
href={'/crowdsourcings'}
>众包创新</a></li>
<li className={`${activePackages === true ? 'pr active' : 'pr'}`}>
<a href={'/crowdsourcing'}>众包创新</a>
</li>
<li className={`${activeForums === true ? 'active' : ''}`}><a href={this.props.Headertop===undefined?"":this.props.Headertop.topic_url}>交流问答</a></li>
<li
style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.auth===null? 'none' : 'block'}}
@ -816,7 +825,7 @@ submittojoinclass=(value)=>{
<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/shixuns`}>我的实训</Link></li>
<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/paths`}>我的实践课程</Link></li>
<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/projects`}>我的项目</Link></li>
{/*<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/package`}>我的众包</Link></li>*/}
<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/package`}>我的众包</Link></li>
<li><a href={`/account/profile`}>账号管理</a></li>
{/*<li><a onClick={()=>this.educoderlogin()} >登入测试接口</a></li>*/}
{/*<li><a onClick={()=>this.trialapplications()} >试用申请</a> </li>*/}
@ -870,9 +879,9 @@ submittojoinclass=(value)=>{
{/* /courses/join_course_multi_role */}
{/*<li>*/}
<a onClick={this.tojoinitem}>加入项目</a>
<a onClick={this.tojoinitem}>加入项目</a>
{/*</li>*/}
<Modal
{tojoinitemtype===true?<Modal
keyboard={false}
title="加入项目"
visible={tojoinitemtype}
@ -897,15 +906,15 @@ submittojoinclass=(value)=>{
<label className="panel-form-label fl">身份</label>
<RadioGroup className="mt10" onChange={this.onChangeRadioGroup}>
<Radio value={1}>管理人员</Radio>
<Radio value={2}>开发人员</Radio>
<Radio value={3}>报告人员</Radio>
<Radio value={"manager"}>管理人员</Radio>
<Radio value={"developer"}>开发人员</Radio>
<Radio value={"reporter"}>报告人员</Radio>
</RadioGroup>
</li>
<p id="none_checked_notice" className="color-orange none f12"
style={{marginLeft: '90px',display:checked_notice===true?'block':"none"}}>至少选择一个身份</p>
style={{marginLeft: '90px',display:checked_notice===true?'block':"none"}}>选择一个身份</p>
<li className="clearfix mt10 edu-txt-center">
<a className="task-btn mr10"
@ -918,7 +927,7 @@ submittojoinclass=(value)=>{
</ul>
</div>
</div>
</Modal>
</Modal>:""}
</ul>
</div>
</div>

@ -32,14 +32,14 @@ if (!window['indexHOCLoaded']) {
// $('head').append($('<link rel="stylesheet" type="text/css" />')
// .attr('href', `${_url_origin}/stylesheets/educoder/antd.min.css?1525440977`));
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?15254409771`));
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?7`));
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?15254409781`));
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?7`));
// index.html有加载
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?15254409781`));
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?7`));
// $('head').append($('<link rel="stylesheet" type="text/css" />')
@ -306,13 +306,11 @@ export function TPMIndexHOC(WrappedComponent) {
<style>{
`
.newContainers{
width: 100%;
/*min-width: 1440px;*/
max-width: unset;
min-width: 1200px;
max-width: unset;
overflow: hidden;
}
// .-task-sidebar{
// right: 270px !important;
// }
`
}</style>
<NewHeader {...this.state} {...this.props}></NewHeader>

@ -199,6 +199,10 @@ function disabledDateTime() {
// disabledSeconds: () => [0, 60],
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
export default class TPMsettings extends Component {
constructor(props) {
super(props)
@ -1144,7 +1148,7 @@ export default class TPMsettings extends Component {
}
onChangeTimePicker =(value, dateString)=> {
this.setState({
opening_time:moment(handleDateStrings(dateString))
opening_time: dateString=== ""?"":moment(handleDateStrings(dateString))
})
}
@ -1871,6 +1875,7 @@ export default class TPMsettings extends Component {
width={178}
locale={locale}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
placeholder="请选择开启时间"
value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
onChange={this.onChangeTimePicker}

@ -339,9 +339,6 @@ export default class TPMevaluation extends Component {
goblakepath=(path,key)=>{
let {main,selectpath,pathtype} =this.state;
let newmain=[]
for(var i=0;i<=key;i++){
newmain.push(main[i])
@ -366,16 +363,20 @@ export default class TPMevaluation extends Component {
});
if(pathtype===2){
// var str=path;
// str.slice(0,str.length-1)
// debugger
// console.log(str)
let paths = path.substring(0,path.length-1);
console.log(paths)
this.setState({
selectpath: path,
selectpath: paths,
})
}
}
// delesavegetfilepath=(value)=>{
// let {selectpatharr} = this.state
// let newarr =selectpatharr;
@ -674,6 +675,7 @@ export default class TPMevaluation extends Component {
this.setState({
selectpath:e.target.value
})
}
updatepath=(e,name,type)=>{
this.setState({
@ -949,6 +951,8 @@ export default class TPMevaluation extends Component {
<Option value={2}>apk/exe</Option>
<Option value={3}>txt</Option>
<Option value={4}>html</Option>
<Option value={5}>mp3</Option>
<Option value={6}>mp4</Option>
</Select>
<a className="ml10" onClick={()=>this.showrepositoryurltip(1)}><img src={getImageUrl("images/educoder/problem.png")}/></a>
<div className="invite-tip clearfix repository_url_tippostion" style={{display:showrepositoryurltiptype===true?"block":"none"}} id="repository_url_tip"
@ -975,20 +979,20 @@ export default class TPMevaluation extends Component {
</div>
{pathoptionvalue===1?<div className="edu-back-white mb10 clearfix">
{pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6?<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb20">待处理图片路径</p>
<div className="df">
<div className="flex1 mr20">
<input type="text" className="input-100-45" autoComplete="off"
id="shixun_file_expect_picture_path" name="challenge[original_picture_path]"
placeholder="请选择版本库中存储了待处理图片的路径。例src/step1/expectedimages"
placeholder="请选择版本库中存储了待处理文件(图片/MP3等)的路径。例src/step1/sourcefiles"
value={shixunfileexpectpicturepath}
onInput={(e)=>this.updatepath(e,"shixunfileexpectpicturepath",2)}
onClick={(e)=>this.getfilepath(e,"shixunfileexpectpicturepath",2)}
/>
<p className="color-grey-9 mt15">
该路径下的文件将在学员评测本关任务时作为原始图片显示在查看效果页供学员参考,任务为图片处理时请指定该路径并注意与程序文件所在文件夹分开
该路径下的文件将在学员评测本关任务时作为原始文件显示在查看效果页供学员参考任务为文件处理时请指定该路径并注意与程序文件所在文件夹分开
</p>
</div>
<div></div>
@ -997,20 +1001,20 @@ export default class TPMevaluation extends Component {
</div>:""}
{pathoptionvalue===1? <div className="edu-back-white mb10 clearfix">
{pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6? <div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb20">标准答案图片路径</p>
<div className="df">
<div className="flex1 mr20">
<input type="text" className="input-100-45" autoComplete="off"
id="shixun_file_standard_picture_path" name="challenge[expect_picture_path]"
placeholder="请选择版本库中存储了标准答案代码输出文件的路径。例src/step1/expectedimages"
placeholder="请选择版本库中存储了标准答案文件(图片/MP3等)的路径。例src/step1/expectedfiles"
value={shixunfilestandardpicturepath}
onInput={(e)=>this.updatepath(e,"shixunfilestandardpicturepath",2)}
onClick={(e)=>this.getfilepath(e,"shixunfilestandardpicturepath",2)}
/>
<p className="color-grey-9 mt15">
该路径下的文件将在学员评测本关任务时作为参考答案显示在查看效果页供学员参考任务输出结果为文件时请指定该路径并注意与程序文件所在文件夹分开
该路径下的文件将在学员评测本关任务时作为参考答案显示在查看效果页供学员参考任务输出结果为文件时请指定该路径并注意与程序文件所在文件夹分开
</p>
</div>
<div></div>
@ -1029,9 +1033,9 @@ export default class TPMevaluation extends Component {
value={shixunfilepicturepath}
onInput={(e)=>this.updatepath(e,"shixunfilepicturepath",2)}
onClick={(e)=>this.getfilepath(e,"shixunfilepicturepath",2)}
placeholder="请在版本库中指定用来保存学员代码实际输出结果的路径。例src/step1/outputimages"/>
placeholder="请在版本库中指定用来保存学员代码实际输出结果的路径。例src/step1/outputfiles"/>
<p className="color-grey-9 mt15">
学员评测本关任务时生成的文件将保存在该路径下并作为实际输出显示在查看效果页供学员确认任务输出结果为文件时请指定该路径并注意与程序文件所在文件夹分开
学员评测本关任务时生成的文件将保存在该路径下并作为实际输出显示在查看效果页供学员确认任务输出结果为文件时请指定该路径并注意与程序文件所在文件夹分开
</p>
</div>
<div></div>
@ -1066,16 +1070,16 @@ export default class TPMevaluation extends Component {
<p className="color-grey-9 mb20"
style={{width:'100%',height:'20px',display:scorevalue===true?'block':'none'}}
>
<span className={"headdfgf color979797"} style={{width:'500px'}} >
系统评分占比
<RadioGroup
value={markvalue}
onChange={this.onChangemarkvalue}
>
<Radio value={true}>均分比例</Radio>
<Radio value={false}>自定义比例</Radio>
</RadioGroup>
</span>
<span className={"headdfgf color979797"} style={{width:'500px'}} >
系统评分占比
<RadioGroup
value={markvalue}
onChange={this.onChangemarkvalue}
>
<Radio value={true}>均分比例</Radio>
<Radio value={false}>自定义比例</Radio>
</RadioGroup>
</span>
</p>

@ -191,7 +191,9 @@ function disabledDateTime() {
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class Newshixuns extends Component {
constructor(props) {
super(props)
@ -743,7 +745,7 @@ class Newshixuns extends Component {
onChangeTimePicker = (value, dateString) => {
this.setState({
TimePickervalue: moment(handleDateStrings(dateString))
TimePickervalue: dateString=== ""?"":moment(handleDateStrings(dateString))
})
}
@ -1288,7 +1290,7 @@ class Newshixuns extends Component {
placeholder="请选择开启时间"
onChange={this.onChangeTimePicker}
value={TimePickervalue && moment(TimePickervalue, "YYYY-MM-DD HH:mm")}
disabledDate={disabledDate}
disabledTime={disabledDateTime}
dropdownClassName="hideDisable"
/>

@ -532,13 +532,14 @@ class Collaborators extends Component {
</Spin>
</div>
<div className="mt10 clearfix">
<span className="fl mr15">
<Checkbox className="fl" checked={allChangechecked} onChange={this.allChange}>全选</Checkbox>
<div className="fl" style={{height: '27px'}}>
<span className="color-orange fl" id="add_teacher_notice"
style={{display: Collaboratorslisttype === true ? 'inline' : 'none'}}>请至少选择一个用户</span>
</div>
</span>
<span className="fl mr15">
<Checkbox className="fl" checked={allChangechecked} onChange={this.allChange}>全选</Checkbox>
<div className="fl" style={{height: '27px'}}>
<span className="color-orange fl" id="add_teacher_notice"
style={{display: Collaboratorslisttype === true ? 'inline' : 'none'}}>请至少选择一个用户</span>
</div>
</span>
</div>

@ -384,11 +384,11 @@ class Infos extends Component{
to={`/users/${username}/projects`}>项目</Link>
</li>
{/*<li className={`${moduleName == 'package' ? 'active' : '' }`}>*/}
{/*<Link*/}
{/*onClick={() => this.setState({moduleName: 'package'})}*/}
{/*to={`/users/${username}/package`}>众包</Link>*/}
{/*</li>*/}
<li className={`${moduleName == 'package' ? 'active' : '' }`}>
<Link
onClick={() => this.setState({moduleName: 'package'})}
to={`/users/${username}/package`}>众包</Link>
</li>
{/*{ data && data.identity!="学生" && <li> <a href={`${this.props.Headertop && this.props.Headertop.old_url}/users/${username}?type=m_bank`}>题库</a></li>}*/}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save