This commit is contained in:
commit
6907b6de7e
|
@ -6,6 +6,11 @@ import Test from '../../pages/Home/img/test.jpg'
|
||||||
|
|
||||||
// 批改
|
// 批改
|
||||||
function Marking(){
|
function Marking(){
|
||||||
|
const teacher_ID=localStorage.getItem('islogin')
|
||||||
|
if(teacher_ID==null){
|
||||||
|
alert('登录过期,请重新登录')
|
||||||
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
|
}
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className='body-right-mark'>
|
<div className='body-right-mark'>
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import './trainmanage.css'
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
// import React, { useEffect, useState } from 'react';
|
||||||
|
// import axios from 'axios';
|
||||||
|
|
||||||
|
|
||||||
|
function TrainManage(){
|
||||||
|
const teacher_ID=localStorage.getItem('islogin')
|
||||||
|
if(teacher_ID==null){
|
||||||
|
alert('登录过期,请重新登录')
|
||||||
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<div className='body-trainmanage'>
|
||||||
|
<p>已批改试卷</p>
|
||||||
|
<div className='line'></div>
|
||||||
|
<div className='train-list-trainmanage'>
|
||||||
|
<ul className='ul1-trainmanage'>
|
||||||
|
<li>
|
||||||
|
<span>111</span>
|
||||||
|
<p>关闭时间:2024-11-5</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span>333</span>
|
||||||
|
<p>关闭时间:2024-11-5</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul className='ul2-trainmanage'>
|
||||||
|
<li>
|
||||||
|
<span>222</span>
|
||||||
|
<p>关闭时间:2024-11-5</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span>444</span>
|
||||||
|
<p>关闭时间:2024-11-5</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<Link to='/teacher/sendtest' className='sendtestpage'>前往发布试卷</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TrainManage
|
|
@ -5,29 +5,13 @@ import axios from 'axios';
|
||||||
// import { useParams } from 'react-router-dom';
|
// import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
function TeacherPage() {
|
function TeacherPage() {
|
||||||
const [isChecked, setisChecked] = useState(false);
|
|
||||||
const [teacher_ID, setTeacher_ID] = useState(localStorage.getItem('islogin'));
|
const teacher_ID = localStorage.getItem('islogin')
|
||||||
|
if(teacher_ID==null){
|
||||||
|
alert('登录过期,请重新登录')
|
||||||
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
|
}
|
||||||
const [classData, setClassData] = useState({});
|
const [classData, setClassData] = useState({});
|
||||||
|
|
||||||
//判断是否登录
|
|
||||||
// useEffect(() => {
|
|
||||||
// if (!isChecked) {
|
|
||||||
// const is_login = localStorage.getItem('islogin');
|
|
||||||
// if (!is_login) {
|
|
||||||
// alert('未登录');
|
|
||||||
// window.location.href = 'http://36.138.114.105:30294/signin';
|
|
||||||
// } else {
|
|
||||||
// if(teacher_ID.length===8){
|
|
||||||
// window.location.href='http://36.138.114.105:30294'
|
|
||||||
// return
|
|
||||||
// }else{
|
|
||||||
// console.log(teacher_ID);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
//可以删
|
|
||||||
const log=(key)=>{
|
const log=(key)=>{
|
||||||
console.log(key);
|
console.log(key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,187 +0,0 @@
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import axios from 'axios';
|
|
||||||
// import { useParams } from 'react-router-dom';
|
|
||||||
import './ManageTest.css'
|
|
||||||
|
|
||||||
function TeacherPage() {
|
|
||||||
|
|
||||||
const teacher_ID = localStorage.getItem('islogin')
|
|
||||||
const [classData, setClassData] = useState({});
|
|
||||||
const [classtest,setClassTest]=useState()
|
|
||||||
const [defaultclass,setDefaultClass]=useState()
|
|
||||||
const [selectedValue, setSelectedValue] = useState('');
|
|
||||||
const [isChecked,setisChecked]=useState(false)
|
|
||||||
const [isDetailedBoxVisible, setIsDetailedBoxVisible] = useState(false);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const select_class = async () => {
|
|
||||||
try {
|
|
||||||
const select_class_src = await axios.post('/api/teacher/select_class',{
|
|
||||||
teacher_ID
|
|
||||||
});
|
|
||||||
setClassData(select_class_src.data['Class']);
|
|
||||||
setDefaultClass(select_class_src.data['default'])
|
|
||||||
const list = Object.keys(select_class_src.data['Class'])
|
|
||||||
setSelectedValue(list[0])
|
|
||||||
setisChecked(true)
|
|
||||||
} catch (error) {
|
|
||||||
alert('获取所有班级出错')
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if(!isChecked){
|
|
||||||
select_class();
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
//选中当前班级
|
|
||||||
|
|
||||||
const handleChange = (event) => {
|
|
||||||
setSelectedValue(event.target.value);
|
|
||||||
};
|
|
||||||
useEffect(()=>{
|
|
||||||
const change_class = async () => {
|
|
||||||
try {
|
|
||||||
const change_class_src = await axios.post('/api/teacher/change_class',{
|
|
||||||
teacher_ID,
|
|
||||||
selectedValue,
|
|
||||||
testID
|
|
||||||
});
|
|
||||||
setDefaultClass(change_class_src.data['default'])
|
|
||||||
} catch (error) {
|
|
||||||
alert('获取默认班级出错')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(isChecked){
|
|
||||||
change_class()
|
|
||||||
}
|
|
||||||
// 更换列表
|
|
||||||
},[selectedValue])
|
|
||||||
|
|
||||||
const [testID,settestID]=useState('')
|
|
||||||
|
|
||||||
const click=()=>{
|
|
||||||
console.log(isDetailedBoxVisible);
|
|
||||||
console.log(detaileddata);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 点击记录时的详细信息
|
|
||||||
const [detaileddata,setdetaileddata]=useState('')
|
|
||||||
|
|
||||||
const click_detailed= async()=>{
|
|
||||||
//获取详细信息
|
|
||||||
try{
|
|
||||||
const detaileddata_src=await axios.post('/api/teacher/detaileddata',{
|
|
||||||
testID,
|
|
||||||
selectedValue,
|
|
||||||
teacher_ID
|
|
||||||
})
|
|
||||||
setdetaileddata(detaileddata_src.data['data'])
|
|
||||||
}catch(error){
|
|
||||||
alert('获取小框信息出错')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
click_detailed()
|
|
||||||
|
|
||||||
},[testID])
|
|
||||||
|
|
||||||
|
|
||||||
const return_detailed=()=>{
|
|
||||||
setIsDetailedBoxVisible(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取随机进退步
|
|
||||||
const [numbers] = useState([...Array(61).keys()].map(num => num - 30));
|
|
||||||
const getRandomNumber = () => {
|
|
||||||
const randomIndex = Math.floor(Math.random() * numbers.length);
|
|
||||||
return numbers[randomIndex];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='body-right-manage'>
|
|
||||||
{/* 详细信息 */}
|
|
||||||
{isDetailedBoxVisible && <div id='detailed'>
|
|
||||||
<p id='splitter'>试卷ID{testID}<span id='return' onClick={return_detailed}>X</span></p>
|
|
||||||
<p style={{display:'flex'}}>
|
|
||||||
<span style={{ flex: 1}}>详情</span>
|
|
||||||
<span style={{ flex: 1}}>分数</span>
|
|
||||||
<span style={{ flex: 1}}>与上次相比</span>
|
|
||||||
<span style={{ flex: 1}}>总评</span>
|
|
||||||
</p>
|
|
||||||
<div>
|
|
||||||
<p>--------------------------------------------------------------------------------------</p>
|
|
||||||
{detaileddata&&<table>
|
|
||||||
<tbody>
|
|
||||||
<div id='detailed_box'>
|
|
||||||
{Object.keys(detaileddata).map((key)=>(
|
|
||||||
<tr style={{display:'flex'}} id='detailed_box_tr'>
|
|
||||||
<td style={{ flex: 1 }}>{detaileddata[key][6]}</td>
|
|
||||||
<td style={{ flex: 1 }}>{detaileddata[key][5] ? detaileddata[key][5] : "未完成"}</td>
|
|
||||||
<td style={{ flex: 1 }}>{detaileddata[key][5] ? `${getRandomNumber()}%` : "未完成"}</td>
|
|
||||||
<td style={{ flex: 1 }}>{detaileddata[key][5] && parseInt(detaileddata[key][5]) >= 60 ? "及格" : (detaileddata[key][5] ? "不及格" : "未完成")}</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</tbody>
|
|
||||||
</table>}
|
|
||||||
</div>
|
|
||||||
</div>}
|
|
||||||
{/* 总体信息 */}
|
|
||||||
<div id='view_history' style={{display:'block'}}>
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr id='view_history_nav' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
||||||
<td style={{ flex: 1 }}>试卷ID</td>
|
|
||||||
<td style={{ flex: 1 }}>发布时间</td>
|
|
||||||
<td style={{ flex: 1 }}>截止时间</td>
|
|
||||||
<td style={{ flex: 1 }}>提交人数</td>
|
|
||||||
<td style={{ flex: 1 }}>平均分</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div id='class_list'>
|
|
||||||
<select name="class_id" onChange={handleChange}>
|
|
||||||
{Object.keys(classData).map((key)=>(
|
|
||||||
<option key={key} value={key}>{key}</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div id='class_portrait'>
|
|
||||||
{/* 班级画像 */}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div id='view_history_box'>
|
|
||||||
{ defaultclass &&<table id='view_history_table'>
|
|
||||||
<tbody>
|
|
||||||
{Object.keys(defaultclass).map((key)=>(
|
|
||||||
<tr className='view_history_content' style={{ display: 'flex', justifyContent: 'space-between' }} key={key} onClick={()=>{
|
|
||||||
settestID(key)
|
|
||||||
setIsDetailedBoxVisible(true)
|
|
||||||
}}>
|
|
||||||
<td style={{ flex: 1 }}>{key}</td>
|
|
||||||
<td style={{ flex: 1 }}>{defaultclass[key][0][0].slice(0, 10)}</td>
|
|
||||||
<td style={{ flex: 1 }}>{defaultclass[key][0][1].slice(0, 10)}</td>
|
|
||||||
<td style={{ flex: 1 }}>{defaultclass[key][2]}人</td>
|
|
||||||
<td style={{ flex: 1 }}>{defaultclass[key][1]}</td>
|
|
||||||
</tr>
|
|
||||||
)).reverse()}
|
|
||||||
</tbody>
|
|
||||||
</table>}
|
|
||||||
</div>
|
|
||||||
<div id='body_bottom_right'>
|
|
||||||
<Link to="/teacher/sendtest"><button id='sendtest_btn'>前往发布新的考试➡</button></Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button onClick={click}>测试</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TeacherPage;
|
|
|
@ -1,279 +0,0 @@
|
||||||
import { useParams } from 'react-router-dom';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import './SendTest.css'
|
|
||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
function SendTest(){
|
|
||||||
// const { key } = useParams();
|
|
||||||
const teacher_ID=localStorage.getItem('islogin')
|
|
||||||
//获取题目
|
|
||||||
const [ChoiceQuestion,SetChoiceQuestion]=useState()
|
|
||||||
const [Completion,SetCompletion]=useState()
|
|
||||||
const [Judge,SetJudge]=useState()
|
|
||||||
|
|
||||||
const subject = async ()=>{
|
|
||||||
try{
|
|
||||||
const subject_src=await axios.post('/api/teacher/return_question',{
|
|
||||||
teacher_ID})
|
|
||||||
SetChoiceQuestion(subject_src.data['选择'])
|
|
||||||
SetCompletion(subject_src.data['填空'])
|
|
||||||
SetJudge(subject_src.data['判断'])
|
|
||||||
}catch(error){
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
useEffect(()=>{
|
|
||||||
subject()
|
|
||||||
},[])
|
|
||||||
//当选择题目时,自动将题目ID填入题目集当中
|
|
||||||
const [ChoiceQuestionSet,SetChoiceQuestionSet]=useState([])
|
|
||||||
const [CompletionQuestionSet,SetCompletionQuestionSet]=useState([])
|
|
||||||
const [JudgeQuestionSet,SetJudgeQuestionSet]=useState([])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//下一步的操作
|
|
||||||
const body=document.getElementById('body')
|
|
||||||
const background=document.getElementById('background')
|
|
||||||
const send_box=document.getElementById('send_box')
|
|
||||||
const [ClassData,SetClassData]=useState([])
|
|
||||||
|
|
||||||
const click_1= async()=>{
|
|
||||||
try {
|
|
||||||
const select_class_src = await axios.post('/api/teacher/select_class', {
|
|
||||||
teacher_ID
|
|
||||||
});
|
|
||||||
background.style.display='block'
|
|
||||||
body.style.display='none'
|
|
||||||
send_box.display='none'
|
|
||||||
SetClassData(select_class_src.data);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//下下一步操作
|
|
||||||
const click_2=()=>{
|
|
||||||
background.style.display='none'
|
|
||||||
body.style.display='none'
|
|
||||||
send_box.style.display='block'
|
|
||||||
}
|
|
||||||
|
|
||||||
//上一步的操作
|
|
||||||
const last_1=()=>{
|
|
||||||
background.style.display='none'
|
|
||||||
body.style.display='block'
|
|
||||||
send_box.display='none'
|
|
||||||
}
|
|
||||||
//上上一步操作
|
|
||||||
const last_2=()=>{
|
|
||||||
background.style.display='block'
|
|
||||||
body.style.display='none'
|
|
||||||
send_box.style.display='none'
|
|
||||||
}
|
|
||||||
|
|
||||||
//选中班级的状态变化
|
|
||||||
const [selectedItems, setSelectedItems] = useState([]);
|
|
||||||
|
|
||||||
const click_div = (key) => {
|
|
||||||
if (selectedItems.includes(key)) {
|
|
||||||
setSelectedItems(prevItems => prevItems.filter(item => item !== key));
|
|
||||||
} else {
|
|
||||||
setSelectedItems(prevItems => [...prevItems, key]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const getClassNames = (key) => {
|
|
||||||
if (selectedItems.includes(key)) {
|
|
||||||
return 'class_div selected';
|
|
||||||
} else {
|
|
||||||
return 'class_div';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//创建数组,00~59
|
|
||||||
const min_list=[]
|
|
||||||
for (let i=0;i<=59;i++){
|
|
||||||
min_list.push(i)
|
|
||||||
}
|
|
||||||
//0~12
|
|
||||||
const hour_list=[]
|
|
||||||
for (let i=0;i<=12;i++){
|
|
||||||
hour_list.push(i)
|
|
||||||
}
|
|
||||||
//获取小时下拉框的值
|
|
||||||
const [HourValue, SetHourValue] = useState('');
|
|
||||||
const gethourvalue=(event)=>{
|
|
||||||
SetHourValue(event.target.value)
|
|
||||||
}
|
|
||||||
//获取分钟下拉框的值
|
|
||||||
const [MinValue,SetMinValue]=useState('')
|
|
||||||
const getminvalue=(event)=>{
|
|
||||||
SetMinValue(event.target.value)
|
|
||||||
}
|
|
||||||
//获取截止时间
|
|
||||||
const [StopTime,SetStopTime]=useState('')
|
|
||||||
const getstoptime=(event)=>{
|
|
||||||
SetStopTime(event.target.value)
|
|
||||||
}
|
|
||||||
// 发布按钮
|
|
||||||
const release= async()=>{
|
|
||||||
try{
|
|
||||||
const release_src=await axios.post('/api/teacher/accept_test',{
|
|
||||||
teacher_ID,
|
|
||||||
ChoiceQuestionSet,//选择题
|
|
||||||
CompletionQuestionSet,//填空题
|
|
||||||
JudgeQuestionSet,//判断题
|
|
||||||
selectedItems,//选择发布班级,为列表
|
|
||||||
HourValue,//小时
|
|
||||||
MinValue,//分钟
|
|
||||||
StopTime,//停止时间?天
|
|
||||||
}
|
|
||||||
)
|
|
||||||
alert('发布成功')
|
|
||||||
window.location.href='http://36.138.114.105:30294/teacher/managetest'
|
|
||||||
}catch{
|
|
||||||
alert('发布失败')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return(
|
|
||||||
<div id='big_body'>
|
|
||||||
<div id='background' style={{display:'none'}}>
|
|
||||||
<p style={{marginLeft:'30px'}}>请选择发布班级</p>
|
|
||||||
{ ClassData &&<ul style={{marginTop:'70px'}} id='class_ul'>
|
|
||||||
{Object.keys(ClassData).map((key)=>(
|
|
||||||
<li key={key}>
|
|
||||||
<div className={getClassNames(key)} onClick={() => click_div(key)}>
|
|
||||||
{key}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>}
|
|
||||||
<button style={{marginLeft:'110px'}} onClick={last_1}>上一步</button>
|
|
||||||
<button style={{marginLeft:'80px'}} onClick={click_2}>下一步</button>
|
|
||||||
</div>
|
|
||||||
<div id='send_box' style={{display:'none'}}>
|
|
||||||
<p>请填写考试时间</p>
|
|
||||||
<select name="" id="" alue={HourValue} onChange={gethourvalue}>
|
|
||||||
{Object.keys(hour_list).map((num)=>(
|
|
||||||
<option value={num} key={num}>{num}</option>
|
|
||||||
))}
|
|
||||||
</select>小时
|
|
||||||
|
|
||||||
<select name="" id="" alue={MinValue} onChange={getminvalue}>
|
|
||||||
{min_list.map((num)=>(
|
|
||||||
<option value={num} key={num}>{num}</option>
|
|
||||||
))}
|
|
||||||
</select>分钟
|
|
||||||
<p>请填写截至时间</p>
|
|
||||||
<input type="text" maxLength={10} style={{width:'30px'}} value={StopTime} onChange={getstoptime} />天后
|
|
||||||
<button onClick={last_2}>上一步</button>
|
|
||||||
<button onClick={release}>发布</button>
|
|
||||||
</div>
|
|
||||||
<div id='body' >
|
|
||||||
<div id='body_top' style={{display:'flex'}}>
|
|
||||||
<div id='body_left'>
|
|
||||||
<input type="checkbox" id='choice'/><span>选择题</span><br />
|
|
||||||
<input type="checkbox" id='fill'/><span>填空</span><br />
|
|
||||||
<input type="checkbox" id='judge'/><span>判断</span><br />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id='body_right'>
|
|
||||||
<div id='choice_box'>
|
|
||||||
<span style={{color:'red'}}>选择题</span>
|
|
||||||
{ChoiceQuestion && <table>
|
|
||||||
<thead>
|
|
||||||
{Object.keys(ChoiceQuestion).map((key)=>(
|
|
||||||
<tr className='line' key={key}>
|
|
||||||
<td className='line'>
|
|
||||||
<p>问题:{ChoiceQuestion[key][1]}</p>
|
|
||||||
<p className='choice_answer'>
|
|
||||||
<span>A:{ChoiceQuestion[key][2]}</span>
|
|
||||||
<span>B:{ChoiceQuestion[key][3]}</span>
|
|
||||||
<span>C:{ChoiceQuestion[key][4]}</span>
|
|
||||||
<span>D:{ChoiceQuestion[key][5]}</span>
|
|
||||||
</p>
|
|
||||||
{/* 获取题目ID */}
|
|
||||||
<input type="checkbox" className='check_box' onClick={(event)=>{
|
|
||||||
if (event.target.checked) {
|
|
||||||
//在选择题目集中添加选择题的ID
|
|
||||||
SetChoiceQuestionSet(items=>([
|
|
||||||
...items,
|
|
||||||
ChoiceQuestion[key][7]
|
|
||||||
]))
|
|
||||||
}else{
|
|
||||||
SetChoiceQuestionSet((items)=>
|
|
||||||
items.filter((item)=>item!==ChoiceQuestion[key][7])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}} /><span>是否选择</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</thead>
|
|
||||||
</table>}
|
|
||||||
</div>
|
|
||||||
<div id='fill_box'>
|
|
||||||
<span style={{color:'red'}}>填空题:</span>
|
|
||||||
{ Completion &&<table>
|
|
||||||
<thead>
|
|
||||||
{Object.keys(Completion).map((key)=>(
|
|
||||||
<tr key={key}>
|
|
||||||
<td className='line'>
|
|
||||||
<p>问题:{Completion[key][1]}<input type='text' /></p>
|
|
||||||
<input type="checkbox" className='check_box' onClick={(event)=>{
|
|
||||||
if(event.target.checked){
|
|
||||||
SetCompletionQuestionSet(items=>([
|
|
||||||
...items,
|
|
||||||
Completion[key][3]
|
|
||||||
]))
|
|
||||||
}else{
|
|
||||||
SetCompletionQuestionSet((items)=>
|
|
||||||
items.filter((item)=>item!==Completion[key][3]))
|
|
||||||
}
|
|
||||||
}}/><span>是否选择</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</thead>
|
|
||||||
</table>}
|
|
||||||
</div>
|
|
||||||
<div id='judge_box'>
|
|
||||||
<span style={{color:'red'}}>判断题:</span>
|
|
||||||
{ Judge &&<table>
|
|
||||||
<thead>
|
|
||||||
{Object.keys(Judge).map((key)=>(
|
|
||||||
<tr key={key}>
|
|
||||||
<td className='line'>
|
|
||||||
<p>问题:{Judge[key][1]}</p>
|
|
||||||
<input type="checkbox" className='check_box' onClick={(event)=>{
|
|
||||||
if(event.target.checked){
|
|
||||||
SetJudgeQuestionSet(items=>([
|
|
||||||
...items,
|
|
||||||
Judge[key][3]
|
|
||||||
]))
|
|
||||||
}else{
|
|
||||||
SetJudgeQuestionSet((items)=>
|
|
||||||
items.filter((item)=>item!==Judge[key][3]))
|
|
||||||
}
|
|
||||||
}}/><span>是否选择</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
|
|
||||||
</thead>
|
|
||||||
</table>}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id='body_btm'>
|
|
||||||
<button id='next' onClick={click_1}>下一步</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SendTest
|
|
|
@ -1,311 +0,0 @@
|
||||||
import React,{ useState ,useEffect} from 'react';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import './SendTrain.css'
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
function SendTrain(){
|
|
||||||
const teacher_ID=localStorage.getItem('islogin')
|
|
||||||
//获取所有基础题的所有题目
|
|
||||||
const [Trainquestion,SetTrainquestion]=useState()
|
|
||||||
//章节内容
|
|
||||||
const [isTrain,setisTrain]=useState(false)
|
|
||||||
//得到题目
|
|
||||||
const [TrainChoice,setTrainChoice]=useState([])
|
|
||||||
const [TrainCompletion,setTrainCompletion]=useState([])
|
|
||||||
const [TrainJudge,setTrainJudge]=useState([])
|
|
||||||
//获取实训
|
|
||||||
const [Train,setTrain]=useState([])
|
|
||||||
//得到班级
|
|
||||||
const [ClassData,SetClassData]=useState([])
|
|
||||||
|
|
||||||
const Train_question_func=async()=>{
|
|
||||||
try{
|
|
||||||
const Train_question_src=await axios.post('/api/teacher/fetch_train_question')
|
|
||||||
SetTrainquestion(Train_question_src.data)
|
|
||||||
}catch{
|
|
||||||
alert('Train_question_func出错')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const SeleactClass= async()=>{
|
|
||||||
try {
|
|
||||||
const select_class_src = await axios.post('/api/teacher/select_class', {
|
|
||||||
teacher_ID
|
|
||||||
});
|
|
||||||
SetClassData(select_class_src.data['Class']);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
Train_question_func()
|
|
||||||
SeleactClass()
|
|
||||||
},[])
|
|
||||||
|
|
||||||
//选中班级的状态变化
|
|
||||||
const [selectedItems, setSelectedItems] = useState([]);
|
|
||||||
|
|
||||||
const click_div = (key) => {
|
|
||||||
if (selectedItems.includes(key)) {
|
|
||||||
setSelectedItems(prevItems => prevItems.filter(item => item !== key));
|
|
||||||
} else {
|
|
||||||
setSelectedItems(prevItems => [...prevItems, key]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const getClassNames = (key) => {
|
|
||||||
if (selectedItems.includes(key)) {
|
|
||||||
return 'Train_class_div Trainselected';
|
|
||||||
} else {
|
|
||||||
return 'Train_class_div';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//发送题目
|
|
||||||
const SendTrainTest=async ()=>{
|
|
||||||
try{
|
|
||||||
const SendTrainSrc=await axios.post('/api/teacher/SendTrainTest',{
|
|
||||||
TrainChoice,
|
|
||||||
TrainCompletion,
|
|
||||||
TrainJudge,
|
|
||||||
HourValue,
|
|
||||||
MinValue,
|
|
||||||
StopTime,
|
|
||||||
selectedItems,
|
|
||||||
Train,
|
|
||||||
teacher_ID
|
|
||||||
})
|
|
||||||
alert('发布成功')
|
|
||||||
}catch{
|
|
||||||
alert('SendTrainTest出错')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const SendTrainBtn=()=>{
|
|
||||||
if(selectedItems.length>0 && (HourValue || MinValue)&&StopTime){
|
|
||||||
SendTrainTest()
|
|
||||||
}else{
|
|
||||||
alert('发布信息未完全')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//切换实训题
|
|
||||||
const clickTrain=()=>{
|
|
||||||
SetTrainquestion(null)
|
|
||||||
setisTrain(true)
|
|
||||||
}
|
|
||||||
const clickQuestion=()=>{
|
|
||||||
Train_question_func()
|
|
||||||
setisTrain(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
//创建数组,00~59
|
|
||||||
const min_list=[]
|
|
||||||
for (let i=0;i<=59;i++){
|
|
||||||
min_list.push(i)
|
|
||||||
}
|
|
||||||
//0~12
|
|
||||||
const hour_list=[]
|
|
||||||
for (let i=0;i<=12;i++){
|
|
||||||
hour_list.push(i)
|
|
||||||
}
|
|
||||||
//获取小时下拉框的值
|
|
||||||
const [HourValue, SetHourValue] = useState('');
|
|
||||||
const gethourvalue=(event)=>{
|
|
||||||
SetHourValue(event.target.value)
|
|
||||||
}
|
|
||||||
//获取分钟下拉框的值
|
|
||||||
const [MinValue,SetMinValue]=useState('')
|
|
||||||
const getminvalue=(event)=>{
|
|
||||||
SetMinValue(event.target.value)
|
|
||||||
}
|
|
||||||
//获取截止时间
|
|
||||||
const [StopTime,SetStopTime]=useState('')
|
|
||||||
const getstoptime=(event)=>{
|
|
||||||
SetStopTime(event.target.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return(
|
|
||||||
<div className='SendTrain_body'>
|
|
||||||
<div className='SendTrain_body_left'>
|
|
||||||
<ul className='SendTrain_body_left_ul'>
|
|
||||||
<li><div className='SendTrain_body_left_ul_div'>题目集</div></li>
|
|
||||||
<li>
|
|
||||||
<button onClick={clickQuestion}>基础题</button>
|
|
||||||
<ul style={{all:'unset'}}>
|
|
||||||
<li>第一章</li>
|
|
||||||
<li>第二章</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><button onClick={clickTrain}>实训题</button></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div className='SendTrain_body_right'>
|
|
||||||
<p>题目选择</p>
|
|
||||||
{/* 实训题 */}
|
|
||||||
{isTrain&&<div className='Train_div'>
|
|
||||||
<div id='Train_1'>
|
|
||||||
<div className='Train_1_left'>
|
|
||||||
设计达梦数据库课程实验实训,按照提供的达梦数据库安装文档,在系统中实现达梦数据库安装、连接及使用
|
|
||||||
</div>
|
|
||||||
<div className='Train_1_right'>
|
|
||||||
<span>
|
|
||||||
<input type="checkbox" value={'达梦数据库连接'} onClick={(event)=>{
|
|
||||||
if(event.target.checked){
|
|
||||||
setTrain(items=>([
|
|
||||||
...items,
|
|
||||||
event.target.value
|
|
||||||
]))
|
|
||||||
}else{
|
|
||||||
setTrain((items)=>
|
|
||||||
items.filter((item)=>item!==event.target.value))
|
|
||||||
}
|
|
||||||
}}/>是否选择
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id='Train_2'>
|
|
||||||
<div className='Train_2_left'>
|
|
||||||
设计和实现一个Web前端开发和DM8数据库后端结合的项目实训。
|
|
||||||
</div>
|
|
||||||
<div className='Train_2_right'>
|
|
||||||
<span>
|
|
||||||
<input type="checkbox" value={'前端与数据库结合'} onClick={(event)=>{
|
|
||||||
if(event.target.checked){
|
|
||||||
setTrain(items=>([
|
|
||||||
...items,
|
|
||||||
event.target.value
|
|
||||||
]))
|
|
||||||
}else{
|
|
||||||
setTrain((items)=>
|
|
||||||
items.filter((item)=>item!==event.target.value))
|
|
||||||
}
|
|
||||||
}}/>是否选择
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>}
|
|
||||||
|
|
||||||
{/* 基础题 */}
|
|
||||||
{Trainquestion &&<table>
|
|
||||||
<span className='title'>选择题</span>
|
|
||||||
<tbody>
|
|
||||||
{Object.keys(Trainquestion['choice']).map((key)=>(
|
|
||||||
<tr key={key}>
|
|
||||||
{/* 章节切换⬇ */}
|
|
||||||
<td className='Trainbox'>
|
|
||||||
<div>{Trainquestion['choice'][key][8]}</div>
|
|
||||||
<tr>
|
|
||||||
<td className='questiontitle'>问.{Trainquestion['choice'][key][1]}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<div className='Train_answer_box'>
|
|
||||||
<tr>A:{Trainquestion['choice'][key][2]}</tr>
|
|
||||||
<tr>B:{Trainquestion['choice'][key][3]}</tr>
|
|
||||||
<tr>C:{Trainquestion['choice'][key][4]}</tr>
|
|
||||||
<tr>D:{Trainquestion['choice'][key][5]}</tr>
|
|
||||||
</div>
|
|
||||||
</tr>
|
|
||||||
<input type="checkbox" className='check_box' onClick={(event)=>{
|
|
||||||
if (event.target.checked) {
|
|
||||||
//在选择题目集中添加选择题的ID
|
|
||||||
setTrainChoice(items=>([
|
|
||||||
...items,
|
|
||||||
Trainquestion['choice'][key][7]
|
|
||||||
]))
|
|
||||||
}else{
|
|
||||||
setTrainChoice((items)=>
|
|
||||||
items.filter((item)=>item!==Trainquestion['choice'][key][7])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}} /><span>是否选择</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
<span className='title'>填空题</span>
|
|
||||||
{Object.keys(Trainquestion['completion']).map((key)=>(
|
|
||||||
<tr key={key}>
|
|
||||||
<td className='Trainbox'>
|
|
||||||
{Trainquestion['completion'][key][4]}
|
|
||||||
<td className='questiontitle'>
|
|
||||||
问.{Trainquestion['completion'][key][1]}
|
|
||||||
</td>
|
|
||||||
<input type="checkbox" className='check_box' onClick={(event)=>{
|
|
||||||
if (event.target.checked) {
|
|
||||||
//在选择题目集中添加选择题的ID
|
|
||||||
setTrainCompletion(items=>([
|
|
||||||
...items,
|
|
||||||
Trainquestion['completion'][key][3]
|
|
||||||
]))
|
|
||||||
}else{
|
|
||||||
setTrainCompletion((items)=>
|
|
||||||
items.filter((item)=>item!==Trainquestion['completion'][key][3])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}} /><span>是否选择</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
<span className='title'>判断题</span>
|
|
||||||
{Object.keys(Trainquestion['judge']).map((key)=>(
|
|
||||||
<tr key={key}>
|
|
||||||
<td className='Trainbox'>
|
|
||||||
{Trainquestion['judge'][key][4]}
|
|
||||||
<td className='judgetitle'>问:{Trainquestion['judge'][key][1]}</td>
|
|
||||||
<input type="checkbox" className='check_box' onClick={(event)=>{
|
|
||||||
if (event.target.checked) {
|
|
||||||
setTrainJudge(items=>([
|
|
||||||
...items,
|
|
||||||
Trainquestion['judge'][key][3]
|
|
||||||
]))
|
|
||||||
}else{
|
|
||||||
setTrainJudge((items)=>
|
|
||||||
items.filter((item)=>item!==Trainquestion['judge'][key][3])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}} /><span>是否选择</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>}
|
|
||||||
<button onClick={SendTrainBtn} id='SendTrainBtn'>发布按钮</button>
|
|
||||||
</div>
|
|
||||||
{/* 右边的内容 */}
|
|
||||||
<div className='right_right'>
|
|
||||||
<div className='OptionBox'>
|
|
||||||
<div className='TrainSelectClass'>
|
|
||||||
<p className='TrainSelectClassP'>请选择发布班级</p>
|
|
||||||
{ ClassData &&<ul id='Train_class_ul'>
|
|
||||||
{Object.keys(ClassData).map((key)=>(
|
|
||||||
<li key={key}>
|
|
||||||
<div className={getClassNames(key)} onClick={() => click_div(key)}>
|
|
||||||
{key}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>}
|
|
||||||
</div>
|
|
||||||
<div className='TrainSelectTime'>
|
|
||||||
<p>请填写考试时间</p>
|
|
||||||
<select name="" id="" alue={HourValue} onChange={gethourvalue}>
|
|
||||||
{Object.keys(hour_list).map((num)=>(
|
|
||||||
<option value={num} key={num}>{num}</option>
|
|
||||||
))}
|
|
||||||
</select>小时
|
|
||||||
<select name="" id="" alue={MinValue} onChange={getminvalue}>
|
|
||||||
{min_list.map((num)=>(
|
|
||||||
<option value={num} key={num}>{num}</option>
|
|
||||||
))}
|
|
||||||
</select>分钟
|
|
||||||
<p>请填写截至时间</p>
|
|
||||||
<input type="text" maxLength={10} style={{width:'30px'}} value={StopTime} onChange={getstoptime} />天后
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SendTrain
|
|
|
@ -8,6 +8,14 @@ import './classid.css'
|
||||||
|
|
||||||
|
|
||||||
function TeacherPage() {
|
function TeacherPage() {
|
||||||
|
const click=()=>{
|
||||||
|
console.log(TestScore);
|
||||||
|
}
|
||||||
|
const teacher_ID=localStorage.getItem('islogin')
|
||||||
|
if(teacher_ID==null){
|
||||||
|
alert('登录过期,请重新登录')
|
||||||
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
|
}
|
||||||
const { key } = useParams();
|
const { key } = useParams();
|
||||||
const [isclick,setisclick]=useState(false)
|
const [isclick,setisclick]=useState(false)
|
||||||
//学生表格
|
//学生表格
|
||||||
|
@ -26,12 +34,6 @@ function TeacherPage() {
|
||||||
class_succeed();
|
class_succeed();
|
||||||
},[])
|
},[])
|
||||||
|
|
||||||
|
|
||||||
//学生画像
|
|
||||||
const student_fig_btn=()=>{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//柱形图
|
//柱形图
|
||||||
const [studentScores, setStudentScores] = useState([]);
|
const [studentScores, setStudentScores] = useState([]);
|
||||||
|
|
||||||
|
@ -45,6 +47,30 @@ function TeacherPage() {
|
||||||
});
|
});
|
||||||
}, [isclick]);
|
}, [isclick]);
|
||||||
|
|
||||||
|
function formatDate(dateString) {
|
||||||
|
// 将日期字符串转换为 Date 对象
|
||||||
|
const date = new Date(dateString);
|
||||||
|
// 获取年份、月份和日期
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const monthIndex = date.getMonth();
|
||||||
|
const day = date.getDate();
|
||||||
|
|
||||||
|
// 构建格式化后的日期字符串
|
||||||
|
const formattedDate = `${year}-${(monthIndex + 1).toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`;
|
||||||
|
return formattedDate;
|
||||||
|
}
|
||||||
|
const[TestScore,setTestScore]=useState()
|
||||||
|
const Find_details=async (ID)=>{
|
||||||
|
try{
|
||||||
|
const Find_details_Src=await axios.post('api/Find_details',{
|
||||||
|
ID
|
||||||
|
})
|
||||||
|
setTestScore(Find_details_Src.data)
|
||||||
|
}catch{
|
||||||
|
alert('Find_details出错')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className='body-right-classId'>
|
<div className='body-right-classId'>
|
||||||
<div id='body-right-bottom'>
|
<div id='body-right-bottom'>
|
||||||
|
@ -66,13 +92,13 @@ function TeacherPage() {
|
||||||
<tbody>
|
<tbody>
|
||||||
{Object.keys(classdata).map((item)=>(
|
{Object.keys(classdata).map((item)=>(
|
||||||
<tr key={item}>
|
<tr key={item}>
|
||||||
<td className='box-content'>班级</td>
|
<td className='box-content'>{classdata[item][2]}</td>
|
||||||
<td className='box-content'>{classdata[item][0]}</td>
|
<td className='box-content'>{classdata[item][0]}</td>
|
||||||
<td className='box-content'>{classdata[item][1]}</td>
|
<td className='box-content'>{classdata[item][1]}</td>
|
||||||
<td className='box-content'>{classdata[item][3]}</td>
|
<td className='box-content'>{classdata[item][3]}</td>
|
||||||
<td className='box-content'>{classdata[item][5]}</td>
|
<td className='box-content'>{classdata[item][5]}</td>
|
||||||
<td className='box-content'>出生日期</td>
|
<td className='box-content'>{formatDate(classdata[item][4])}</td>
|
||||||
<td className='box-content'><button onClick={student_fig_btn}>查看详情</button></td>
|
<td className='box-content'><button onClick={()=>Find_details(classdata[item][1])} style={{border:'none'}}>查看详情</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -83,6 +109,8 @@ function TeacherPage() {
|
||||||
<div className='body-test-score'>
|
<div className='body-test-score'>
|
||||||
<h3>成绩</h3>
|
<h3>成绩</h3>
|
||||||
<div className='body-test-score-bar'>
|
<div className='body-test-score-bar'>
|
||||||
|
<div className='studentName'>名字</div>
|
||||||
|
<button onClick={click}>测试</button>
|
||||||
<select>
|
<select>
|
||||||
<option value="">请选择科目</option>
|
<option value="">请选择科目</option>
|
||||||
<option value="china">语文</option>
|
<option value="china">语文</option>
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
}
|
}
|
||||||
#body-right-student-box td {
|
#body-right-student-box td {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid #ccc;
|
border-bottom: 1px solid #ccc;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.box-content {
|
.box-content {
|
||||||
|
@ -99,3 +99,10 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
}
|
}
|
||||||
|
.studentName{
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
width: 72px;
|
||||||
|
margin-left: 50px;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
function List_pods(){
|
||||||
|
return(
|
||||||
|
<div></div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import Computer from '../pages/Home/img/training.jpg';
|
||||||
function HeaderNav() {
|
function HeaderNav() {
|
||||||
|
|
||||||
const outlog=()=>{
|
const outlog=()=>{
|
||||||
localStorage.removeItem('islogin')
|
localStorage.clear()
|
||||||
// setisChecked(false)
|
// setisChecked(false)
|
||||||
alert('注销成功')
|
alert('注销成功')
|
||||||
window.location.href='http://36.138.114.105:30294/signin'
|
window.location.href='http://36.138.114.105:30294/signin'
|
||||||
|
|
|
@ -12,7 +12,7 @@ import Logo from '../pages/Home/img/logo.jpg'
|
||||||
function HeaderNavTeacher() {
|
function HeaderNavTeacher() {
|
||||||
|
|
||||||
const outlog=()=>{
|
const outlog=()=>{
|
||||||
localStorage.removeItem('islogin')
|
localStorage.clear()
|
||||||
// setisChecked(false)
|
// setisChecked(false)
|
||||||
alert('注销成功')
|
alert('注销成功')
|
||||||
window.location.href='http://36.138.114.105:30294/signin'
|
window.location.href='http://36.138.114.105:30294/signin'
|
||||||
|
|
|
@ -12,22 +12,11 @@ import { max, min } from 'lodash';
|
||||||
// 首页
|
// 首页
|
||||||
function Home(){
|
function Home(){
|
||||||
const [isChecked,setisChecked]=useState(false)
|
const [isChecked,setisChecked]=useState(false)
|
||||||
//判断是否登录
|
const student_ID=localStorage.getItem('islogin')
|
||||||
// useEffect(()=>{
|
if(student_ID==null){
|
||||||
// if (!isChecked){
|
alert('未登录,请先前往登录')
|
||||||
// const is_login=localStorage.getItem('islogin')
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
// if(!is_login){
|
}
|
||||||
// alert('未登录')
|
|
||||||
// window.location.href='http://localhost:3000/signin'
|
|
||||||
// }else{
|
|
||||||
// console.log(is_login);
|
|
||||||
// console.log('已登录');
|
|
||||||
// setisChecked(true)
|
|
||||||
// }
|
|
||||||
// //组件加载时自动调用login函数进行登录检测
|
|
||||||
// }
|
|
||||||
// },[]);//在组件加载时只调用一次
|
|
||||||
|
|
||||||
//课表数据
|
//课表数据
|
||||||
const [lesson, setLesson] = useState([]);
|
const [lesson, setLesson] = useState([]);
|
||||||
const [firstlesson, setfirstlesson] = useState([]);
|
const [firstlesson, setfirstlesson] = useState([]);
|
||||||
|
|
|
@ -9,6 +9,10 @@ import axios from 'axios';
|
||||||
// 首页 学习分析
|
// 首页 学习分析
|
||||||
function SubjectPage(){
|
function SubjectPage(){
|
||||||
const student_ID=localStorage.getItem('islogin')
|
const student_ID=localStorage.getItem('islogin')
|
||||||
|
if(student_ID==null){
|
||||||
|
alert('登录过期,请重新登录')
|
||||||
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
|
}
|
||||||
//点击li弹出图像窗口
|
//点击li弹出图像窗口
|
||||||
const [SubjectModal,setSubjectModal] = useState(false);
|
const [SubjectModal,setSubjectModal] = useState(false);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@ import { useEffect, useState } from 'react';
|
||||||
function Exam(){
|
function Exam(){
|
||||||
const {examId} = useParams()
|
const {examId} = useParams()
|
||||||
const student_ID=localStorage.getItem('islogin')
|
const student_ID=localStorage.getItem('islogin')
|
||||||
|
if(student_ID==null){
|
||||||
|
alert('登录过期,请重新登录')
|
||||||
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
|
}
|
||||||
// 初始化倒计时状态
|
// 初始化倒计时状态
|
||||||
const [countdown, setCountdown] = useState(0);
|
const [countdown, setCountdown] = useState(0);
|
||||||
const Countdown=true
|
const Countdown=true
|
||||||
|
|
|
@ -10,6 +10,10 @@ import moment from 'moment';
|
||||||
// 首页 题目集
|
// 首页 题目集
|
||||||
function SubjectPage(){
|
function SubjectPage(){
|
||||||
const student_ID=localStorage.getItem('islogin')
|
const student_ID=localStorage.getItem('islogin')
|
||||||
|
if(student_ID==null){
|
||||||
|
alert('登录过期,请重新登录')
|
||||||
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
|
}
|
||||||
const [testdata,settestdata]=useState('')
|
const [testdata,settestdata]=useState('')
|
||||||
const [time,settime]=useState(moment().format('YYYY-MM-DD HH:mm:ss'))
|
const [time,settime]=useState(moment().format('YYYY-MM-DD HH:mm:ss'))
|
||||||
const [result,setresult]=useState({})
|
const [result,setresult]=useState({})
|
||||||
|
|
|
@ -128,4 +128,14 @@
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.answered {
|
||||||
|
/* 例如,改变题目的背景色 */
|
||||||
|
width: 40px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: rgb(136, 243, 209);
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,21 @@ import axios from 'axios';
|
||||||
|
|
||||||
function Operation1() {
|
function Operation1() {
|
||||||
const click=()=>{
|
const click=()=>{
|
||||||
console.log(TrainData);
|
console.log(answeredJudge);
|
||||||
}
|
}
|
||||||
const clear=()=>{
|
const clear=()=>{
|
||||||
localStorage.clear('choice_answers');
|
localStorage.removeItem('choice_answers');
|
||||||
setchoice_answer({})
|
setchoice_answer({})
|
||||||
localStorage.clear('completion_answer')
|
localStorage.removeItem('completion_answer')
|
||||||
setcompletion_answer({})
|
setcompletion_answer({})
|
||||||
localStorage.clear('judge_answer')
|
localStorage.removeItem('judge_answer')
|
||||||
setjudge_answer({})
|
setjudge_answer({})
|
||||||
|
localStorage.removeItem('answeredChoice')
|
||||||
|
setAnsweredChoice([])
|
||||||
|
localStorage.removeItem('answeredComple')
|
||||||
|
setAnsweredComple([])
|
||||||
|
localStorage.removeItem('answeredJudge')
|
||||||
|
setAnsweredJudge([])
|
||||||
}
|
}
|
||||||
|
|
||||||
const { operateID } = useParams();
|
const { operateID } = useParams();
|
||||||
|
@ -33,28 +39,24 @@ function Operation1() {
|
||||||
})
|
})
|
||||||
const returnData=TrainDataSrc.data
|
const returnData=TrainDataSrc.data
|
||||||
setTrainData(returnData)
|
setTrainData(returnData)
|
||||||
settime(parseInt(returnData['operateID'][4]))
|
setCountdown(60*parseInt(returnData['operateID'][4]))
|
||||||
}catch{
|
}catch{
|
||||||
alert('TrainDataFunc出错')
|
alert('TrainDataFunc出错')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
TrainDataFunc()
|
TrainDataFunc()
|
||||||
},[])
|
},[])
|
||||||
//倒计时
|
//倒计时
|
||||||
const [countdown, setCountdown] = useState(0);
|
const [countdown, setCountdown] = useState();
|
||||||
const [time,settime]=useState()
|
const [time,settime]=useState()
|
||||||
// 倒计时初始化
|
// 倒计时初始化
|
||||||
useEffect(() => {
|
|
||||||
const examDuration = 60 * time; // 假设考试时长为1小时
|
|
||||||
setCountdown(examDuration);
|
|
||||||
}, [time]);
|
|
||||||
|
|
||||||
// 倒计时更新
|
// 倒计时更新
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let interval = setInterval(() => {
|
let interval = setInterval(() => {
|
||||||
if (countdown > 0) {
|
if (countdown != 0) {
|
||||||
setCountdown(countdown - 1);
|
setCountdown(countdown - 1);
|
||||||
} else {
|
} else {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
|
@ -79,6 +81,11 @@ function Operation1() {
|
||||||
const [choice_answer,setchoice_answer]=useState({})
|
const [choice_answer,setchoice_answer]=useState({})
|
||||||
const [completion_answer,setcompletion_answer]=useState({})
|
const [completion_answer,setcompletion_answer]=useState({})
|
||||||
const [judge_answer,setjudge_answer]=useState({})
|
const [judge_answer,setjudge_answer]=useState({})
|
||||||
|
//选中反馈
|
||||||
|
const [answeredChoice, setAnsweredChoice] = useState([]);
|
||||||
|
const [answeredComple, setAnsweredComple] = useState([]);
|
||||||
|
const [answeredJudge, setAnsweredJudge] = useState([]);
|
||||||
|
|
||||||
|
|
||||||
//给选择题添加事件监听器
|
//给选择题添加事件监听器
|
||||||
const handleOptionChange = (event) => {
|
const handleOptionChange = (event) => {
|
||||||
|
@ -86,6 +93,10 @@ function Operation1() {
|
||||||
const key = parseInt(event.target.name.replace('group', ''));
|
const key = parseInt(event.target.name.replace('group', ''));
|
||||||
const updatedChoiceAnswer = { ...choice_answer, [key]: selectedValue };
|
const updatedChoiceAnswer = { ...choice_answer, [key]: selectedValue };
|
||||||
setchoice_answer(updatedChoiceAnswer);
|
setchoice_answer(updatedChoiceAnswer);
|
||||||
|
// 更新已做题目的状态
|
||||||
|
if (!answeredChoice.includes(key)) {
|
||||||
|
setAnsweredChoice([...answeredChoice, key]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
//填空题
|
//填空题
|
||||||
const handleInputChange = (event) => {
|
const handleInputChange = (event) => {
|
||||||
|
@ -94,6 +105,10 @@ function Operation1() {
|
||||||
...completion_answer,
|
...completion_answer,
|
||||||
[name]: value
|
[name]: value
|
||||||
});
|
});
|
||||||
|
if (!answeredComple.includes(parseInt(name))) {
|
||||||
|
setAnsweredComple([...answeredComple, parseInt(name)]);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//判断题
|
//判断题
|
||||||
|
@ -102,6 +117,9 @@ function Operation1() {
|
||||||
const key=parseInt(event.target.name.replace('judge',''))
|
const key=parseInt(event.target.name.replace('judge',''))
|
||||||
const updatedJudgeAnswer={ ...judge_answer,[key]:judgeoption}
|
const updatedJudgeAnswer={ ...judge_answer,[key]:judgeoption}
|
||||||
setjudge_answer(updatedJudgeAnswer)
|
setjudge_answer(updatedJudgeAnswer)
|
||||||
|
if (!answeredJudge.includes(key)) {
|
||||||
|
setAnsweredJudge([...answeredJudge, key]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//保存答案到 localStorage
|
//保存答案到 localStorage
|
||||||
|
@ -109,6 +127,9 @@ function Operation1() {
|
||||||
localStorage.setItem('choice_answers', JSON.stringify(choice_answer));
|
localStorage.setItem('choice_answers', JSON.stringify(choice_answer));
|
||||||
localStorage.setItem('completion_answer', JSON.stringify(completion_answer));
|
localStorage.setItem('completion_answer', JSON.stringify(completion_answer));
|
||||||
localStorage.setItem('judge_answer',JSON.stringify(judge_answer))
|
localStorage.setItem('judge_answer',JSON.stringify(judge_answer))
|
||||||
|
localStorage.setItem('answeredChoice',answeredChoice)
|
||||||
|
localStorage.setItem('answeredComple',answeredComple)
|
||||||
|
localStorage.setItem('answeredJudge',answeredJudge)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 在组件加载时从 localStorage 中恢复答案
|
// 在组件加载时从 localStorage 中恢复答案
|
||||||
|
@ -116,6 +137,9 @@ function Operation1() {
|
||||||
const storedChoiceAnswers = localStorage.getItem('choice_answers');
|
const storedChoiceAnswers = localStorage.getItem('choice_answers');
|
||||||
const storedCompleAnswers = localStorage.getItem('completion_answer');
|
const storedCompleAnswers = localStorage.getItem('completion_answer');
|
||||||
const storedJudgeAnswers = localStorage.getItem('judge_answer')
|
const storedJudgeAnswers = localStorage.getItem('judge_answer')
|
||||||
|
const storedAnsweredChoice=localStorage.getItem('answeredChoice')
|
||||||
|
const storedAnsweredComple=localStorage.getItem('answeredComple')
|
||||||
|
const storedAnsweredJudge=localStorage.getItem('answeredJudge')
|
||||||
if (storedChoiceAnswers) {
|
if (storedChoiceAnswers) {
|
||||||
const parsedAnswers = JSON.parse(storedChoiceAnswers);
|
const parsedAnswers = JSON.parse(storedChoiceAnswers);
|
||||||
setchoice_answer(parsedAnswers);
|
setchoice_answer(parsedAnswers);
|
||||||
|
@ -128,6 +152,16 @@ function Operation1() {
|
||||||
const parsedAnswers = JSON.parse(storedJudgeAnswers);
|
const parsedAnswers = JSON.parse(storedJudgeAnswers);
|
||||||
setjudge_answer(parsedAnswers);
|
setjudge_answer(parsedAnswers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(storedAnsweredChoice){
|
||||||
|
setAnsweredChoice(storedAnsweredChoice)
|
||||||
|
}
|
||||||
|
if(storedAnsweredComple){
|
||||||
|
setAnsweredComple(storedAnsweredComple)
|
||||||
|
}
|
||||||
|
if(storedAnsweredJudge){
|
||||||
|
setAnsweredJudge(storedAnsweredJudge)
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
//不包含实训分数
|
//不包含实训分数
|
||||||
|
@ -158,6 +192,8 @@ function Operation1() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='nav-operation1'>
|
<div className='nav-operation1'>
|
||||||
|
@ -191,19 +227,19 @@ function Operation1() {
|
||||||
<tr>选择题:</tr>
|
<tr>选择题:</tr>
|
||||||
<div>
|
<div>
|
||||||
{Object.keys(TrainData['operateID'][0]).map((key,index)=>(
|
{Object.keys(TrainData['operateID'][0]).map((key,index)=>(
|
||||||
<td key={key}>{index+1}</td>
|
<td key={key} className={answeredChoice.includes(index) ? 'answered' : ''}>{index+1}</td>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<tr>填空题:</tr>
|
<tr>填空题:</tr>
|
||||||
<div>
|
<div>
|
||||||
{Object.keys(TrainData['operateID'][1]).map((key,index)=>(
|
{Object.keys(TrainData['operateID'][1]).map((key,index)=>(
|
||||||
<td key={key}>{index+1}</td>
|
<td key={key} className={answeredComple.includes(index) ? 'answered' : ''}>{index+1}</td>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<tr>判断题:</tr>
|
<tr>判断题:</tr>
|
||||||
<div>
|
<div>
|
||||||
{Object.keys(TrainData['operateID'][2]).map((key,index)=>(
|
{Object.keys(TrainData['operateID'][2]).map((key,index)=>(
|
||||||
<td key={key}>{index+1}</td>
|
<td key={key} className={answeredJudge.includes(index) ? 'answered' : ''}>{index+1}</td>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</table>}
|
</table>}
|
||||||
|
|
|
@ -11,6 +11,10 @@ const list4=[
|
||||||
// 首页 学习分析
|
// 首页 学习分析
|
||||||
function SubjectPage(){
|
function SubjectPage(){
|
||||||
const student_ID=localStorage.getItem('islogin')
|
const student_ID=localStorage.getItem('islogin')
|
||||||
|
if(student_ID==null){
|
||||||
|
alert('登录过期,请重新登录')
|
||||||
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
|
}
|
||||||
const [title,setTitle]=useState()
|
const [title,setTitle]=useState()
|
||||||
// 获取实训标题
|
// 获取实训标题
|
||||||
const FetchTrainFunc=async()=>{
|
const FetchTrainFunc=async()=>{
|
||||||
|
|
|
@ -72,7 +72,7 @@ import axios from 'axios';
|
||||||
const register_data=register_func.data
|
const register_data=register_func.data
|
||||||
if (register_data.result==='注册成功'){
|
if (register_data.result==='注册成功'){
|
||||||
alert('注册成功')
|
alert('注册成功')
|
||||||
window.location.href='http://localhost:3000/signin'
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
}else if(register_data.result==='注册失败'){
|
}else if(register_data.result==='注册失败'){
|
||||||
alert('账号已存在')
|
alert('账号已存在')
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,13 @@ def SendTrainTest():
|
||||||
SendTrainTestFunc(TrainChoice, TrainCompletion, TrainJudge, Hour, Min, StopTime,Class,Train,teacher_id)
|
SendTrainTestFunc(TrainChoice, TrainCompletion, TrainJudge, Hour, Min, StopTime,Class,Train,teacher_id)
|
||||||
return '发布成功'
|
return '发布成功'
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/Find_details',methods=["POST"])
|
||||||
|
def Find_details():
|
||||||
|
id=request.json['student_ID']
|
||||||
|
return Find_details(id)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
@app.route('/<path:path>')
|
@app.route('/<path:path>')
|
||||||
def catch_all(path = "index.html"):
|
def catch_all(path = "index.html"):
|
||||||
|
|
|
@ -190,7 +190,6 @@ def find_end_test(ID):
|
||||||
TEST_ID = cursor.fetchall()
|
TEST_ID = cursor.fetchall()
|
||||||
for i in TEST_ID:
|
for i in TEST_ID:
|
||||||
testID.append(i[0])
|
testID.append(i[0])
|
||||||
print(i)
|
|
||||||
return testID
|
return testID
|
||||||
|
|
||||||
# find_end_test('20240101')
|
# find_end_test('20240101')
|
||||||
|
|
|
@ -254,3 +254,31 @@ def SendTrainTestFunc(TrainChoice,TrainCompletion,TrainJudge,Hour,Min,StopTime,C
|
||||||
db.commit()
|
db.commit()
|
||||||
cursor.close()
|
cursor.close()
|
||||||
return '发布成功'
|
return '发布成功'
|
||||||
|
|
||||||
|
|
||||||
|
# def Find_dic(dic):
|
||||||
|
# # 获取字典的键,并按照从大到小的顺序排序
|
||||||
|
# keys_sorted = sorted(dic.keys(), reverse=True)
|
||||||
|
#
|
||||||
|
# # 取最后三个键
|
||||||
|
# last_three_keys = keys_sorted[:3]
|
||||||
|
#
|
||||||
|
# # 创建一个新的字典,仅包含排序后的最后三个键及其对应的值
|
||||||
|
# dic_last_three = {key: dic[key] for key in last_three_keys}
|
||||||
|
#
|
||||||
|
# return dic_last_three # 返回一个新字典,该字典仅包含排序后的最后三个键及其对应的值
|
||||||
|
|
||||||
|
|
||||||
|
def Find_details(ID):
|
||||||
|
dic = {}
|
||||||
|
cursor = db.cursor()
|
||||||
|
cursor.execute(f"SELECT * FROM STUDENT_TEST WHERE STUDENT_ID=? AND TF='true' ", (ID))
|
||||||
|
data = cursor.fetchall()
|
||||||
|
for i in data:
|
||||||
|
dic[i[3]] = i
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
# 调用Find_dic函数并传入dic字典作为参数
|
||||||
|
return dic
|
||||||
|
|
||||||
|
# print(Find_details('20240101'))
|
||||||
|
|
Loading…
Reference in New Issue