diff --git a/src/glcc/api.js b/src/glcc/api.js
index e86f2a6f..c0e710cd 100644
--- a/src/glcc/api.js
+++ b/src/glcc/api.js
@@ -152,6 +152,15 @@ export function getAuditList(params) {
});
}
+// 审核课题列表(匹配成功)
+export function getLockedAuditList(params) {
+ return fetch({
+ url: '/api/applyInformation/lockedAuditList',
+ method: 'get',
+ params,
+ });
+}
+
// 导师审核报名课题
export function auditPassTask(data) {
return fetch({
@@ -249,3 +258,31 @@ export async function findStudentTaskByTaskId(params) {
params: params,
});
}
+
+// 返回年月日时间
+export function formatParsedResult(setting, type= "range") {
+ if(setting && setting[0]){
+ const dataMap = setting[0].value.split(',');
+ const startDate = new Date(dataMap[0]);
+ const endDate = new Date(dataMap[1]);
+
+ const startYear = startDate.getFullYear();
+ const startMonth = startDate.getMonth() + 1;
+ const startDay = startDate.getDate();
+ const startHour = startDate.getHours();
+
+ const endYear = endDate.getFullYear();
+ const endMonth = endDate.getMonth() + 1;
+ const endDay = endDate.getDate();
+ const endHour = endDate.getHours();
+
+ let result = `${startYear}年${startMonth}月${startDay}日${startHour}点-${endYear}年${endMonth}月${endDay}日${endHour}点`;
+ if(type === "start"){
+ result= `${startYear}年${startMonth}月${startDay}日${startHour}点`;
+ }else if(type === "end"){
+ result= `${endYear}年${endMonth}月${endDay}日${endHour}点`;
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/glcc/home/index.jsx b/src/glcc/home/index.jsx
index 16e0086f..6dde7f5c 100644
--- a/src/glcc/home/index.jsx
+++ b/src/glcc/home/index.jsx
@@ -22,7 +22,7 @@ import './index.scss';
// period: 项目报名阶段("repoApply")
// match:{params:{id=2023}} 注意默认值记得每届修改
export default (props) => {
- const { current_user, history, round, match:{params:{id=2023}}, period, showLoginDialog, glccSettings, repoPublic, showMatchingBut, isResultPublic} = props;
+ const { current_user, history, round, match:{params:{id=2023}}, period, showLoginDialog, glccSettings, repoPublic, showMatchingBut, isResultPublic, hasRole, isMediumExamineByToTutor, checkedTaskId} = props;
useEffect(() => {
if (!current_user.user_id) {
@@ -51,7 +51,7 @@ export default (props) => {
*/}
{/* 往期回顾 */}
{round !== 2 &&
-
+
考核结果
@@ -123,30 +123,30 @@ export default (props) => {
查看各课题入选学生名单
}
- {/* 学生结项考核 */}
- {/* {!hasRole && checkedTaskId &&
+ {/* 学生中期考核 */}
+ {period === "mediumExamine1" && checkedTaskId &&

-
结项考核
+
中期考核
学生提交考核材料
- } */}
- {/* 导师结项考核 */}
- {/* {hasRole && new Date().getTime() > new Date('2022/10/01 8:0').getTime() &&
+ }
+ {/* 导师中期考核 */}
+ {hasRole && isMediumExamineByToTutor &&

-
结项考核
+
中期考核
-
导师拟定结项考核结果
- } */}
+
导师拟定中期考核结果
+ }
{/* 结项考核结果公示页 */}
- {/* {
+ {period === "mediumExamine3" &&
考核结果
-
结项课题考核结果公示
- } */}
+
中期课题考核结果公示
+ }
}
{/* */}
diff --git a/src/glcc/img/banner-interim1.png b/src/glcc/img/banner-interim1.png
new file mode 100644
index 00000000..457e2796
Binary files /dev/null and b/src/glcc/img/banner-interim1.png differ
diff --git a/src/glcc/img/resultBanner4.png b/src/glcc/img/resultBanner4.png
new file mode 100644
index 00000000..c56307f3
Binary files /dev/null and b/src/glcc/img/resultBanner4.png differ
diff --git a/src/glcc/index.jsx b/src/glcc/index.jsx
index d33d0bfa..3b4afac0 100644
--- a/src/glcc/index.jsx
+++ b/src/glcc/index.jsx
@@ -100,7 +100,8 @@ const Glcc = (propsF) => {
const [isMatching, setIsMatching] = useState(false);
// 导师-学生配对结果公示阶段
const [isResultPublic, setIsResultPublic] = useState(false);
- console.log('isResultPublic', isResultPublic);
+ // 导师中期考核评审阶段
+ const [isMediumExamineByToTutor, setIsMediumExamineByToTutor] = useState(false);
useEffect(()=>{
if(id && id === "2022"){
@@ -125,8 +126,11 @@ const Glcc = (propsF) => {
// 是否处于导师-学生配对结果公示阶段
const resultPublic = res.data.filter(item=>item.name === "stuPublic");
resultPublic[0] && setIsResultPublic(judge(nowTime, resultPublic[0].value, "range"))
+ // 是否处于导师中期考核评审阶段
+ const mediumExamine2 = res.data.filter(item=>item.name === "mediumExamine2");
+ mediumExamine2[0] && setIsMediumExamineByToTutor(judge(nowTime, mediumExamine2[0].value, "range"))
// 过滤掉 可并行进行的阶段
- const filterRepoPublic = res.data.filter(item=>["repoPublic", "repoApply1", "matching", "stuPublic"].indexOf(item.name) === -1);
+ const filterRepoPublic = res.data.filter(item=>["repoPublic", "repoApply1", "matching", "stuPublic", "mediumExamine2"].indexOf(item.name) === -1);
const periodIndex = filterRepoPublic.findIndex(item=>judge(nowTime, item.value, "range"));
periodIndex !== -1 && setPeriod(filterRepoPublic[periodIndex].name);
}
@@ -164,17 +168,17 @@ const Glcc = (propsF) => {
const [hasRole, setHasRole] = useState(false);
useEffect(() => {
- // 登录状态+导师-学生配对阶段
- current_user && current_user.user_id && isMatching && hasAuditRole({ userId: current_user.user_id, round: currentRound }).then(res => {
+ // 登录状态+导师-学生配对阶段/中期审核
+ current_user && current_user.user_id && (isMatching || isMediumExamineByToTutor) && hasAuditRole({ userId: current_user.user_id, round: currentRound }).then(res => {
if (res && res.message === 'success' && res.data.hasRole) {
setHasRole(true);
}
})
- }, [current_user, isMatching])
+ }, [current_user, isMatching, isMediumExamineByToTutor])
useEffect(()=>{
- // 获取用户课题报名信息(todo:学生报名阶段请求)
- (period === "stuApply" || period === "stuApply1") && current_user && current_user.login && getStudentApplyInfo({userId: current_user.user_id, round: round}).then(response=>{
+ // 获取用户课题报名信息
+ (period === "stuApply" || period === "stuApply1" || period === "mediumExamine1") && current_user && current_user.login && getStudentApplyInfo({userId: current_user.user_id, round: round}).then(response=>{
if(response && response.message === "success"){
// setData(response.data.rows);
const data = {};
@@ -182,8 +186,9 @@ const Glcc = (propsF) => {
response.data && response.data.registrationStudentTaskList.map(item=>{
data[item.taskId] = item.id;
item.locked && setLockedTaskName(item.taskName);
- item.passStatus && item.mediumExaminationPass && setCheckedTaskId(item.taskId);
- item.passStatus && item.mediumExaminationPass && setStudentRegId(item.studentRegId);
+ // 结项考核: && item.mediumExaminationPass
+ item.locked && setCheckedTaskId(item.taskId);
+ item.locked && setStudentRegId(item.studentRegId);
// 取当前报名的课题数()
if(item.subRound === 1){
data1[item.taskId] = item.id;
@@ -308,34 +313,34 @@ const Glcc = (propsF) => {
>
{/* 中期审核-结果公示 */}
-
(
)}
- >
+ >}
{/* 中期审核-学生 */}
-
(
-
+
)}
- >
+ >}
{/* 中期审核-导师 */}
-
(
-
+
)}
- >
+ >}
{/* 首页 */}
(
-
+
)}
>
@@ -343,7 +348,7 @@ const Glcc = (propsF) => {
(
-
+
)}
>
diff --git a/src/glcc/interimReview/result.jsx b/src/glcc/interimReview/result.jsx
index a32c810d..4aa7536d 100644
--- a/src/glcc/interimReview/result.jsx
+++ b/src/glcc/interimReview/result.jsx
@@ -3,6 +3,7 @@ import { Input, Table, Tooltip, Checkbox } from 'antd';
import { getMediumTermExamineInfoList } from '../api';
import ProjectDetail from '../project/component/projectDetail';
import resultBanner from "../img/resultBanner3.png";
+import resultBanner1 from "../img/resultBanner4.png";
import bgPng from "../img/bgPng.png";
import './index.scss';
import '../checkResult/index.scss';
@@ -11,7 +12,7 @@ import '../project/index.scss';
const { Search } = Input;
// 课题列表
-function CheckResult({current_user, history, round, id}) {
+function CheckResult({round, id}) {
// 输入搜索框
const [keyword, setKeyword] = useState(undefined);
const [data, setData] = useState([]);
@@ -29,7 +30,7 @@ function CheckResult({current_user, history, round, id}) {
curPage: current,
keyword,
pageSize,
- term: 2,
+ term: id === "2023" ? 1 : 2,
round
}
getMediumTermExamineInfoList(params).then(response => {
@@ -97,10 +98,10 @@ function CheckResult({current_user, history, round, id}) {
return (
-

+
-
+
开源夏令营 / {id === "2023" ? '中期' : '结项'}课题考核结果公示
{ setCurrent(1); setKeyword(value) }} />
diff --git a/src/glcc/interimReview/studentSubmit.jsx b/src/glcc/interimReview/studentSubmit.jsx
index 75974551..ff4619b2 100644
--- a/src/glcc/interimReview/studentSubmit.jsx
+++ b/src/glcc/interimReview/studentSubmit.jsx
@@ -2,28 +2,37 @@ import React, { useEffect, useState } from "react";
import { Form, Upload, Input, Icon, Button, message, Modal } from "antd";
import { Link } from "react-router-dom";
import banner from '../img/banner-interim.png';
+import banner1 from '../img/banner-interim1.png';
import img1 from '../img/img1.png';
import bg from '../img/bgPng.png';
import { httpUrl, main_site_url } from '../fetch';
-import {getMediumTermExamineInfo, submitMedium} from '../api';
+import {getMediumTermExamineInfo, submitMedium, formatParsedResult} from '../api';
import './index.scss';
function StudentSubmit(props){
- const {form, checkedTaskId, studentRegId, history} = props;
+ const {form, checkedTaskId, studentRegId, period, currentRound, glccSettings, isMediumExamineByToTutor} = props;
+ const mediumExamine = glccSettings && glccSettings.filter(item=>item.name === "mediumExamine1");
+ const mediumExamine2 = glccSettings && glccSettings.filter(item=>item.name === "mediumExamine2");
+ let overtime = false;
+ if(mediumExamine2 && mediumExamine2[0]){
+ const nowTime = new Date().getTime();
+ const timeArr = mediumExamine2[0].value.split(",").map(item=>{
+ // replaceAll不兼容低版本浏览器(如搜狗)
+ const data = item && item.replace(/-/g,'/');
+ return new Date(data).getTime()
+ });
+ overtime = nowTime > timeArr[1];
+ }
const {getFieldDecorator, validateFieldsAndScroll } = form;
const [detail, setDetail] = useState(undefined);
const [reload, setReload] = useState(undefined);
const [fileList, setFileList] = useState(undefined);
// 学生提交信息之后按钮置灰(确保无重复提交)
const [disabled, setDisabled] = useState(false);
- // 学生提交材料时间
- const submitTime = new Date().getTime() < new Date('2022/10/17 24:0').getTime();
- // 学生提醒导师评分时间
- const lookTime = new Date().getTime() > new Date('2022/10/15 0:0').getTime() && new Date().getTime() < new Date('2022/10/23 24:0').getTime();
useEffect(()=>{
// 查询是否已经提交考核材料
- checkedTaskId && getMediumTermExamineInfo(checkedTaskId,{term: 2}).then(res=>{
+ checkedTaskId && getMediumTermExamineInfo(checkedTaskId,{round: currentRound, term: period === "mediumExamine1" ? 1 : 2}).then(res=>{
if(res && res.message === "success"){
setDetail(res.data);
}
@@ -37,18 +46,19 @@ function StudentSubmit(props){
validateFieldsAndScroll((err, values) => {
if(!err){
Modal.confirm({
- title: "确认提交结项考核材料?",
+ title: `确认提交${period === "mediumExamine1" ? '中期' : '结项'}考核材料?`,
content: "提交后将无法修改考核材料,请进行二次确认",
onOk: ()=>{
const {pptAttachment, defenceVideoUrl, codeOrPrUrl} = values;
- const pptAttachmentId = pptAttachment.file.response.data.id;
+ const pptAttachmentId = pptAttachment.file && pptAttachment.file.response && pptAttachment.file.response.data.id;
const params = {
pptAttachmentId,
codeOrPrUrl,
defenceVideoUrl,
taskId: checkedTaskId,
studentRegId: studentRegId,
- term: 2
+ round: currentRound,
+ term: period === "mediumExamine1" ? 1 : 2
}
submitMedium(params).then(res=>{
if(res && res.message === "success"){
@@ -72,30 +82,38 @@ function StudentSubmit(props){
}
})
}
- // 检查文件上传是否符合规定
+
function changeFileList(e) {
- const {fileList} = e;
- const lastFile = fileList.splice(fileList.length-1, fileList.length);
- setFileList(lastFile);
+ const {file} = e;
+ file && file.status && setFileList([file]);
+ }
+
+ // 检查文件上传是否符合规定
+ function beforeUpload(file){
+ const isLt100M = file.size / 1024 / 1024 < 100;
+ if (!isLt100M) {
+ message.error(`文件大小必须小于${100}MB!`);
+ }
+ return isLt100M;
}
return
-

+
-
开源夏令营 / 提交结项考核材料
+
开源夏令营 / 提交{period === "mediumExamine1" ? '中期' : '结项'}考核材料
材料提交说明:
-
1、请各位学生
下载PPT模板 ,根据课题开发进展,按照PPT模板要求填写课题学习调研方案、开发进度及开发成果等考核材料;
+
1、请各位学生
下载PPT模板 ,根据课题开发进展,按照PPT模板要求填写课题学习调研方案、开发进度及开发成果等考核材料;
2、欢迎各位学生录制本课题答辩视频,将视频链接填写至下方视频介绍填写栏;
-
3、学生提交考核材料的时间为2022年10月1日8点至2022年10月14日24点,请在截止时间前提交;
+
3、学生提交考核材料的时间为{formatParsedResult(mediumExamine)},请在截止时间前提交;
4、若导师已给出评分,各位学生可在此页面查看自己的结项考核成绩。对考核成绩有异议的学生请及时联系您的导师。

- 结项考核
+ {period === "mediumExamine1" ? '中期' : '结项'}考核
- {submitTime && !detail ?
{getFieldDecorator('defenceVideoUrl', {
rules: [{ required: true, message: '请输入视频链接!'}, {pattern: /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/,message: "请正确输入链接"}],
@@ -109,7 +127,7 @@ function StudentSubmit(props){
{getFieldDecorator('pptAttachment', {
rules: [{ required: true, message: '请上传PPT附件!' }],
- })(
+ })(
)}
@@ -122,8 +140,8 @@ function StudentSubmit(props){
{!detail &&
很遗憾,您在指定时间内未提交考核材料
}
- {detail && lookTime && !detail.glccTutorEvaluation &&
您的课题导师暂未评分,请提醒导师尽快提交结项考核评分
}
- {detail && new Date().getTime() > new Date('2022/10/24 10:0').getTime() && !detail.glccTutorEvaluation &&
很遗憾,您的导师尚未评分,您未通过结项考核
}
+ {detail && isMediumExamineByToTutor && !detail.glccTutorEvaluation &&
您的课题导师暂未评分,请提醒导师尽快提交结项考核评分
}
+ {detail && overtime && !detail.glccTutorEvaluation &&
很遗憾,您的导师尚未评分,您未通过结项考核
}
{detail && detail.glccTutorEvaluation &&
您的课题导师对您的结项考核评价如下,如有异议,请及时联系导师进行更改。
diff --git a/src/glcc/interimReview/tutorReview.jsx b/src/glcc/interimReview/tutorReview.jsx
index 0820ce2a..c0636232 100644
--- a/src/glcc/interimReview/tutorReview.jsx
+++ b/src/glcc/interimReview/tutorReview.jsx
@@ -2,7 +2,7 @@ import React, {useState, useEffect, useCallback} from "react";
import { Form, Input, Icon, Button, Tabs, Radio, message } from "antd";
import { Link } from "react-router-dom";
import bg from '../img/bgPng.png';
-import { getAuditList, getMediumTermExamineInfo, submitTutorEvaluation, updateTutorEvaluation, hasAuditRole } from '../api';
+import { getLockedAuditList, getMediumTermExamineInfo, submitTutorEvaluation, updateTutorEvaluation, hasAuditRole, formatParsedResult } from '../api';
import './index.scss';
import '../check/index.scss'
import Nodata from "../../forge/Nodata";
@@ -11,7 +11,7 @@ const { TabPane } = Tabs;
const { TextArea } = Input;
function TutorReview(props){
- const {form, current_user, showNotification, history} = props;
+ const {form, current_user, showNotification, history, hasRole, isMediumExamineByToTutor, currentRound, glccSettings} = props;
const {getFieldDecorator, setFieldsValue, validateFieldsAndScroll, resetFields } = form;
const [taskId, setTaskId] = useState();
const [taskList, setTaskList] = useState([]);
@@ -22,20 +22,15 @@ function TutorReview(props){
const [isEdit, setIsEdit] = useState(false);
// 导师提交信息之后按钮置灰(确保无重复提交)
const [disabled, setDisabled] = useState(false);
-
+ const mediumExamine2 = glccSettings && glccSettings.filter(item=>item.name === "mediumExamine2");
+ const mediumExamine3 = glccSettings && glccSettings.filter(item=>item.name === "mediumExamine3");
useEffect(() => {
- if(!new Date().getTime() > new Date('2022/10/01 8:0').getTime()){
+ if(!isMediumExamineByToTutor || !hasRole){
history.push("/glcc");
}else if (!current_user.login) {
- history.push('/login?go_page=/glcc/final/examination');
- }else{
- hasAuditRole({ userId: current_user.user_id }).then(res => {
- if (!(res && res.message == 'success' && res.data.hasRole)) {
- history.push('/glcc');
- }
- })
+ history.push('/login?go_page=/glcc/middle/examination');
}
- getAuditList({ userId: current_user.user_id, pass: 1 }).then(res => {
+ getLockedAuditList({ userId: current_user.user_id, pass: 1, round: currentRound }).then(res => {
if (res.message === 'success') {
const filterStuNull = res.data.rows.filter(item=>{return item.studentName !== null})
setTaskList(filterStuNull);
@@ -48,7 +43,8 @@ function TutorReview(props){
useEffect(()=>{
// 查询是否已经提交考核材料
- taskId && getMediumTermExamineInfo(taskId,{term: 2}).then(res=>{
+ // 结项考核
+ taskId && getMediumTermExamineInfo(taskId,{round: currentRound, term: isMediumExamineByToTutor ? 1 : 2}).then(res=>{
if(res && res.message === "success"){
setDetail(res.data);
if(res && res.data && res.data.glccTutorEvaluation){
@@ -69,7 +65,8 @@ function TutorReview(props){
...values,
mediumTermExamineMaterialId: detail.id,
tutorUserId: detail.studentRegId,
- term: 2
+ round: currentRound,
+ term: isMediumExamineByToTutor ? 1 : 2
}
if(detail.glccTutorEvaluation){
params['id'] = detail.glccTutorEvaluation.id;
@@ -88,6 +85,8 @@ function TutorReview(props){
}
})
}
+ }else{
+ setDisabled(false);
}
})
}
@@ -116,9 +115,13 @@ function TutorReview(props){
导师考核说明:
1、请各位导师从“工作态度”“开发进度”“项目完成质量”“总体评分”四个角度,根据学生提交的考核材料与实际开发情况客观地进行打分。打分标准分为:S:特别优秀、A:优秀、B:良好、C:合格、D:不合格五个等级。
-
2、“总体评分”这一项将决定学生是否通过本次考核。若总体评分为“S、A、B、C”,则视为通过结项考核。若该结果为“D”,则该课题结项考核不通过,不予发放结项奖金。请各位导师谨慎做出评价。
+
2、“总体评分”这一项将决定学生是否通过本次考核。若总体评分为“S、A、B、C”,则视为通过中期考核。若该结果为“D”,则该课题中期考核不通过,课题将自动终止。请各位导师谨慎做出评价。
+
3、导师提交打分结果后,可对考核结果进行更改,更改考核结果截止日期为{mediumExamine2 && formatParsedResult(mediumExamine2, 'end')}。
+
4、北京时间{mediumExamine3 && formatParsedResult(mediumExamine3, "start")}前GLCC官网将公布中期考核结果,敬请留意。
+ {/* 结项考核文案 */}
+ {/*
2、“总体评分”这一项将决定学生是否通过本次考核。若总体评分为“S、A、B、C”,则视为通过结项考核。若该结果为“D”,则该课题结项考核不通过,不予发放结项奖金。请各位导师谨慎做出评价。
3、导师提交打分结果后,可对考核结果进行更改,期间考核结果也将实时反馈给学生;更改考核结果截止时间为2022年10月20日24点。
-
4、北京时间2022年10月24日20点前GLCC官网将公布结项考核结果,敬请留意。
+
4、北京时间2022年10月24日20点前GLCC官网将公布结项考核结果,敬请留意。
*/}
{ resetFields(); setTaskId(e); setIsEdit(false); setWordNum(0); setDisabled(false);}} activeKey={taskId + ''}>
@@ -175,7 +178,7 @@ function TutorReview(props){
{wordNum} / 2000
{/* 导师结项考核时间为true */}
- {false &&
+ {isMediumExamineByToTutor &&
{(!detail.glccTutorEvaluation || (detail.glccTutorEvaluation && isEdit)) && }
{detail.glccTutorEvaluation && !isEdit && }
}