diff --git a/public/react/src/common/course/WordsBtn.js b/public/react/src/common/course/WordsBtn.js index 85a85cfb6..68b278507 100644 --- a/public/react/src/common/course/WordsBtn.js +++ b/public/react/src/common/course/WordsBtn.js @@ -8,20 +8,20 @@ class WordsBtn extends Component { } render() { - let{to, href,targets, style2 }=this.props + let{to, href,targets, style2, style, className, ...others }=this.props return( { to==undefined&&targets==undefined ? {this.props.children}: targets!=undefined? {this.props.children} : {this.props.children} } diff --git a/public/react/src/modules/courses/ListPageIndex.js b/public/react/src/modules/courses/ListPageIndex.js index 730a1bdce..8c5652838 100644 --- a/public/react/src/modules/courses/ListPageIndex.js +++ b/public/react/src/modules/courses/ListPageIndex.js @@ -33,6 +33,12 @@ const StudentsList= Loadable({ loader: () => import('./members/studentsList'), loading: Loading, }); +//分班列表 +const CourseGroupList= Loadable({ + loader: () => import('./members/CourseGroupList'), + loading: Loading, +}); + const Eduinforms= Loadable({ loader: () => import('./gradinforms/Eduinforms.js'), loading: Loading, @@ -234,7 +240,7 @@ class ListPageIndex extends Component{ > () + (props) => () } > diff --git a/public/react/src/modules/courses/members/CourseGroupList.js b/public/react/src/modules/courses/members/CourseGroupList.js new file mode 100644 index 000000000..ec0b23fb3 --- /dev/null +++ b/public/react/src/modules/courses/members/CourseGroupList.js @@ -0,0 +1,238 @@ +// 分班列表 加入分班 + +import React, { useState, useEffect, useRef } from 'react' + +import { Input,Checkbox,Table, Pagination, Modal,Menu ,Spin, Tooltip , Divider, Popconfirm } from "antd"; +import ClipboardJS from 'clipboard' +import axios from 'axios' +import _ from 'lodash' + +import '../css/Courses.css' +import '../css/members.css' + +import CourseLayoutcomponent from '../common/CourseLayoutComponent' +import Titlesearchsection from '../common/titleSearch/TitleSearchSection' +import ColorCountText from '../common/titleSearch/ColorCountText' + +import { WordsBtn, trigger, on, off, getUrl, downloadFile , sortDirections, NoneData } from 'educoder' +import Modals from "../../modals/Modals"; + +import DownloadMessageysl from "../../modals/DownloadMessageysl"; +import CreateGroupByImportModal from './modal/CreateGroupByImportModal' +import ChangeRolePop from './ChangeRolePop' +import CourseGroupListTable from './CourseGroupListTable' + +import './studentsList.css' +/** + 角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生 +*/ +function CourseGroupList(props) { + const [searchValue, setSearchValue] = useState('') + const [isSpin, setIsSpin] = useState(true) + + const [DownloadType, setDownloadType] = useState() + const [DownloadMessageval, setDownloadMessageval] = useState() + + const [listRes, setListRes] = useState({}) + const createGroupModalEl = useRef(null); + + const courseId = props.match.params.coursesId + + useEffect(() => { + fetchAll() + on('updateNavSuccess', onOperationSuccess) + return () => { + off('updateNavSuccess', onOperationSuccess) + } + }, []) + function onOperationSuccess() { + fetchAll() + props.updataleftNavfun() + } + async function fetchAll() { + const url = `/courses/${courseId}/course_groups.json` + setIsSpin(true) + const response = await axios.get(url, { params: { + search: searchValue + }}); + console.log(response) + setIsSpin(false) + if (response) { + setListRes(response.data) + } + } + const onConfirm = async () => { + } + + function createGroupImportSuccess() { + + } + function addDir() { + trigger('groupAdd', props.coursesids) + } + function deleteDir() { + + } + function onPressEnter() { + fetchAll() + } + function onInputSearchChange(e) { + setSearchValue(e.target.value) + } + function Downloadcal() { + + } + const confirmysl = (url) => { + axios.get(url + 'export=true').then((response) => { + if(response === undefined){ + return + } + if(response.data.status&&response.data.status===-1){ + + }else if(response.data.status&&response.data.status===-2){ + if(response.data.message === "100"){ + // 已超出文件导出的上限数量(100 ),建议: + setDownloadType(true) + setDownloadMessageval(100) + }else { + //因附件资料超过500M + setDownloadType(true) + setDownloadMessageval(500) + } + }else { + props.slowDownload(url) + } + }).catch((error) => { + console.log(error) + }); + } + + const isAdmin = props.isAdmin(); + const isSuperAdmin = props.isSuperAdmin(); + const isParent = true; + // const searchValue = ''; + const isCourseEnd= props.isCourseEnd(); + + const course_group_id= ''; + + + const total_count = listRes.group_count; + const none_group_member_count = listRes.none_group_member_count; + const course_groups = listRes.course_groups + const current_group_id = listRes.current_group_id + + let exportUrl = `/courses/${courseId}/export_member_scores_excel.xlsx?`; //总成绩 + let exportUrltwo = `/courses/${courseId}/export_couser_info.xlsx?`; //课堂信息 + let exportUrlthree = `/courses/${courseId}/export_member_act_score.xlsx?`; //活跃度 + return ( + + + = 10} + searchPlaceholder={ '请输入分班名称进行搜索' } + firstRowRight={ + + { // pageType !== TYPE_STUDENTS && + isSuperAdmin && + {/* ref="createGroupByImportModal" */} + + {/* this.refs['createGroupByImportModal'].setVisible(true) */} + {createGroupModalEl.current.setVisible(true)}}>导入创建分班 + } + { + // pageType !== TYPE_STUDENTS && + !isCourseEnd && isAdmin && isParent && addDir()}>新建分班 } + {/* { + isAdmin && !isParent && course_group_id != 0 && deleteDir()}>删除分班 } */} + {/* { + isAdmin && !isParent && course_group_id != 0 && this.renameDir()}>分班重命名 } */} + + { isAdmin && +
  • + 导出 + +
  • + } +
    + } + secondRowLeft={ + total_count ? : '' + } + onPressEnter={onPressEnter} + >
    + +
    + 未分班: + {none_group_member_count}个学生 + + {props.history.push(`/courses/${courseId}/course_groups/0`)}}>查看 +
    + + + {course_groups && !!course_groups.length ? +
    + + + +
    : + } +
    +
    + ) +} +export default CourseGroupList \ No newline at end of file diff --git a/public/react/src/modules/courses/members/CourseGroupListTable.js b/public/react/src/modules/courses/members/CourseGroupListTable.js new file mode 100644 index 000000000..e26e951ce --- /dev/null +++ b/public/react/src/modules/courses/members/CourseGroupListTable.js @@ -0,0 +1,210 @@ +import React, { useState, useEffect } from 'react' + +import { Input,Checkbox,Table, Pagination, Modal,Menu ,Spin, Tooltip , Badge, Popconfirm } from "antd"; +import axios from 'axios' + +import { WordsBtn, trigger, on, off, getUrl, downloadFile , sortDirections } from 'educoder' +import ClipboardJS from 'clipboard' + +/** + 角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生 + course_members_count: 0 + id: 2441 + invite_code: "WUNX9K" + member_manager: "全部教师" + name: "e'e'e" +*/ + +const clipboardMap = {} +function CourseGroupListTable(props) { + const [serachValue, setSerachValue] = useState('') + + const courseId = props.match.params.coursesId + + useEffect(() => { + const course_groups = props.course_groups + if (!course_groups) { + return; + } + course_groups.forEach((record) => { + const id = record.id + debugger; + let _clipboard = new ClipboardJS(`.copyBtn_${id}`); + _clipboard.on('success', (e) => { + props.showNotification('复制成功') + }); + clipboardMap[id] = _clipboard + }) + return () => { + course_groups.forEach((record) => { + const id = record.id + + if (clipboardMap[id]) { + clipboardMap[id].destroy(); + clipboardMap[id] = null; + } + }) + } + }, [props.course_groups]) + function buildColumns() { + const columns=[{ + title: '序号', + dataIndex: 'id', + key: 'id', + align:'center', + width:"5%", + className:"color-grey-6", + render: (id, record, index) => { + return index + 1 + } + }, + { + title: '分班名称', + dataIndex: 'name', + key: 'name', + align:'center', + width:"25%", + className:"color-grey-6", + render: (name, record, index) => { + return 11 ? name : ''} onClick={() => onGoDetail(record)} style={''} + className="overflowHidden1" style2={{maxWidth: '180px', verticalAlign: 'bottom'}}> + {name} + } + }, + + { + title: '学生成员', + dataIndex: 'course_members_count', + key: 'course_members_count', + align:'center', + width:"8%", + className:"color-grey-6", + render: (course_members_count, record, index) => { + return course_members_count + } + } + ]; + if (!isNotMember) { + columns.push({ + title: '管理教师', + dataIndex: 'member_manager', + key: 'member_manager', + align:'center', + width:"27%", + className:"color-grey-6", + render: (member_manager, record, index) => { + return member_manager + } + }) + const aCol = (isAdmin ? { + title: '邀请码', + dataIndex: 'invite_code', + key: 'invite_code', + align:'center', + width:"10%", + className:"color-grey-6", + render: (invite_code, record, index) => { + return invite_code + } + } : { + title: '你当前所在分班', + dataIndex: 'group', + key: 'group', + align:'center', + width:"20%", + className:"color-grey-6", + render: (invite_code, record, index) => { + return props.current_group_id == record.id && + } + }) + columns.push( aCol ); + } + + columns.push({ + title: '操作', + dataIndex: 'setting', + key: 'setting', + align:'center', + width:"25%", + className:"color-grey-6", + render: (none, record, index) => { + return + {!isCourseEnd && isAdmin && onDelete(record)} style={'grey'}>删除分班} + {isAdmin && 复制邀请码 } + {isStudent && addToDir(record)} style={''}>加入分班} + onGoDetail(record)} style={''}>查看 + + } + }) + + return columns + } + const addToDir = async (record) => { + const courseId = props.match.params.coursesId + const url = `/courses/${courseId}/join_course_group.json` + const course_group_id = record.id + + const response = await axios.post(url, { + course_group_id + }) + if (response && response.data.status == 0) { + props.showNotification('加入成功') + props.updataleftNavfun() + props.onOperationSuccess && props.onOperationSuccess() + } + } + + function onDelete(record) { + props.confirm({ + content:
    +
    该分班的学生将被移动到“未分班”
    +
    是否确认删除?
    +
    , + onOk: () => { + // const cid = this.props.match.params.coursesId + + const url = `/course_groups/${record.id}.json` + axios.delete(url) + .then((response) => { + if (response.data.status == 0) { + props.showNotification('删除成功') + props.onOperationSuccess && props.onOperationSuccess() + // props.history.push(response.data.right_url) + } + }) + .catch(function (error) { + console.log(error); + }); + } + }) + } + function onGoDetail(record) { + props.history.push(`/courses/${courseId}/course_groups/${record.id}`) + } + const isAdmin = props.isAdmin(); + const isSuperAdmin = props.isSuperAdmin(); + const isStudent = props.isStudent() + const isNotMember = props.isNotMember() + + + const isParent = true; + const isCourseEnd= props.isCourseEnd(); + + const course_groups = props.course_groups + const columns = buildColumns() + return ( + + + {/* onChange={onTableChange} */} +
    + +
    + ) +} +export default CourseGroupListTable \ No newline at end of file diff --git a/public/react/src/modules/courses/members/studentsList.css b/public/react/src/modules/courses/members/studentsList.css index ebab316a0..797305629 100644 --- a/public/react/src/modules/courses/members/studentsList.css +++ b/public/react/src/modules/courses/members/studentsList.css @@ -1,3 +1,4 @@ -.stu_table .ant-table-thead > tr > th, .stu_table .ant-table-tbody > tr > td { +.stu_table .ant-table-thead > tr > th, .stu_table .ant-table-tbody > tr > td, +.courseGroupList .ant-table-thead > tr > th, .courseGroupList .ant-table-tbody > tr > td { padding: 14px 6px; } \ No newline at end of file diff --git a/public/react/src/modules/courses/members/studentsList.js b/public/react/src/modules/courses/members/studentsList.js index 3a5a55b71..9acc4c0bf 100644 --- a/public/react/src/modules/courses/members/studentsList.js +++ b/public/react/src/modules/courses/members/studentsList.js @@ -833,7 +833,7 @@ class studentsList extends Component{
    - {students && students.length && + {students && !!students.length &&
    }