diff --git a/app/controllers/course_modules_controller.rb b/app/controllers/course_modules_controller.rb index 6e8afd525..fccc28f6d 100644 --- a/app/controllers/course_modules_controller.rb +++ b/app/controllers/course_modules_controller.rb @@ -48,9 +48,9 @@ class CourseModulesController < ApplicationController tip_exception("已存在同名子目录") if @course_module.course_second_categories.exists?(name: params[:name].strip) ActiveRecord::Base.transaction do begin - @course_module.course_second_categories.create!(name: params[:name].strip, category_type: @course_module.module_type, + category = @course_module.course_second_categories.create!(name: params[:name].strip, category_type: @course_module.module_type, course_id: @course.id, position: @course_module.course_second_categories.count + 1) - normal_status(0, "添加成功") + render :json => {category_id: category.id, status: 0, message: "添加成功"} rescue Exception => e uid_logger_error(e.message) tip_exception("添加子目录失败") diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 791d145c2..117475894 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -9,19 +9,20 @@ class FilesController < ApplicationController before_action :set_pagination, only: %i[index public_with_course_and_project mine_with_course_and_project] before_action :validate_upload_params, only: %i[upload import] before_action :find_file, only: %i[show setting update] + before_action :publish_params, only: %i[upload import update] SORT_TYPE = %w[created_on downloads quotes] def index sort = params[:sort] || 0 # 0: 降序;1: 升序 sort_type = params[:sort_type] || 'created_on' # created_on:时间排序, downloads:下载次数排序; quotes: 引用次数排序 - course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id + @course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id @user = current_user - @attachments = course_second_category_id.to_i == 0 ? @course.attachments : @course.attachments.by_course_second_category_id(course_second_category_id) - @attachments = @attachments.includes(attachment_group_settings: :course_group, author: [:user_extension, :course_members]) + @attachments = @course_second_category_id.to_i == 0 ? @course.attachments.includes(:course_second_category) : @course.attachments.by_course_second_category_id(@course_second_category_id) + @attachments = @attachments.includes(author: [:user_extension, :course_members]) .ordered(sort: sort.to_i, sort_type: sort_type.strip) - get_category(@course, course_second_category_id) + get_category(@course, @course_second_category_id) @total_count = @attachments.size @publish_count = @attachments.published.size @unpublish_count = @total_count - @publish_count @@ -137,9 +138,9 @@ class FilesController < ApplicationController def upload attachment_ids = params[:attachment_ids] course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id - is_unified_setting = params.has_key?(:is_unified_setting) ? params[:is_unified_setting] : true - publish_time = params[:publish_time] - course_group_publish_times = params[:course_group_publish_times] || [] + # is_unified_setting = params.has_key?(:is_unified_setting) ? params[:is_unified_setting] : true + # publish_time = params[:publish_time] + # course_group_publish_times = params[:course_group_publish_times] || [] begin attachment_ids.each do |attchment_id| @@ -148,9 +149,12 @@ class FilesController < ApplicationController attachment.container = @course attachment.course_second_category_id = course_second_category_id attachment.description = params[:description] - attachment.is_public = params[:is_public] ? 1 : 0 - attachment.set_publish_time(publish_time) if is_unified_setting - attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank? + attachment.is_public = params[:is_public] && @course.is_public == 1 ? 1 : 0 + attachment.is_publish = @atta_is_publish + attachment.delay_publish = @atta_delay_publish + attachment.publish_time = @atta_publish_time + # attachment.set_publish_time(publish_time) if is_unified_setting + # attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank? attachment.save! end end @@ -188,8 +192,9 @@ class FilesController < ApplicationController attach_copied_obj.created_on = Time.now attach_copied_obj.author = current_user attach_copied_obj.is_public = 0 - attach_copied_obj.is_publish = 1 - attach_copied_obj.publish_time = Time.now + attach_copied_obj.is_publish = @atta_is_publish + attach_copied_obj.delay_publish = @atta_delay_publish + attach_copied_obj.publish_time = @atta_publish_time attach_copied_obj.course_second_category_id = course_second_category_id attach_copied_obj.copy_from = ori.copy_from.nil? ? ori.id : ori.copy_from if attach_copied_obj.attachtype == nil @@ -209,11 +214,7 @@ class FilesController < ApplicationController def update return normal_status(403, "您没有权限进行该操作") if current_user.course_identity(@course) >= 5 && @file.author != current_user - is_unified_setting = params[:is_unified_setting] - publish_time = params[:publish_time] - publish_time = format_time(Time.parse(publish_time)) unless publish_time.blank? is_public = params[:is_public] - course_group_publish_times = params[:course_group_publish_times] || [] @old_attachment = @file @new_attachment = Attachment.find_by_id params[:new_attachment_id] @@ -225,25 +226,29 @@ class FilesController < ApplicationController old_course_second_category_id = @old_attachment.course_second_category_id @old_attachment.copy_attributes_from_new_attachment(@new_attachment) - @old_attachment.is_public = is_public == true ? 1 : 0 if is_public @old_attachment.course_second_category_id = old_course_second_category_id @old_attachment.save! @new_attachment.delete end + @old_attachment.is_public = is_public == true && @course.is_public == 1 ? 1 : 0 + @old_attachment.is_publish = @atta_is_publish + @old_attachment.delay_publish = @atta_delay_publish + @old_attachment.publish_time = @atta_publish_time + if params[:description] && !params[:description].strip.blank? && params[:description] != @old_attachment.description @old_attachment.description = params[:description] end - @old_attachment.set_public(is_public) + # @old_attachment.set_public(is_public) - if is_unified_setting - @old_attachment.set_publish_time(publish_time) - @old_attachment.attachment_group_settings.destroy_all - end + # if is_unified_setting + # @old_attachment.set_publish_time(publish_time) + # @old_attachment.attachment_group_settings.destroy_all + # end - if publish_time.blank? && @course.course_groups.size > 0 && !is_unified_setting - @old_attachment.set_course_group_publish_time(@course, course_group_publish_times) - end + # if publish_time.blank? && @course.course_groups.size > 0 && !is_unified_setting + # @old_attachment.set_course_group_publish_time(@course, course_group_publish_times) + # end @old_attachment.save! rescue Exception => e @@ -304,11 +309,19 @@ class FilesController < ApplicationController end def file_validate_sort_type - normal_status(-2, "参数sort_tyope暂时只支持 'created_on', 'quotes', 'downloads'") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip) + normal_status(-2, "参数sort_type暂时只支持 'created_on', 'quotes', 'downloads'") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip) end def validate_upload_params find_attachment_ids find_course_second_category_id end + + def publish_params + tip_exception("缺少发布参数") if params[:delay_publish].blank? + tip_exception("缺少延期发布的时间参数") if params[:delay_publish].to_i == 1 && params[:publish_time].blank? + @atta_is_publish = params[:delay_publish].to_i == 1 && params[:publish_time].to_time > Time.now ? 0 : 1 + @atta_delay_publish = params[:delay_publish].to_i + @atta_publish_time = params[:delay_publish].to_i == 1 && params[:publish_time] ? params[:publish_time] : Time.now + end end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index ae28e7d52..9c60317bd 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -9,6 +9,8 @@ class Attachment < ApplicationRecord belongs_to :course, foreign_key: :container_id, optional: true has_many :attachment_group_settings, :dependent => :destroy has_many :attachment_histories, -> { order(version: :desc) }, :dependent => :destroy + # 二级目录 + belongs_to :course_second_category, optional: true scope :by_filename_or_user_name, -> (keywords) { joins(:author).where("filename like :search or LOWER(concat(users.lastname, users.firstname)) LIKE :search", :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank? } diff --git a/app/views/attachments/_attachment.json.jbuilder b/app/views/attachments/_attachment.json.jbuilder index a8ad0a286..a21bf31c4 100644 --- a/app/views/attachments/_attachment.json.jbuilder +++ b/app/views/attachments/_attachment.json.jbuilder @@ -4,10 +4,11 @@ json.is_public attachment.publiced? # json.is_lock attachment.locked?(@is_member) json.is_lock !attachment.publiced? json.is_publish attachment.published? +json.delay_publish attachment.delay_publish json.publish_time attachment.publish_time json.unified_setting attachment.unified_setting json.filesize number_to_human_size(attachment.filesize) -json.quotes attachment.quotes_count +# json.quotes attachment.quotes_count json.description attachment.description json.downloads_count attachment.downloads_count json.created_on attachment.created_on diff --git a/app/views/courses/mine.json.jbuilder b/app/views/courses/mine.json.jbuilder index c82e31f6b..41368d883 100644 --- a/app/views/courses/mine.json.jbuilder +++ b/app/views/courses/mine.json.jbuilder @@ -1,5 +1,5 @@ json.partial! "commons/success" json.data do - json.array! @courses, :id, :name, :updated_at + json.array! @courses, :id, :name, :updated_at, :created_at, :end_date end diff --git a/app/views/files/index.json.jbuilder b/app/views/files/index.json.jbuilder index 7fe3bf5b7..0002cf299 100644 --- a/app/views/files/index.json.jbuilder +++ b/app/views/files/index.json.jbuilder @@ -13,7 +13,10 @@ json.data do json.author do json.partial! "users/user_simple", user: attachment.author end - json.partial! "files/course_groups", attachment_group_settings: attachment.attachment_group_settings + # json.partial! "files/course_groups", attachment_group_settings: attachment.attachment_group_settings + if @course_second_category_id.to_i == 0 + json.category_name attachment.course_second_category&.name + end end end end diff --git a/app/views/files/show.json.jbuilder b/app/views/files/show.json.jbuilder index 941e66619..71359ccfd 100644 --- a/app/views/files/show.json.jbuilder +++ b/app/views/files/show.json.jbuilder @@ -1,3 +1,3 @@ json.partial! 'attachments/attachment', attachment: @file -json.partial! "files/course_groups", attachment_group_settings: @file.attachment_group_settings +# json.partial! "files/course_groups", attachment_group_settings: @file.attachment_group_settings json.partial! "attachment_histories/list", attachment_histories: @attachment_histories \ No newline at end of file diff --git a/app/views/homework_commons/show.json.jbuilder b/app/views/homework_commons/show.json.jbuilder index e78166fe0..8d5abc8bc 100644 --- a/app/views/homework_commons/show.json.jbuilder +++ b/app/views/homework_commons/show.json.jbuilder @@ -4,11 +4,11 @@ json.partial! "homework_btn_check", locals: {identity: @user_course_identity, ho json.partial! "student_btn_check", locals: {identity: @user_course_identity, homework: @homework, work: @work} -json.description @homework.description - # 实训作业才有说明 if @homework.homework_type == "practice" json.explanation @homework.explanation +else + json.description @homework.description end # 附件 diff --git a/db/migrate/20191014061301_migrate_course_atta.rb b/db/migrate/20191014061301_migrate_course_atta.rb new file mode 100644 index 000000000..04d085c0d --- /dev/null +++ b/db/migrate/20191014061301_migrate_course_atta.rb @@ -0,0 +1,7 @@ +class MigrateCourseAtta < ActiveRecord::Migration[5.2] + def change + add_column :attachments, :delay_publish, :boolean, default: 0 + + Attachment.where(container_type: "Course").where(is_publish: 0).where("publish_time > '#{(Time.now).strftime("%Y-%m-%d %H:%M:%S")}'").update_all(delay_publish: 1) + end +end diff --git a/public/react/src/modules/courses/coursesPublic/SelectResource.js b/public/react/src/modules/courses/coursesPublic/SelectResource.js index c323d1bae..0e76059c8 100644 --- a/public/react/src/modules/courses/coursesPublic/SelectResource.js +++ b/public/react/src/modules/courses/coursesPublic/SelectResource.js @@ -1,17 +1,34 @@ import React,{ Component } from "react"; -import { Modal,Checkbox,Select,Input,Spin,Icon} from "antd"; +import { Modal,Checkbox,Select,Input,Spin,Icon,Radio,DatePicker} from "antd"; +import locale from 'antd/lib/date-picker/locale/zh_CN'; import axios from'axios'; +import {handleDateString} from 'educoder'; import NoneData from "../coursesPublic/NoneData"; import Modals from '../../modals/Modals'; - +import moment from 'moment'; const Option = Select.Option; const Search = Input.Search; - +const dateFormat ="YYYY-MM-DD HH:mm" function formatDate(date) { var dateee = new Date(date).toJSON(); return new Date(+new Date(dateee) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '') } - +function range(start, end) { + const result = []; + for (let i = start; i < end; i++) { + result.push(i); + } + return result; +} +function disabledDateTime() { + return { + disabledMinutes: () => range(1, 30).concat(range(31, 60)), + // disabledSeconds: () => range(1,60) + } +} +function disabledDate(current) { + return current && current < moment().endOf('day').subtract(1, 'days'); +} class Selectresource extends Component{ constructor(props){ super(props); @@ -23,7 +40,9 @@ class Selectresource extends Component{ Resourcelist:undefined, hometypepvisible:true, getallfiles:false, - searchtype:'getallfiles' + searchtype:'getallfiles', + Radiovalue:0, + datatime:undefined } } componentDidMount() { @@ -32,11 +51,7 @@ class Selectresource extends Component{ componentDidUpdate = (prevProps) => { - let {getallfiles}=this.state; - - if ( prevProps.visible != this.props.visible ) { - } } @@ -197,7 +212,7 @@ class Selectresource extends Component{ savecouseShixunModal=()=>{ - let {patheditarry}=this.state; + let {patheditarry,datatime,Radiovalue}=this.state; let {coursesId,attachmentId}=this.props; let url="/files/import.json"; @@ -212,19 +227,28 @@ class Selectresource extends Component{ }) } + if(this.state.Radiovalue===1){ + if(datatime===undefined||datatime===null||datatime=== ""){ + this.setState({ + Radiovaluetype:true + }) + return + }else{ + this.setState({ + Radiovaluetype:false + }) + } + } + axios.post(url, { course_id:coursesId, attachment_ids:patheditarry, course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId, + delay_publish:Radiovalue, + publish_time:Radiovalue===1?datatime:undefined } ).then((response) => { if(response.data.status===0){ - // this.setState({ - // Modalstype:true, - // Modalstopval:response.data.message, - // ModalSave:this.ModalCancelModalCancel, - // loadtype:true - // }) this.ModalCancelModalCancel(); this.props.updataleftNavfun(); this.props.showNotification("选用资源成功"); @@ -236,15 +260,33 @@ class Selectresource extends Component{ } - selectCloseList=(value)=>{ + RadioonChange=(e)=>{ + if(e.target.value===0){ + this.setState({ + datatime:undefined + }) + } this.setState({ - category_id:value + Radiovalue: e.target.value, + }); + } + + onChangeTimepublish= (date, dateString) => { + + this.setState({ + datatime:handleDateString(dateString), }) + } render(){ - let {Searchvalue,type,category_id,Resourcelist,hometypepvisible,patheditarry}=this.state; - let {visible,shixunmodallist}=this.props; + let {Searchvalue,type,Resourcelist,hometypepvisible,patheditarry,datatime}=this.state; + let {visible}=this.props; const antIcon = ; + const radioStyle = { + display: 'block', + height: '30px', + lineHeight: '30px', + }; return(
{/*提示*/} @@ -373,10 +415,36 @@ class Selectresource extends Component{ }
- +
+ 发布设置: + + + 立即发布 + + + 延迟发布 + this.onChangeTimepublish(e,index,undefined,1)} + disabledTime={disabledDateTime} + disabledDate={disabledDate} + disabled={this.state.Radiovalue===1?false:true} + /> + + (按照设置的时间定时发布) + +
{this.state.patheditarrytype===true?

请选择资源

:""} - + {this.state.Radiovaluetype===true?

发布时间不能为空

:""}
取消 确定 diff --git a/public/react/src/modules/courses/coursesPublic/SelectSetting.js b/public/react/src/modules/courses/coursesPublic/SelectSetting.js index eae1f4e3b..0b7aad29e 100644 --- a/public/react/src/modules/courses/coursesPublic/SelectSetting.js +++ b/public/react/src/modules/courses/coursesPublic/SelectSetting.js @@ -165,9 +165,9 @@ class Selectsetting extends Component{ axios.put(url,{ course_id:coursesId, new_attachment_id:newfileList.length===0?undefined:newfileList, - // course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId, + course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId, is_public:is_public, - publish_time:Radiovalue===0?undefined:datatime===undefined?moment(new Date()).format('YYYY-MM-DD HH'):datatime, + publish_time:Radiovalue===0?undefined:datatime===undefined?moment(new Date(),dateFormat):datatime, description:description, delay_publish:Radiovalue }).then((result)=>{ diff --git a/public/react/src/modules/courses/coursesPublic/SendToFilesModal.js b/public/react/src/modules/courses/coursesPublic/SendToFilesModal.js index d14d5d267..319ab8304 100644 --- a/public/react/src/modules/courses/coursesPublic/SendToFilesModal.js +++ b/public/react/src/modules/courses/coursesPublic/SendToFilesModal.js @@ -1,9 +1,11 @@ import React, { Component } from "react"; import { Modal, Checkbox, Input, Spin} from "antd"; -import axios from 'axios' +import axios from 'axios'; +import moment from 'moment'; import ModalWrapper from "../common/ModalWrapper"; import InfiniteScroll from 'react-infinite-scroller'; +const dateFormat ="YYYY-MM-DD HH:mm" const Search = Input.Search const pageCount = 15; class Sendtofilesmodal extends Component{ @@ -170,7 +172,12 @@ class Sendtofilesmodal extends Component{ bottom: 93px; width: 82%; text-align: center; - }`} + } + .ModalWrappertitle{ + background: #D0E8FC; + padding: 10px; + } + `}

选择的{moduleName}发送到指定课堂

@@ -183,7 +190,12 @@ class Sendtofilesmodal extends Component{ >
- {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} + +

+

课堂名称
+
更新时间
+
结束时间
+

- +
{course.name}
+
{moment(course.updated_at).format('YYYY-MM-DD HH:mm')}
+
{course.end_date}

) }) } - {loading && hasMore && ( -
- -
- )} - {/* TODO */} - {/* { - !hasMore &&
没有更多了。。
- } */} +