This commit is contained in:
commit
ee1c6935e0
|
@ -5,267 +5,9 @@ import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
// 首页 课程班级
|
// 首页 课程班级
|
||||||
function Exam(){
|
function Exam(){
|
||||||
const {examId} = useParams()
|
|
||||||
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=true
|
|
||||||
|
|
||||||
//创建答案字典,将用户填入的答案添加到答案字典
|
|
||||||
const [choice_answer,setchoice_answer]=useState({})
|
|
||||||
const [completion_answer,setcompletion_answer]=useState({})
|
|
||||||
const [judge_answer,setjudge_answer]=useState({})
|
|
||||||
|
|
||||||
const [testdata,settestdata]=useState('')
|
|
||||||
const test_func= async()=>{
|
|
||||||
try{
|
|
||||||
const test_src= await axios.post('/api/student/get_test',{student_ID})
|
|
||||||
const test_data=test_src.data['data']
|
|
||||||
settestdata(test_data)
|
|
||||||
}catch(error){
|
|
||||||
alert(error)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
useEffect(()=>{
|
|
||||||
test_func()
|
|
||||||
},[])
|
|
||||||
// 倒计时初始化
|
|
||||||
useEffect(() => {
|
|
||||||
const examDuration = 10;
|
|
||||||
setCountdown(examDuration);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// 转换秒数为时分秒格式
|
|
||||||
const formatTime = (seconds) => {
|
|
||||||
const hours = Math.floor(seconds / 3600);
|
|
||||||
const minutes = Math.floor((seconds % 3600) / 60);
|
|
||||||
const secs = seconds % 60;
|
|
||||||
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const [changetime,setchangetime]=useState(true)
|
|
||||||
|
|
||||||
// 倒计时更新
|
|
||||||
useEffect(() => {
|
|
||||||
let interval = setInterval(() => {
|
|
||||||
if (countdown > 0) {
|
|
||||||
setCountdown(countdown - 1);
|
|
||||||
}else{
|
|
||||||
clearInterval(interval)
|
|
||||||
alert('时间到!已强制交卷')
|
|
||||||
//与下面点击
|
|
||||||
let sum = 0;
|
|
||||||
for (let item of testdata[examId][0][0]) {
|
|
||||||
for (let i of item) {
|
|
||||||
if (i[6] === choice_answer[sum]) {
|
|
||||||
// 使用函数式更新
|
|
||||||
setscore(prevscore => prevscore + 2);
|
|
||||||
}else{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(let item of testdata[examId][0][1]){
|
|
||||||
for(let i of item){
|
|
||||||
if(i[2]===completion_answer[sum]){
|
|
||||||
setscore(prevscore => prevscore + 2);
|
|
||||||
}else{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(let item of testdata[examId][0][2]){
|
|
||||||
for(let i of item){
|
|
||||||
console.log(i);
|
|
||||||
if(i[2]===judge_answer[sum]){
|
|
||||||
setscore(prevscore => prevscore + 2);
|
|
||||||
}else{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sum++; // 每次循环完一个 item 后,sum 加 1
|
|
||||||
}
|
|
||||||
console.log(score);
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
}, [countdown]);
|
|
||||||
|
|
||||||
//提交按钮按钮并进行对照批改
|
|
||||||
//设置总分 score
|
|
||||||
const [score,setscore]=useState(0)
|
|
||||||
|
|
||||||
// 计算成绩
|
|
||||||
const submit = async() => {
|
|
||||||
alert('提交成功')
|
|
||||||
let sum = 0;
|
|
||||||
for (let item of testdata[examId][0][0]) {
|
|
||||||
for (let i of item) {
|
|
||||||
if (i[6] === choice_answer[sum]) {
|
|
||||||
// 使用函数式更新
|
|
||||||
setscore(prevscore => prevscore + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(let item of testdata[examId][0][1]){
|
|
||||||
for(let i of item){
|
|
||||||
if(i[2]===completion_answer[sum]){
|
|
||||||
setscore(prevscore => prevscore + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(let item of testdata[examId][0][2]){
|
|
||||||
for(let i of item){
|
|
||||||
if(i[2]===judge_answer[sum]){
|
|
||||||
setscore(prevscore => prevscore + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sum++; // 每次循环完一个 item 后,sum 加 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const [isMounted, setIsMounted] = useState(false);
|
|
||||||
useEffect(()=>{
|
|
||||||
if(isMounted){
|
|
||||||
const score_func=async()=>{
|
|
||||||
try{
|
|
||||||
const score_entry_src=await axios.post('/api/student/score_entry',{
|
|
||||||
student_ID,
|
|
||||||
score,
|
|
||||||
examId
|
|
||||||
})
|
|
||||||
}catch(error){
|
|
||||||
alert(error)
|
|
||||||
}
|
|
||||||
window.location.href='http://36.138.114.105:30294/subject'
|
|
||||||
}
|
|
||||||
score_func()
|
|
||||||
}else{
|
|
||||||
setIsMounted(true)
|
|
||||||
}
|
|
||||||
},[score])
|
|
||||||
|
|
||||||
|
|
||||||
//给选择题添加事件监听器
|
|
||||||
const handleOptionChange = (event) => {
|
|
||||||
const selectedValue = event.target.value;
|
|
||||||
const key = parseInt(event.target.name.replace('group', ''));
|
|
||||||
const updatedChoiceAnswer = { ...choice_answer, [key]: selectedValue };
|
|
||||||
setchoice_answer(updatedChoiceAnswer);
|
|
||||||
};
|
|
||||||
|
|
||||||
//填空题
|
|
||||||
const handleInputChange = (event) => {
|
|
||||||
const { name, value } = event.target;
|
|
||||||
setcompletion_answer({
|
|
||||||
...completion_answer,
|
|
||||||
[name]: value
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//判断题
|
|
||||||
const handleJudgeOption=(event)=>{
|
|
||||||
const judgeoption=event.target.value;
|
|
||||||
const key=parseInt(event.target.name.replace('judge',''))
|
|
||||||
const updatedJudgeAnswer={ ...judge_answer,[key]:judgeoption}
|
|
||||||
setjudge_answer(updatedJudgeAnswer)
|
|
||||||
}
|
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className="test">
|
<div></div>
|
||||||
<div className='nav-test'>
|
)
|
||||||
{testdata&&<div className='nav1'>
|
}
|
||||||
<p>试卷ID:{examId}</p>
|
|
||||||
<p>发布人:{testdata[examId][5]}</p>
|
|
||||||
<div className='time'>
|
|
||||||
{/* 倒计时 */}
|
|
||||||
<h1>剩余时间:{formatTime(countdown)}</h1>
|
|
||||||
</div>
|
|
||||||
</div>}
|
|
||||||
</div>
|
|
||||||
<div className='body-box'>
|
|
||||||
<div className="body-left-test">
|
|
||||||
<p>题目</p>
|
|
||||||
<ul>
|
|
||||||
<li>判断题</li>
|
|
||||||
<li>选择题</li>
|
|
||||||
<li>解答题</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div className='body-right-test'>
|
|
||||||
{/* 右边的题目 */}
|
|
||||||
|
|
||||||
<div id='choice_box'>
|
export default Exam
|
||||||
<span style={{color:'red'}}>选择题</span>
|
|
||||||
<table>
|
|
||||||
{testdata&&<thead>
|
|
||||||
{Object.keys(testdata[examId][0][0]).map((key)=>(
|
|
||||||
<tr key={key}>
|
|
||||||
<td>
|
|
||||||
<span style={{fontSize:'30px'}}>{parseInt(key,10)+1}:{testdata[examId][0][0][key][0][1]}</span>
|
|
||||||
<div>
|
|
||||||
<label><input type="radio" value={testdata[examId][0][0][key][0][2]} onChange={handleOptionChange} name={`group${key}`}/>A: {testdata[examId][0][0][key][0][2]}</label>
|
|
||||||
<br />
|
|
||||||
<label><input type="radio" value={testdata[examId][0][0][key][0][3]} onChange={handleOptionChange} name={`group${key}`}/>B: {testdata[examId][0][0][key][0][3]}</label>
|
|
||||||
<br />
|
|
||||||
<label><input type="radio" value={testdata[examId][0][0][key][0][4]} onChange={handleOptionChange} name={`group${key}`}/>C: {testdata[examId][0][0][key][0][4]}</label>
|
|
||||||
<br />
|
|
||||||
<label><input type="radio" value={testdata[examId][0][0][key][0][5]} onChange={handleOptionChange} name={`group${key}`}/>D: {testdata[examId][0][0][key][0][5]}</label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</thead>}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
{/* */}
|
|
||||||
<div id='comple_box'>
|
|
||||||
<span style={{color:'red'}}>填空题</span>
|
|
||||||
<table>
|
|
||||||
{ testdata&&<thead>
|
|
||||||
{Object.keys(testdata[examId][0][1]).map((key)=>(
|
|
||||||
<tr key={key}>
|
|
||||||
<td>
|
|
||||||
<div>
|
|
||||||
<p>{parseInt(key,10)+1}:{testdata[examId][0][1][key][0][1]}
|
|
||||||
<input type="text" className='input_txt' onChange={handleInputChange} name={key}/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</thead>}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div id='judge_box'>
|
|
||||||
<span style={{color:'red'}}>判断题</span>
|
|
||||||
{ testdata&&<table>
|
|
||||||
<thead>
|
|
||||||
{Object.keys(testdata[examId][0][2]).map((key)=>(
|
|
||||||
<tr>
|
|
||||||
<td key={key}>
|
|
||||||
<div>
|
|
||||||
<p>{parseInt(key,10)+1}:{testdata[examId][0][2][key][0][1]}</p>
|
|
||||||
<label><input type="radio" name={`judge${key}`} onChange={handleJudgeOption} value={true}/>T</label>
|
|
||||||
<label><input type="radio" name={`judge${key}`} onChange={handleJudgeOption} value={false}/>F</label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</thead>
|
|
||||||
</table>}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button id='submit' onClick={submit}>提交</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)};
|
|
||||||
|
|
||||||
export default Exam;
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import url('https://fonts.font.im/css?family=Caveat');
|
|
||||||
|
|
||||||
/* 右侧页面 */
|
/* 右侧页面 */
|
||||||
.body-right-subject{
|
.body-right-subject{
|
||||||
|
@ -81,7 +81,6 @@
|
||||||
font-size: 45px;
|
font-size: 45px;
|
||||||
/* color: #ff6666; */
|
/* color: #ff6666; */
|
||||||
color: rgb(252, 102, 102);
|
color: rgb(252, 102, 102);
|
||||||
font-family: 'Caveat', cursive;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ function SubjectPage(){
|
||||||
window.location.href='http://36.138.114.105:30294/'
|
window.location.href='http://36.138.114.105:30294/'
|
||||||
}
|
}
|
||||||
const [testdata,settestdata]=useState('')
|
const [testdata,settestdata]=useState('')
|
||||||
|
const [FalseData,setFalseData]=useState('')
|
||||||
|
const [NotFalse,setNotFalse]=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({})
|
||||||
|
|
||||||
|
@ -20,7 +22,9 @@ function SubjectPage(){
|
||||||
const test=async()=>{
|
const test=async()=>{
|
||||||
try{
|
try{
|
||||||
const test_src= await axios.post('/api/student/get_test',{student_ID})
|
const test_src= await axios.post('/api/student/get_test',{student_ID})
|
||||||
settestdata(test_src.data['data'])
|
settestdata(test_src.data['True'])
|
||||||
|
setFalseData(test_src.data['FalseTest'][1])
|
||||||
|
setNotFalse(test_src.data['FalseTest'][2])
|
||||||
}catch(error){
|
}catch(error){
|
||||||
alert('test出错')
|
alert('test出错')
|
||||||
}
|
}
|
||||||
|
@ -29,87 +33,58 @@ function SubjectPage(){
|
||||||
test()
|
test()
|
||||||
},[])
|
},[])
|
||||||
|
|
||||||
const [EndTestList,setEndTestList]=useState([])
|
const click=()=>{
|
||||||
//获取他已经做过的试卷
|
console.log(testdata);
|
||||||
const end_test=async()=>{
|
console.log(FalseData);
|
||||||
try{
|
console.log(NotFalse);
|
||||||
const end_test_src=await axios.post('/api/student/get_end_student',{student_ID})
|
|
||||||
const obj=end_test_src.data['result']
|
|
||||||
setEndTestList(obj)
|
|
||||||
}catch(error){
|
|
||||||
alert(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
end_test()
|
|
||||||
},[])
|
|
||||||
|
|
||||||
//过期试卷
|
|
||||||
const [outtest,setouttest]=useState({})
|
|
||||||
//分过期试卷⬇
|
|
||||||
useEffect(()=>{
|
|
||||||
let test_list= []
|
|
||||||
for (const key in testdata) {
|
|
||||||
if(testdata[key][4]<time || EndTestList.includes(Number(key))){
|
|
||||||
setouttest({...outtest,[key]:testdata[key]})
|
|
||||||
test_list.push(key)
|
|
||||||
}else{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Object.fromEntries() 方法是 JavaScript 的 Object 对象的一个静态方法,用于将一个键值对数组转换为一个对象。它是 Object.entries() 方法的逆操作。
|
|
||||||
const newOuttest = {...outtest,...Object.fromEntries(test_list.map(key => [key, testdata[key]]))};
|
|
||||||
// 更新 outtest
|
|
||||||
setouttest(newOuttest);
|
|
||||||
// 删除 testdata 中对应的项
|
|
||||||
test_list.forEach(key => delete testdata[key]);
|
|
||||||
find_result_func()
|
|
||||||
}, [testdata]);
|
|
||||||
|
|
||||||
const find_result_func=async()=>{
|
|
||||||
try{
|
|
||||||
const find_result=await axios.post('/api/student/fetch_result',{
|
|
||||||
student_ID
|
|
||||||
})
|
|
||||||
setresult(find_result.data['result'])
|
|
||||||
}catch{
|
|
||||||
alert('这里出错')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className="body">
|
<div className="body">
|
||||||
<div className="body-right-subject">
|
<div className="body-right-subject">
|
||||||
<h3>正在进行的考试与练习</h3>
|
<h3>正在进行的考试与练习</h3>
|
||||||
{ testdata &&<div className='test-subject'>
|
{ FalseData &&<div className='test-subject'>
|
||||||
{Object.keys(testdata).map((key)=>(
|
{Object.keys(FalseData).map((key)=>(
|
||||||
<div className='test-box' key={key}>
|
<div className='test-box' key={key}>
|
||||||
<p>试卷ID:{testdata[key][6]}</p>
|
<p>试卷ID:{key}</p>
|
||||||
<span>发布者:{testdata[key][5]}</span>
|
<span>发布者:{'小陈老师'}</span>
|
||||||
<div>发布时间:{testdata[key][3]}</div>
|
<div>发布时间:{FalseData[key][5]}</div>
|
||||||
<div>截至时间:{testdata[key][4]}</div>
|
<div>截至时间:{FalseData[key][6]}</div>
|
||||||
<Link to={`/exam/${testdata[key][6]}`} className="exam-btn">
|
<Link to={`/exam/${FalseData[key][8]}`} className="exam-btn">
|
||||||
考试
|
考试
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>}
|
</div>}
|
||||||
<h3>已结束或完成的试卷与练习</h3>
|
<h3>已结束或完成的试卷与练习</h3>
|
||||||
{ outtest&& result&&<div className='test-subject'>
|
{ testdata&& result&&<div className='test-subject'>
|
||||||
{Object.keys(outtest).map((key)=>{
|
{Object.keys(testdata).map((key)=>{
|
||||||
const score = result[key] !== null ? result[key] + "分" : "缺考";
|
|
||||||
return(
|
return(
|
||||||
<div className='test-box' key={key}>
|
<div className='test-box' key={key}>
|
||||||
<p>试卷ID:{outtest[key][6]}</p>
|
<p>试卷ID:{testdata[key][0][3]}</p>
|
||||||
<span>发布者:{outtest[key][5]}</span>
|
<span>发布者:{'小陈老师'}</span>
|
||||||
<div>发布时间:{outtest[key][3]}</div>
|
<div>发布时间:{testdata[key][1][0][5]}</div>
|
||||||
<div>截至时间:{outtest[key][4]}</div>
|
<div>截至时间:{testdata[key][1][0][6]}</div>
|
||||||
<div id='score'>{score}</div>
|
<div id='score'>{testdata[key][0][5]}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>}
|
||||||
|
{ NotFalse&& result&&<div className='test-subject'>
|
||||||
|
{Object.keys(NotFalse).map((key)=>{
|
||||||
|
return(
|
||||||
|
<div className='test-box' key={key}>
|
||||||
|
<p>试卷ID:{NotFalse[key][0][8]}</p>
|
||||||
|
<span>发布者:{'小陈老师'}</span>
|
||||||
|
<div>发布时间:{NotFalse[key][0][5]}</div>
|
||||||
|
<div>截至时间:{NotFalse[key][0][6]}</div>
|
||||||
|
<div id='score'>{'超时'}</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>}
|
</div>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)};
|
)};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import top from '../img/top.jpg'
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
function Operation1() {
|
function Operation1() {
|
||||||
|
const student_ID=localStorage.getItem('islogin')
|
||||||
const[isTrue,setisTrue]=useState(true)
|
const[isTrue,setisTrue]=useState(true)
|
||||||
const click=()=>{
|
const click=()=>{
|
||||||
console.log(60 * parseInt(TrainData['operateID'][4]));
|
console.log(60 * parseInt(TrainData['operateID'][4]));
|
||||||
|
@ -37,7 +38,8 @@ function Operation1() {
|
||||||
const TrainDataFunc=async()=>{
|
const TrainDataFunc=async()=>{
|
||||||
try{
|
try{
|
||||||
const TrainDataSrc=await axios.post('/api/student/TrainData',{
|
const TrainDataSrc=await axios.post('/api/student/TrainData',{
|
||||||
operateID
|
operateID,
|
||||||
|
student_ID
|
||||||
})
|
})
|
||||||
const returnData=TrainDataSrc.data
|
const returnData=TrainDataSrc.data
|
||||||
setTrainData(returnData)
|
setTrainData(returnData)
|
||||||
|
@ -49,7 +51,7 @@ function Operation1() {
|
||||||
TrainDataFunc()
|
TrainDataFunc()
|
||||||
},[])
|
},[])
|
||||||
|
|
||||||
useEffect(()=>{
|
function daojishi(){
|
||||||
if(localStorage.getItem('time')){
|
if(localStorage.getItem('time')){
|
||||||
setCountdown(localStorage.getItem('time'))
|
setCountdown(localStorage.getItem('time'))
|
||||||
}else{
|
}else{
|
||||||
|
@ -57,6 +59,11 @@ function Operation1() {
|
||||||
setCountdown(60 * parseInt(TrainData['operateID'][4]))
|
setCountdown(60 * parseInt(TrainData['operateID'][4]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
daojishi()
|
||||||
|
console.log('a');
|
||||||
},[TrainData])
|
},[TrainData])
|
||||||
|
|
||||||
//倒计时
|
//倒计时
|
||||||
|
@ -65,7 +72,7 @@ function Operation1() {
|
||||||
// 倒计时更新
|
// 倒计时更新
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let interval = setInterval(() => {
|
let interval = setInterval(() => {
|
||||||
if (countdown > 0 ) {
|
if (countdown !== 0 ) {
|
||||||
setCountdown(countdown - 1);
|
setCountdown(countdown - 1);
|
||||||
localStorage.setItem('time',countdown-1)
|
localStorage.setItem('time',countdown-1)
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,6 +83,14 @@ function Operation1() {
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [countdown]);
|
}, [countdown]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(countdown<0){
|
||||||
|
console.log('c');
|
||||||
|
setCountdown(60 * parseInt(TrainData['operateID'][4]))
|
||||||
|
localStorage.removeItem('time')
|
||||||
|
}
|
||||||
|
},[TrainData])
|
||||||
|
|
||||||
// 转换秒数为时分秒格式
|
// 转换秒数为时分秒格式
|
||||||
const formatTime = (seconds) => {
|
const formatTime = (seconds) => {
|
||||||
const hours = Math.floor(seconds / 3600);
|
const hours = Math.floor(seconds / 3600);
|
||||||
|
@ -140,7 +155,8 @@ function Operation1() {
|
||||||
localStorage.setItem('answeredChoice',answeredChoice)
|
localStorage.setItem('answeredChoice',answeredChoice)
|
||||||
localStorage.setItem('answeredComple',answeredComple)
|
localStorage.setItem('answeredComple',answeredComple)
|
||||||
localStorage.setItem('answeredJudge',answeredJudge)
|
localStorage.setItem('answeredJudge',answeredJudge)
|
||||||
localStorage.setItem('TrainTest',TrainData['operatrID'][3][0])
|
localStorage.setItem('TrainData',JSON.stringify(TrainData))
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 在组件加载时从 localStorage 中恢复答案
|
// 在组件加载时从 localStorage 中恢复答案
|
||||||
|
@ -230,7 +246,7 @@ function Operation1() {
|
||||||
<div className='nav-operation1'>
|
<div className='nav-operation1'>
|
||||||
{/* 导航 */}
|
{/* 导航 */}
|
||||||
{/* <h1>{OperationId}</h1> */}
|
{/* <h1>{OperationId}</h1> */}
|
||||||
<p>剩余时间:{formatTime(countdown)}</p>
|
<p>剩余时间:{countdown >=0 && formatTime(countdown)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='body-operation1'>
|
<div className='body-operation1'>
|
||||||
<div className='nav-left-operation1'>
|
<div className='nav-left-operation1'>
|
||||||
|
|
|
@ -8,32 +8,77 @@ import arrowleft from '../img/arrowleft.jpg'
|
||||||
import arrowright from '../img/arrowright.jpg'
|
import arrowright from '../img/arrowright.jpg'
|
||||||
import bottom from '../img/bottom.jpg'
|
import bottom from '../img/bottom.jpg'
|
||||||
import top from '../img/top.jpg'
|
import top from '../img/top.jpg'
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
function Operation2() {
|
function Operation2() {
|
||||||
|
const student_ID=localStorage.getItem('islogin')
|
||||||
const { operateID } = useParams();
|
const { operateID } = useParams();
|
||||||
//获取剩余时间
|
const [isTrue,setisTrue]=useState(false)
|
||||||
|
|
||||||
|
const TrainData=JSON.parse(localStorage.getItem('TrainData'))
|
||||||
|
|
||||||
|
//获取链接
|
||||||
|
const [Src,setSrc]=useState()
|
||||||
|
const Train1=async()=>{
|
||||||
|
try{
|
||||||
|
const Train1Src=await axios.post('/api/student/FindTrain1Src',{
|
||||||
|
student_ID,
|
||||||
|
operateID
|
||||||
|
})
|
||||||
|
setSrc(Train1Src.data['Src'])
|
||||||
|
}catch{
|
||||||
|
alert('Train1出错')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//终端
|
//终端
|
||||||
const terminalObj = useRef(null);
|
const terminalObj = useRef(null);
|
||||||
let sock = null;
|
let sock = null;
|
||||||
const [terminal, setTerminal] = useState(null);
|
const [terminal, setTerminal] = useState(null);
|
||||||
useEffect(() => {
|
|
||||||
if (terminal == null){
|
useEffect(()=>{
|
||||||
setTerminal(new Terminal({
|
if(TrainData['operateID'][3][0]==='达梦数据库连接'){
|
||||||
cols: 80,
|
console.log('第一个');
|
||||||
rows: 27,
|
Train1()
|
||||||
fontSize: 23
|
setisTrue(true)
|
||||||
}));
|
|
||||||
|
|
||||||
|
if (terminal == null){
|
||||||
|
setTerminal(new Terminal({
|
||||||
|
cols: 80,
|
||||||
|
rows: 27,
|
||||||
|
fontSize: 23
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}else{
|
||||||
|
console.log('第二个');
|
||||||
|
Train1()
|
||||||
|
setisTrue(false)
|
||||||
}
|
}
|
||||||
}, [])
|
},[])
|
||||||
|
const click=()=>{
|
||||||
|
console.log(Src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// if (terminal == null){
|
||||||
|
// setTerminal(new Terminal({
|
||||||
|
// cols: 80,
|
||||||
|
// rows: 27,
|
||||||
|
// fontSize: 23
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
// }, [])
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
|
|
||||||
// if (terminal != null){
|
// if (terminal != null){
|
||||||
// terminal.open(terminalObj.current );
|
// terminal.open(terminalObj.current );
|
||||||
// sock = new WebSocket("ws://192.168.0.40:8765");
|
// // sock = new WebSocket("ws://192.168.0.40:8765");
|
||||||
|
// sock = new WebSocket(Src);
|
||||||
// terminal.onData((data) => {
|
// terminal.onData((data) => {
|
||||||
// sock?.send(data);
|
// sock?.send(data);
|
||||||
// });
|
// });
|
||||||
|
@ -59,10 +104,13 @@ function Operation2() {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//删除函数
|
||||||
|
const DEL=()=>{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
//倒计时
|
//倒计时
|
||||||
// const { OperationId } = useParams();
|
// const { OperationId } = useParams();
|
||||||
const [test_data, setTestData] = useState('');
|
|
||||||
const [countdown, setCountdown] = useState(0);
|
const [countdown, setCountdown] = useState(0);
|
||||||
|
|
||||||
// 倒计时初始化
|
// 倒计时初始化
|
||||||
|
@ -96,9 +144,10 @@ function Operation2() {
|
||||||
const [isSubjectDropdownOpen, setIsSubjectDropdownOpen] = useState(false);
|
const [isSubjectDropdownOpen, setIsSubjectDropdownOpen] = useState(false);
|
||||||
|
|
||||||
const tijiao = ()=>{
|
const tijiao = ()=>{
|
||||||
clearInterval()
|
setCountdown(0)
|
||||||
localStorage.removeItem('time')
|
localStorage.removeItem('time')
|
||||||
window.location.href='http://baidu.com'
|
alert('提交成功')
|
||||||
|
window.location.href='http://localhost:3000/train'
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -131,8 +180,25 @@ function Operation2() {
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className='body-right2'>
|
<div className='body-right2'>
|
||||||
第二页(实训题)的右边页面
|
|
||||||
<div style={{width: "1430px",position:'absolute',right:'0'}} ref={terminalObj} onContextMenu={pasteContent}></div>
|
|
||||||
|
<button onClick={click}>测试按钮</button>
|
||||||
|
{/* 前端连接数据库⬇ */}
|
||||||
|
{ !isTrue&&<div>
|
||||||
|
<Link to={Src}>{TrainData['operateID'][3][0]}</Link>
|
||||||
|
<br />
|
||||||
|
点击以上链接前往实训
|
||||||
|
</div>}
|
||||||
|
{/* 前端连接数据库 ⬆*/}
|
||||||
|
|
||||||
|
{/* 达梦数据库连接 ⬇*/}
|
||||||
|
{ isTrue&&
|
||||||
|
<div>
|
||||||
|
<p>{TrainData['operateID'][3][0]}</p>
|
||||||
|
<div style={{width: "1430px",position:'absolute',right:'0'}} ref={terminalObj} onContextMenu={pasteContent}></div>
|
||||||
|
</div>}
|
||||||
|
{/* 达梦数据库连接⬆ */}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<Link className='btn-back2' to={`/operation1/${operateID}`} style={{color:'#000',textDecoration:'none'}}>
|
<Link className='btn-back2' to={`/operation1/${operateID}`} style={{color:'#000',textDecoration:'none'}}>
|
||||||
<p>上一页</p>
|
<p>上一页</p>
|
||||||
|
|
|
@ -23,12 +23,11 @@ import ClassID from '../TeacherPages/classlistpages/classId';
|
||||||
import ManageTest from '../TeacherPages/TestManage/ManageTest';
|
import ManageTest from '../TeacherPages/TestManage/ManageTest';
|
||||||
import SendTest from '../TeacherPages/TestManage/SendTest';
|
import SendTest from '../TeacherPages/TestManage/SendTest';
|
||||||
import Marking from '../TeacherPages/MarkingPages/Marking';
|
import Marking from '../TeacherPages/MarkingPages/Marking';
|
||||||
import SendTrain from '../TeacherPages/TrainManage/SendTrain';
|
import SendTrain from '../TeacherPages/Trainmanage/SendTrain'
|
||||||
import TrainManage from '../TeacherPages/TrainManage/Trainmanage';
|
import TrainManage from '../TeacherPages/Trainmanage/Trainmanage'
|
||||||
import StudentLink from '../TeacherPages/MarkingPages/StudentLink';
|
import StudentLink from '../TeacherPages/MarkingPages/StudentLink';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 定义一个组件来包裹除了特定页面(exam)外的所有页面使其有导航
|
// 定义一个组件来包裹除了特定页面(exam)外的所有页面使其有导航
|
||||||
const MainLayout = ({ headerNav:HeaderNav }) => {
|
const MainLayout = ({ headerNav:HeaderNav }) => {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -99,7 +99,14 @@ def get_lesson(): # 获取课程
|
||||||
def get_test(): # 获取试卷以及历史试卷
|
def get_test(): # 获取试卷以及历史试卷
|
||||||
data = request.json
|
data = request.json
|
||||||
ID = data['student_ID']
|
ID = data['student_ID']
|
||||||
return jsonify({"data": fetch_test_func(ID)})
|
result1=fetch_test_func(ID)
|
||||||
|
result2=falseTest_func(ID)
|
||||||
|
return jsonify({"True":result1,'FalseTest':result2})
|
||||||
|
|
||||||
|
@app.route('/api/student/get_testID',methods=['POST'])
|
||||||
|
def get_testID(): # 获取试卷ID
|
||||||
|
ID=request.json['student_ID']
|
||||||
|
return jsonify({'data': 'a'})
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/student/fetch_result', methods=['POST']) # 查找成绩
|
@app.route('/api/student/fetch_result', methods=['POST']) # 查找成绩
|
||||||
|
@ -147,6 +154,13 @@ def HistoryTrain():
|
||||||
result=HistoryTrainFunc(ID)
|
result=HistoryTrainFunc(ID)
|
||||||
return jsonify({'HistoryTrain': result})
|
return jsonify({'HistoryTrain': result})
|
||||||
|
|
||||||
|
@app.route('/api/student/FindTrain1Src',methods=['POST'])
|
||||||
|
def FindTrain1Src():
|
||||||
|
ID = request.json['student_ID']
|
||||||
|
testID=request.json['operateID']
|
||||||
|
result=FindTrain1SrcFunc(ID,testID)
|
||||||
|
return jsonify({'Src':result})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 以下为教师功能—————————————————————————————————————————————————————————————————————
|
# 以下为教师功能—————————————————————————————————————————————————————————————————————
|
||||||
|
|
|
@ -3,6 +3,11 @@ import json
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
from Crypto.Random import get_random_bytes
|
from Crypto.Random import get_random_bytes
|
||||||
import base64
|
import base64
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# 获取当前日期和时间
|
||||||
|
current_datetime = datetime.now()
|
||||||
|
Time=current_datetime.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
db = dmPython.connect(user='SYSDBA', password='dameng!!', host="36.138.114.105", port="32522")
|
db = dmPython.connect(user='SYSDBA', password='dameng!!', host="36.138.114.105", port="32522")
|
||||||
|
|
||||||
|
@ -123,63 +128,44 @@ def student_succeed_func(ID):
|
||||||
# fetch_testID('20240101')
|
# fetch_testID('20240101')
|
||||||
def fetch_test_func(ID):#获取试卷
|
def fetch_test_func(ID):#获取试卷
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
cursor.execute(f'SELECT TEST_ID FROM STUDENT_TEST WHERE STUDENT_ID={ID}')
|
TrueTestDic={}
|
||||||
testID = []
|
TruetestID=[]
|
||||||
TEST_ID = cursor.fetchall()
|
cursor.execute(f"SELECT * FROM STUDENT_TEST WHERE STUDENT_ID=? AND TF='true'",(ID))
|
||||||
for i in TEST_ID:
|
for i in cursor.fetchall():
|
||||||
testID.append(i[0])
|
TruetestID.append(i[3])
|
||||||
test_succeed = {} # 初始化一个空字典,用于保存结果
|
TrueTestDic[i[3]]=i
|
||||||
|
|
||||||
for i in testID:
|
for index in TruetestID:
|
||||||
cursor.execute(f'SELECT * FROM TEST_BANK WHERE ID={i}')
|
cursor.execute(f"SELECT * FROM TEST_BANK WHERE ID=?",(index))
|
||||||
test = cursor.fetchall()[0]
|
TrueTestDic[index]=TrueTestDic[index],cursor.fetchall()
|
||||||
test = list(test)
|
# print(TrueTestDic)
|
||||||
# print(test)
|
return TrueTestDic
|
||||||
# 开始时间及结束时间
|
|
||||||
releasetime = test[5]
|
|
||||||
endtime = test[6]
|
|
||||||
# 持续时间
|
|
||||||
hour = test[3]
|
|
||||||
min = test[4]
|
|
||||||
# 发布人
|
|
||||||
cursor.execute(f'SELECT TEACHER_ID FROM TEACHER_MIDDLE_SUBJECT WHERE SUBJECT=(?)', (test[9]))
|
|
||||||
teacher_id = cursor.fetchone()[0]
|
|
||||||
cursor.execute(f'SELECT TEACHER_NAME FROM TEACHER WHERE TEACHER_ID=(?)', (teacher_id))
|
|
||||||
teacher_name = cursor.fetchone()[0]
|
|
||||||
#试卷ID
|
|
||||||
test_id = test[8]
|
|
||||||
|
|
||||||
choice_list = test[0]
|
|
||||||
completion_list = test[1]
|
|
||||||
judge_list = test[2]
|
|
||||||
choice_list = json.loads(choice_list)
|
|
||||||
completion_list = json.loads(completion_list)
|
|
||||||
judge_list = json.loads(judge_list)
|
|
||||||
|
|
||||||
# 初始化存储选项的列表
|
|
||||||
choice = []
|
|
||||||
completion = []
|
|
||||||
judge = []
|
|
||||||
|
|
||||||
for j in list(choice_list):
|
|
||||||
cursor.execute(f'SELECT * FROM CHOICE_QUESTION_BANK WHERE ID=(?)', (j))
|
|
||||||
choice.append(cursor.fetchall())
|
|
||||||
|
|
||||||
for j in list(completion_list):
|
|
||||||
cursor.execute(f'SELECT * FROM COMPLETION_QUESTION_BANK WHERE ID=(?)', (j))
|
|
||||||
completion.append(cursor.fetchall())
|
|
||||||
|
|
||||||
for j in list(judge_list):
|
|
||||||
cursor.execute(f'SELECT * FROM T_OR_F_QUESTION_BANK WHERE ID=(?)', (j))
|
|
||||||
judge.append(cursor.fetchall())
|
|
||||||
|
|
||||||
# 存储结果到test_succeed字典中
|
|
||||||
test_succeed[i] = [[choice, completion, judge], hour, min, releasetime, endtime,teacher_name,test_id]
|
|
||||||
|
|
||||||
# 在循环之外打印结果
|
|
||||||
return test_succeed
|
|
||||||
# fetch_test_func('20240101')
|
# fetch_test_func('20240101')
|
||||||
|
|
||||||
|
def falseTest_func(ID):
|
||||||
|
cursor = db.cursor()
|
||||||
|
FalseTestDic={}
|
||||||
|
NOTFalseTestDic={}
|
||||||
|
FalseTestID=[]
|
||||||
|
|
||||||
|
cursor.execute(f"SELECT * FROM STUDENT_TEST WHERE STUDENT_ID=? AND TF='false'",(ID))
|
||||||
|
for i in cursor.fetchall():
|
||||||
|
FalseTestID.append(i[3])
|
||||||
|
|
||||||
|
for index in FalseTestID:
|
||||||
|
cursor.execute(f"SELECT * FROM TEST_BANK WHERE ID=?",(index))
|
||||||
|
if cursor.fetchall()[0][6]>Time:
|
||||||
|
cursor.execute(f"SELECT * FROM TEST_BANK WHERE ID=?", (index))
|
||||||
|
FalseTestDic[index]=cursor.fetchall()[0]
|
||||||
|
else:
|
||||||
|
cursor.execute(f"SELECT * FROM TEST_BANK WHERE ID=?", (index))
|
||||||
|
NOTFalseTestDic[index]=cursor.fetchall()
|
||||||
|
|
||||||
|
return {'1':FalseTestDic,'2':NOTFalseTestDic}
|
||||||
|
|
||||||
|
|
||||||
|
# falseTest_func('20240101')
|
||||||
|
|
||||||
# 查找学生已经完成的记录
|
# 查找学生已经完成的记录
|
||||||
def find_end_test(ID):
|
def find_end_test(ID):
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
|
@ -280,6 +266,17 @@ def HistoryTrainFunc(ID):
|
||||||
|
|
||||||
# HistoryTrainFunc('20240101')
|
# HistoryTrainFunc('20240101')
|
||||||
|
|
||||||
|
def FindTrain1SrcFunc(ID,testID):
|
||||||
|
cursor=db.cursor()
|
||||||
|
cursor.execute("SELECT LINK FROM TRAINSCORE WHERE STUDENT_ID=? AND TEST_ID=?",(ID,testID))
|
||||||
|
result=cursor.fetchall()[0][0]
|
||||||
|
print(result)
|
||||||
|
cursor.close()
|
||||||
|
return result
|
||||||
|
|
||||||
|
# FindTrain1SrcFunc('20240101','3')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue