diff --git a/src/glcc/img/banner-interim.png b/src/glcc/img/banner-interim.png
new file mode 100644
index 000000000..38f6bb7d9
Binary files /dev/null and b/src/glcc/img/banner-interim.png differ
diff --git a/src/glcc/img/img1.png b/src/glcc/img/img1.png
new file mode 100644
index 000000000..084309c1e
Binary files /dev/null and b/src/glcc/img/img1.png differ
diff --git a/src/glcc/img/img2.png b/src/glcc/img/img2.png
new file mode 100644
index 000000000..5f8c18c29
Binary files /dev/null and b/src/glcc/img/img2.png differ
diff --git a/src/glcc/img/resultBanner3.png b/src/glcc/img/resultBanner3.png
new file mode 100644
index 000000000..b15d8c1e8
Binary files /dev/null and b/src/glcc/img/resultBanner3.png differ
diff --git a/src/glcc/index.jsx b/src/glcc/index.jsx
index f5908e001..2afd4ff40 100644
--- a/src/glcc/index.jsx
+++ b/src/glcc/index.jsx
@@ -61,6 +61,21 @@ const Result = Loadable({
loader: () => import("./checkResult"),
loading: Loading,
});
+// 中期考核-学生
+const StudentSubmit = Loadable({
+ loader: () => import("./interimReview/studentSubmit"),
+ loading: Loading,
+});
+// 中期考核-导师
+const TutorReview = Loadable({
+ loader: () => import("./interimReview/tutorReview"),
+ loading: Loading,
+});
+// 中期考核-结果公示
+const MiddleResult = Loadable({
+ loader: () => import("./interimReview/result"),
+ loading: Loading,
+});
const Glcc = (propsF) => {
const {current_user, showLoginDialog} = propsF;
// 判断时间是否在开源夏令营报名时间内(4月15日~5月20日)
@@ -70,6 +85,10 @@ const Glcc = (propsF) => {
const studentApplyStart = new Date().getTime() > new Date('2022-05-26').getTime();
const isStudentApplyDate = new Date().getTime() > new Date('2022-05-26').getTime() && new Date().getTime() < new Date('2022-06-25 0:0').getTime();
const secondStudentApplyDate = new Date().getTime() > new Date('2022-06-29 1:0').getTime() && new Date().getTime() < new Date('2022-06-30 0:0').getTime();
+ // 学生中期考核提交资料时间
+ const checkTime1 = new Date().getTime() > new Date('2022-08-12 8:0').getTime() && new Date().getTime() < new Date('2022-08-18 24:0').getTime();
+ // 导师中期考核时间
+ const checkTime2 = new Date().getTime() > new Date('2022-08-12 10:0').getTime() && new Date().getTime() < new Date('2022-08-24 24:0').getTime();
// 用户已报名课题id数组
const [applyTaskId, setApplyTaskId] = useState({});
@@ -78,6 +97,8 @@ const Glcc = (propsF) => {
const [cancelCount,setCancelCount]=useState(0);
// 用户是否已经被导师选中
const [lockedTaskName, setLockedTaskName] = useState(undefined);
+ // 用户与导师双向选定的课题id
+ const [checkedTaskId, setCheckedTaskId] = useState(undefined);
useEffect(()=>{
// 获取用户课题报名信息current_user user_id
@@ -88,6 +109,7 @@ const Glcc = (propsF) => {
response.data && response.data.registrationStudentTaskList.map(item=>{
data[item.taskId] = item.id;
item.locked && setLockedTaskName(item.taskName);
+ item.passStatus && setCheckedTaskId(item.taskId);
})
setApplyTaskId(data);
response.data&&setCancelCount(Number(response.data.cancelCount));
@@ -183,11 +205,35 @@ const Glcc = (propsF) => {
)}
>
+ {/* 中期审核-结果公示 */}
+
(
+
+ )}
+ >
+
+ {/* 中期审核-学生 */}
+
(
+
+ )}
+ >
+
+ {/* 中期审核-导师 */}
+
(
+
+ )}
+ >
+
{/* 首页 */}
(
-
+
)}
>
diff --git a/src/glcc/interimReview/index.scss b/src/glcc/interimReview/index.scss
new file mode 100644
index 000000000..a03467f85
--- /dev/null
+++ b/src/glcc/interimReview/index.scss
@@ -0,0 +1,191 @@
+.interimBox{
+ background-image:linear-gradient(180deg,#ebf2ff 0%,#ebf2ff 43.09%,#f3f4f8 100%);
+ padding-bottom: 125px;
+ position: relative;
+ .bg1, .bg2{
+ width: 150px;
+ position: absolute;
+ top: 45%;
+ left: 6%;
+ }
+ .bg2{
+ top: auto;
+ left: auto;
+ right: 20%;
+ bottom: 0;
+ }
+ &.glcc-check .bg1{top: 36%;}
+ .bannerInterim{
+ width: 100%;
+ }
+ .navBox{
+ padding: 20px 0 10px;
+ color:#202d40;
+ border-bottom: 1px dashed #bec5d5;
+ .linkBox{
+ color:#a4aabb;
+ &:hover{color: $primary-color;}
+ }
+ }
+ .mainBox{
+ width: 1200px;
+ margin: 0 auto;
+ z-index: 1;
+ position: relative;
+ }
+ .tipBox{
+ padding: 12px 20px;
+ color:#6c7283;
+ line-height: 2.5;
+ background-color:#e4edff;
+ .spanBox{color: #000;}
+ div{line-height: 1.8;margin-bottom: 10px;}
+ }
+ .titleBox{color: #333;}
+ .referBox{
+ margin-top: 25px;
+ background-color:rgba(255, 255, 255, 0.27);
+ border:1px solid #ffffff;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-around;
+ padding: 30px 0;
+ position: relative;
+ .referItem{
+ width: 47%;
+ display: flex;
+ .ant-form-item-control-wrapper{flex-grow: 1;}
+ &.oneCont{
+ width: 97%;
+ .ant-upload-list-item{width: 30%;}
+ .ant-upload-list-item:hover .ant-upload-list-item-info{background: none;}
+ }
+ .ant-input, .uploadBox{
+ border-color:#b3c3db;
+ background: none !important;
+ }
+ .contentBox{
+ padding: 10px 11px 20px
+ }
+ }
+ &.tutor{
+ border: none;
+ margin-top: -20px;
+ background: none;
+ .remarkBox{
+ position: relative;
+ flex: 0.97;
+ }
+ .oneCont{display: block;}
+ .wordNum{
+ position: absolute;
+ right: 55px;
+ bottom: 10px;
+ }
+ .referItem{margin-bottom: 5px;}
+ }
+ }
+ .tutorContent{
+ border: 1px solid #fff;
+ margin-top: 40px;
+ background-color: #f1f6ff;
+ .task-tabs {
+ margin-top: 0px;
+ border: none;
+ background: none;
+ .task-title-stuName{
+ font-weight:700;
+ color:#6c7283;
+ padding-bottom: 25px;
+ border-bottom:1px dashed #bec5d5;
+ }
+ }
+ }
+ .reviewBox{
+ .title{
+ color:#333333;
+ display: flex;
+ align-items: center;
+ .blueBox{
+ display: inline-block;
+ width:5px;
+ height:14px;
+ background-color:#466aff;
+ margin-right: 8px;
+ }
+ }
+ .flexBox{
+ color:#202d40;
+ border-bottom: 1px dashed #bec5d5;
+ div{
+ display: flex;
+ align-items: baseline;
+ margin-bottom: 10px;
+ .blueSpan{
+ color: $primary-color;
+ word-break: break-all;
+ display: block;
+ flex: 1;
+ }
+ .pptAttachment{
+ color: $primary-color;
+ max-width: 80%;
+ }
+ }
+ }
+ }
+ .resultBox{
+ padding: 30px 20px 50px 20px;
+ .blueBg{
+ width: 85%;
+ display: inline-block;
+ padding: 4px 10px;
+ background-color:rgba(70, 106, 255, 0.05);
+ border-radius:4px;
+ word-break: break-all;
+ }
+ .mustSpan{
+ position: relative;
+ padding-left: 10px;
+ &::before{
+ content: '*';
+ color: #ff3838;
+ font-size: 18px;
+ position: absolute;
+ left: 8px;
+ top: 3px;
+ }
+ &.ppt::before{
+ top: -2px;
+ left: 12px;
+ }
+ }
+ .flexBox{
+ border: none;
+ width: 100%;
+ }
+ .tutorRes{
+ background-color:rgba(107, 136, 255, 0.05);
+ border-radius:4px;
+ color:#6c7283;
+ padding: 16px 30px 30px 20px;
+ .smallTil{
+ color: #202d40;
+ }
+ .blueSpan{color: $primary-color;}
+ }
+ .tutorRemark{
+ flex: 1;
+ color:#6c7283;
+ }
+ }
+}
+.interimBox.resultListBox{
+ .searchBox{
+ display: flex;
+ align-items: center;
+ }
+ .resultListTable th.columnsResult.actionBox .ant-table-column-title{
+ visibility: visible;
+ }
+}
\ No newline at end of file
diff --git a/src/glcc/interimReview/result.jsx b/src/glcc/interimReview/result.jsx
new file mode 100644
index 000000000..48395b85b
--- /dev/null
+++ b/src/glcc/interimReview/result.jsx
@@ -0,0 +1,141 @@
+import React, { useEffect, useState } from 'react';
+import { Input, Table, Tooltip, Checkbox } from 'antd';
+import { getPassList, hasAuditRole } from '../api';
+import ProjectDetail from '../project/component/projectDetail';
+import resultBanner from "../img/resultBanner3.png";
+import bgPng from "../img/bgPng.png";
+import './index.scss';
+import '../checkResult/index.scss';
+import '../project/taskList/index.scss';
+import '../project/index.scss';
+const { Search } = Input;
+
+// 课题列表
+function CheckResult({current_user, history}) {
+ // 输入搜索框
+ // 已通过
+ const [pass, setPass] = useState(false);
+ const [keyword, setKeyword] = useState(undefined);
+ const [data, setData] = useState([]);
+ // table
+ const [current, setCurrent] = useState(1);
+ const [total, setTotal] = useState(0);
+ const [pageSize, setPageSize] = useState(20);
+ const [loading, setLoading] = useState(false);
+ const [expandedRowKeys, setExpandedRowKeys] = useState([]);
+ const time = new Date().getTime() > new Date('2022-06-28 1:0').getTime() && new Date().getTime() < new Date('2022-07-01 0:0').getTime();
+
+ useEffect(()=>{
+ // 未到时间
+ if(new Date().getTime() < new Date('2022-06-28 1:0').getTime()){
+ history.push('/glcc');
+ }
+ hasAuditRole({ userId: current_user.user_id }).then(res => {
+ // 7.1之前 普通用户不可以进入此页面
+ if (!(res && res.message == 'success' && res.data.hasRole) && new Date().getTime() < new Date('2022-07-01 12:0').getTime()) {
+ history.push('/glcc');
+ }
+ })
+ },[])
+
+ useEffect(() => {
+ setLoading(true);
+ setExpandedRowKeys([]);
+ const params = {
+ curPage: current,
+ keyword,
+ pageSize,
+ }
+ getPassList(params).then(response => {
+ if (response && response.message === "success") {
+ setData(response.data.rows);
+ setTotal(response.data.total);
+ }
+ setLoading(false);
+ })
+ }, [keyword, current, pageSize])
+
+ const columns = [
+ { title: '序号', dataIndex: 'index', align: 'center', className:"columnsResult", width: '6%', render: (text, item, index) =>
{(current-1)*pageSize+index + 1} },
+ { title: '入选学生', dataIndex: 'studentName', className:"columnsResult taskName", width: '10%', ellipsis: true},
+ { title: '课题导师', dataIndex: 'tutorName', className:"columnsResult", width: '10%', ellipsis: true},
+ { title: '课题名称', dataIndex: 'taskName', className:"columnsResult", width: '20%', ellipsis: true, render: (text, item) =>
{window.open(`/glcc/subjects/detail/${item.taskId}`)}}>{text} },
+ { title: '项目名称', dataIndex: 'projectName', className:"columnsResult", ellipsis: true, width: '14%', render: (text) =>
{text} },
+ { title: '项目简介', dataIndex: 'introduce', className:"columnsResult", width: '13%', ellipsis: true},
+ { title: '答辩视频', dataIndex: 'tutorName', className:"columnsResult", width: '15%', ellipsis: true, render: (text, item) =>
{window.open(`/glcc/subjects/detail/${item.taskId}`)}}>{text}},
+ { title: '考核结果', dataIndex: 'action', align: 'center', className:"columnsResult actionBox", render: (text, item, index) =>
{'未通过'}},
+ ]
+
+ const customExpandIcon = (props) => {
+ if (props.expanded) {
+ return
{
+ props.onExpand(props.record, e);
+ }}>项目简介
+ } else {
+ return
{
+ props.onExpand(props.record, e);
+ }}>项目简介
+ }
+ }
+
+ const expandRow = (record) => {
+ return
+ }
+
+ // 展开收起行回调
+ function onExpand(expanded, record){
+ const keys = new Set(expandedRowKeys);
+ if(expanded){
+ keys.add(record.id);
+ }else{
+ keys.delete(record.id);
+ }
+ setExpandedRowKeys(Array.from(keys));
+ }
+
+ // 改变pagesize
+ function onShowSizeChange(current, pageSize){
+ window.scrollTo(0, 0);
+ setCurrent(1);
+ setPageSize(pageSize);
+ }
+
+ // 切换页数
+ function changePage(page, pageSize){
+ window.scrollTo(0, 0);
+ setCurrent(page);
+ }
+
+ return (
+
+

+
+
+
+
+
{setCurrent(1);setPass(e.target.checked)}}>已通过
+
{ setCurrent(1); setKeyword(value) }} />
+
+
+
+
+

+

+
+
+ )
+}
+export default CheckResult;
\ No newline at end of file
diff --git a/src/glcc/interimReview/studentSubmit.jsx b/src/glcc/interimReview/studentSubmit.jsx
new file mode 100644
index 000000000..0807460c9
--- /dev/null
+++ b/src/glcc/interimReview/studentSubmit.jsx
@@ -0,0 +1,114 @@
+import React, { useEffect, useState } from "react";
+import { Form, Upload, Input, Icon, Button } from "antd";
+import { Link } from "react-router-dom";
+import banner from '../img/banner-interim.png';
+import img1 from '../img/img1.png';
+import bg from '../img/bgPng.png';
+import { main_site_url, httpUrl } from '../fetch';
+import {getMediumTermExamineInfo, submitMedium} from '../api';
+import './index.scss';
+
+function StudentSubmit(props){
+ const {form, checkedTaskId, checkTime1} = props;
+ const {getFieldDecorator, validateFieldsAndScroll } = form;
+ const [detail, setDetail] = useState(undefined);
+ const [reload, setReload] = useState(undefined);
+ const [fileList, setFileList] = useState(undefined);
+
+ useEffect(()=>{
+ if(!checkTime1){
+ window.location.href="/glcc";
+ }
+ }, [])
+
+ useEffect(()=>{
+ // 查询是否已经提交考核材料
+ checkedTaskId && getMediumTermExamineInfo(checkedTaskId).then(res=>{
+ if(res && res.message === "success"){
+ setDetail(res.data);
+ }
+ })
+ },[checkedTaskId, reload])
+
+ // 学生提交材料
+ function submit(e){
+ e.preventDefault();
+ validateFieldsAndScroll((err, values) => {
+ if(!err){
+ const {pptAttachment, defenceVideoUrl, codeOrPrUrl} = values;
+ const pptAttachmentId = pptAttachment.file.response.data.id;
+ const params = {
+ pptAttachmentId,
+ codeOrPrUrl,
+ defenceVideoUrl,
+ taskId: checkedTaskId,
+ studentRegId: detail.studentRegId
+ }
+ console.log('params', params);
+ submitMedium(params).then(res=>{
+ console.log('提交', res);
+ if(res && res.message === "success"){
+ setReload(Math.random());
+ }
+ })
+ }
+ })
+ }
+ // 检查文件上传是否符合规定
+ function changeFileList(e) {
+ const {fileList} = e;
+ const lastFile = fileList.splice(fileList.length-1, fileList.length);
+ setFileList(lastFile);
+ }
+ return
+

+

+

+
+
开源夏令营 / 提交中期考核材料
+
+
材料提交说明:
+
1、请各位学生下载PPT模板 ,根据课题开发进展,按照PPT模板要求填写课题学习调研方案、开发进度及开发成果、下半阶段工作计划等考核材料;
+
2、欢迎各位学生录制本课题答辩视频,将视频链接填写至下方视频介绍填写栏;
+
3、学生提交考核材料的时间为2022年8月12日8点至2022年8月18日24点,请在截止时间前提交。若在截止时间未提交中期考核表,则默认自动放弃,该课题将自动终止。
+
+
+

+ 中期考核
+
+ {!detail ?
+ {getFieldDecorator('defenceVideoUrl', {
+ rules: [{ required: true, message: '请输入视频链接!'}, {pattern: /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/,message: "请正确输入链接"}],
+ })()}
+
+
+ {getFieldDecorator('codeOrPrUrl', {
+ rules: [{pattern: /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/,message: "请正确输入链接"}],
+ })()}
+
+
+ {getFieldDecorator('pptAttachment', {
+ rules: [{ required: true, message: '请输入代码或pr链接!' }],
+ })(
+ )}
+
+
+
+
+ :
+
+ {detail.glccTutorEvaluation &&
+
您的课题导师对您的中期考核评价如下,如有异议,请及时联系导师进行更改。
+
工作态度: A
开发进度: B
项目完成质量: C
总体评分: D
+
导师评语: 此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语此处为导师评语
+
}
+
}
+
+
+}
+export default Form.create()(StudentSubmit);
\ No newline at end of file
diff --git a/src/glcc/interimReview/tutorReview.jsx b/src/glcc/interimReview/tutorReview.jsx
new file mode 100644
index 000000000..fb6098a84
--- /dev/null
+++ b/src/glcc/interimReview/tutorReview.jsx
@@ -0,0 +1,172 @@
+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 } from '../api';
+import './index.scss';
+import '../check/index.scss'
+import Nodata from "../../forge/Nodata";
+import {httpUrl} from '../fetch';
+const { TabPane } = Tabs;
+const { TextArea } = Input;
+
+function TutorReview(props){
+ const {form, current_user, showNotification, checkTime2} = props;
+ const {getFieldDecorator, setFieldsValue, validateFieldsAndScroll } = form;
+ const [taskId, setTaskId] = useState();
+ const [taskList, setTaskList] = useState([]);
+ const [wordNum, setWordNum] = useState(0);
+ const [detail, setDetail] = useState(undefined);
+ const [reload, setReload] = useState(undefined);
+
+ useEffect(() => {
+ if(!checkTime2){
+ window.location.href="/glcc";
+ }else{
+ getAuditList({ userId: current_user.user_id, pass: 1 }).then(res => {
+ if (res.message == 'success') {
+ setTaskList(res.data.rows);
+ res.data.rows.length && setTaskId(res.data.rows[0].id);
+ } else {
+ res && showNotification(res.message || '查询课题列表失败');
+ }
+ })
+ }
+ }, [])
+
+ useEffect(()=>{
+ // 查询是否已经提交考核材料
+ taskId && getMediumTermExamineInfo(taskId).then(res=>{
+ if(res && res.message === "success"){
+ setDetail(res.data);
+ if(res && res.data && res.data.glccTutorEvaluation){
+ const {totalityEvaluation, comment} = res.data.glccTutorEvaluation;
+ console.log('totalityEvaluation', totalityEvaluation, comment);
+ setFieldsValue({...res.data.glccTutorEvaluation});
+ }
+ }
+ })
+ },[taskId, reload])
+
+ // 学生提交材料
+ function submit(e){
+ e.preventDefault();
+ validateFieldsAndScroll((err, values) => {
+ console.log('aaa', err, values);
+ if(!err){
+ const params = {
+ ...values,
+ mediumTermExamineMaterialId: detail.id,
+ tutorUserId: detail.studentRegId
+ }
+ if(detail.glccTutorEvaluation){
+ params['id'] = detail.glccTutorEvaluation.id;
+ updateTutorEvaluation(params).then(res=>{
+ if(res && res.message === "success"){
+ console.log('评论', res);
+ message.success("修改成功");
+ setReload(Math.random());
+ }
+ })
+ }else{
+ submitTutorEvaluation(params).then(res=>{
+ if(res && res.message === "success"){
+ console.log('评论', res);
+ message.success("您已成功评分");
+ setReload(Math.random());
+ }
+ })
+ }
+ }
+ })
+ }
+
+ const RadioGroup =
+ A
+ B
+ C
+ D
+ ;
+
+ const helper = useCallback(
+ (label, name, rules, widget, className) => (
+
+ {getFieldDecorator(name, { rules, validateFirst: true })(widget)}
+
+ ),[taskId, reload]
+ );
+
+ return
+

+

+
+
开源夏令营 / 导师拟定考核结果
+
+
导师考核说明:
+
1、请各位导师根据“工作态度”“开发进度”“项目完成质量”“总体评分”四个角度,根据学生提交的考核材料与实际开发情况客观地进行打分。打分标准分为:S:特别优秀、A:优秀、B:良好、C:合格、D:不合格五个等级。
+
2、“总体评分”这一项将决定学生是否通过本次考核。若总体评分为“S、A、B、C”,则视为通过中期考核。若该结果为“D”,则该课题中期考核不通过,课题将自动终止。请各位导师谨慎做出评价。
+
3、在审核阶段 (2022年8月12日10点至2022年8月24日24点) 导师提交打分结果后,可对考核结果进行更改,期间考核结果也将实时反馈给学生。
+
4、北京时间2022年8月26日20点前GLCC官网将公布中期考核结果,敬请留意。
+
+
+
{ setTaskId(e) }} activeKey={taskId + ''}>
+ {
+ taskList.map((item, i) => {
+ return
+ {item.studentName} — {item.taskName}
+
+ })
+ }
+
+ {detail ?
+ {/* 学生提交的资料 */}
+
+
导师评分
+ {/* 导师打分 */}
+
+
+
+
+
:
}
+
+
+
+}
+export default Form.create()(TutorReview);
\ No newline at end of file