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

newyslclassrooms
caicai8 5 years ago
commit de899cbccb

@ -330,7 +330,7 @@ class ApplicationController < ActionController::Base
end end
if !User.current.logged? && Rails.env.development? if !User.current.logged? && Rails.env.development?
User.current = User.find 1 User.current = User.find 3117
end end

@ -8,7 +8,8 @@ class CourseVideosController < ApplicationController
def create def create
title = params[:name].strip title = params[:name].strip
link = params[:link].strip link = params[:link].strip
@course.course_videos.create!(title: title, link: link, is_link: 1, user_id: current_user.id) course_second_category_id = params[:category_id] || 0
@course.course_videos.create!(title: title, link: link, is_link: 1, user_id: current_user.id, course_second_category_id: course_second_category_id)
render_ok render_ok
end end

@ -2,13 +2,13 @@ class FilesController < ApplicationController
include MessagesHelper include MessagesHelper
before_action :require_login, :check_auth, except: %i[index] before_action :require_login, :check_auth, except: %i[index]
before_action :find_course, except: %i[public_with_course_and_project mine_with_course_and_project] before_action :find_course, except: %i[public_with_course_and_project mine_with_course_and_project update_visits]
before_action :find_ids, only: %i[bulk_delete bulk_send bulk_move bulk_public bulk_publish] before_action :find_ids, only: %i[bulk_delete bulk_send bulk_move bulk_public bulk_publish]
before_action :file_validate_sort_type, only: :index before_action :file_validate_sort_type, only: :index
before_action :validate_send_message_to_course_params, only: :bulk_send before_action :validate_send_message_to_course_params, only: :bulk_send
before_action :set_pagination, only: %i[index public_with_course_and_project mine_with_course_and_project] before_action :set_pagination, only: %i[index public_with_course_and_project mine_with_course_and_project]
before_action :validate_upload_params, only: %i[import] before_action :validate_upload_params, only: %i[import]
before_action :find_file, only: %i[show setting update] before_action :find_file, only: %i[show setting update update_visits]
before_action :publish_params, only: %i[upload import update] before_action :publish_params, only: %i[upload import update]
SORT_TYPE = %w[created_on downloads quotes] SORT_TYPE = %w[created_on downloads quotes]
@ -289,6 +289,11 @@ class FilesController < ApplicationController
@old_attachment.save! @old_attachment.save!
@new_attachment.delete @new_attachment.delete
end end
if params[:name].present? && params[:link].present?
tip_exception("资源名称不能超过60个字符") if params[:name].strip.length > 60
@old_attachment.filename = params[:name].strip
@old_attachment.link = params[:link].strip
end
@old_attachment.is_public = is_public == true && @course.is_public == 1 ? 1 : 0 @old_attachment.is_public = is_public == true && @course.is_public == 1 ? 1 : 0
@old_attachment.is_publish = @atta_is_publish @old_attachment.is_publish = @atta_is_publish
@old_attachment.delay_publish = @atta_delay_publish @old_attachment.delay_publish = @atta_delay_publish
@ -350,6 +355,11 @@ class FilesController < ApplicationController
end end
end end
def update_visits
@file.increment!(:downloads)
render_ok
end
private private
def find_file def find_file
@file = Attachment.find params[:id] @file = Attachment.find params[:id]

@ -54,10 +54,10 @@ class Users::VideosController < Users::BaseController
end end
def destroy def destroy
video = observed_user.videos.find_by(id: params[:video_id]) video = Video.find_by(id: params[:id])
render_forbidden unless video.user_id != observed_user.id || !current_user.admin_or_business? return render_forbidden unless video.user_id == current_user.id || current_user.admin_or_business?
return render_not_found if video.blank? return render_not_found if video.blank?
return render_error('该状态下不能删除视频') unless video.pending? return render_error('该状态下不能删除视频') unless video.published?
video.destroy! video.destroy!
@ -85,6 +85,6 @@ class Users::VideosController < Users::BaseController
end end
def batch_publish_params def batch_publish_params
params.permit(videos: %i[video_id title course_id]) params.permit(videos: %i[video_id title course_id category_id])
end end
end end

@ -42,6 +42,7 @@ class Weapps::AttendancesController < ApplicationController
end end
def student_attendances def student_attendances
tip_exception(403) if @user_course_identity > Course::STUDENT
# tip_exception("学生身份的签到列表") if @user_course_identity != Course::STUDENT # tip_exception("学生身份的签到列表") if @user_course_identity != Course::STUDENT
member = @course.students.find_by(user_id: current_user.id) member = @course.students.find_by(user_id: current_user.id)
if member.present? if member.present?
@ -62,11 +63,11 @@ class Weapps::AttendancesController < ApplicationController
where("attendance_date = '#{current_date}' and start_time <= '#{current_end_time}' and end_time > '#{current_end_time}'") where("attendance_date = '#{current_date}' and start_time <= '#{current_end_time}' and end_time > '#{current_end_time}'")
@history_count = @history_attendances.size @history_count = @history_attendances.size
# 当前签到如果存在快捷签到,则直接签到 # 当前签到如果存在快捷签到,则直接签到(不在这里处理)
quick_attendances = @current_attendances.where(mode: "QUICK") # quick_attendances = @current_attendances.where(mode: "QUICK")
if quick_attendances.present? # if quick_attendances.present?
student_direct_attendance quick_attendances, member # student_direct_attendance quick_attendances, member
end # end
student_attendance_ids = @history_attendances.pluck(:id) student_attendance_ids = @history_attendances.pluck(:id)
student_attendance_ids += @current_attendances.present? ? @current_attendances.pluck(:id) : [] student_attendance_ids += @current_attendances.present? ? @current_attendances.pluck(:id) : []

@ -28,19 +28,24 @@ class Weapps::CourseMemberAttendancesController < ApplicationController
end end
def create def create
tip_exception("签到码不能为空") if params[:code].blank? tip_exception("签到码不能为空") if params[:attendance_mode] != "QUICK" && params[:code].blank?
tip_exception("attendance_mode参数不对") unless ["NUMBER", "QRCODE"].include?(params[:attendance_mode]) tip_exception("attendance_mode参数不对") unless ["NUMBER", "QRCODE", "QUICK"].include?(params[:attendance_mode])
attendance = CourseAttendance.find_by(attendance_code: params[:code]) if params[:attendance_mode] == "QUICK"
tip_exception("签到码输入有误") if attendance.blank? || attendance.course.blank? attendance = CourseAttendance.find_by(id: params[:attendance_id])
else
attendance = CourseAttendance.find_by(attendance_code: params[:code])
end
tip_exception("该签到不存在") if attendance.blank? || attendance.course.blank?
member = attendance.course.students.find_by(user_id: current_user.id) member = attendance.course.students.find_by(user_id: current_user.id)
tip_exception("签到码输入有误") if member.blank? tip_exception("该签到不存在") if member.blank?
tip_exception("不在签到时间内") unless attendance.current_attendance? tip_exception("不在签到时间内") unless attendance.current_attendance?
tip_exception("只支持数字签到") if attendance.mode != "ALL" && attendance.mode == "NUMBER" && params[:attendance_mode] == "QRCODE" tip_exception("只支持数字签到") if attendance.mode != "ALL" && attendance.mode == "NUMBER" && params[:attendance_mode] != "NUMBER"
tip_exception("只支持二维码签到") if attendance.mode != "ALL" && attendance.mode == "QRCODE" && params[:attendance_mode] == "NUMBER" tip_exception("只支持二维码签到") if attendance.mode != "ALL" && attendance.mode == "QRCODE" && params[:attendance_mode] != "QRCODE"
tip_exception("只支持快捷签到") if attendance.mode == "QUICK" && params[:attendance_mode] != "QUICK"
current_attendance = attendance.course_member_attendances.find_by(user_id: current_user.id) current_attendance = attendance.course_member_attendances.find_by(user_id: current_user.id)
if current_attendance.present? if current_attendance.present?

@ -41,7 +41,8 @@ class Videos::BatchPublishService < ApplicationService
# 如果是课堂上传则创建课堂记录 # 如果是课堂上传则创建课堂记录
Rails.logger.info("#####param: #{ param[:course_id]}") Rails.logger.info("#####param: #{ param[:course_id]}")
if param[:course_id].present? if param[:course_id].present?
video.course_videos.create!(course_id: param[:course_id]) course_second_category_id = params[:category_id] || 0
video.course_videos.create!(course_id: param[:course_id], course_second_category_id: course_second_category_id)
end end
end end
end end

@ -1,5 +1,6 @@
json.id attachment.id json.id attachment.id
json.title attachment.title json.title attachment.title
json.link attachment.link
json.is_public attachment.publiced? json.is_public attachment.publiced?
# json.is_lock attachment.locked?(@is_member) # json.is_lock attachment.locked?(@is_member)
json.is_lock !attachment.publiced? json.is_lock !attachment.publiced?
@ -15,4 +16,4 @@ json.created_on attachment.created_on
json.content_type attachment.content_type json.content_type attachment.content_type
json.is_pdf attachment.is_pdf? json.is_pdf attachment.is_pdf?
json.url attachment.is_pdf? ? download_url(attachment,disposition:"inline") : download_url(attachment) json.url attachment.is_pdf? ? download_url(attachment,disposition:"inline") : download_url(attachment)
json.play_url attachment_show_users_path(file_name: local_path(attachment)) json.play_url attachment.link.present? ? nil : attachment_show_users_path(file_name: local_path(attachment))

@ -1,4 +1,4 @@
json.(attendance, :name, :mode) json.(attendance, :id, :name, :mode)
json.attendance_date attendance.attendance_date.strftime("%Y/%m/%d") json.attendance_date attendance.attendance_date.strftime("%Y/%m/%d")
json.start_time attendance.start_time.strftime("%H:%M") json.start_time attendance.start_time.strftime("%H:%M")
json.end_time attendance.end_time.strftime("%H:%M") json.end_time attendance.end_time.strftime("%H:%M")

@ -195,7 +195,7 @@ Rails.application.routes.draw do
resource :unread_message_info, only: [:show] resource :unread_message_info, only: [:show]
# 视频 # 视频
resources :videos, only: [:index, :update] do resources :videos, only: [:index, :update, :destroy] do
collection do collection do
get :review get :review
post :batch_publish post :batch_publish
@ -464,6 +464,7 @@ Rails.application.routes.draw do
end end
member do member do
get :histories get :histories
post :update_visits
end end
end end

@ -10,7 +10,7 @@ import { CNotificationHOC } from './common/CNotificationHOC'
import {ImageLayerOfCommentHOC} from '../page/layers/ImageLayerOfCommentHOC' import {ImageLayerOfCommentHOC} from '../page/layers/ImageLayerOfCommentHOC'
import "./css/Courses.css" import "./css/Courses.css"
//引入对应跳转的组件 //引入对应跳转的组件
//里面有资源
const ListPageIndex = Loadable({ const ListPageIndex = Loadable({
loader: () => import('./ListPageIndex'), loader: () => import('./ListPageIndex'),
loading:Loading, loading:Loading,

@ -1,6 +1,6 @@
import React,{ Component } from "react"; import React, {Component} from "react";
import { WordsBtn } from 'educoder'; import {WordsBtn} from 'educoder';
import {Tooltip,message} from 'antd'; import {Tooltip, message} from 'antd';
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
import {getImageUrl} from 'educoder'; import {getImageUrl} from 'educoder';
import axios from 'axios' import axios from 'axios'
@ -10,25 +10,40 @@ import CoursesListType from '../coursesPublic/CoursesListType';
import Showoldfiles from "../coursesPublic/Showoldfiles"; import Showoldfiles from "../coursesPublic/Showoldfiles";
import Modals from '../../modals/Modals'; import Modals from '../../modals/Modals';
class Fileslistitem extends Component{ class Fileslistitem extends Component {
constructor(props){ constructor(props) {
super(props); super(props);
this.state = { this.state = {}
}
} }
settingList=()=>{ settingList = (bools) => {
let {discussMessage}=this.props let {discussMessage} = this.props
this.setState({ this.setState({
discussMessageid:discussMessage.id discussMessageid: discussMessage.id
}) })
this.props.Settingtypes(discussMessage.id) if (bools === true) {
} this.props.Settingtypes(discussMessage.id)
} else {
this.props.Settingtypess(discussMessage.id)
}
showfiles=(list)=>{ }
if(this.props.checkIfLogin()===false){ //外链
showfiless = (url,id) => {
window.open(url)
let urls=`/files/${id}/update_visits.json`;
axios.post(urls,{
}).then((result)=>{
if(result.data.status===0){
this.props.Updateresourcepage()
}else{
this.props.showNotification(result.data.message);
}
})
}
showfiles = (list) => {
if (this.props.checkIfLogin() === false) {
this.props.showLoginDialog() this.props.showLoginDialog()
return return
} }
@ -43,21 +58,21 @@ class Fileslistitem extends Component{
// return // return
// } // }
if(list.is_history_file===false){ if (list.is_history_file === false) {
// this.props.DownloadFileA(list.title,list.url) // this.props.DownloadFileA(list.title,list.url)
//window.location.href=list.url; //window.location.href=list.url;
window.open(list.url, '_blank'); window.open(list.url, '_blank');
}else{ } else {
let {discussMessage,coursesId}=this.props let {discussMessage, coursesId} = this.props
let file_id=discussMessage.id let file_id = discussMessage.id
let url="/files/"+file_id+"/histories.json" let url = "/files/" + file_id + "/histories.json"
axios.get(url,{ axios.get(url, {
params:{ params: {
course_id:coursesId course_id: coursesId
}, },
}).then((result)=>{ }).then((result) => {
if(result.data.attachment_histories.length===0){ if (result.data.attachment_histories.length === 0) {
// if(result.data.is_pdf===true){ // if(result.data.is_pdf===true){
// this.props.ShowOnlinePdf(result.data.url) // this.props.ShowOnlinePdf(result.data.url)
// //预览pdf // //预览pdf
@ -66,64 +81,66 @@ class Fileslistitem extends Component{
// } // }
// this.props.DownloadFileA(result.data.title,result.data.url) // this.props.DownloadFileA(result.data.title,result.data.url)
window.open(list.url, '_blank'); window.open(list.url, '_blank');
}else{ } else {
this.setState({ this.setState({
Showoldfiles:true, Showoldfiles: true,
allfiles:result.data allfiles: result.data
}) })
} }
}).catch((error)=>{ }).catch((error) => {
console.log(error) console.log(error)
}) })
} }
} }
closaoldfilesprops=()=>{ closaoldfilesprops = () => {
this.setState({ this.setState({
Showoldfiles:false, Showoldfiles: false,
}) })
} }
onDelete = (id) => { onDelete = (id) => {
this.setState({ this.setState({
Modalstype:true, Modalstype: true,
Modalstopval:"是否确认删除?", Modalstopval: "是否确认删除?",
ModalCancel:this.cancelmodel, ModalCancel: this.cancelmodel,
ModalSave:()=>this.savedelete(id), ModalSave: () => this.savedelete(id),
}) })
} }
cancelmodel=()=>{ cancelmodel = () => {
this.setState({ this.setState({
Modalstype:false, Modalstype: false,
Loadtype:false, Loadtype: false,
Modalstopval:"", Modalstopval: "",
ModalCancel:"", ModalCancel: "",
ModalSave:"", ModalSave: "",
checkBoxValues:[], checkBoxValues: [],
}) })
} }
savedelete=(id)=>{ savedelete = (id) => {
this.setState({ this.setState({
Modalstype:false, Modalstype: false,
}) })
const cid = this.props.match.params.coursesId const cid = this.props.match.params.coursesId
const url = `/files/bulk_delete.json`; const url = `/files/bulk_delete.json`;
axios.delete(url, { data: { axios.delete(url, {
course_id:cid, data: {
course_id: cid,
ids: [id], ids: [id],
}}) }
})
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
//Modalstopval:response.data.message, //Modalstopval:response.data.message,
@ -132,11 +149,11 @@ class Fileslistitem extends Component{
this.setState({ this.setState({
// Modalstype:true, // Modalstype:true,
// Modalstopval:"删除成功", // Modalstopval:"删除成功",
ModalsBottomval:"", ModalsBottomval: "",
// ModalSave:this.cancelmodel, // ModalSave:this.cancelmodel,
// Loadtype:true, // Loadtype:true,
checkBoxValues:[], checkBoxValues: [],
checkAllValue:false checkAllValue: false
}) })
this.props.showNotification("删除成功"); this.props.showNotification("删除成功");
@ -147,28 +164,30 @@ class Fileslistitem extends Component{
}); });
} }
eventStop = (event) =>{ eventStop = (event) => {
event.stopPropagation() event.stopPropagation()
} }
render(){ render() {
const { checkBox, const {
discussMessage,index checkBox,
discussMessage, index
} = this.props; } = this.props;
return( let bools = discussMessage.link && discussMessage.link ? false : true;
return (
<div className="graduateTopicList boardsList"> <div className="graduateTopicList boardsList">
{/*提示*/} {/*提示*/}
{this.state.Modalstype&&this.state.Modalstype===true?<Modals {this.state.Modalstype && this.state.Modalstype === true ? <Modals
modalsType={this.state.Modalstype} modalsType={this.state.Modalstype}
modalsTopval={this.state.Modalstopval} modalsTopval={this.state.Modalstopval}
modalCancel={this.state.ModalCancel} modalCancel={this.state.ModalCancel}
modalSave={this.state.ModalSave} modalSave={this.state.ModalSave}
modalsBottomval={this.state.ModalsBottomval} modalsBottomval={this.state.ModalsBottomval}
loadtype={this.state.Loadtype} loadtype={this.state.Loadtype}
/>:""} /> : ""}
<Showoldfiles <Showoldfiles
{...this.props} {...this.props}
visible={this.state.Showoldfiles} visible={this.state.Showoldfiles}
@ -213,67 +232,130 @@ class Fileslistitem extends Component{
margin-top:2px; margin-top:2px;
} }
`}</style> `}</style>
<div className="clearfix ds pr contentSection" style={{cursor : this.props.isAdmin ? "pointer" : "default"}} onClick={() => window.$(`.sourceitem${index} input`).click() }> <div className="clearfix ds pr contentSection" style={{cursor: this.props.isAdmin ? "pointer" : "default"}}
<h6 onClick={(event)=>this.eventStop(event)}> onClick={() => window.$(`.sourceitem${index} input`).click()}>
<h6 onClick={(event) => this.eventStop(event)}>
<span className={`sourceitem${index} fl mr12 mt3`}> <span className={`sourceitem${index} fl mr12 mt3`}>
{checkBox} {checkBox}
</span> </span>
{ {
this.props.isAdmin ? <a this.props.isAdmin ?
// href={"/courses/" + coursesId + "/graduation/graduation_tasks/" + categoryid + "/" + taskid + "/list"} (bools === true ?
onClick={()=>this.showfiles(discussMessage)} <a
title={discussMessage.title} // href={"/courses/" + coursesId + "/graduation/graduation_tasks/" + categoryid + "/" + taskid + "/list"}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a> : "" onClick={() => this.showfiles(discussMessage)}
title={discussMessage.title}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
:
<a
// href={"/courses/" + coursesId + "/graduation/graduation_tasks/" + categoryid + "/" + taskid + "/list"}
onClick={() => this.showfiless(discussMessage.link,discussMessage.id)}
title={discussMessage.title}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
)
: ""
} }
{ {
this.props.isStudent? <a this.props.isStudent ?
onClick={()=>this.showfiles(discussMessage)} (bools === true ?
title={discussMessage.title} <a
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a> :"" onClick={() => this.showfiles(discussMessage)}
title={discussMessage.title}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
:
<a
onClick={() => this.showfiless(discussMessage.link,discussMessage.id)}
title={discussMessage.title}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
)
: ""
} }
{ {
this.props.isNotMember===true? this.props.isNotMember === true ?
discussMessage.is_lock === true ? discussMessage.is_lock === true ?
<span className="fl mt3 font-16 font-bd color-dark maxwidth580 pointer" title={"私有属性,非课堂成员不能访问"}>{discussMessage.title}</span> <span className="fl mt3 font-16 font-bd color-dark maxwidth580 pointer"
:<a title={"私有属性,非课堂成员不能访问"}>{discussMessage.title}</span>
onClick={()=>this.showfiles(discussMessage)} :
title={discussMessage.title} (bools === true ?
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>:""
<a
onClick={() => this.showfiles(discussMessage)}
title={discussMessage.title}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a> :
<a
onClick={() =>this.showfiless(discussMessage.link,discussMessage.id)}
title={discussMessage.title}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
)
: ""
} }
{ {
discussMessage.is_lock === true ? discussMessage.is_lock === true ?
<Tooltip title={"私有属性,非课堂成员不能访问"} placement="bottom"> <Tooltip title={"私有属性,非课堂成员不能访问"} placement="bottom">
<i className="iconfont icon-guansuo color-grey-c ml10 font-16 fl mt4"></i> <i className="iconfont icon-guansuo color-grey-c ml10 font-16 fl mt4"></i>
</Tooltip> </Tooltip>
:"" : ""
}
<style>
{
`
.fwlz{
width:40px;
height:20px;
border-radius:2px;
border:1px solid rgba(250,100,0,1);
font-size:12px;
font-family:MicrosoftYaHei;
color:rgba(250,100,0,1);
text-align: center;
margin-left: 15px;
}
`
}
</style>
{
discussMessage.link && discussMessage.link ?
<p className="fl mt3 fwlz pointer">外链</p>
:
""
} }
{discussMessage.is_publish===false?<CoursesListType typelist={["未发布"]} typesylename={""}/>:""}
{this.props.isAdmin? {discussMessage.is_publish === false ? <CoursesListType typelist={["未发布"]} typesylename={""}/> : ""}
<span className={"fr mt2"} onClick={(event)=>this.eventStop(event)}>
{this.props.isAdmin ?
<span className={"fr mt2"} onClick={(event) => this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 ml20 fr"> <WordsBtn style="blue" className="colorblue font-16 ml20 fr">
<a className="btn colorblue fontweight400" <a className="btn colorblue fontweight400"
onClick={()=>this.settingList()}>设置</a> onClick={() => this.settingList(bools)}>设置</a>
</WordsBtn> </WordsBtn>
</span>:""} </span> : ""}
{this.props.isStudent===true&&this.props.current_user.login===discussMessage.author.login? {this.props.isStudent === true && this.props.current_user.login === discussMessage.author.login ?
<span className={"fr mt2"} onClick={(event)=>this.eventStop(event)}> <span className={"fr mt2"} onClick={(event) => this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 ml20 fr"> <WordsBtn style="blue" className="colorblue font-16 ml20 fr">
<a className="btn colorblue fontweight400" <a className="btn colorblue fontweight400"
onClick={()=>this.settingList()}>设置</a> onClick={() => this.settingList(bools)}>设置</a>
</WordsBtn> </WordsBtn>
<WordsBtn style="blue" className="colorblue font-16 ml20 fr"> <WordsBtn style="blue" className="colorblue font-16 ml20 fr">
<a className="btn colorblue fontweight400" <a className="btn colorblue fontweight400"
onClick={()=>this.onDelete(discussMessage.id)}>删除</a> onClick={() => this.onDelete(discussMessage.id)}>删除</a>
</WordsBtn> </WordsBtn>
</span>:""} </span> : ""}
</h6> </h6>
<style> <style>
{ {
@ -288,7 +370,6 @@ class Fileslistitem extends Component{
</style> </style>
<style> <style>
{ {
` `
@ -315,28 +396,45 @@ class Fileslistitem extends Component{
{/*</p>}*/} {/*</p>}*/}
<p className={this.props.isAdmin===true?"color-grey panel-lightgrey mt8 fl ml30":"color-grey panel-lightgrey mt8 fl ml13"} style={{width:'100%'}}> <p
className={this.props.isAdmin === true ? "color-grey panel-lightgrey mt8 fl ml30" : "color-grey panel-lightgrey mt8 fl ml13"}
style={{width: '100%'}}>
<span className="mr50"> <span className="mr50">
<span className="mr15 color-dark">{discussMessage.author.name}</span> <span className="mr15 color-dark">{discussMessage.author.name}</span>
<span className="mr15 color-grey9">大小 {discussMessage.filesize}</span> {
<span className="mr15 color-grey9">下载 {discussMessage.downloads_count}</span> bools ?
<span className="mr15 color-grey9">大小 {discussMessage.filesize}</span>
:
""
}
{
bools ?
<span className="mr15 color-grey9">下载 {discussMessage.downloads_count}</span>
:
<span className="mr15 color-grey9">点击次数{discussMessage.downloads_count}</span>
}
{/*<span className="mr15 color-grey9">引用 {discussMessage.quotes}</span>*/} {/*<span className="mr15 color-grey9">引用 {discussMessage.quotes}</span>*/}
<span className="mr15 color-grey-c"> <span className="mr15 color-grey-c">
{/*{moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm:ss')}*/} {/*{moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm:ss')}*/}
{/*{moment(discussMessage.publish_time).fromNow()}*/} {/*{moment(discussMessage.publish_time).fromNow()}*/}
{ discussMessage.publish_time===null?"": {discussMessage.publish_time === null ? "" :
discussMessage.is_publish===true?"":"发布于"} discussMessage.is_publish === true ? "" : "发布于"}
{ discussMessage.publish_time===null?"":discussMessage.is_publish===true?moment(discussMessage.publish_time).fromNow():moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm')} {discussMessage.publish_time === null ? "" : discussMessage.is_publish === true ? moment(discussMessage.publish_time).fromNow() : moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm')}
</span> </span>
</span> </span>
{discussMessage&&discussMessage.category_name===null?"":this.props.child===false?<div className="color-grey9 task-hide fr mr30" title={discussMessage&&discussMessage.category_name} {discussMessage && discussMessage.category_name === null ? "" : this.props.child === false ?
style={{"max-width":"268px"}}>所属目录{discussMessage&&discussMessage.category_name} <div className="color-grey9 task-hide fr mr30" title={discussMessage && discussMessage.category_name}
</div>:""} style={{"max-width": "268px"}}>所属目录{discussMessage && discussMessage.category_name}
</div> : ""}
</p> </p>
<p
<p className={this.props.isAdmin===true?"color-grey panel-lightgrey mt8 fl ml30":"color-grey panel-lightgrey mt8 fl ml13"} style={{width:'94%'}}> className={this.props.isAdmin === true ? "color-grey panel-lightgrey mt8 fl ml30" : "color-grey panel-lightgrey mt8 fl ml13"}
style={{width: '94%'}}>
<style> <style>
{ {
` `
@ -349,7 +447,8 @@ class Fileslistitem extends Component{
` `
} }
</style> </style>
<span className="color-dark isspans">资源描述 :{discussMessage.description===null?"暂无描述":discussMessage.description}</span> <span
className="color-dark isspans">资源描述 :{discussMessage.description === null ? "暂无描述" : discussMessage.description}</span>
{/*<span className="mr50">*/} {/*<span className="mr50">*/}
{/*/!*<span className="mr15 color-dark"></span>*!/*/} {/*/!*<span className="mr15 color-dark"></span>*!/*/}
{/*<span className="mr15 color-dark">*/} {/*<span className="mr15 color-dark">*/}
@ -365,4 +464,5 @@ class Fileslistitem extends Component{
) )
} }
} }
export default Fileslistitem; export default Fileslistitem;

@ -6,6 +6,8 @@ import Modals from '../../modals/Modals';
import Sendtofilesmodal from "../coursesPublic/SendToFilesModal"; import Sendtofilesmodal from "../coursesPublic/SendToFilesModal";
import Selectresource from "../coursesPublic/SelectResource"; import Selectresource from "../coursesPublic/SelectResource";
import Sendresource from "../coursesPublic/sendResource"; import Sendresource from "../coursesPublic/sendResource";
import SendResources from "../coursesPublic/sendResources";
import Selectsetting from "../coursesPublic/SelectSetting"; import Selectsetting from "../coursesPublic/SelectSetting";
import HomeworkModal from "../coursesPublic/HomeworkModal"; import HomeworkModal from "../coursesPublic/HomeworkModal";
import Fileslistitem from './Fileslistitem'; import Fileslistitem from './Fileslistitem';
@ -34,7 +36,9 @@ class Fileslists extends Component{
name:"", name:"",
sendTotype:false, sendTotype:false,
Accessoryvisible:false, Accessoryvisible:false,
discussMessageid:undefined, Addanexternallink:false,
Exterchainname:"添加外链",
discussMessageid:undefined,
course_modules:undefined, course_modules:undefined,
has_course_groups:false, has_course_groups:false,
course_is_public:undefined, course_is_public:undefined,
@ -229,16 +233,15 @@ class Fileslists extends Component{
filesId:list.id, filesId:list.id,
name:list.name, name:list.name,
course_is_public:result.data.data.course_is_public, course_is_public:result.data.data.course_is_public,
isSpin:false,
page:page page:page
}) })
} }
} }
}else{ }
this.setState({ this.setState({
isSpin:false isSpin:false
}) })
}
}).catch((error)=>{ }).catch((error)=>{
console.log(error) console.log(error)
this.setState({ this.setState({
@ -570,8 +573,45 @@ class Fileslists extends Component{
}) })
} }
//添加外链资源设置
sendResourcessls = (ints,bool) => {
if(bool===true){
if(ints===1){
this.setState({
Addanexternallink:true,
Exterchainname:"添加外链"
})
}else{
this.setState({
Addanexternallink:true,
Exterchainname:"资源设置"
})
}
}else{
this.setState({
Addanexternallink:false,
})
if(ints===1){
this.Updateresourcepage();
}
}
}
Updateresourcepage=()=>{
let{pagesize,tagname,searchValue,page,sort,sorttype,coursesecondcategoryid}=this.state;
this.getfileslist(pagesize,page,tagname,searchValue,sort,sorttype,coursesecondcategoryid);
}
Cancelvisible=()=>{
Cancelvisible=()=>{
this.setState({ this.setState({
Accessoryvisible:false, Accessoryvisible:false,
@ -587,6 +627,14 @@ class Fileslists extends Component{
}) })
} }
Settingtypess=(id)=>{
this.setState({
Addanexternallink:true,
Exterchainname:"资源设置",
discussMessageid:id,
})
}
moveTos=(id)=>{ moveTos=(id)=>{
let {checkBoxValues} = this.state; let {checkBoxValues} = this.state;
@ -729,7 +777,9 @@ class Fileslists extends Component{
course_is_public, course_is_public,
filesId, filesId,
child, child,
sort sort,
Addanexternallink,
Exterchainname
} = this.state; } = this.state;
let category_id= this.props.match.params.category_id; let category_id= this.props.match.params.category_id;
@ -781,7 +831,7 @@ class Fileslists extends Component{
loadtype={Loadtype} loadtype={Loadtype}
/>:""} />:""}
{ {
shixunmodal===true||Accessoryvisible===true||Settingtype===true?<style> shixunmodal===true||Accessoryvisible===true||Settingtype===true||Addanexternallink===true?<style>
{ {
` `
body { body {
@ -821,6 +871,22 @@ class Fileslists extends Component{
has_course_groups={this.state.has_course_groups} has_course_groups={this.state.has_course_groups}
attachmentId={this.state.coursesecondcategoryid} attachmentId={this.state.coursesecondcategoryid}
/>:""} />:""}
{/*添加外链*/}
{Addanexternallink&&Addanexternallink===true?<SendResources
{...this.props}
{...this.state}
modalname={Exterchainname}
visible={Addanexternallink}
discussMessageid={discussMessageid}
Cancelname={"取消"}
Savesname={"确认"}
Cancel={()=>this.sendResourcessls(2,false)}
categoryid={category_id}
setupdate={(ints,bool)=>this.sendResourcessls(ints,bool)}
has_course_groups={this.state.has_course_groups}
attachmentId={this.state.coursesecondcategoryid}
/>:""}
{/*设置资源*/} {/*设置资源*/}
{Settingtype&&Settingtype===true?<Selectsetting {Settingtype&&Settingtype===true?<Selectsetting
{...this.props} {...this.props}
@ -858,8 +924,10 @@ class Fileslists extends Component{
{this.props.isAdmin()?parseInt(this.props.match.params.main_id)!=parseInt(this.props.coursesids)?<WordsBtn style="blue" onClick={()=>this.editDir(name)} className={"mr30 font-16"}>目录重命名</WordsBtn>:"":""} {this.props.isAdmin()?parseInt(this.props.match.params.main_id)!=parseInt(this.props.coursesids)?<WordsBtn style="blue" onClick={()=>this.editDir(name)} className={"mr30 font-16"}>目录重命名</WordsBtn>:"":""}
{this.props.isAdmin()||this.props.isStudent() ? this.props.user&&this.props.user.main_site===true? <WordsBtn style="blue" className="mr30 font-16" onClick={()=>this.addResource()}>选用资源</WordsBtn>:"":""} {this.props.isAdmin()||this.props.isStudent() ? this.props.user&&this.props.user.main_site===true? <WordsBtn style="blue" className="mr30 font-16" onClick={()=>this.addResource()}>选用资源</WordsBtn>:"":""}
{this.props.isAdmin()||this.props.isStudent() ? <WordsBtn style="blue" className=" font-16" onClick={()=>this.sendResources()}>上传资源</WordsBtn>:""} {this.props.isAdmin()||this.props.isStudent() ? <WordsBtn style="blue" className="mr30 font-16" onClick={()=>this.sendResources()}>上传资源</WordsBtn>:""}
</React.Fragment> {this.props.isAdmin()||this.props.isStudent() ? <WordsBtn style="blue" className=" font-16" onClick={()=>this.sendResourcessls(1,true)}>添加外链</WordsBtn>:""}
</React.Fragment>
} }
secondRowLeft={ secondRowLeft={
@ -997,11 +1065,13 @@ class Fileslists extends Component{
{...this.props} {...this.props}
{...this.state} {...this.state}
discussMessage={item} discussMessage={item}
Updateresourcepage={()=>this.Updateresourcepage()}
isAdmin={this.props.isAdmin()} isAdmin={this.props.isAdmin()}
isStudent={this.props.isStudent()} isStudent={this.props.isStudent()}
isNotMember={this.props.isNotMember()} isNotMember={this.props.isNotMember()}
checkBox={this.props.isAdmin()?<Checkbox value={item.id} key={item.id}></Checkbox>:""} checkBox={this.props.isAdmin()?<Checkbox value={item.id} key={item.id}></Checkbox>:""}
Settingtypes={(id)=>this.Settingtypes(id)} Settingtypes={(id)=>this.Settingtypes(id)}
Settingtypess={(id)=>this.Settingtypess(id)}
coursesId={this.props.match.params.coursesId} coursesId={this.props.match.params.coursesId}
updatafiledfun={()=>this.updatafiled()} updatafiledfun={()=>this.updatafiled()}
index={index} index={index}

@ -0,0 +1,539 @@
import React,{ Component } from "react";
import { Modal,Checkbox,Upload,Button,Icon,message,DatePicker,Select,Tooltip,Radio,Input} from "antd";
import axios from 'axios';
import Modals from '../../modals/Modals';
import {getUploadActionUrl,handleDateString,appendFileSizeToUploadFileAll} from 'educoder';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import moment from 'moment';
const CheckboxGroup = Checkbox.Group;
const Option = Select.Option;
function range(start, end) {
const result = [];
for (let i = start; i < end; i++) {
result.push(i);
}
return result;
}
function disabledDateTime() {
return {
// disabledHours: () => range(0, 24).splice(4, 20),
disabledMinutes: () => range(1, 30).concat(range(31, 60)),
// disabledSeconds: () => [0, 60],
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
const dateFormat="YYYY-MM-DD HH:mm";
class sendResources extends Component{
constructor(props){
super(props);
this.state={
group_ids:[],
fileList:[],
Modalstype:false,
Modalstopval:"",
ModalCancel:"",
ModalSave:"",
fileListtype:false,
loadtype:false,
is_public:false,
datatime:undefined,
resourcesname:"",
resourceurl:"",
addonAfteronelens3:0,
// moment(new Date()).format('YYYY-MM-DD HH:mm:ss'),
course_group_publish_times:[
{
course_group_id : undefined,
publish_time :""
}],
course_groups:undefined,
course_groups_count:undefined,
Radiovalue:0,
Radiovaluetype:false,
resourceurlbool:false,
resourcesnamebool:false,
}
}
componentDidMount() {
}
//勾选实训
shixunhomeworkedit=(list)=>{
this.setState({
group_ids:list
})
}
// 附件相关 START
handleChange = (info) => {
console.log(info)
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
let fileList = info.fileList;
if (info.file.status != "removed") {
this.setState({
fileList: appendFileSizeToUploadFileAll(fileList),
fileListtype: true
});
} else {
this.setState({
fileList: appendFileSizeToUploadFileAll(fileList),
});
}
}
}
onAttachmentRemove = (file) => {
if(!file.percent || file.percent == 100){
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
axios.delete(url, {
})
.then((response) => {
if (response.data) {
const { status } = response.data;
if (status == 0) {
this.setState({
fileListtype:false,
fileList:[]
})
}
}
})
.catch(function (error) {
console.log(error);
});
this.setState({
fileListtype:false,
})
}else{
this.setState({
fileListtype:false,
fileList:[]
})
}
}
ModalCancelModalCancel=()=>{
this.setState({
Modalstype:false,
Modalstopval:"",
ModalSave:this.ModalCancelModalCancel,
loadtype:false
})
this.props.Cancel()
}
Saves=()=>{
let {resourcesname,resourceurl,description,is_public,datatime,Radiovalue} =this.state;
const reg = /^[\s\S]*.*[^\s][\s\S]*$/;
if (!reg.test(resourcesname)) {
this.setState({
resourcesnamebool:true
})
return;
}
if (!reg.test(resourceurl)) {
this.setState({
resourceurlbool:true
})
return;
}
if(this.state.Radiovalue===1){
if(datatime===undefined||datatime===null||datatime=== ""){
this.setState({
Radiovaluetype:true
})
return
}else{
this.setState({
Radiovaluetype:false
})
}
}
if(description===undefined){
}else if(description.length>100){
this.setState({
descriptiontype:true
})
return
}
if(this.props.Exterchainname==="资源设置"){
//设置
let coursesId=this.props.match.params.coursesId;
let attachmentId=this.props.attachmentId;
let url="/files/"+this.props.discussMessageid+".json";
axios.put(url,{
name:resourcesname,
link:resourceurl,
course_id:coursesId,
course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId,
is_public:is_public,
publish_time:Radiovalue===1?datatime===undefined? undefined:datatime:undefined,
description:description,
delay_publish:Radiovalue,
}).then((result)=>{
if(result.data.status===0){
this.ModalCancelModalCancel();
this.props.updataleftNavfun();
this.props.showNotification("设置资源成功");
this.props.setupdate(1,false)
}else{
this.props.showNotification(result.data.message);
}
})
}else{
let coursesId=this.props.match.params.coursesId;
let attachmentId=this.props.attachmentId;
let url="/files/upload.json";
axios.post(url,{
name:resourcesname,
link:resourceurl,
course_id:coursesId,
course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId,
is_public:is_public,
publish_time:Radiovalue===1?datatime===undefined? undefined:datatime:undefined,
description:description,
delay_publish:Radiovalue,
}).then((result)=>{
if(result.data.status===0){
this.ModalCancelModalCancel();
this.props.updataleftNavfun();
this.props.showNotification("上传资源成功");
this.props.setupdate(1,false)
}else{
this.props.showNotification(result.data.message);
}
})
}
}
settextarea=(e)=>{
this.setState({
description:e.target.value
})
}
onChangepublic=(e)=>{
this.setState({
is_public:e.target.checked
})
}
onChangeTimepublish= (date, dateString,key,type) => {
if(type===1){
this.setState({
datatime:handleDateString(dateString),
})
}else if(type===2){
let {course_group_publish_times}=this.state;
let newgroup_publish=course_group_publish_times;
for(var i=0; i<newgroup_publish.length; i++){
if(i===parseInt(key)){
newgroup_publish[i].publish_time=handleDateString(dateString);
}
}
this.setState({
course_group_publish_times:newgroup_publish,
})
}
}
RadioonChange=(e)=>{
if(e.target.value===0){
this.setState({
datatime:undefined
})
}
this.setState({
Radiovalue: e.target.value,
});
}
handleChanges=(e)=>{
let les=e.target.value.length;
if(e.target.value.length>=61){
}else{
this.setState({
resourcesname:e.target.value,
addonAfteronelens3:les,
resourcesnamebool:false,
})
}
}
handleChangess=(e)=>{
this.setState({
resourceurl:e.target.value,
resourceurlbool:false,
})
}
render(){
let { newfileListtype,descriptiontype,
is_public,
datatime,
resourcesname,
resourceurl,
addonAfteronelens3,
resourceurlbool,
resourcesnamebool,
}=this.state;
const uploadProps = {
width: 600,
// showUploadList:false,
action: `${getUploadActionUrl()}`,
onChange: this.handleChange,
onRemove: this.onAttachmentRemove,
beforeUpload: (file) => {
// console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
this.props.showNotification('文件大小必须小于150MB!');
}
return isLt150M;
},
};
const radioStyle = {
display: 'block',
height: '30px',
lineHeight: '30px',
};
return(
<div>
{/*提示*/}
<Modals
modalsType={this.state.Modalstype}
modalsTopval={this.state.Modalstopval}
modalCancel={this.state.ModalCancel}
modalSave={this.state.ModalSave}
loadtype= {this.state.loadtype}
/>
<Modal
keyboard={false}
className={"HomeworkModal"}
title={this.props.modalname}
visible={this.props.visible}
closable={false}
footer={null}
destroyOnClose={true}
>
<div className="task-popup-content">
<p className="task-popup-text-center font-16">
<span className={"color-blue underline"}> </span>
</p>
<style>{`
.uploadBtn.ant-btn {
border: none;
color: #4CACFF;
box-shadow: none;
background: transparent;
border:1px solid #4CACFF;
padding-left: 6px;
margin-right: 5px;
}
.ant-upload-list-item:hover .ant-upload-list-item-info{
padding: 0 12px 0 0px;
background-color:#fff;
}
.upload_1 .ant-upload-list {
width: 350px;
}
.ant-upload-select{
float: left;
}
.winth540{
width: 540px;
height: 34px;
}
.winth540 .ant-input-group-wrapper{
width: 86% !important;
}
.flexoo .ant-input{
width: 86% !important;
}
`}</style>
<p className={"winth540"} style={{
width: '100%',
display: "flex",
flexDirection:"row",
}}>
<span className="color-ooo fl mt6">资源名称</span>
<Input className="" placeholder="请输入资源名称最大限制60字符" value={resourcesname} onChange={this.handleChanges} addonAfter={String(addonAfteronelens3)+"/60"} maxLength={60} />
</p>
{
resourcesnamebool?
<p className=" color-red" style={{
marginLeft: "13%"
}}>请输入资源名称</p>
:
""
}
<p className={resourcesnamebool===true?"winth540 flexoo mt10":"winth540 flexoo mt16"} style={{
width: '100%',
display: "flex",
flexDirection:"row",
}}>
<span className="color-ooo fl mt6">链接地址</span>
<Input className="" placeholder="请输入外链url" value={resourceurl} onChange={this.handleChangess} />
</p>
{
resourceurlbool?
<p className=" color-red" style={{
marginLeft: "13%"
}}>请输入外链url</p>
:
""
}
<p className={this.state.fileListtype===true?"mt25":""}>
<style>{`
.ant-checkbox-wrapper{
margin-left:0px !important;
margin-top:10px;
}
`}</style>
{this.props.course_is_public===true?<div>
<span className={"color-ooo"}>公开</span><Checkbox checked={is_public} onChange={this.onChangepublic}>
<span className={"font-14 color-ooo"}>选中所有用户可见否则课堂成员可见</span>
</Checkbox>
</div>:""}
<style>{`
.Selectleft20{
margin-left: 20px !important;
width: 176px;
height: 40px;
}
#startimes .ant-calendar-picker-icon{
margin-top:-11px;
}
.resourcebox{
max-height:150px;
overflow: auto;
}
`}</style>
</p>
<div className={this.props.course_is_public===true?"mt10":""}>
<span className={"color-ooo fl mt6"}>发布设置</span>
<Radio.Group onChange={this.RadioonChange} value={this.state.Radiovalue} style={{'width': '460px'}}>
<Radio style={radioStyle} value={0}>
立即发布
</Radio>
<Tooltip placement="bottom" title={this.props.isStudent()===true?"不支持学生延迟发布":""}>
<Radio style={radioStyle} value={1} className={"fl"} disabled={this.props.isStudent()}>
<span className={"mr5"}>延期发布</span>
<DatePicker
dropdownClassName="hideDisable"
showTime={{ format: 'HH:mm' }}
locale={locale}
format={dateFormat}
placeholder="请选择发布时间"
id={"startime"}
showToday={false}
width={"210px"}
value={this.state.Radiovalue===1?datatime===undefined||datatime===""?undefined:moment(datatime, dateFormat):undefined}
onChange={(e,index)=>this.onChangeTimepublish(e,index,undefined,1)}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={this.state.Radiovalue===1?false:true}
/>
</Radio>
</Tooltip>
<span className={"fl mt5 color-grey-c"}>(按照设置的时间定时发布)</span>
</Radio.Group>
</div>
<div className="mt10" style={{
width: '100%',
display: "flex",
flexDirection:"row",
}}>
<span className="color-ooo fl mt6">资源描述</span>
{/*{course_group_publish_timestype===true?<p className={"color-red mt10"}>请填写完整</p>:""}*/}
<textarea placeholder="请在此输入资源描述最大限制100个字符" className={"mt10"} value={this.state.description} onInput={this.settextarea} style={{
width: '86%',
height:'120px',
border:'1px solid rgba(234,234,234,1)',
padding: '10px'
}}></textarea>
</div>
{descriptiontype===true?<p className={"color-red"}>请输入资源描述最大限制100个字符</p>:""}
{this.state.Radiovaluetype===true?<p className={"color-red"}>发布时间不能为空</p>:""}
<div className="clearfix mt30 edu-txt-center mb10">
<a className="task-btn color-white mr70" onClick={this.props.Cancel}>{this.props.Cancelname}</a>
<a className="task-btn task-btn-orange" onClick={()=>this.Saves()}>{this.props.Savesname}</a>
</div>
</div>
</Modal>
</div>
)
}
}
export default sendResources;
Loading…
Cancel
Save