Merge branch 'dev_aliyun' into develop

dev_cs_new
daiao 6 years ago
commit 276f37b574

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

@ -64,10 +64,10 @@ class ApplicationController < ActionController::Base
# 发送及记录激活码 # 发送及记录激活码
# 发送验证码type 1注册手机验证码 2找回密码手机验证码 3找回密码邮箱验证码 4绑定手机 5绑定邮箱 # 发送验证码type 1注册手机验证码 2找回密码手机验证码 3找回密码邮箱验证码 4绑定手机 5绑定邮箱
# 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码 # 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码 9验证手机号有效
def check_verification_code(code, send_type, value) def check_verification_code(code, send_type, value)
case send_type case send_type
when 1, 2, 4 when 1, 2, 4, 9
# 手机类型的发送 # 手机类型的发送
sigle_para = {phone: value} sigle_para = {phone: value}
status = Educoder::Sms.send(mobile: value, code: code) status = Educoder::Sms.send(mobile: value, code: code)
@ -241,14 +241,17 @@ class ApplicationController < ActionController::Base
User.current = User.find 57703 User.current = User.find 57703
end 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 # User.current = User.find 81403
end end
@ -583,4 +586,8 @@ class ApplicationController < ActionController::Base
def render_parameter_missing def render_parameter_missing
render json: { status: -1, message: '参数缺失' } render json: { status: -1, message: '参数缺失' }
end end
def set_export_cookies
cookies[:fileDownload] = true
end
end end

@ -1027,7 +1027,10 @@ class CoursesController < ApplicationController
tip_exception(403,"无权限操作") tip_exception(403,"无权限操作")
elsif @all_members.size == 0 elsif @all_members.size == 0
normal_status(-1,"课堂暂时没有学生") normal_status(-1,"课堂暂时没有学生")
elsif params[:export].present? && params[:export]
normal_status(0,"正在下载中")
else else
set_export_cookies
member_to_xlsx(@course, @all_members, @c_homeworks, @c_exercises, @c_tasks) member_to_xlsx(@course, @all_members, @c_homeworks, @c_exercises, @c_tasks)
filename_ = "#{current_user.real_name}_#{@course.name}_全部成绩_#{Time.now.strftime('%Y%m%d_%H%M%S')}" filename_ = "#{current_user.real_name}_#{@course.name}_全部成绩_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
render xlsx: "#{format_sheet_name filename_.strip}",template: "courses/export_member_scores_excel.xlsx.axlsx", render xlsx: "#{format_sheet_name filename_.strip}",template: "courses/export_member_scores_excel.xlsx.axlsx",

@ -1,7 +1,7 @@
class DiscussesController < ApplicationController class DiscussesController < ApplicationController
LIMIT = 10 LIMIT = 10
before_action :find_container, only: [:index, :hidden] 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 def index
page = params[:page].to_i page = params[:page].to_i
@ -28,6 +28,48 @@ class DiscussesController < ApplicationController
@current_user = current_user @current_user = current_user
end 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 def new_message
onclick_time = Myshixun.find(params[:myshixun_id]).try(:onclick_time) 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]). ids = Discuss.where(user_id: User.current.id, dis_id: params[:container_id], dis_type: params[:container_type]).

@ -1261,6 +1261,7 @@ class ExercisesController < ApplicationController
else else
respond_to do |format| respond_to do |format|
format.xlsx{ format.xlsx{
set_export_cookies
get_export_users(@exercise,@course,@export_ex_users) get_export_users(@exercise,@course,@export_ex_users)
exercise_export_name_ = exercise_export_name_ =
"#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
@ -1286,6 +1287,7 @@ class ExercisesController < ApplicationController
if params[:export].present? && params[:export] if params[:export].present? && params[:export]
normal_status(0,"正在下载中") normal_status(0,"正在下载中")
else else
set_export_cookies
render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets
end end
end end

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

@ -116,10 +116,11 @@ class GamesController < ApplicationController
@qrcode_str = Base64.encode64( qr.to_img.resize(400,400).to_s ) @qrcode_str = Base64.encode64( qr.to_img.resize(400,400).to_s )
else else
@type = "image"
#conv = Iconv.new("GBK", "utf-8") #conv = Iconv.new("GBK", "utf-8")
@game_challenge = @game.challenge @game_challenge = @game.challenge
type = @game_challenge.show_type type = @game_challenge.show_type
@type = shixun_show_type type
workspace_path = @game.try(:picture_path) workspace_path = @game.try(:picture_path)
@answer_path = "#{Rails.root}/#{workspace_path}/#{@game_challenge.expect_picture_path}" @answer_path = "#{Rails.root}/#{workspace_path}/#{@game_challenge.expect_picture_path}"
@user_path = "#{Rails.root}/#{workspace_path}/#{@game_challenge.picture_path}" @user_path = "#{Rails.root}/#{workspace_path}/#{@game_challenge.picture_path}"

@ -132,6 +132,8 @@ class GraduationTasksController < ApplicationController
tip_exception(403, "无权限操作") tip_exception(403, "无权限操作")
elsif complete_works == 0 elsif complete_works == 0
normal_status(-1,"暂无用户提交") normal_status(-1,"暂无用户提交")
elsif params[:export].present? && params[:export]
normal_status(0,"正在下载中")
else else
respond_to do |format| respond_to do |format|
format.xlsx{ format.xlsx{
@ -148,12 +150,17 @@ class GraduationTasksController < ApplicationController
zip_works = @work_excel.where("work_status > 0") zip_works = @work_excel.where("work_status > 0")
status = checkfileSize(zip_works) status = checkfileSize(zip_works)
if status == 0 if status == 0
respond_to do |format| if params[:export].present? && params[:export]
format.zip{ normal_status(0,"正在下载中")
zipfile = zip_homework_common @task, zip_works else
file = decode64(zipfile[0][:base64file]) respond_to do |format|
send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' format.zip{
} set_export_cookies
zipfile = zip_homework_common @task, zip_works
file = decode64(zipfile[0][:base64file])
send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip'
}
end
end end
else else
normal_status(status,status == -2 ? "500M" : "无附件可下载") normal_status(status,status == -2 ? "500M" : "无附件可下载")

@ -271,7 +271,12 @@ class GraduationTopicsController < ApplicationController
students = course.students.joins(user: :user_extension).order("user_extensions.student_id") students = course.students.joins(user: :user_extension).order("user_extensions.student_id")
graduation_topic_to_xlsx(students,course) graduation_topic_to_xlsx(students,course)
topic_export_name_ = "#{current_user.real_name}_#{course.name}_毕设选题_#{Time.now.strftime('%Y%m%d_%H%M%S')}" topic_export_name_ = "#{current_user.real_name}_#{course.name}_毕设选题_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
render xlsx: "#{topic_export_name_.strip}",template: "graduation_topics/export.xlsx.axlsx",locals: {table_columns:@topic_head_cells,topic_users:@topic_body_cells} if params[:export].present? && params[:export]
normal_status(0,"正在下载中")
else
set_export_cookies
render xlsx: "#{topic_export_name_.strip}",template: "graduation_topics/export.xlsx.axlsx",locals: {table_columns:@topic_head_cells,topic_users:@topic_body_cells}
end
rescue Exception => e rescue Exception => e
uid_logger(e.message) uid_logger(e.message)
missing_template missing_template

@ -212,7 +212,7 @@ class HomeworkCommonsController < ApplicationController
else else
respond_to do |format| respond_to do |format|
format.xlsx{ format.xlsx{
cookies[:fileDownload] = true set_export_cookies
student_work_to_xlsx(@work_excel,@homework) student_work_to_xlsx(@work_excel,@homework)
exercise_export_name = "#{current_user.real_name}_#{@course.name}_#{@homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" exercise_export_name = "#{current_user.real_name}_#{@course.name}_#{@homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
render xlsx: "#{exercise_export_name.strip}",template: "homework_commons/works_list.xlsx.axlsx",locals: render xlsx: "#{exercise_export_name.strip}",template: "homework_commons/works_list.xlsx.axlsx",locals:
@ -223,8 +223,6 @@ class HomeworkCommonsController < ApplicationController
elsif params[:format] == "zip" elsif params[:format] == "zip"
if @user_course_identity >= Course::STUDENT if @user_course_identity >= Course::STUDENT
tip_exception(403, "无权限操作") tip_exception(403, "无权限操作")
elsif params[:export].present? && params[:export]
normal_status(0,"正在下载中")
else else
if @work_excel.present? if @work_excel.present?
zip_works = @work_excel&.where("work_status > 0") zip_works = @work_excel&.where("work_status > 0")
@ -234,13 +232,17 @@ class HomeworkCommonsController < ApplicationController
end end
if status == 0 if status == 0
respond_to do |format| if params[:export].present? && params[:export]
format.zip{ normal_status(0,"正在下载中")
cookies[:fileDownload] = true else
zipfile = zip_homework_common @homework, zip_works respond_to do |format|
file = decode64(zipfile[0][:base64file]) format.zip{
send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' set_export_cookies
} zipfile = zip_homework_common @homework, zip_works
file = decode64(zipfile[0][:base64file])
send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip'
}
end
end end
else else
normal_status(status, status == -2 ? "500M" : "无附件可下载") normal_status(status, status == -2 ? "500M" : "无附件可下载")
@ -334,7 +336,7 @@ class HomeworkCommonsController < ApplicationController
@messages = @messages.parent_comment @messages = @messages.parent_comment
end 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 end
def reference_answer def reference_answer

@ -1,5 +1,9 @@
class MemosController < ApplicationController 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 include ApplicationHelper
# GET /memos # GET /memos
@ -8,27 +12,21 @@ class MemosController < ApplicationController
@user = current_user @user = current_user
@memos = Memo.all @memos = Memo.all
s_order = (params[:order] == "replies_count" ? "all_replies_count" : params[:order]) || "updated_at" s_order = (params[:order] == "replies_count" ? "all_replies_count" : params[:order]) || "updated_at"
#@tidding_count = unviewed_tiddings(current_user) if current_user.present? # @tidding_count = unviewed_tiddings(current_user) if current_user.present?
page = params[:page].to_i page = params[:page] || 1
limit = params[:limit] || 15
search = params[:search] search = params[:search]
offset = page * 15
forum_id = params[:forum] 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] tag_repertoire_id = params[:tag_repertoire_id]
sql = sql =
if forum_id 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" "forum_id = #{forum_id} and root_id is null"
elsif search elsif !search.blank?
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}%'"
"forum_id in(3, 5) and root_id is null and subject like '%#{search}%'"
else 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 end
if tag_repertoire_id if tag_repertoire_id
@ -41,27 +39,27 @@ class MemosController < ApplicationController
sql += " and all_replies_count != 0" sql += " and all_replies_count != 0"
end end
memos = Memo.field_for_list.includes(:praise_tread, :author).where("#{sql}") memos = Memo.field_for_list.where("#{sql}")
@memos_count = memos.length @memos_count = memos.length
@memos = memos.order("sticky = 1 desc, #{Memo.table_name}.#{s_order} desc").offset(offset).limit(15) @memos = memos.order("sticky = 1 desc, #{Memo.table_name}.#{s_order} desc").page(page).per(limit)
@my_memos_count = Memo.user_posts(current_user.try(:id)).count @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 @tags_info = MemoTagRepertoire.find_by_sql("SELECT tag_repertoire_id, tr.name, count(*) cnt
FROM memo_tag_repertoires mtr join tag_repertoires tr on 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, tr.id = mtr.tag_repertoire_id group by tag_repertoire_id order by cnt desc,
tag_repertoire_id desc limit 9") 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 end
# GET /memos/1
# GET /memos/1.json # GET /memos/1.json
def show def show
# tidding_count = unviewed_tiddings(current_user) if current_user # tidding_count = unviewed_tiddings(current_user) if current_user
@user = current_user @user = current_user
# TODO 附件最后再做
# attachments_list =
@memo.update_column(:viewed_count, @memo.viewed_count+1) @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 end
# GET /memos/new # GET /memos/new
@ -71,43 +69,44 @@ class MemosController < ApplicationController
# GET /memos/1/edit # GET /memos/1/edit
def edit def edit
@tag_list = TagRepertoire.field_for_list.order("name asc")
@memo_tags = @memo.tag_repertoires.field_for_list
@attachments = @memo.attachments
end end
# POST /memos
# POST /memos.json # POST /memos.json
def create def create
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
@memo = Memo.new(memo_params) @memo = Memo.new(memo_params)
@memo.author = current_user @memo.author = current_user
# TODO 保存附件
# @memo.save_attachments(params[:attachments]) if params[:attachments]
@memo.save! @memo.save!
Attachment.associate_container(params[:attachment_ids], @memo.id, @memo.class.name)
params[:tags].each do |tag| 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 end
@status = 0 normal_status("帖子创建成功")
@message = "帖子创建成功!"
rescue Exception => e rescue Exception => e
@status = -1 tip_exception("帖子创建失败,原因:#{e}")
@message = "帖子创建失败,原因:#{e}"
raise ActiveRecord::Rollback raise ActiveRecord::Rollback
end end
end end
end end
# PATCH/PUT /memos/1
# PATCH/PUT /memos/1.json # PATCH/PUT /memos/1.json
def update def update
respond_to do |format| ActiveRecord::Base.transaction do
if @memo.update(memo_params) begin
format.html { redirect_to @memo, notice: 'Memo was successfully updated.' } @memo.update_attributes!(memo_params)
format.json { render :show, status: :ok, location: @memo } Attachment.associate_container(params[:attachment_ids], @memo.id, @memo.class.name)
else @memo.memo_tag_repertoires.destroy_all
format.html { render :edit } params[:tags].each do |tag|
format.json { render json: @memo.errors, status: :unprocessable_entity } 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 end
end end
@ -116,21 +115,88 @@ class MemosController < ApplicationController
# DELETE /memos/1.json # DELETE /memos/1.json
def destroy def destroy
@memo.destroy @memo.destroy
respond_to do |format| normal_status("删除成功")
format.html { redirect_to memos_url, notice: 'Memo was successfully destroyed.' } end
format.json { head :no_content }
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
end end
private def hidden
# Use callbacks to share common setup or constraints between actions. tip_exception("不能对主贴进行隐藏操作") if @memo.parent_id.nil?
def set_memo begin
@memo = Memo.find(params[:id]) @memo.update_attributes!(hidden: !@memo.hidden)
normal_status("更新成功")
rescue Exception => e
tip_exception("更新失败,原因:#{e}")
raise ActiveRecord::Rollback
end 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. ActiveRecord::Base.transaction do
def memo_params begin
params.fetch(:memo, {}) 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
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 end

@ -24,7 +24,7 @@ class MyshixunsController < ApplicationController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
@shixun = Shixun.select(:id, :identifier).find(@myshixun.shixun_id) @shixun = Shixun.select(:id, :identifier).find(@myshixun.shixun_id)
@myshixun.destroy @myshixun.destroy!
StudentWork.where(:myshixun_id => @myshixun.id).update_all(:myshixun_id => 0, :work_status => 0) StudentWork.where(:myshixun_id => @myshixun.id).update_all(:myshixun_id => 0, :work_status => 0)

@ -945,9 +945,12 @@ class PollsController < ApplicationController
tip_exception(403,"无权限操作") tip_exception(403,"无权限操作")
elsif (@poll.polls_status == 1) || (@poll_export_questions.size == 0) || (@poll_commit_ids.size == 0) elsif (@poll.polls_status == 1) || (@poll_export_questions.size == 0) || (@poll_commit_ids.size == 0)
normal_status(-1,"暂无用户提交") normal_status(-1,"暂无用户提交")
elsif params[:export].present? && params[:export]
normal_status(0,"正在下载中")
else else
respond_to do |format| respond_to do |format|
format.xlsx{ format.xlsx{
set_export_cookies
polls_export_name_ = "#{current_user.real_name}_#{@course.name}_#{@poll.polls_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" polls_export_name_ = "#{current_user.real_name}_#{@course.name}_#{@poll.polls_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
polls_user_commit = poll_commit_result(@poll,@poll_export_questions,@poll_users,@poll_commit_ids) polls_user_commit = poll_commit_result(@poll,@poll_export_questions,@poll_users,@poll_commit_ids)
render xlsx: "#{polls_export_name_.strip}",template: "polls/commit_result.xlsx.axlsx",locals: {polls_user_commit:polls_user_commit} render xlsx: "#{polls_export_name_.strip}",template: "polls/commit_result.xlsx.axlsx",locals: {polls_user_commit:polls_user_commit}

@ -1,10 +1,2 @@
class ProjectsController < ApplicationController 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 end

@ -43,7 +43,7 @@ class Users::BaseController < ApplicationController
page = page_value page = page_value
per_page = per_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: 为实现第一页少一条记录,让前端放置新建入口 # note: 为实现第一页少一条记录,让前端放置新建入口
if page == 1 if page == 1

@ -1,4 +1,6 @@
class Users::ProjectsController < Users::BaseController class Users::ProjectsController < Users::BaseController
skip_before_action :check_observed_user_exists!, only: [:search]
def index def index
projects = Users::ProjectService.new(observed_user, query_params).call 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) @projects = paginate(projects.includes(:project_score, owner: { user_extension: :school }), special: true)
end 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 private
def query_params def query_params

@ -11,7 +11,7 @@ class ZipsController < ApplicationController
if params[:export].present? && params[:export] if params[:export].present? && params[:export]
normal_status(0,"正在下载中") normal_status(0,"正在下载中")
else else
cookies[:fileDownload] = true set_export_cookies
send_file service.zip, filename: filename_, type: 'application/zip' send_file service.zip, filename: filename_, type: 'application/zip'
end end
@ -27,6 +27,7 @@ class ZipsController < ApplicationController
if params[:export].present? && params[:export] if params[:export].present? && params[:export]
normal_status(0,"正在下载中") normal_status(0,"正在下载中")
else else
set_export_cookies
send_file exercises.ex_zip, filename: file_name_, type: 'application/zip' send_file exercises.ex_zip, filename: file_name_, type: 'application/zip'
end end
rescue Exception => e rescue Exception => e

@ -329,6 +329,23 @@ module ApplicationHelper
content content
end 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) def strip_export_title(content)
con_ = "" con_ = ""
if content.length > 0 if content.length > 0

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

@ -6,7 +6,7 @@ module GamesHelper
end end
# 获取目录下所有文件,返回一个文件名的数组 type是查看文件的类型image表示图片 # 获取目录下所有文件,返回一个文件名的数组 type是查看文件的类型image表示图片
# type [[1, "图片"], [2, "apk/exe"], [3, "txt"], [4, "html"]] # type [[1, "图片"], [2, "apk/exe"], [3, "txt"], [4, "html"], [5, "mp3"], [6, "mp4"]]
def get_dir_filename(path, type, game_id) def get_dir_filename(path, type, game_id)
answer_picture = [] answer_picture = []
return answer_picture unless File.directory?(path) return answer_picture unless File.directory?(path)
@ -39,6 +39,12 @@ module GamesHelper
end end
f.close f.close
@type = 'txt' @type = 'txt'
elsif extension == 'mp3' && type == 5
answer_picture << file
@type = 'mp3'
elsif extension == 'mp4' && type == 6
answer_picture << file
@type = 'mp4'
end end
end end
@ -51,4 +57,21 @@ module GamesHelper
"编译失败,请在测试结果中查看具体的错误信息" : test_set.try(:actual_output) "编译失败,请在测试结果中查看具体的错误信息" : test_set.try(:actual_output)
end end
end end
def shixun_show_type type
case type.to_i
when 1
"image"
when 2
"apk/exe"
when 3
"txt"
when 4
"html"
when 5
"mp3"
when 6
"mp4"
end
end
end end

@ -1,5 +1,6 @@
class Challenge < ApplicationRecord class Challenge < ApplicationRecord
# difficulty: 关卡难度: 1.简单 2.中等 3.困难 # difficulty: 关卡难度: 1.简单 2.中等 3.困难
# show_type: 效果展示:-1.无效果 1.图片 2.apk/exe 3.txt 4.html 5.mp3 6.mp4
default_scope { order("challenges.position asc") } default_scope { order("challenges.position asc") }
belongs_to :shixun, :touch => true, counter_cache: true belongs_to :shixun, :touch => true, counter_cache: true

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

@ -6,7 +6,7 @@ class Memo < ApplicationRecord
has_many :memo_tag_repertoires, dependent: :destroy has_many :memo_tag_repertoires, dependent: :destroy
has_many :tag_repertoires, :through => :memo_tag_repertoires 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 has_one :praise_tread_cache, as: :object, dependent: :destroy
belongs_to :author, class_name: 'User', foreign_key: 'author_id' belongs_to :author, class_name: 'User', foreign_key: 'author_id'
@ -14,6 +14,7 @@ class Memo < ApplicationRecord
has_many :descendants, foreign_key: :root_id, class_name: 'Memo' has_many :descendants, foreign_key: :root_id, class_name: 'Memo'
has_many :children, foreign_key: :parent_id, class_name: 'Memo' has_many :children, foreign_key: :parent_id, class_name: 'Memo'
has_many :attachments, as: :container, dependent: :destroy
scope :field_for_list, lambda{ scope :field_for_list, lambda{
select([:id, :subject, :author_id, :sticky, :updated_at, :language, :reward, :all_replies_count, :viewed_count, :forum_id]) 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 end
def manager_of_memo?(memo) def manager_of_memo?(memo)
id == memo.author_id || admin? id == memo.author_id || admin? || business?
end end
# 是否是项目管理者 # 是否是项目管理者

@ -148,30 +148,6 @@ class DiscussesService
@discuss = Discuss.select([:id, :hidden, :reward, :dis_type, :dis_id, :position, :challenge_id, :root_id]).find(id) @discuss = Discuss.select([:id, :hidden, :reward, :dis_type, :dis_id, :position, :challenge_id, :root_id]).find(id)
end 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 def recommends
hot_shixuns = Shixun.field_for_recommend.published.order("myshixuns_count desc").limit(2) 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) newest_shixuns = Shixun.field_for_recommend.published.order("created_at desc").limit(2)
@ -185,6 +161,30 @@ class DiscussesService
return recommend_shixuns return recommend_shixuns
end 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 def object_to_hash objects
objects.map{|o| o.attributes.dup} objects.map{|o| o.attributes.dup}

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

@ -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 json.code @code

@ -24,5 +24,29 @@ elsif @type == "txt"
json.contents @contents.html_safe json.contents @contents.html_safe
elsif @type =="qrcode" elsif @type =="qrcode"
json.qrcode_str @qrcode_str 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
end
end end

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

@ -1,8 +1,14 @@
json.(memo, :id, :subject, :is_md, :content, :sticky, :reward, :viewed_count) json.memo do
json.id memo.id
json.tag memo.tag_repertoires.map(&:name) json.subject memo.subject
json.time memo.created_at json.is_md memo.is_md
json.replies_count memo.all_replies_count json.content memo.content
json.attachments_list [] json.sticky memo.sticky
json.user_praise memo.praise_tread.user_liker(@user.try(:id)) ? true : false json.reward memo.reward
json.memo_praise_count = memo.praise_tread.liker.count 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, json.(memo, :id, :subject, :author_id, :sticky,
:updated_at, :language, :reward, :all_replies_count, :updated_at, :language, :reward, :all_replies_count,
:viewed_count, :forum_id) :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.replies_count memo.all_replies_count
json.tag memo.tag_repertoires.map(&:name) json.tag memo.tag_repertoires.map(&:name)
json.user_name memo.author.full_name json.user_name memo.author.full_name

@ -7,10 +7,10 @@ json.username memo.author.full_name
json.reward memo.reward json.reward memo.reward
json.hidden memo.hidden json.hidden memo.hidden
json.permission @user.manager_of_memo?(memo) json.permission @user.manager_of_memo?(memo)
json.praise_count memo.praise_tread.liker.count json.praise_count memo.praise_treads.select{|pt| pt.praise_or_tread == 1}.count
json.user_praise memo.praise_tread.select{|pt| pt.user_id == @user.id}.length > 0 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.user_login memo.author.login
json.admin @user.admin json.admin @user.admin? || @user.business?
json.children do json.children do
json.array! memo.children_of_reply do |child| 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: 消息数 # tidding_count: 消息数
# # # #
json.memo_list do json.memo_list @memos do |memo|
json.array! @memos do |memo| json.(memo, :id, :subject, :sticky,
json.partial! "memos/memo_list", locals: {memo: memo} :updated_at, :language, :reward,
end :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 end
json.memo_count @memos_count json.memo_count @memos_count
json.hot_memos do json.hot_memos do
json.array! @hot_memos do |hm| 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.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) json.tag hm.tag_repertoires.map(&:name)
end end
end end
json.hot_tags @tags_info.map{|o| o.attributes.dup.except("cnt", "id")} 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.tag_list @tag_list
json.forums @csrf_token json.forums forum_list

@ -1,5 +1,9 @@
json.partial! "memos/memo", memo: @memo 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.memo_replies do
json.array! @memos do |memo| json.array! @memos do |memo|
json.partial! "memos/replies_list", memo: memo json.partial! "memos/replies_list", memo: memo
@ -9,10 +13,11 @@ end
json.author_info do json.author_info do
json.username @memo.author.full_name json.username @memo.author.full_name
# TODO watched_by 插件没法用,等把lib文件载入后在打开代码 # 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.image_url url_to_avatar(@memo.author)
json.identity @memo.author.identity json.identity @memo.author.identity
json.login @memo.author.login json.login @memo.author.login
json.user_id @memo.author.id json.user_id @memo.author.id
end end
json.recommend_shixuns @recommend_shixuns

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

@ -20,7 +20,18 @@ Rails.application.routes.draw do
put 'commons/unhidden', to: 'commons#unhidden' put 'commons/unhidden', to: 'commons#unhidden'
delete 'commons/delete', to: 'commons#delete' 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 resources :tem_tests
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html # 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 get :system_update
resource :trial_apply, only: [:create] resource :trial_apply, only: [:create]
resources :projects, only: [] do resources :projects, module: :users, only: [] do
get :search, on: :collection get :search, on: :collection
end end
@ -222,6 +233,7 @@ Rails.application.routes.draw do
resources :discusses do resources :discusses do
collection do collection do
get :new_message get :new_message
get :forum_discusses
end end
member do member do

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;} .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*/ /*TPM*/
.shixunDetail_top{width: 100%;background-image: url("/images/educoder/shixun-detail.jpg");background-size: 100% 100%;height: 240px; .shixunDetail_top{width: 100%;background-image: url("/images/educoder/shixun-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;
}
.task-item{margin-top: 30px;padding-bottom: 30px;border-bottom: 1px solid #eee} .task-item{margin-top: 30px;padding-bottom: 30px;border-bottom: 1px solid #eee}
.task-item:last-child{border-bottom: none;} .task-item:last-child{border-bottom: none;}
.challengeNav a.active{color: #4CACFF;} .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%;} .pathNavLine{position: absolute;bottom: -8px;width: 100%;}
.path-nav li{float: left;padding: 0px 30px;height: 42px;} .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 a{color:#fff;font-size: 16px;display: block; height: 40px;}
.path-nav li.active a{border-bottom: 3px solid #4CACFF;color:#4CACFF;} .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; .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;} .subhead_content{width: 1200px;margin: 0px auto;}
.pathInfo li{text-align: center;float: left;margin-right: 38px;} .pathInfo li{text-align: center;float: left;margin-right: 38px;}
.pathInfo li span{display: block;} .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; .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)} .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{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;} .inviteTipbtn a:hover{color: #4cacff!important;}
@ -3048,3 +3065,354 @@ a.singlepublishtwo{
/*课程目标VS毕业要求指标点*/ /*课程目标VS毕业要求指标点*/
.CourseTargetPoint thead th{vertical-align: baseline;} .CourseTargetPoint thead th{vertical-align: baseline;}
.CourseTargetPoint tbody tr td{vertical-align: top;} .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
}

@ -288,23 +288,12 @@ class App extends Component {
<Trialapplicationreview {...this.props} {...this.state}></Trialapplicationreview> <Trialapplicationreview {...this.props} {...this.state}></Trialapplicationreview>
<Addcourses {...this.props} {...this.state}/> <Addcourses {...this.props} {...this.state}/>
<AccountProfile {...this.props} {...this.state}/> <AccountProfile {...this.props} {...this.state}/>
{/*{*/}
{/* isRender === true?*/}
{/* <LoginDialog></LoginDialog> : ""*/}
{/*}*/}
{/*{*/}
{/* isRenders === true?*/}
{/*<Trialapplication></Trialapplication>*/}
{/*:""*/}
{/*}*/}
<Router> <Router>
<Switch> <Switch>
{/*<Route path="/login" component={LoginRegisterPage}/>*/}
{/*众包创新*/} {/*/!*众包创新*!/*/}
<Route path={"/crowdsourcings"} component={ProjectPackages}/> {/*<Route path={"/crowdsourcing"} component={ProjectPackages}/>*/}
{/*认证*/} {/*认证*/}
<Route path="/account" component={AccountPage}/> <Route path="/account" component={AccountPage}/>
@ -327,9 +316,7 @@ class App extends Component {
render={ render={
(props) => (<UsersInfo {...this.props} {...props} {...this.state} />) (props) => (<UsersInfo {...this.props} {...props} {...this.state} />)
}></Route> }></Route>
{/*<Route*/}
{/* path="/trialapplication" component={Trialapplication}*/}
{/*/>*/}
<Route <Route
path="/changepassword" component={EducoderLogin} path="/changepassword" component={EducoderLogin}
/> />
@ -349,14 +336,6 @@ class App extends Component {
{/*列表页*/} {/*列表页*/}
<Route path="/shixuns" component={TPMShixunsIndexComponent}/> <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> <Route path="/paths" component={ShixunPaths}></Route>
@ -370,16 +349,9 @@ class App extends Component {
{/*课堂*/} {/*课堂*/}
<Route path="/courses" component={CoursesIndex} {...this.props}></Route> <Route path="/courses" component={CoursesIndex} {...this.props}></Route>
{/* 课堂讨论 */} {/* <Route path="/forums" component={ForumsIndexComponent}>
{/* <Route path="/board" component = {BoardIndex} {...this.props}></Route> */} </Route> */}
{/* <Route path="/tpforums" component={TPForumsIndexComponent}>
</Route> */}
{/* <Route path="/myshixuns/:shixunId/stages/:stageId" component={Index}/> */}
{/* 兴趣页面*/}
{/*<Route path="/interest" component={Interestpage}/>*/}
<Route path="/comment" component={CommentComponent}/> <Route path="/comment" component={CommentComponent}/>
<Route path="/testMaterial" component={TestMaterialDesignComponent}/> <Route path="/testMaterial" component={TestMaterialDesignComponent}/>
<Route path="/test" component={TestIndex}/> <Route path="/test" component={TestIndex}/>
@ -387,14 +359,9 @@ class App extends Component {
<Route path="/testRCComponent" component={TestComponent}/> <Route path="/testRCComponent" component={TestComponent}/>
<Route path="/testUrlQuery" component={TestUrlQueryComponent}/> <Route path="/testUrlQuery" component={TestUrlQueryComponent}/>
{/* <Route component={NotFoundPage}/> */}
{/*列表页*/}
{/*<Route component={TPMShixunsIndexComponent}/>*/}
{/*首页*/}
<Route exact path="/" component={ShixunsHome}/> <Route exact path="/" component={ShixunsHome}/>
<Route component={Shixunnopage}/> <Route component={Shixunnopage}/>
{/*<Route component={ShixunsHome}/>*/}
</Switch> </Switch>
</Router> </Router>

@ -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 DMDEditor } from './components/markdown/DMDEditor'
export { default as Clappr } from './components/media/Clappr'
export { default as ImageLayerHook } from './hooks/ImageLayerHook' 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 { Redirect } from 'react-router';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Clappr } from 'educoder'
import axios from 'axios'; import axios from 'axios';
import EffectDisplayContent from './EffectDisplayContent'
class EvaluateSuccessEffectDisplay extends Component { class EvaluateSuccessEffectDisplay extends Component {
constructor(props) { constructor(props) {
super(props) super(props)
@ -35,7 +35,8 @@ class EvaluateSuccessEffectDisplay extends Component {
// qrcode // qrcode
// const type = 'image' // 'qrcode' // const type = 'image' // 'qrcode'
const { type, qrcode_str, 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') { if (type == 'qrcode') {
// 单张图片比如安卓评测完显示qrcode // 单张图片比如安卓评测完显示qrcode
return ( return (
@ -54,22 +55,35 @@ class EvaluateSuccessEffectDisplay extends Component {
return ( return (
<div className="task-popup-content"> <div className="task-popup-content">
<div className="clearfix"> <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>
<p className="edu-txt-center fl font-18 with33 mr03precent">预期输出图片</p> <p className="edu-txt-center fl font-18 with33 mr03precent">预期输出图片</p>
</div> </div>
<div className="clearfix" id="picture-content"> <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"> <div className="fl with33 mr03precent pt10 mb50">
{orignal_picture[0] && <img alt="Icon" {user_picture.map(item => {
src={ orignal_picture[0].pic_url}/>} return (
</div> <img alt="Icon"
<div className="fl with33 mr03precent pt10 mb50"> src={ item.pic_url}/> )
{user_picture[0] && <img alt="Icon" })}
src={ user_picture[0].pic_url }/>} </div>
</div>
<div className="fl with33 mr03precent pt10 mb50"> <div className="fl with33 mr03precent pt10 mb50">
{ answer_picture[0] && <img alt="Icon" {answer_picture.map(item => {
src={ answer_picture[0].pic_url}/> } return (
<img alt="Icon"
src={ item.pic_url}/> )
})}
{/* { answer_picture[0] && <img alt="Icon"
src={ answer_picture[0].pic_url}/> } */}
</div> </div>
</div> </div>
</div> </div>
@ -88,7 +102,31 @@ class EvaluateSuccessEffectDisplay extends Component {
return ( return (
<iframe id="_displayIframe"></iframe> <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"> /* <div className="with49 fr">
<p className="font-18 mb20 edu-txt-center">预期输出</p> <p className="font-18 mb20 edu-txt-center">预期输出</p>

@ -66,7 +66,7 @@ class CommonWorkDetailIndex extends Component{
this.state = { this.state = {
DownloadType:false, DownloadType:false,
DownloadMessageval:undefined, DownloadMessageval:undefined,
donwloading: false, donwloading:false,
} }
} }
initWorkDetailCommonState = (data) => { initWorkDetailCommonState = (data) => {
@ -106,7 +106,10 @@ class CommonWorkDetailIndex extends Component{
/// 确认是否下载 /// 确认是否下载
confirmysl(url){ confirmysl(url){
axios.get(url).then((response) => { axios.get(url+ '&export=true').then((response) => {
if(response===undefined){
return
}
if(response.data.status&&response.data.status===-1){ if(response.data.status&&response.data.status===-1){
}else if(response.data.status&&response.data.status===-2){ }else if(response.data.status&&response.data.status===-2){
@ -187,7 +190,9 @@ class CommonWorkDetailIndex extends Component{
let params = {} let params = {}
if (isListModule) { if (isListModule) {
// TODO // TODO
params =this.child._getRequestParams()!==undefined?this.child._getRequestParams():{}; if(this.child!=undefined) {
params = this.child._getRequestParams() !== undefined ? this.child._getRequestParams() : {};
}
} }
// console.log("普通作业176176176"); // console.log("普通作业176176176");
// console.log(params); // console.log(params);
@ -311,15 +316,15 @@ class CommonWorkDetailIndex extends Component{
导出<i className="iconfont icon-xiajiantou font-12 ml2"></i> 导出<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu" style={{"right":"-34px","left":"unset","height":"auto"}}> <ul className="drop_down_menu" style={{"right":"-34px","left":"unset","height":"auto"}}>
<li> <li>
<a href={"javascript:void(0)"} className="color-dark" <a href={"javascript:void(0)"} className="color-dark"
onClick={() => this.confirmysl(exportResultUrl, exportParams)} onClick={() => this.confirmysl(exportResultUrl)}
>导出成绩</a> >导出成绩</a>
</li> </li>
<li> <li>
<a href={"javascript:void(0)"} className="color-dark" <a href={"javascript:void(0)"} className="color-dark"
onClick={() => this.confirmysl(exportUrl, exportParams)} onClick={() => this.confirmysl(exportUrl)}
>导出作品附件</a> >导出作品附件</a>
</li> </li>
</ul> </ul>

@ -425,7 +425,8 @@ class CommonWorkList extends Component{
teacher_comment: arg_teacher_comment.length == 0 ? '' : arg_teacher_comment[0], teacher_comment: arg_teacher_comment.length == 0 ? '' : arg_teacher_comment[0],
order, order,
limit: PAGE_SIZE, limit: PAGE_SIZE,
b_order: orderMap[order] b_order: orderMap[order],
group_id:arg_course_group,
} }
} }
fetchList = () => { fetchList = () => {

@ -44,7 +44,7 @@ class TabRightComponents extends Component{
} }
/// 确认是否下载 /// 确认是否下载
confirmysl(url){ confirmysl(url){
axios.get(url).then((response) => { axios.get(url + '?export=true' ).then((response) => {
if(response.data.status&&response.data.status===-1){ if(response.data.status&&response.data.status===-1){
}else if(response.data.status&&response.data.status===-2){ }else if(response.data.status&&response.data.status===-2){

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

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

@ -16,12 +16,17 @@ function range(start, end) {
} }
return result; return result;
} }
function disabledDateTime() { function disabledDateTime() {
return { return {
disabledMinutes: () => range(1, 30).concat(range(31, 60)), disabledMinutes: () => range(1, 30).concat(range(31, 60)),
// disabledSeconds: () => range(1,60) // disabledSeconds: () => range(1,60)
} }
} }
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class Selectsetting extends Component{ class Selectsetting extends Component{
constructor(props){ constructor(props){
super(props); super(props);
@ -698,6 +703,7 @@ class Selectsetting extends Component{
onChange={(e,index)=>this.onChangeTimepublishs(e,index,key)} onChange={(e,index)=>this.onChangeTimepublishs(e,index,key)}
// onChange={ this.onChangeTimepublish } // onChange={ this.onChangeTimepublish }
disabledTime={disabledDateTime} 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!=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)} value={datatime===undefined||datatime===""?"":moment(datatime, dateFormat)}
onChange={this.onChangeTimepublish} onChange={this.onChangeTimepublish}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
/> />
</span> </span>
</p>:""} </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"; const dateFormat="YYYY-MM-DD HH:mm";
class Sendresource extends Component{ class Sendresource extends Component{
constructor(props){ constructor(props){
@ -525,6 +530,7 @@ class Sendresource extends Component{
onChange={(e,index)=>this.onChangeTimepublish(e,index,key,2)} onChange={(e,index)=>this.onChangeTimepublish(e,index,key,2)}
// onChange={ this.onChangeTimepublish } // onChange={ this.onChangeTimepublish }
disabledTime={disabledDateTime} 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!=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>:""} {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)} value={datatime===undefined||datatime===""?undefined:moment(datatime, dateFormat)}
onChange={(e,index)=>this.onChangeTimepublish(e,index,undefined,1)} onChange={(e,index)=>this.onChangeTimepublish(e,index,undefined,1)}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
/> />
</span> </span>
</p>:""} </p>:""}

@ -33,6 +33,21 @@ class ExerciseDisplay extends Component{
this.state = { this.state = {
exercise_questions: [], exercise_questions: [],
exercise_group_id:[],
page:1,
limit:10,
searchtext:"",
order: "end_at",
}
}
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
} }
} }
componentDidMount = () => { componentDidMount = () => {
@ -49,6 +64,21 @@ class ExerciseDisplay extends Component{
console.log(error); console.log(error);
}); });
} }
try {
this.props.triggerRef(this);
}catch (e) {
}
}
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
}
} }
render() { render() {
// let { question_title, question_score, question_type, question_choices, standard_answer, // let { question_title, question_score, question_type, question_choices, standard_answer,

@ -23,6 +23,7 @@ function range(start, end) {
} }
return result; return result;
} }
function disabledDateTime() { function disabledDateTime() {
return { return {
// disabledHours: () => range(0, 24).splice(4, 20), // disabledHours: () => range(0, 24).splice(4, 20),
@ -30,6 +31,11 @@ function disabledDateTime() {
// disabledSeconds: () => [0, 60], // disabledSeconds: () => [0, 60],
}; };
} }
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
const dataformat="YYYY-MM-DD HH:mm"; const dataformat="YYYY-MM-DD HH:mm";
class Exercisesetting extends Component{ class Exercisesetting extends Component{
@ -63,17 +69,46 @@ class Exercisesetting extends Component{
choice_random:true, choice_random:true,
time:0, time:0,
publish_timetype:false, publish_timetype:false,
end_timetype:false end_timetype:false,
exercise_group_id:[],
page:1,
limit:10,
searchtext:"",
order: "end_at",
} }
console.log("Exercisesetting"); console.log("Exercisesetting");
console.log("69"); console.log("69");
console.log(props); console.log(props);
} }
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
}
}
//加载 //加载
componentDidMount=()=>{ componentDidMount=()=>{
this.getSettingInfo(); this.getSettingInfo();
// window.addEventListener('click', this.handleClick); // window.addEventListener('click', this.handleClick);
try {
this.props.triggerRef(this);
}catch (e) {
}
}
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
}
} }
// handleClick=(e)=>{ // handleClick=(e)=>{
@ -607,6 +642,7 @@ class Exercisesetting extends Component{
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD HH:mm"
showToday={false} showToday={false}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimepublish} onChange={this.onChangeTimepublish}
value={publish_time && moment(publish_time,"YYYY-MM-DD HH:mm")} value={publish_time && moment(publish_time,"YYYY-MM-DD HH:mm")}
disabled={ publish_timetype===true?true:!flagPageEdit } disabled={ publish_timetype===true?true:!flagPageEdit }
@ -632,6 +668,7 @@ class Exercisesetting extends Component{
width={"240px"} width={"240px"}
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD HH:mm"
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimeEnd} onChange={this.onChangeTimeEnd}
value={end_time && moment(end_time,"YYYY-MM-DD HH:mm")} value={end_time && moment(end_time,"YYYY-MM-DD HH:mm")}
disabled={ end_timetype===true?true:!flagPageEdit} disabled={ end_timetype===true?true:!flagPageEdit}

@ -23,15 +23,32 @@ class Exercisestatisticalresult extends Component {
exercise_group_id:[], exercise_group_id:[],
page:1, page:1,
limit:10, limit:10,
searchtext:"",
order: "end_at",
} }
} }
componentDidMount() { componentDidMount() {
let{sort,exercise_group_id,page,limit}=this.state; let{sort,exercise_group_id,page,limit}=this.state;
this.updatefun(sort,exercise_group_id,page,limit) this.updatefun(sort,exercise_group_id,page,limit);
} try {
this.props.triggerRef(this);
}catch (e) {
}
}
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
}
}
updatefun=(sort,exercise_group_id,page,limit)=>{ updatefun=(sort,exercise_group_id,page,limit)=>{
let ExerciseId=this.props.match.params.Id; let ExerciseId=this.props.match.params.Id;
let url = `/exercises/`+ExerciseId+`/exercise_result.json`; let url = `/exercises/`+ExerciseId+`/exercise_result.json`;

@ -1213,6 +1213,11 @@ class Studentshavecompletedthelist extends Component {
// console.log("2222222222222"); // console.log("2222222222222");
// console.log(this.props.isAdmin()); // console.log(this.props.isAdmin());
// } // }
try {
this.props.triggerRef(this);
}catch (e) {
}
} }
componentWillReceiveProps = (nextProps) => { componentWillReceiveProps = (nextProps) => {
@ -1384,7 +1389,8 @@ class Studentshavecompletedthelist extends Component {
loadingstate: true, loadingstate: true,
}) })
} }
console.log(response);
console.log(1393);
thiss.Generatenewdatasy(response.data.exercise_users, response); thiss.Generatenewdatasy(response.data.exercise_users, response);
} }
}).catch((error) => { }).catch((error) => {
@ -1984,9 +1990,14 @@ class Studentshavecompletedthelist extends Component {
}).then((response) => { }).then((response) => {
// console.log("528"); // console.log("528");
// console.log(JSON.stringify(response)); // console.log(JSON.stringify(response));
if(response===undefined){
return
}
this.setState({ this.setState({
loadingstate: false, loadingstate: false,
}) })
console.log(response);
console.log(1997);
this.Generatenewdatasy(response.data.exercise_users, response); this.Generatenewdatasy(response.data.exercise_users, response);
}).catch((error) => { }).catch((error) => {
console.log(error) console.log(error)
@ -2279,22 +2290,8 @@ class Studentshavecompletedthelist extends Component {
this.Searchdatasys(this.state.order, this.state.commit_status, this.state.review, this.state.checkedValuesineinfo, this.state.searchtext, 1, this.state.limit); this.Searchdatasys(this.state.order, this.state.commit_status, this.state.review, this.state.checkedValuesineinfo, this.state.searchtext, 1, this.state.limit);
} }
} };
//搜索学生 文字输入 //搜索学生按钮输入 老师
inputSearchValues = (e) => {
// console.log(e.target.value)
if (e.target.value === "") {
this.setState({
searchtext: undefined,
})
} else {
this.setState({
searchtext: e.target.value,
})
}
}
//搜索学生按钮输入
searchValues = (value) => { searchValues = (value) => {
//点击直接搜索 //点击直接搜索
// if(value === ""){ // if(value === ""){
@ -2313,8 +2310,36 @@ class Studentshavecompletedthelist extends Component {
// console.log(value) // console.log(value)
};
_getRequestParams() {
const { order, checkedValuesineinfo,course_groupyslstwo ,searchtext, page ,limit,course_groupyslsthree} = this.state
return {
page,
review:course_groupyslsthree,
commit_status:course_groupyslstwo,
search:searchtext,
exercise_group_id:checkedValuesineinfo,
limit: limit,
order,
}
} }
//搜索学生 文字输入
inputSearchValues = (e) => {
// console.log(e.target.value)
if (e.target.value === "") {
this.setState({
searchtext: undefined,
})
} else {
this.setState({
searchtext: e.target.value,
})
}
};
//排序 //排序
funordersy = (e) => { funordersy = (e) => {
if (e === "end_at") { if (e === "end_at") {

@ -1,7 +1,7 @@
import React,{ Component } from "react"; 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 {Link,NavLink} from 'react-router-dom';
import { WordsBtn ,ActionBtn} from 'educoder'; import { WordsBtn ,ActionBtn,queryString,downloadFile} from 'educoder';
import CoursesListType from '../coursesPublic/CoursesListType'; import CoursesListType from '../coursesPublic/CoursesListType';
import '../css/members.css'; import '../css/members.css';
import '../css/busyWork.css'; import '../css/busyWork.css';
@ -19,7 +19,7 @@ import Ecerciseallbackagain from './Ecerciseallbackagain';
const polls_status={1:"未发布",2:"提交中",3:"已截止",4:"已结束"} const polls_status={1:"未发布",2:"提交中",3:"已截止",4:"已结束"}
const start_Value={0:"继续答题",1:"查看答题",2:"开始答题"} const start_Value={0:"继续答题",1:"查看答题",2:"开始答题"}
const qs = require('qs');
//试卷主要设置页面 //试卷主要设置页面
class Testpapersettinghomepage extends Component{ class Testpapersettinghomepage extends Component{
constructor(props) { constructor(props) {
@ -33,6 +33,7 @@ class Testpapersettinghomepage extends Component{
current_status:undefined, current_status:undefined,
DownloadType:false, DownloadType:false,
DownloadMessageval:undefined, DownloadMessageval:undefined,
donwloading:false,
} }
} }
//切换tab //切换tab
@ -163,8 +164,17 @@ class Testpapersettinghomepage extends Component{
} }
/// 确认是否下载 /// 确认是否下载
confirmysl(url){ confirmysl(url,child){
axios.get(url).then((response) => { let params ={}
if(child!=undefined){
params =child._getRequestParams()!==undefined?child._getRequestParams():{};
}
console.log("170");
console.log(params);
axios.get(url+`?${queryString.stringify(params)}`+ '&export=true').then((response) => {
if(response===undefined){
return
}
if(response.data.status&&response.data.status===-1){ if(response.data.status&&response.data.status===-1){
}else if(response.data.status&&response.data.status===-2){ }else if(response.data.status&&response.data.status===-2){
@ -183,8 +193,21 @@ class Testpapersettinghomepage extends Component{
}) })
} }
}else { }else {
this.props.showNotification(`正在下载中`); this.setState({ donwloading: true })
window.open("/api"+url, '_blank'); 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) => { }).catch((error) => {
console.log(error) console.log(error)
@ -218,6 +241,7 @@ class Testpapersettinghomepage extends Component{
// DownloadMessageval:undefined // DownloadMessageval:undefined
// }) // })
// } // }
bindRef = ref => { this.child = ref };
goback=()=>{ goback=()=>{
// let {datalist}=this.state; // let {datalist}=this.state;
// let courseId=this.props.match.params.coursesId; // let courseId=this.props.match.params.coursesId;
@ -236,6 +260,7 @@ class Testpapersettinghomepage extends Component{
let {tab,visible,Commonheadofthetestpaper}=this.state; let {tab,visible,Commonheadofthetestpaper}=this.state;
const isAdmin =this.props.isAdmin(); const isAdmin =this.props.isAdmin();
const isStudent = this.props.isStudent(); const isStudent = this.props.isStudent();
// TODO
return( return(
<div className="newMain clearfix "> <div className="newMain clearfix ">
@ -342,14 +367,14 @@ class Testpapersettinghomepage extends Component{
`} `}
</style> </style>
<div className={"studentList_operation_ul mt23"}> <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> 导出<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu" style={{"right":"-34px","left":"unset","height":"auto"}}> <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`)}>学生成绩</a></li> <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>*/} {/*<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> </ul>
</li>:""} </li></Spin>:""}
</div> </div>
{ {
@ -400,22 +425,22 @@ class Testpapersettinghomepage extends Component{
/> />
{ {
// 教师列表 // 教师列表
parseInt(tab[0])==0 && <Studentshavecompletedthelist {...this.props} {...this.state} setcourse_groupysls={(value)=>this.setcourse_groupysls(value)} current_status = {this.state.current_status}></Studentshavecompletedthelist> parseInt(tab[0])==0 && <Studentshavecompletedthelist {...this.props} {...this.state} triggerRef={this.bindRef} setcourse_groupysls={(value)=>this.setcourse_groupysls(value)} current_status = {this.state.current_status}></Studentshavecompletedthelist>
} }
{/*统计结果*/} {/*统计结果*/}
{ {
parseInt(tab[0])==1 && <Exercisestatisticalresult {...this.props} {...this.state}></Exercisestatisticalresult> parseInt(tab[0])==1 && <Exercisestatisticalresult {...this.props} {...this.state} triggerRef={this.bindRef}></Exercisestatisticalresult>
} }
{ {
parseInt(tab[0])==2 && <ExerciseDisplay {...this.props} {...this.state}></ExerciseDisplay> parseInt(tab[0])==2 && <ExerciseDisplay {...this.props} {...this.state} triggerRef={this.bindRef}></ExerciseDisplay>
} }
{ {
parseInt(tab[0])==3 && <WrappedExercisesetting {...this.props} {...this.state} ></WrappedExercisesetting> parseInt(tab[0])==3 && <WrappedExercisesetting {...this.props} {...this.state} triggerRef={this.bindRef}></WrappedExercisesetting>
} }
</div> </div>
</div> </div>

@ -27,6 +27,11 @@ function disabledDateTime() {
}; };
} }
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class GraduationTaskssettingapp extends Component{ class GraduationTaskssettingapp extends Component{
constructor(props){ constructor(props){
@ -896,7 +901,7 @@ class GraduationTaskssettingapp extends Component{
} }
/// 确认是否下载 /// 确认是否下载
confirmysl(url){ confirmysl(url){
axios.get(url).then((response) => { axios.get(url + '?export=true' ).then((response) => {
if(response === undefined){ if(response === undefined){
return return
} }
@ -1181,6 +1186,7 @@ class GraduationTaskssettingapp extends Component{
value={publish_time===null||publish_time===""?"":moment(publish_time, dateFormat)} value={publish_time===null||publish_time===""?"":moment(publish_time, dateFormat)}
onChange={this.onChangeTimepublish} onChange={this.onChangeTimepublish}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={this.props.isAdmin()===true?starttimetype===true?true:flagPageEdit===true?false:true:true} disabled={this.props.isAdmin()===true?starttimetype===true?true:flagPageEdit===true?false:true:true}
className={ this.state.publishTimetypes===true?"noticeTip":""} className={ this.state.publishTimetypes===true?"noticeTip":""}
/> />
@ -1218,6 +1224,7 @@ class GraduationTaskssettingapp extends Component{
value={end_time===null||end_time===""?"":moment(end_time, dateFormat)} value={end_time===null||end_time===""?"":moment(end_time, dateFormat)}
onChange={this.onChangeTimeend} onChange={this.onChangeTimeend}
disabledTime={disabledDateTime} 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.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} disabled={this.props.isAdmin()===true?endtimetype===true?true:flagPageEdit===true?false:true:true}
className={this.state.endTimetypes===true||end_timetype===true?"noticeTip":""} className={this.state.endTimetypes===true||end_timetype===true?"noticeTip":""}
@ -1269,6 +1276,7 @@ class GraduationTaskssettingapp extends Component{
width={"210px"} width={"210px"}
value={latetime===null||latetime===""?"":moment(latetime, dateFormat)} value={latetime===null||latetime===""?"":moment(latetime, dateFormat)}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimelatetime} onChange={this.onChangeTimelatetime}
disabled={this.props.isAdmin()===true?allowlate===true||allowlate===1?flagPageEdit===true?false:true:true:true} disabled={this.props.isAdmin()===true?allowlate===true||allowlate===1?flagPageEdit===true?false:true:true:true}
className={ latetimetype===true?"noticeTip":""} className={ latetimetype===true?"noticeTip":""}
@ -1319,6 +1327,7 @@ class GraduationTaskssettingapp extends Component{
width={"210px"} width={"210px"}
value={commenttime===null||commenttime=== ""?"":moment(commenttime, dateFormat)} value={commenttime===null||commenttime=== ""?"":moment(commenttime, dateFormat)}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimecommenttime} onChange={this.onChangeTimecommenttime}
disabled={this.props.isAdmin()===true?flagPageEdit===true?false:true:true} disabled={this.props.isAdmin()===true?flagPageEdit===true?false:true:true}
className={ commenttimetype===true?"noticeTip":""} className={ commenttimetype===true?"noticeTip":""}

@ -645,7 +645,7 @@ class GraduationTaskssettinglist extends Component{
b_order:b_order, b_order:b_order,
search:search, search:search,
} }
axios.get(url,{ axios.get(url + '?export=true',{
params params
}).then((response) => { }).then((response) => {
if(response === undefined){ if(response === undefined){

@ -199,7 +199,7 @@ class GraduationTasksquestions extends Component{
/// 确认是否下载 /// 确认是否下载
confirmysl(url){ confirmysl(url){
axios.get(url).then((response) => { axios.get(url + '?export=true').then((response) => {
if(response === undefined){ if(response === undefined){
return return
} }

@ -322,7 +322,7 @@ onBoardsNew=()=>{
} }
/// 确认是否下载 /// 确认是否下载
confirmysl(url){ confirmysl(url){
axios.get(url).then((response) => { axios.get(url + '?export=true').then((response) => {
if(response.data.status&&response.data.status===-1){ if(response.data.status&&response.data.status===-1){
}else if(response.data.status&&response.data.status===-2){ }else if(response.data.status&&response.data.status===-2){

@ -127,7 +127,7 @@ class studentsList extends Component{
} }
/// 确认是否下载 /// 确认是否下载
confirmysl(url){ confirmysl(url){
axios.get(url).then((response) => { axios.get(url + '&export=true').then((response) => {
if(response === undefined){ if(response === undefined){
return return
} }

@ -28,6 +28,9 @@ function disabledDateTime() {
}; };
} }
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class CoursesNew extends Component { class CoursesNew extends Component {
@ -572,6 +575,7 @@ class CoursesNew extends Component {
width={"210px"} width={"210px"}
value={datatime === undefined ? "" :datatime === null ? "" : moment(datatime, dateFormat)} value={datatime === undefined ? "" :datatime === null ? "" : moment(datatime, dateFormat)}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
dropdownClassName="hideDisable" dropdownClassName="hideDisable"
onChange={this.onChangeTimepublishs} onChange={this.onChangeTimepublishs}
/> />

@ -75,7 +75,7 @@ class PollDetailIndex extends Component{
/// 确认是否下载 /// 确认是否下载
confirmysl(url){ confirmysl(url){
axios.get(url).then((response) => { axios.get(url + '?export=true' ).then((response) => {
if(response.data.status&&response.data.status===-1){ if(response.data.status&&response.data.status===-1){
}else if(response.data.status&&response.data.status===-2){ }else if(response.data.status&&response.data.status===-2){

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

@ -2214,7 +2214,7 @@ class Listofworksstudentone extends Component {
confirmysl(url){ confirmysl(url){
axios.get(url).then((response) => { axios.get(url + '&export=true').then((response) => {
if(response === undefined){ if(response === undefined){
return return
} }

@ -539,7 +539,7 @@ class ShixunStudentWork extends Component {
} }
confirmysl(url){ confirmysl(url){
axios.get(url).then((response) => { axios.get(url + '?export=true').then((response) => {
if(response === undefined){ if(response === undefined){
return return
} }

@ -47,6 +47,9 @@ function disabledDateTime() {
} }
} }
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class Trainingjobsetting extends Component { class Trainingjobsetting extends Component {
//unifiedsetting 统一设置 //unifiedsetting 统一设置
@ -1766,16 +1769,16 @@ class Trainingjobsetting extends Component {
daochushixunbaogao=()=>{ daochushixunbaogao=()=>{
let url =`/zip/shixun_report?homework_common_id=${this.props.match.params.homeworkid}`; let url =`/zip/shixun_report?homework_common_id=${this.props.match.params.homeworkid}`;
this.confirmysl(url); this.confirmysl(url, url + '&export=true');
} }
daochuzuoye =() =>{ daochuzuoye =() =>{
let url = `/homework_commons/${this.props.match.params.homeworkid}/works_list.xlsx`; let url = `/homework_commons/${this.props.match.params.homeworkid}/works_list.xlsx`;
this.confirmysl(url); this.confirmysl(url, url + '?export=true');
} }
confirmysl(url){ confirmysl(url, urlWithExport){
axios.get(url).then((response) => { axios.get(urlWithExport).then((response) => {
if(response === undefined){ if(response === undefined){
return return
} }
@ -1935,6 +1938,7 @@ class Trainingjobsetting extends Component {
id={"publishtimeid"} id={"publishtimeid"}
disabledDate={this.disabledStartDatestart} disabledDate={this.disabledStartDatestart}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
className={borreds} className={borreds}
showTime={{ format: 'HH:mm' }} showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD HH:mm"
@ -1967,6 +1971,7 @@ class Trainingjobsetting extends Component {
showToday={false} showToday={false}
id={"end_timeid"} id={"end_timeid"}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
showTime={{ format: 'HH:mm' }} showTime={{ format: 'HH:mm' }}
className={borredss} className={borredss}
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD HH:mm"
@ -2049,6 +2054,7 @@ class Trainingjobsetting extends Component {
showToday={false} showToday={false}
id={"late_timeid"} id={"late_timeid"}
disabledTime={disabledDateTime} disabledTime={disabledDateTime}
disabledDate={disabledDate}
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD HH:mm"
value={late_time && moment(late_time, dataformat)} value={late_time && moment(late_time, dataformat)}
onChange={this.onEndChangeys} onChange={this.onEndChangeys}

@ -339,16 +339,16 @@ class Workquestionandanswer extends Component {
daochushixunbaogao=()=>{ daochushixunbaogao=()=>{
let url =`/zip/shixun_report?homework_common_id=${this.props.match.params.homeworkid}`; let url =`/zip/shixun_report?homework_common_id=${this.props.match.params.homeworkid}`;
this.confirmysl(url); this.confirmysl(url, url + '&export=true');
} }
daochuzuoye =() =>{ daochuzuoye =() =>{
let url = `/homework_commons/${this.props.match.params.homeworkid}/works_list.xlsx`; let url = `/homework_commons/${this.props.match.params.homeworkid}/works_list.xlsx`;
this.confirmysl(url); this.confirmysl(url, url + '?export=true');
} }
confirmysl(url){ confirmysl(url, urlWithExport){
axios.get(url).then((response) => { axios.get(urlWithExport).then((response) => {
if(response === undefined){ if(response === undefined){
return return
} }

@ -500,7 +500,9 @@ class DetailCardsEditAndAdd extends Component{
<div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" key={key}> <div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" key={key}>
<li className="fl with40"> <li className="fl with40">
<Checkbox <Checkbox
id={"shixun_input_"+item.shixun_id} value={item.shixun_id} id={"shixun_input_"+item.shixun_id}
value={item.shixun_id}
key={item.shixun_id}
className="fl task-hide edu-txt-left" className="fl task-hide edu-txt-left"
style={{"width":"298px"}} style={{"width":"298px"}}
name="shixun_homework[]" name="shixun_homework[]"

@ -533,7 +533,9 @@ class DetailCardsEditAndEdit extends Component{
<div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" key={key}> <div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" key={key}>
<li className="fl with40"> <li className="fl with40">
<Checkbox <Checkbox
id={"shixun_input_"+item.shixun_id} value={item.shixun_id} id={"shixun_input_"+item.shixun_id}
value={item.shixun_id}
key={item.shixun_id}
className="fl task-hide edu-txt-left" className="fl task-hide edu-txt-left"
style={{"width":"298px"}} style={{"width":"298px"}}
name="shixun_homework[]" name="shixun_homework[]"

@ -15,7 +15,6 @@ class sendPanel extends Component{
openSearch:false, openSearch:false,
sendToCourseId:undefined, sendToCourseId:undefined,
sendToShixunArray:[], sendToShixunArray:[],
shixunNum:0,
Modalstype:false, Modalstype:false,
cardsModalcancel:this.cardsModalcancel, cardsModalcancel:this.cardsModalcancel,
cardsModalsave:this.cardsModalsave, cardsModalsave:this.cardsModalsave,
@ -35,7 +34,9 @@ class sendPanel extends Component{
//隐藏发送至弹框 //隐藏发送至弹框
hideSenttothevalue =()=>{ hideSenttothevalue =()=>{
this.setState({ this.setState({
sentShixunPath:false sentShixunPath:false,
sendToShixunArray:[],
sendToCourseId:undefined,
}) })
} }
//打开课堂列表下拉框 //打开课堂列表下拉框
@ -63,7 +64,7 @@ class sendPanel extends Component{
changeCheckBoxs=(list)=>{ changeCheckBoxs=(list)=>{
this.setState({ this.setState({
sendToShixunArray:list, sendToShixunArray:list,
shixunNum:list.length // shixunNum:list.length
}) })
} }
@ -86,7 +87,9 @@ class sendPanel extends Component{
Modalstype:true, Modalstype:true,
sentShixunPath:false, sentShixunPath:false,
Modalstopval:result.data.message, Modalstopval:result.data.message,
courseurl:result.data.url courseurl:result.data.url,
sendToShixunArray:[],
sendToCourseId:undefined,
}) })
} }
}).catch((error)=>{ }).catch((error)=>{
@ -118,8 +121,33 @@ class sendPanel extends Component{
let {courseurl}=this.state; let {courseurl}=this.state;
window.location.href =courseurl; 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(){ render(){
let{sentShixunPath,sendToCourseList,openSearch,shixunNum,Modalstype,Modalstopval,Modalsbottomval,cardsModalcancel,cardsModalsave}= this.state; let{sentShixunPath,sendToCourseList,Modalstype,Modalstopval,Modalsbottomval,cardsModalcancel,cardsModalsave}= this.state;
return( return(
<div> <div>
@ -178,7 +206,7 @@ class sendPanel extends Component{
</Select> </Select>
</div> </div>
<div className="edu-back-skyblue pl15 pr15 clearfix over280 pt5"> <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)=>{ sendToCourseList && sendToCourseList.stages.map((item,key)=>{
@ -197,7 +225,16 @@ class sendPanel extends Component{
</CheckboxGroup> </CheckboxGroup>
</div> </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"> <div className="mt20 clearfix edu-txt-center">
<a onClick={this.hideSenttothevalue} className="pop_close task-btn mr30">取消</a> <a onClick={this.hideSenttothevalue} className="pop_close task-btn mr30">取消</a>
<a className="task-btn task-btn-orange" onClick={this.submitInfo}>确定</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 || ""; const _placeholder = placeholder || "";
// amp; // amp;
// 编辑时要传memoId // 编辑时要传memoId
const imageUrl = `/upload_with_markdown?container_id=&container_type=Memo`; const imageUrl = `/api/attachments.json`;
// 创建editorMd // 创建editorMd
let react_id = `react_${_id}`; let react_id = `react_${_id}`;

@ -4,6 +4,9 @@ import axios from 'axios';
import { Input ,Icon,Button,Pagination} from 'antd'; import { Input ,Icon,Button,Pagination} from 'antd';
import moment from 'moment'; import moment from 'moment';
import '../packageconcnet.css'; import '../packageconcnet.css';
import AccountProfile from"../../user/AccountProfile";
import LoginDialog from '../../login/LoginDialog';
const { Search } = Input; const { Search } = Input;
let categorylist=[ let categorylist=[
@ -45,7 +48,9 @@ class PackageConcent extends Component {
sort_direction:"desc", sort_direction:"desc",
page:1, page:1,
per_page:20, per_page:20,
categories:[] categories:[],
isRender:false,
AccountProfiletype:false
} }
} }
//desc, desc, asc //desc, desc, asc
@ -134,12 +139,66 @@ class PackageConcent extends Component {
this.setdatas(category,keyword,value,sort_directionvalue,page) 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() { 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 ( return (
<div className="educontent clearfix mtf10" style={{flex: "1 0 auto"}}> <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="stud-class-set">
<div className="news"> <div className="news">
<div className="edu-class-inner container clearfix"> <div className="edu-class-inner container clearfix">
@ -153,12 +212,12 @@ class PackageConcent extends Component {
<p className="clearfix" > <p className="clearfix" >
<p style={{height: '50px'}}> <p style={{height: '50px'}}>
<Search placeholder="输入标题名称进行检索" <Search placeholder="输入标题名称进行检索"
style={{ width: 749}}
className="packinput" className="packinput"
enterButton={<span><Icon type="search" className="mr5"/> 搜索</span>} enterButton={<span><Icon type="search" className="mr5"/> 搜索</span>}
onSearch={ (value)=>this.setdatafuns(value)} /> onSearch={ (value)=>this.setdatafuns(value)} />
<Button type="primary" className="setissues fr" size={"large"}> <Button type="primary" className="setissues fr" size={"large"}>
<a href="/crowdsourcings/new" >发布需求</a> <a onClick={()=>this.onReleaseRequirements("/crowdsourcing/new")}>发布需求</a>
</Button> </Button>
</p> </p>
</p> </p>
@ -224,7 +283,7 @@ class PackageConcent extends Component {
<div className=" item-head-title"> <div className=" item-head-title">
<a className={"fl mt3 font-20 font-bd color-dark maxwidth700 "} <a className={"fl mt3 font-20 font-bd color-dark maxwidth700 "}
href={"/crowdsourcings/"+item.id} onClick={()=>this.onReleaseRequirements("/crowdsourcing/"+item.id)}
title={item.title} title={item.title}
>{item.title}</a> >{item.title}</a>
</div> </div>

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

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

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

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

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

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

@ -617,8 +617,10 @@ submittojoinclass=(value)=>{
let activeShixuns = false; let activeShixuns = false;
let activePaths = false; let activePaths = false;
let coursestype=false; let coursestype=false;
let activePackages=false;
if (match.path === '/forums') {
if (match.path === '/forums') {
activeForums = true; activeForums = true;
} else if (match.path.startsWith('/shixuns')) { } else if (match.path.startsWith('/shixuns')) {
activeShixuns = true; activeShixuns = true;
@ -626,14 +628,12 @@ submittojoinclass=(value)=>{
activePaths = true; activePaths = true;
} else if (match.path.startsWith('/courses')) { } else if (match.path.startsWith('/courses')) {
coursestype = true; coursestype = true;
}else { }else if (match.path.startsWith('/crowdsourcing')) {
activePackages = true;
}else {
activeIndex = true; 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 ( return (
<div className="newHeader" id="nHeader" > <div className="newHeader" id="nHeader" >
@ -716,10 +716,9 @@ submittojoinclass=(value)=>{
/> />
</li> </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.moop_cases_url}>教学案例</a></li>
<li className=""><a <li className={`${activePackages === true ? 'pr active' : 'pr'}`}>
// href={this.props.Headertop===undefined?"":this.props.Headertop.crowdsourcing_url} <a href={'/crowdsourcing'}>众包创新</a>
href={'/crowdsourcings'} </li>
>众包创新</a></li>
<li className={`${activeForums === true ? 'active' : ''}`}><a href={this.props.Headertop===undefined?"":this.props.Headertop.topic_url}>交流问答</a></li> <li className={`${activeForums === true ? 'active' : ''}`}><a href={this.props.Headertop===undefined?"":this.props.Headertop.topic_url}>交流问答</a></li>
<li <li
style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.auth===null? 'none' : 'block'}} style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.auth===null? 'none' : 'block'}}

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

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

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

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

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

@ -404,11 +404,11 @@ class Infos extends Component{
{/* 众包 */} {/* 众包 */}
{/* http://localhost:3007/courses/1309/homework/9300/setting */} {/* http://localhost:3007/courses/1309/homework/9300/setting */}
<Route exact path="/users/:username/package" {/*<Route exact path="/users/:username/package"*/}
render={ {/*render={*/}
(props) => (<InfosPackage {...this.props} {...props} {...this.state} />) {/*(props) => (<InfosPackage {...this.props} {...props} {...this.state} />)*/}
} {/*}*/}
></Route> {/*></Route>*/}
{/* 课堂 */} {/* 课堂 */}
{/* http://localhost:3007/courses/1309/homework/9300/setting */} {/* http://localhost:3007/courses/1309/homework/9300/setting */}

@ -2,16 +2,35 @@ import React, { Component } from 'react';
import { SnackbarHOC } from 'educoder'; import { SnackbarHOC } from 'educoder';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom'; import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import {Tooltip,Menu,Pagination,Spin} from 'antd'; import {Tooltip,Menu,Pagination,Spin} from 'antd';
import Loadable from 'react-loadable';
import Loading from '../../../Loading';
import axios from 'axios'; import axios from 'axios';
import NoneData from '../../courses/coursesPublic/NoneData'
import {getImageUrl} from 'educoder'; import {getImageUrl} from 'educoder';
import { TPMIndexHOC } from '../../tpm/TPMIndexHOC'; import NoneData from '../../courses/coursesPublic/NoneData'
import { CNotificationHOC } from '../../courses/common/CNotificationHOC'
import "./usersInfo.css" import "./usersInfo.css"
import Create from './publicCreatNew' import moment from 'moment';
let categorylist=[
{name:"全部",value:undefined},
{name:"前端开发",value:"front"},
{name:"后端开发",value:"backend"},
{name:"移动开发",value:"mobile"},
{name:"数据库",value:"database"},
{name:"云计算和大数据",value:"cloud_compute_and_big_data"},
{name:"人工智能",value:"ai"},
{name:"运维与测试",value:"devops_and_test"},
{name:"其他",value:"other"},
]
//
function setcategorylist(val){
let vals=""
categorylist.some((item,key)=> {
if (item.name === val) {
vals=item.value
return true
}
}
)
return vals
}
class InfosPackage extends Component{ class InfosPackage extends Component{
constructor(props){ constructor(props){
super(props); super(props);
@ -19,8 +38,8 @@ class InfosPackage extends Component{
category:undefined, category:undefined,
status:undefined, status:undefined,
page:1, page:1,
per_page:16, per_page:20,
sort_direction:'desc',
totalCount:undefined, totalCount:undefined,
data:undefined, data:undefined,
isSpin:false isSpin:false
@ -36,12 +55,14 @@ class InfosPackage extends Component{
} }
getCourses=(category,status,page)=>{ getCourses=(category,status,page)=>{
let url=`/users/${this.props.match.params.username}/courses.json`; let url=`/users/${this.props.match.params.username}/project_packages.json`;
axios.get((url),{params:{ axios.get((url),{params:{
category, category,
status, status,
page, page,
per_page: this.props.is_current && category && page ==1?17:16 sort_by:"published_at",
sort_direction:'desc',
per_page:20
}}).then((result)=>{ }}).then((result)=>{
if(result){ if(result){
this.setState({ this.setState({
@ -103,21 +124,98 @@ class InfosPackage extends Component{
} = this.state; } = this.state;
let is_current=this.props.is_current; let is_current=this.props.is_current;
console.log(this.props.current_user&&this.props.current_user.user_identity==="学生") // console.log(data)
return( return(
<div className="educontent"> <div className="educontent mb50">
<Spin size="large" spinning={isSpin}> <Spin size="large" spinning={isSpin}>
<div className="white-panel edu-back-white pt25 pb25 clearfix "> <div className="white-panel edu-back-white pt25 pb25 clearfix ">
<li className={category ? "" : "active"}><a href="javascript:void(0)" onClick={()=>this.changeCategory()}>全部</a></li> <li className={category ? "" : "active"}><a onClick={()=>this.changeCategory()}>全部</a></li>
<li className={category=="manage" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("manage")}>{is_current ? "我":"TA"}管理的</a></li> <li className={category=="manage" ? "active" : ""}><a onClick={()=>this.changeCategory("manage")}>{is_current ? "我":"TA"}管理的</a></li>
<li className={category=="study" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("study")}>{is_current ? "我":"TA"}参与的</a></li> <li className={category=="bidden" ? "active" : ""}><a onClick={()=>this.changeCategory("bidden")}>{is_current ? "我":"TA"}参与的</a></li>
</div> </div>
{
category=="manage"?
<div className="edu-back-white padding20-30 clearfix secondNav bor-top-greyE">
<li className={status ? "" : "active"}><a onClick={()=>this.changeStatus()}>全部</a></li>
<li className={status=="unpublished" ? "active" : ""}><a onClick={()=>this.changeStatus("unpublished")}>未发布</a></li>
<li className={status=="bidding" ? "active" : ""}><a onClick={()=>this.changeStatus("bidding")}>竞标中</a></li>
<li className={status=="finished" ? "active" : ""}><a onClick={()=>this.changeStatus("finished")}>已完成</a></li>
</div>: category=="bidden"?
<div className="edu-back-white padding20-30 clearfix secondNav bor-top-greyE">
<li className={status ? "" : "active"}><a onClick={()=>this.changeStatus()}>全部</a></li>
<li className={status=="bidding_lost" ? "active" : ""}><a onClick={()=>this.changeStatus("bidding_lost")}>未中标</a></li>
<li className={status=="bidding_won" ? "active" : ""}><a onClick={()=>this.changeStatus("bidding_won")}>已中标</a></li>
</div>:""
}
<p className="pl25 pr25 clearfix font-12 mb20 mt20"> <p className="pl25 pr25 clearfix font-12 mb20 mt20">
<span className="fl color-grey-9">{0}</span> <span className="fl color-grey-9">{totalCount}</span>
<span className="fr color-grey-9">发布时间</span> <span className="fr color-grey-9">发布时间</span>
</p> </p>
{/*bidden_status: "pending"*/}
{/*category_id: 2*/}
{/*status: "published"*/}
{/*type: "bidden"*/}
{data===undefined?<NoneData></NoneData>:data.project_packages.length===0?<NoneData></NoneData>:data.project_packages.map((item,key)=>{
return(
<div className="educontent project-packages-list" key={key}>
<div className="project-package-item project-package-11">
<div className="item-image">
<img alt="图片" src={`/images/educoder/project_packages/${setcategorylist(item.category_name)}.png`} />
</div>
<div className="item-body">
<div className="item-head">
<div className="item-head-title" title={item.title}>
<a href={`/crowdsourcing/${item.id}`}>{item.title}</a>
</div>
<div className="item-head-tags">
</div>
<div className="item-head-blank"></div>
<div className="item-head-price">
{item.min_price===null?"":<span>{item.min_price}</span>}
{item.max_price===null||item.min_price===null?"":<span>~</span>}
{item.max_price===null?"":<span>{item.max_price}</span>}
{item.min_price===null&&item.max_price===null?<span>可议价</span>:""}
</div>
</div>
<div className="item-category">
<div className="item-category-item">{item.category_name}</div>
</div>
<div className="item-other">
<div className="item-group item-other-visit">
<span className="item-group-icon"><i className="fa fa-eye"></i></span>
<span className="item-group-text">{item.visit_count}人浏览</span>
</div>
<div className="item-group item-other-deadline">
<span className="item-group-icon"><i className="fa fa-clock-o"></i></span>
<span className="item-group-text">{moment(item.deadline_at).endOf('day').fromNow()}竞标截止</span>
</div>
<div className="item-group item-other-bidding">
<span className="item-group-icon"><i className="fa fa-user"></i></span>
<span className="item-group-text">{item.bidding_users_count}人竞标</span>
</div>
<div className="item-group"></div>
<div className="item-group item-other-publish-at">
发布于{item.published_at}
</div>
</div>
</div>
</div>
</div>
)})}
{
totalCount >20 &&
<div className="mt30 mb50 edu-txt-center">
<Pagination showQuickJumper total={totalCount} onChange={this.changePage} pageSize={20} current={page}/>
</div>
}
</Spin> </Spin>
</div> </div>
) )

@ -334,8 +334,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;} .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*/ /*TPM*/
.shixunDetail_top{width: 100%;background-image: url("/images/educoder/shixun-detail.jpg");background-size: 100% 100%;height: 240px; .shixunDetail_top{width: 100%;background-image: url("/images/educoder/shixun-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;
}
.task-item{margin-top: 30px;padding-bottom: 30px;border-bottom: 1px solid #eee} .task-item{margin-top: 30px;padding-bottom: 30px;border-bottom: 1px solid #eee}
.task-item:last-child{border-bottom: none;} .task-item:last-child{border-bottom: none;}
.challengeNav a.active{color: #4CACFF;} .challengeNav a.active{color: #4CACFF;}
@ -422,14 +426,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%;} .pathNavLine{position: absolute;bottom: -8px;width: 100%;}
.path-nav li{float: left;padding: 0px 30px;height: 42px;} .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 a{color:#fff;font-size: 16px;display: block; height: 40px;}
.path-nav li.active a{border-bottom: 3px solid #4CACFF;color:#4CACFF;} .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; .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;} .subhead_content{width: 1200px;margin: 0px auto;}
.pathInfo li{text-align: center;float: left;margin-right: 38px;} .pathInfo li{text-align: center;float: left;margin-right: 38px;}
.pathInfo li span{display: block;} .pathInfo li span{display: block;}
@ -469,7 +482,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; .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)} .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{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;} .inviteTipbtn a:hover{color: #4cacff!important;}
@ -3055,7 +3072,11 @@ a.singlepublishtwo{
padding: 0px; padding: 0px;
} }
.project_packagesHead{width: 100%;margin-bottom:40px;background-size: 100% 100%;background-image: url("/images/educoder/project_packagesHead.jpg");height: 240px; .project_packagesHead{width: 100%;margin-bottom:40px;background-size: 100% 100%;background-image: url("/images/educoder/project_packagesHead.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;
}
/* 个人中心-众包 */ /* 个人中心-众包 */
@ -3340,4 +3361,354 @@ a.singlepublishtwo{
#trophyreturn i{ #trophyreturn i{
font-size: 16px!important; font-size: 16px!important;
color: #AAAAAA; color: #AAAAAA;
} }
/*众包*/
.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
}

@ -1,5 +0,0 @@
require 'rails_helper'
RSpec.describe ForumsController, type: :controller do
end

@ -1,15 +0,0 @@
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the ForumsHelper. For example:
#
# describe ForumsHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe ForumsHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save