Merge branch 'feature_GLCC' of http://106.75.45.236:3000/tongChong/forgeplus-react into feature_GLCC2
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1652870557319') format('woff2'),
|
||||
url('iconfont.woff?t=1652870557319') format('woff'),
|
||||
url('iconfont.ttf?t=1652870557319') format('truetype');
|
||||
src: url('iconfont.woff2?t=1652927945088') format('woff2'),
|
||||
url('iconfont.woff?t=1652927945088') format('woff'),
|
||||
url('iconfont.ttf?t=1652927945088') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name=”Keywords” Content=”issue,bug,tracker,软件工程,课程实践″>
|
||||
<meta name=”Description” Content=”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”>
|
||||
<meta name="theme-color" content="#000000">
|
||||
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/iconfont.css">
|
||||
|
|
|
@ -25,7 +25,7 @@ if (isDev) {
|
|||
}
|
||||
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'student'
|
||||
}
|
||||
window._debugType = debugType;
|
||||
export function initAxiosInterceptors(props) {
|
||||
|
|
|
@ -11,7 +11,7 @@ function SystemNotice({showNotice,system_notification,history,login,hideSystemNo
|
|||
|
||||
useEffect(()=>{
|
||||
|
||||
if(system_notification && !system_notification.is_read && showNotice && login){
|
||||
if((system_notification && !system_notification.is_read) && showNotice && login){
|
||||
setVisible(true);
|
||||
}
|
||||
},[system_notification,login])
|
||||
|
@ -22,11 +22,12 @@ function SystemNotice({showNotice,system_notification,history,login,hideSystemNo
|
|||
axios.post(url,{
|
||||
system_notification_id:system_notification.id
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setVisible(false);
|
||||
hideSystemNotice();
|
||||
}
|
||||
}).catch(error=>{})
|
||||
setVisible(false);
|
||||
hideSystemNotice();
|
||||
}).catch(error=>{
|
||||
setVisible(false);
|
||||
hideSystemNotice();
|
||||
})
|
||||
}else{
|
||||
setVisible(false);
|
||||
hideSystemNotice();
|
||||
|
|
|
@ -129,6 +129,10 @@ const Source = Loadable({
|
|||
loader: () => import('../Source/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Server = Loadable({
|
||||
loader: () => import('../Server/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
const DevIndex = Loadable({
|
||||
loader: () => import('../DevOps/Index'),
|
||||
loading: Loading,
|
||||
|
@ -168,6 +172,8 @@ function checkPathname(projectsId, owner, pathname) {
|
|||
name = "source"
|
||||
} else if (url.indexOf(`/wiki`) > -1) {
|
||||
name = "wiki"
|
||||
} else if (url.indexOf(`/server`) > -1) {
|
||||
name = "server"
|
||||
}
|
||||
}
|
||||
return name;
|
||||
|
@ -651,6 +657,12 @@ class Detail extends Component {
|
|||
:
|
||||
<Spin spinning={secondSync} className="spinstyle" tip="正在同步镜像" size="large">
|
||||
<Switch {...this.props}>
|
||||
{/* 服务 */}
|
||||
<Route path="/:owner/:projectsId/server"
|
||||
render={
|
||||
() => (<Server {...this.props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 资源 */}
|
||||
<Route path="/:owner/:projectsId/source"
|
||||
render={
|
||||
|
|
|
@ -228,14 +228,14 @@
|
|||
li{
|
||||
text-align: center;
|
||||
padding:0px;
|
||||
margin-right: 40px;
|
||||
margin-right: 35px;
|
||||
display: flex;
|
||||
& > a{
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
height: 36px;
|
||||
line-height: 24px;
|
||||
display: block;
|
||||
display: flex;
|
||||
color: #000!important;
|
||||
&> span.num{
|
||||
line-height: 24px;
|
||||
|
|
|
@ -8,11 +8,13 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
|||
useEffect(()=>{
|
||||
if(list){
|
||||
// 没有资源库banner但是通过连接进资源库页面时
|
||||
if(pathname && pathname==="source"){
|
||||
let a = list.filter(item=>item.menu_name === "resources");
|
||||
if(a && a.length === 0){
|
||||
history.push(`/${owner}/${projectsId}`);
|
||||
}
|
||||
let a = list.filter(item=>item.menu_name === "resources");
|
||||
if((pathname && pathname==="source") && (a && a.length === 0)){
|
||||
history.push(`/${owner}/${projectsId}`);
|
||||
}
|
||||
let b = list.filter(item=>item.menu_name === "server");
|
||||
if((pathname && pathname.indexOf("server") > 0) && (b && b.length === 0)){
|
||||
history.push(`/${owner}/${projectsId}`);
|
||||
}
|
||||
setMenuName(list);
|
||||
}
|
||||
|
@ -106,6 +108,15 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
|||
</Link>
|
||||
</li>
|
||||
}
|
||||
{
|
||||
item.menu_name === "services" &&
|
||||
<li className={pathname === "server" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/${owner}/${projectsId}/server`, state }}>
|
||||
<i className={"iconfont icon-fuwuicon color-grey-3 mr5 font-15"} style={{marginTop:"1px"}}></i>
|
||||
<span>服务</span>
|
||||
</Link>
|
||||
</li>
|
||||
}
|
||||
{
|
||||
item.menu_name === "activity" &&
|
||||
<li className={pathname==="activity" ? "active" : ""}>
|
||||
|
|
|
@ -33,7 +33,7 @@ export default Form.create()(
|
|||
const [fileList, setFileList] = useState(undefined);
|
||||
const [attachment, setAttachment] = useState(undefined);
|
||||
const [options , setOptions] = useState(undefined);
|
||||
const stable = history && history.location && history.location.state.stable;
|
||||
const stable = history && history.location && history.location.state&&history.location.state.stable;
|
||||
const { projectsId, versionId , owner } = match.params;
|
||||
|
||||
useEffect(()=>{
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import React from 'react';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import "./index.scss";
|
||||
import Loadable from 'react-loadable';
|
||||
import Loading from '../../Loading';
|
||||
|
||||
|
||||
const List = Loadable({
|
||||
loader: () => import('./List'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Data = Loadable({
|
||||
loader: () => import('./data'),
|
||||
loading: Loading,
|
||||
})
|
||||
function ServerIndex(props){
|
||||
return(
|
||||
<div className="panels">
|
||||
<Switch {...props}>
|
||||
<Route path="/:owner/:projectsId/server/:id"
|
||||
render={
|
||||
() => (<Data {...props}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/:owner/:projectsId/server"
|
||||
render={
|
||||
() => (<List {...props}/>)
|
||||
}
|
||||
></Route>
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default ServerIndex;
|
|
@ -0,0 +1,48 @@
|
|||
import React,{useState , useEffect} from 'react';
|
||||
import AgreementModal from './agreementModal';
|
||||
|
||||
function Main(props){
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const { owner , projectsId } = props.match.params;
|
||||
const [ has_trace_user , setHas_trace_user ] = useState(false);
|
||||
|
||||
const { current_user , resetUserInfo } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(current_user){
|
||||
setHas_trace_user(current_user.has_trace_user);
|
||||
}
|
||||
},[current_user])
|
||||
|
||||
function onOk(){
|
||||
setVisible(false);
|
||||
resetUserInfo && resetUserInfo();
|
||||
props.history.push(`/${owner}/${projectsId}/server/1`);
|
||||
}
|
||||
|
||||
function openDetail(){
|
||||
if(!has_trace_user){
|
||||
setVisible(true);
|
||||
}else{
|
||||
props.history.push(`/${owner}/${projectsId}/server/1`);
|
||||
}
|
||||
}
|
||||
return(
|
||||
<div>
|
||||
<AgreementModal visible={visible} onCancel={()=>setVisible(false)} onOk={onOk}/>
|
||||
<ul className="serverlist">
|
||||
<li>
|
||||
<span className="servername">
|
||||
<img src={require('./img/logo.png')} alt=""/>
|
||||
<a onClick={openDetail}>重晴鸟代码溯源系统</a>
|
||||
</span>
|
||||
<p className="task-hide-2 serverdesc">支持软件源代码的溯源分析、自主度评估、开源漏洞检测、开源许可证合规性分析等</p>
|
||||
<span className="serverbtn">
|
||||
<a onClick={openDetail} className="btnhover">查看详情</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Main;
|
|
@ -0,0 +1,65 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Modal , Checkbox } from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
function AgreementModal({ visible , onCancel , onOk}){
|
||||
const [ agree , setAgree ] = useState(false);
|
||||
function changeAgree(e){
|
||||
setAgree(e.target.checked);
|
||||
}
|
||||
// 不同意
|
||||
function unAgree(){
|
||||
setAgree(false);
|
||||
onCancel();
|
||||
}
|
||||
// 同意协议
|
||||
function agreeFunc(){
|
||||
const url = `/traces/trace_users.json`;
|
||||
axios.post(url).then(result=>{
|
||||
if(result){
|
||||
agree && onOk();
|
||||
setAgree(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
return(
|
||||
<Modal
|
||||
visible={visible}
|
||||
title="用户协议及声明条款"
|
||||
onCancel={onCancel}
|
||||
onOk={onOk}
|
||||
className="agreementModal"
|
||||
width="700px"
|
||||
footer={
|
||||
<div className="agreeBtn">
|
||||
<a onClick={unAgree}>不同意</a>
|
||||
<a className={agree ? "agree btnhover" : 'notagree'} onClick={ agreeFunc}>同意协议</a>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="agreementCon">
|
||||
<div className="agreementDesc">
|
||||
<p>在使用本系统前,请您务必仔细阅读下列条款: 本系统的资料、信息及其他内容均由国家超级计算无锡中心、中国科学院计算技术研究所、清华大学和北京大学提供,任何人进入本系统、阅读本系统所载任何内容、从本系统下载任何资料或使用本系统提供的任何资料,即表示同意遵守这些条款。如果您不同意遵守这些条款,请勿继续使用本系统。提供方有权对这些条款不时进行更新,前述更新之后的条款将在本系统进行公布,并自公布之日起生效。</p>
|
||||
<p className="blod">版权声明</p>
|
||||
<p>本系统所提供任何内容,包括但不限于数据、文字、图表或图象,其所有权、著作权及其他权利均由提供方享有。前述权利受中华人民共和国的法律、法规、规章、规范性法律文件及相关国际条约的保护;对前述权利的任何侵犯行为均有可能导致民事、行政或刑事责任,一切后果均由侵权行为人承担。未经提供方事先书面许可,您不得以任何方式复制、修改、传播、出版、转载或展示本系统的任何内容。</p>
|
||||
<p>本系统采用但非本系统原创的所有内容,其版权归版权所有人所有;转载的部分内容源自其他系统,因无法和版权权利人联系,如果您是前述内容的版权权利人,请与我们联系并提供证明材料和详实说明,我们将及时加注版权信息;如果您提出异议,我们将立即撤除任何涉及版权问题的内容。对于独家授权本系统提供的任何内容,如您需要转载,应当事先得到本系统和版权所有人的同意。</p>
|
||||
<p className="blod">引用本系统内容</p>
|
||||
<p>1. 在遵守国家法律以及本协议的情况下,您可以出于非商业目的浏览、下载本系统的内容。如出于商业目的使用(如:拷贝、下载、存储、通过硬盘拷贝或电子抓取系统发送、转换、演示、传播、出版本系统的任何内容,或创造与前述内容有关的演绎作品或衍生产品),则必须事先经过提供方的书面许可,并在使用时注明来源和版权标记。</p>
|
||||
<p>2. 如果您需要使用本系统包含的由任何其他主体提供的内容,请直接与版权权利人联系。</p>
|
||||
<p className="blod">免责条款</p>
|
||||
<p>对本系统的内容,我们已尽最大努力审核,但对于内容的正确性、完整性、及时性、有效性、稳定性、可用性、不侵犯他人权利等方面,不提供任何形式(无论明示或默示)的保证。我们不保证服务器的稳定性,任何由于黑客入侵或攻击、计算机病毒侵入或发作、因政府管制而造成的暂时性关闭等影响网络正常经营的不可抗力而造成的资料泄露、丢失、被盗用或被篡改等,本系统均得免责。我们不保证您在任何时候均可浏览、阅读、使用本系统;不保证本系统的内容不存在打印、复制及其他输入方面的错误。提供方有权随时更改本系统任何内容。 在任何情况下,对于无法进入本系统或无法使用本系统内容而导致的任何直接的、间接的、附带的、给第三人造成的损失(包括但不限于,利润损失、信息数据丢失、财产毁坏损失),提供方均不承担任何责任。 本系统提供的站外链接仅为用户提供方便,但链接的系统不属于本系统的控制范围或管理范畴,故提供方对链接系统所传送或登载的任何形式的内容不承担任何责任。 任何用户在本系统发表的商业信息、个人信息、留言以及其他信息,均不代表本系统以及提供方的立场,且与本系统与提供方无关,相关责任由作者完全承担;本系统有权对上述商业信息、个人信息、留言以及其他信息随时进行删除。</p>
|
||||
<p>本系统支持用户在使用本系统系统过程中的合法经营行为,但因用户的作为或不作为所造成的后果概由用户自行承担。</p>
|
||||
<p className="blod">隐私保护声明</p>
|
||||
<p>本系统承诺按照相关法律的规定、本系统的隐私政策,保护本系统收集的用户个人信息。我们建议您认真阅读本隐私保护声明。</p>
|
||||
<p className="blod">适用法律与争议解决</p>
|
||||
<p>因本公告或使用本系统所发生的争议适用中华人民共和国法律。因本公告或使用本系统发生争议,应当协商解决,协商不成的,由本公司所在地人民法院受理解决。</p>
|
||||
<p className="blod">终止协议或退出服务</p>
|
||||
<p>如果您希望不再使用本系统提供的服务,或者您不同意上述条款及更新内容,您可以选择终止协议或者退出服务具体请联系客服人员。</p>
|
||||
</div>
|
||||
<Checkbox checked={agree} onChange={changeAgree}>我已阅读并同意《用户协议及声明条款》</Checkbox>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default AgreementModal;
|
|
@ -0,0 +1,184 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import DataEmpty from './dataEmpty';
|
||||
import DetectionModal from './detectionModal';
|
||||
import { Table , Spin, message } from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
function Data(props){
|
||||
const [ detectionVisible , setDetectionVisible ] = useState(false);
|
||||
const [ dataSource , setDataSource ] = useState(undefined);
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ spining , setSpining ] = useState(true);
|
||||
const [ relayCount , setRelayCount ] = useState(5);
|
||||
const [ repeatId , setRepeatId ] = useState(undefined);
|
||||
const [ repeatBranch , setRepeatBranch ] = useState(undefined);
|
||||
|
||||
const { owner , projectsId } = props.match.params;
|
||||
const { current_user , isManager } = props;
|
||||
const limit = 15;
|
||||
|
||||
|
||||
function onDetectionOk(){
|
||||
props.showNotification("扫描成功!");
|
||||
setDetectionVisible(false);
|
||||
setSpining(true);
|
||||
Init();
|
||||
}
|
||||
|
||||
function Init(){
|
||||
const url = `/traces/${owner}/${projectsId}/task_results.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
page,limit
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setDataSource(result.data.data);
|
||||
setRelayCount(result.data.left_tasks_count);
|
||||
setSpining(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
setSpining(true);
|
||||
Init();
|
||||
},[])
|
||||
|
||||
|
||||
// 重新扫描
|
||||
function repeatCheck(project_id,branch){
|
||||
if(relayCount <= 0){
|
||||
message.error("无可用检测次数");
|
||||
return;
|
||||
}
|
||||
setRepeatId(project_id);
|
||||
setRepeatBranch(branch);
|
||||
setDetectionVisible(true);
|
||||
}
|
||||
|
||||
function createCheck(){
|
||||
if(relayCount <= 0){
|
||||
message.error("无可用检测次数");
|
||||
return;
|
||||
}
|
||||
setRepeatBranch(undefined);
|
||||
setRepeatId(undefined);
|
||||
setDetectionVisible(true);
|
||||
}
|
||||
|
||||
function handleDownExcel(task_id){
|
||||
setSpining(true);
|
||||
const url = `/api/traces/${owner}/${projectsId}/task_pdf.json?task_id=${task_id}`;
|
||||
// window.open(`/api/traces/${owner}/${projectsId}/task_pdf.json?task_id=${task_id}`);
|
||||
const x = new XMLHttpRequest();
|
||||
x.open('GET', url, true)
|
||||
x.responseType = 'blob';
|
||||
x.onload = (e) => {
|
||||
// 会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。
|
||||
const url = window.URL.createObjectURL(x.response)
|
||||
const a = document.createElement('a')
|
||||
a.href = url;
|
||||
a.download = "report.pdf";
|
||||
a.click();
|
||||
setSpining(false);
|
||||
}
|
||||
x.send();
|
||||
console.log("spining");
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<DetectionModal
|
||||
visible={detectionVisible}
|
||||
onCancel={()=>setDetectionVisible(false)}
|
||||
onOk={onDetectionOk}
|
||||
owner={owner}
|
||||
projectsId={projectsId}
|
||||
relayCount={relayCount}
|
||||
repeatId={repeatId}
|
||||
repeatBranch={repeatBranch}
|
||||
/>
|
||||
<div className="servertitle">
|
||||
<span className="systitle">重晴鸟代码溯源系统</span>
|
||||
{ isManager && <a className="btnhover" onClick={createCheck}>新建分析</a> }
|
||||
</div>
|
||||
<Spin spinning={spining}>
|
||||
<div style={{minHeight:"400px"}}>
|
||||
{
|
||||
dataSource && dataSource.length >0 &&
|
||||
<div>
|
||||
<ul className="dataUl">
|
||||
<li className="dataUlhead">
|
||||
<span>序号</span>
|
||||
<span>分支名称</span>
|
||||
<span>检测状态</span>
|
||||
<span>检测时间</span>
|
||||
{ isManager && <span>操作</span> }
|
||||
</li>
|
||||
{
|
||||
dataSource.map((e,key)=>{
|
||||
return(
|
||||
<div key={key}>
|
||||
<li className="dataUlbody">
|
||||
<span>{key + 1 }</span>
|
||||
<span title={e.branch_tag}>{e.branch_tag}</span>
|
||||
<span>
|
||||
{
|
||||
e.detect_status === "fail" ?
|
||||
<span className="failure">失败</span>
|
||||
: e.detect_status==="detecting" ?
|
||||
<div className="running">
|
||||
<span className="percentline" style={{width:`${e.detect_process}%`}}></span>
|
||||
<span className="percentNum" style={{left:`${e.detect_process+5}%`}}>{e.detect_process}%</span>
|
||||
</div>
|
||||
:
|
||||
<span className="success">成功</span>
|
||||
}
|
||||
</span>
|
||||
<span>{e.detect_startdate}</span>
|
||||
{
|
||||
isManager &&
|
||||
<span>
|
||||
<div className="operationBtns">
|
||||
{
|
||||
e.detect_status ==="detecting" ?
|
||||
<span>重新扫描</span>
|
||||
:
|
||||
<a onClick={()=>repeatCheck(e.project_id,e.branch_tag)}>重新扫描</a>
|
||||
}
|
||||
{/* {
|
||||
(e.detect_status ==="fail" || e.detect_status ==="detecting") ?
|
||||
<span>查看<i className="iconfont icon-sanjiaoxing-down"></i></span>
|
||||
:
|
||||
<a>查看<i className="iconfont icon-sanjiaoxing-down"></i></a>
|
||||
} */}
|
||||
{
|
||||
(e.detect_status ==="fail" || e.detect_status ==="detecting") ?
|
||||
<span>下载报告</span>
|
||||
:
|
||||
<a onClick={()=>handleDownExcel(e.task_id)}>下载报告</a>
|
||||
}
|
||||
</div>
|
||||
</span>
|
||||
}
|
||||
</li>
|
||||
{false && <iframe src="www.baidu.com" id={`htmlIframe_${key}`} frameBorder="0" name={`htmlIframe_${key}`} style={{ background: '#fff', height: '100%', width: '100%' }}></iframe>}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(dataSource === null || (dataSource && dataSource.length === 0)) &&
|
||||
<DataEmpty />
|
||||
}
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Data;
|
|
@ -0,0 +1,18 @@
|
|||
import React from 'react';
|
||||
import { Divider} from 'antd';
|
||||
|
||||
|
||||
function DataEmpty(props){
|
||||
return(
|
||||
<div className="dataEmpty">
|
||||
<div className="dataemptyCon">
|
||||
<img src={require('./img/nullicon.png')} width="68px" alt=""/>
|
||||
<span className="nullTitle">暂无数据</span>
|
||||
<p className="nullDesc">重睛鸟代码溯源及安全审查系统是一款完全自主、面向主流语言的代码审查大数据平台。主要功能包含软件源代码的溯源分析、自主度评估、开源漏洞检测、开源许可证合规性分析,支持分析结果多层次可视化展示等,可用于提高软件代码的可控性与安全性。</p>
|
||||
<Divider />
|
||||
<p className="nullSubDesc">对每个仓库,可进行代码检测总次数仅为 <span style={{color:"rgba(70, 106, 255, 1)",fontSize:"20px"}}>5</span> 次</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default DataEmpty;
|
|
@ -0,0 +1,162 @@
|
|||
import React, { useState , forwardRef, useEffect } from 'react';
|
||||
import { Modal , Form , Select } from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
function DetectionModal({form , visible , onCancel , onOk , projectsId, owner , relayCount , repeatId , repeatBranch }){
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
||||
const [ check , setCheck ] = useState(false);
|
||||
const [ branch , setBranch ] = useState("");
|
||||
const [ branchList , setBranchList ] = useState([]);
|
||||
const source = axios.CancelToken.source();
|
||||
const layout = {
|
||||
labelCol: { span: 5 },
|
||||
wrapperCol: { span: 18 },
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
if(visible && owner && projectsId){
|
||||
const url = `/${owner}/${projectsId}/branches.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setBranchList(result.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
},[owner,projectsId,visible])
|
||||
|
||||
// 取消检测
|
||||
function onCancelFunc(){
|
||||
source.cancel();
|
||||
if(check) {
|
||||
setCheck(false);
|
||||
} else{
|
||||
onCancel();
|
||||
}
|
||||
}
|
||||
// 开始检测
|
||||
function onOkFunc(){
|
||||
validateFields((error,values)=>{
|
||||
if(!error){
|
||||
setCheck(true);
|
||||
setBranch(values.branch);
|
||||
if(repeatId){
|
||||
// 重新扫描
|
||||
const url = `/traces/${owner}/${projectsId}/reload_task.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
project_id:repeatId,
|
||||
branch_name:repeatBranch
|
||||
}
|
||||
},{
|
||||
CancelToken:source.token
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
onOk();
|
||||
}
|
||||
setCheck(false);
|
||||
}).catch(error=>{})
|
||||
}else{
|
||||
// 新建分析
|
||||
const url = `/traces/${owner}/${projectsId}/tasks.json`;
|
||||
axios.post(url,{
|
||||
branch_name:values.branch
|
||||
},{
|
||||
CancelToken:source.token
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
onOk();
|
||||
}
|
||||
setCheck(false);
|
||||
}).catch(error=>{})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return(
|
||||
<Modal
|
||||
visible={visible}
|
||||
title=""
|
||||
onCancel={onCancel}
|
||||
className="agreementModal"
|
||||
width="635px"
|
||||
footer={
|
||||
<div className="agreeBtn">
|
||||
<a onClick={onCancelFunc}>取消</a>
|
||||
{ !check && relayCount !== 0 && <a className={"agree btnhover"} onClick={onOkFunc}>开始检测</a> }
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<div className="detectionAnimation">
|
||||
<ul className={check ? "animationUl action" : "animationUl" }>
|
||||
<li><img src={require('./img/1.png')} width="166px" alt=""/></li>
|
||||
<li><img src={require('./img/2.png')} width="136px" alt=""/></li>
|
||||
<li><img src={require('./img/3.png')} width="96px" alt=""/></li>
|
||||
<li><img src={require('./img/4.png')} width="96px" alt=""/></li>
|
||||
<li><img src={require('./img/5.png')} width="15px" alt=""/></li>
|
||||
<li><img src={require('./img/6.png')} width="25px" alt=""/></li>
|
||||
<li><img src={require('./img/7.png')} width="1px" alt=""/></li>
|
||||
</ul>
|
||||
{
|
||||
check ?
|
||||
<p className="lastTimes">正在开启检测,请等待...</p>
|
||||
:
|
||||
<p className="lastTimes">剩余扫描次数<span>{relayCount}</span></p>
|
||||
}
|
||||
</div>
|
||||
<div className="formDiv">
|
||||
<Form {...layout}>
|
||||
{
|
||||
!check && !repeatBranch &&
|
||||
<Form.Item label="检测分支" colon={false} labelAlign={"left"}>
|
||||
{getFieldDecorator("branch",{
|
||||
rules:[{required:true,message:"请选择要检测的分支"}]
|
||||
})(
|
||||
<Select placeholder="请选择仓库分支" showSearch style={{width:"360px"}}>
|
||||
{
|
||||
branchList && branchList.length >0 ?
|
||||
branchList.map((i,k)=>{
|
||||
return(
|
||||
<Select.Option value={i.name}>{i.name}</Select.Option>
|
||||
)
|
||||
})
|
||||
:
|
||||
<Select.Option value={""}>暂无分支</Select.Option>
|
||||
}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
}
|
||||
<div className="checkInfos">
|
||||
{
|
||||
((check && branch) || repeatBranch) &&
|
||||
<div>
|
||||
<span>检测分支</span>
|
||||
<p className="task-hide" title={branch || repeatBranch}>{branch || repeatBranch}</p>
|
||||
</div>
|
||||
}
|
||||
<div>
|
||||
<span>检测类型</span>
|
||||
<p>快速-组件级</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>检测参数</span>
|
||||
<div style={{flex:1}}>
|
||||
<p>解析层级:2</p>
|
||||
<p>最小解析文件行数:10</p>
|
||||
<p>许可证检测类型:开源软件</p>
|
||||
<span className="color-grey-6">文件相似阈值</span>
|
||||
<ul>
|
||||
<li>行数:20</li>
|
||||
<li>相似比例:50%</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default Form.create()(forwardRef(DetectionModal));
|
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 260 B |
After Width: | Height: | Size: 349 B |
After Width: | Height: | Size: 88 B |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 692 B |
|
@ -0,0 +1,454 @@
|
|||
.panels{
|
||||
width: 1200px;
|
||||
margin:20px auto;
|
||||
}
|
||||
.btnhover{
|
||||
background-color: #466aff;
|
||||
color: #fff!important;
|
||||
&:hover{
|
||||
background-color: rgba(26, 71, 255, 1)!important;
|
||||
color: #fff!important;
|
||||
}
|
||||
}
|
||||
.servertitle{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color:#fafcff;
|
||||
border:1px solid rgba(42, 97, 255, 0.23);
|
||||
border-radius:3px 3px 0px 0px;
|
||||
justify-content: space-between;
|
||||
padding:12px 16px;
|
||||
.systitle{
|
||||
font-weight:500;
|
||||
color:#333333;
|
||||
font-size:16px;
|
||||
}
|
||||
a{
|
||||
width:88px;
|
||||
height:36px;
|
||||
line-height: 36px;
|
||||
background-color:#466aff;
|
||||
border-radius:5px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.dataEmpty{
|
||||
margin-top: 25px;
|
||||
background-color:#fafcff;
|
||||
border-radius:4px 4px 0px 0px;
|
||||
min-height: 418px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.dataemptyCon{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
max-width: 665px;
|
||||
text-align: center;
|
||||
.nullTitle{
|
||||
font-size: 22px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin:15px 0px 28px!important;
|
||||
color: #333;
|
||||
}
|
||||
.nullDesc{
|
||||
color:#666666;
|
||||
font-size:14px;
|
||||
line-height:28px;
|
||||
}
|
||||
.ant-divider{
|
||||
min-width: 500px;
|
||||
width: 500px;
|
||||
border-top:1px solid rgba(90, 117, 193, 0.23);
|
||||
margin:18px 0px!important;
|
||||
height: 0px;
|
||||
}
|
||||
.nullSubDesc{
|
||||
color:#333333;
|
||||
font-size:16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.agreementModal{
|
||||
.ant-modal-header{
|
||||
padding:0px ;
|
||||
height: 56px;
|
||||
background:url('./img/modaltitle.png') 100% 100% ;
|
||||
color: #fff;
|
||||
.ant-modal-title{
|
||||
color: #fff;
|
||||
height: 56px;
|
||||
line-height: 56px!important;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.ant-modal-close{
|
||||
top:0px!important;
|
||||
color: #fff;
|
||||
}
|
||||
.ant-modal-body{
|
||||
padding:0px;
|
||||
}
|
||||
.agreementCon{
|
||||
height: 400px;
|
||||
overflow-y: auto;
|
||||
padding:20px;
|
||||
p{
|
||||
line-height: 26px;
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
margin-bottom: 8px!important;
|
||||
&.blod{
|
||||
font-weight:500;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
.agreeBtn{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 67px;
|
||||
justify-content: center;
|
||||
a{
|
||||
display: block;
|
||||
height:36px;
|
||||
line-height: 34px;
|
||||
margin:0px 20px;
|
||||
background-color:#ffffff;
|
||||
border:1px solid;
|
||||
border-color:#d0d0d0;
|
||||
border-radius:4px;
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
color:#666666;
|
||||
font-size:15px;
|
||||
&.notagree{
|
||||
background-color:rgba(177, 192, 255, 1);
|
||||
border-color:rgba(177, 192, 255, 1);
|
||||
color: #fff!important;
|
||||
cursor: default;
|
||||
}
|
||||
&.agree{
|
||||
background-color:#466aff;
|
||||
border-color:rgba(177, 192, 255, 1);
|
||||
color: #fff!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.detectionAnimation{
|
||||
height: 240px;
|
||||
width: 100%;
|
||||
background-image: url('./img/detectionBG.png');
|
||||
background-size: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
.animationUl{
|
||||
width: 166px;
|
||||
height: 166px;
|
||||
position: relative;
|
||||
&.action li{
|
||||
-webkit-animation: App-logo-spin infinite 5s linear;
|
||||
animation: App-logo-spin infinite 5s linear;
|
||||
}
|
||||
li{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
&:last-child{
|
||||
align-items: flex-end;
|
||||
height: 96px;
|
||||
bottom: 36px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@keyframes App-logo-spin {
|
||||
from{
|
||||
transform:rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
}
|
||||
.lastTimes{
|
||||
color: #fff;
|
||||
margin-top: 6px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
display: flex;
|
||||
span{
|
||||
font-size: 20px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.dataTable,.dataUl{
|
||||
.ant-table-thead > tr > th{
|
||||
background-color: #fff;
|
||||
div{
|
||||
color: rgba(51, 51, 51, 1);
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
.ant-table-tbody > tr:hover > td{
|
||||
background-color: rgba(248, 250, 255, 1)!important;
|
||||
}
|
||||
|
||||
.failure{
|
||||
display: block;
|
||||
height:32px;
|
||||
line-height:32px;
|
||||
background-color:rgba(230, 0, 6, 0.1);
|
||||
border:1px solid;
|
||||
border-color:#fcb6c2;
|
||||
border-radius:4px;
|
||||
color: rgba(255, 12, 12, 1);
|
||||
width:58px;
|
||||
text-align: center;
|
||||
}
|
||||
.success{
|
||||
display: block;
|
||||
height:32px;
|
||||
line-height:32px;
|
||||
background-color:rgba(83, 255, 163, 0.1);
|
||||
border:1px solid;
|
||||
border-color:rgba(0, 184, 67, 1);
|
||||
border-radius:4px;
|
||||
color: rgba(0, 156, 68, 1);
|
||||
width:58px;
|
||||
text-align: center;
|
||||
}
|
||||
.running{
|
||||
position: relative;
|
||||
width: 137px;
|
||||
height: 22px;
|
||||
background-color: rgba(75, 75, 75, 0.1);
|
||||
border-radius:26px;
|
||||
span.percentline{
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top:0px;
|
||||
height: 100%;
|
||||
background-color: rgba(80, 156, 255, 1);
|
||||
border-radius:26px;
|
||||
text-align: center;
|
||||
line-height: 24px;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
}
|
||||
}
|
||||
.percentNum{
|
||||
position: absolute;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.operationBtns{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
a,span{
|
||||
margin:0px 14px;
|
||||
position: relative;
|
||||
color: rgba(70, 106, 255, 1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 26px;
|
||||
}
|
||||
span{
|
||||
color: rgba(197, 204, 225, 1)!important;
|
||||
cursor: default;
|
||||
}
|
||||
a > i,span>i{
|
||||
width: 13px;
|
||||
}
|
||||
a::before,span::before{
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 12px;
|
||||
top:7px;
|
||||
background-color: rgba(213, 213, 213, 1);
|
||||
left: -14px;
|
||||
}
|
||||
a:first-child::before,span:first-child::before{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.dataUl{
|
||||
&>div{
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
li{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
height: 66px;
|
||||
align-items: center;
|
||||
color:#333333;
|
||||
&>span{
|
||||
padding:0px 10px;
|
||||
text-align: left;
|
||||
}
|
||||
&>span:first-child{
|
||||
width: 7%;
|
||||
text-align: center;
|
||||
}
|
||||
&>span:nth-child(2){
|
||||
width: 30%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
&>span:nth-child(3){
|
||||
flex:1;
|
||||
}
|
||||
&>span:nth-child(4){
|
||||
width: 16%;
|
||||
}
|
||||
&>span:last-child{
|
||||
width: 30%;
|
||||
text-align: center;
|
||||
}
|
||||
&.dataUlhead{
|
||||
font-size:16px;
|
||||
}
|
||||
&.dataUlbody{
|
||||
font-size: 14px;
|
||||
&:hover{
|
||||
background-color:#f8faff
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.formDiv{
|
||||
width: 430px;
|
||||
margin:0px auto;
|
||||
padding:20px 0px;
|
||||
.has-error .ant-form-explain{
|
||||
position: absolute;
|
||||
bottom: -15px;
|
||||
}
|
||||
.ant-form-item-label{
|
||||
width: 70px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin-top: 4px;
|
||||
label{
|
||||
color:#20294a;
|
||||
font-size:15px;
|
||||
}
|
||||
}
|
||||
.ant-row.ant-form-item{
|
||||
margin-bottom: 12px!important;
|
||||
}
|
||||
.ant-form-item-required::before{
|
||||
display: none;
|
||||
}
|
||||
.checkInfos{
|
||||
&>div{
|
||||
display: flex;
|
||||
&>span{
|
||||
display: block;
|
||||
width: 70px;
|
||||
line-height: 32px;
|
||||
text-align: left;
|
||||
color:#20294a;
|
||||
font-size:15px;
|
||||
}
|
||||
ul{
|
||||
display: flex;
|
||||
margin-top: 15px;
|
||||
li:first-child{
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
p,ul>li{
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding:0px 12px;
|
||||
background-color:#f5f7ff;
|
||||
border-radius:4px;
|
||||
color:#666666;
|
||||
margin-bottom: 15px!important;
|
||||
flex:1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.serverlist{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
min-height: 500px;
|
||||
align-content: flex-start;
|
||||
li{
|
||||
width: 368px;
|
||||
margin-right: 36px;
|
||||
height: 198px;
|
||||
background-image:url('./img/bg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
margin-bottom: 20px!important;
|
||||
padding:30px 40px 0px 40px;
|
||||
position: relative;
|
||||
&:nth-child(3n+1){
|
||||
margin-left: -10px;
|
||||
}
|
||||
&:nth-child(3n){
|
||||
margin-right: -10px;
|
||||
}
|
||||
.servername{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
img{
|
||||
margin-right: 8px;
|
||||
width: 42px;
|
||||
}
|
||||
a{
|
||||
font-weight:500;
|
||||
color:#466aff;
|
||||
font-size:17px;
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
.serverbtn{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.serverdesc{
|
||||
-webkit-line-clamp: 3;
|
||||
line-height: 25px;
|
||||
color:#525662;
|
||||
font-size:15px;
|
||||
}
|
||||
.serverbtn{
|
||||
position: absolute;
|
||||
height: 56px;
|
||||
background-color: transparent;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
opacity: 0;
|
||||
transition: 0.3s;
|
||||
a{
|
||||
display: block;
|
||||
width: 224px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ const menu = [
|
|||
// {name:"资源库",index:"resources"},
|
||||
{name:"里程碑",index:"versions"},
|
||||
{name:"维基 (Wiki)",index:"wiki"},
|
||||
{name:"服务",index:"services"},
|
||||
{name:"动态",index:"activity"},
|
||||
]
|
||||
class Setting extends Component {
|
||||
|
|
|
@ -102,7 +102,7 @@ class Infos extends Component {
|
|||
}else if(pathname === `/${username}/followers`){
|
||||
this.setState({menuKey:undefined,route_type:"followers"});
|
||||
}else{
|
||||
this.setState({menuKey:undefined,route_type:undefined});
|
||||
this.setState({menuKey:"6",route_type:undefined});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,6 @@ class Infos extends Component {
|
|||
const { current_user } = this.props;
|
||||
const { username } = this.props.match.params;
|
||||
const { user, isSpin, route_type , undo_events , menuKey , avatarVisible } = this.state;
|
||||
|
||||
return (
|
||||
<div className="newMain clearfix">
|
||||
{
|
||||
|
|
|
@ -9,7 +9,6 @@ import banner from "../img/banner.png";
|
|||
import studentSvg from "../img/student.png";
|
||||
import './index.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { color } from 'echarts/lib/theme/light';
|
||||
|
||||
const Option = Select.Option;
|
||||
const gradeList = [
|
||||
|
@ -27,12 +26,14 @@ function Apply(props) {
|
|||
// 可用于开发时不同账号报名
|
||||
// current_user && (current_user.user_id = 6)
|
||||
// current_user && (current_user.userName = "创新使者")
|
||||
const isStudentApplyDate = new Date().getTime() > new Date('2022-05-26').getTime() && new Date().getTime() < new Date('2022-06-26').getTime();
|
||||
|
||||
const { getFieldDecorator, validateFields, setFieldsValue, validateFieldsAndScroll } = form;
|
||||
const [imageUrl, setImageUrl] = useState(undefined);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [reload, setReload] = useState();
|
||||
const [userApplyInfo, setUserApplyInfo] = useState(undefined);
|
||||
const [editable, setEditable] = useState(true);
|
||||
const [editable, setEditable] = useState(isStudentApplyDate);
|
||||
const [files, setFiles] = useState([]);
|
||||
const [files1, setFiles1] = useState([]);
|
||||
const initTask = {
|
||||
|
@ -44,24 +45,24 @@ function Apply(props) {
|
|||
const [allTaskList, setAllTaskList] = useState([]);
|
||||
|
||||
// 学生报名时间范围内
|
||||
const isStudentApplyDate = Date.parse(new Date()) > 1653494400000 && Date.parse(new Date()) < 1656086400000;
|
||||
// 已过学生报名时间
|
||||
const studentApplyEnd = Date.parse(new Date()) > 1656086400000;
|
||||
|
||||
useEffect(() => {
|
||||
// 进入此页面到填写页面
|
||||
// setTimeout(()=>{
|
||||
setTimeout(()=>{
|
||||
let clientWidth = document.body.clientWidth;
|
||||
let scrollHeight = 500 * clientWidth / 1920;
|
||||
window.scrollTo(0, scrollHeight);
|
||||
});
|
||||
// window.scrollTo(0, 50);
|
||||
|
||||
if (!isStudentApplyDate) {
|
||||
if (new Date().getTime() < new Date('2022-05-26').getTime()) {
|
||||
// 不在开源夏令营报名时间之内
|
||||
window.location.href = "/glcc/student/2";
|
||||
} else if (current_user && current_user.login) {
|
||||
|
||||
} else {
|
||||
window.location.href = "/login?go_page=/glcc";
|
||||
window.location.href = `/login?go_page=/glcc/student/apply/${taskId}`;
|
||||
}
|
||||
}, [])
|
||||
|
||||
|
@ -262,12 +263,11 @@ function Apply(props) {
|
|||
// 自荐书上传
|
||||
function bookChange(info, i) {
|
||||
if (info.file.status === 'uploading' || info.file.status === "done" || info.file.status === 'removed') {
|
||||
setLoading(true);
|
||||
// setLoading(true);
|
||||
if (info.file.status === "done") {
|
||||
changeTaskItem('memoAttachmentId', info.fileList[0].response && info.fileList[0].response.data.id, i)
|
||||
}
|
||||
if (info.file.status === 'removed') {
|
||||
console.log(1111)
|
||||
changeTaskItem('memoAttachmentId', '', i);
|
||||
}
|
||||
console.log(info.fileList);
|
||||
|
@ -278,9 +278,9 @@ function Apply(props) {
|
|||
}
|
||||
}
|
||||
|
||||
if (info.file.status === "done" || info.file.status === 'removed') {
|
||||
setLoading(false);
|
||||
}
|
||||
// if (info.file.status === "done" || info.file.status === 'removed') {
|
||||
// setLoading(false);
|
||||
// }
|
||||
}
|
||||
|
||||
// 支持文件下载
|
||||
|
@ -392,7 +392,7 @@ function Apply(props) {
|
|||
{getFieldDecorator("location", {
|
||||
rules: []
|
||||
})(
|
||||
<Cascader popupClassName="glcc_cascader" placeholder="请选择省份城市" options={locData} className={editable ? "" : "disabledInput"} disabled={editable ? false : true} />
|
||||
<Cascader expandTrigger="hover" popupClassName="glcc_cascader" placeholder="请选择省份城市" options={locData} className={editable ? "" : "disabledInput"} disabled={editable ? false : true} />
|
||||
)}
|
||||
</Form.Item>
|
||||
{helper('所在年级',
|
||||
|
@ -408,7 +408,7 @@ function Apply(props) {
|
|||
'phone',
|
||||
[{ required: true, message: "请正确输入联系电话" },
|
||||
{ max: 14, message: '超出限制长度14位字符,请重新编辑' },
|
||||
{ pattern: /[\d-]{4,14}$/, message: '请正确输入联系电话' }],
|
||||
{ pattern: /(^(\d{3,4}-)?\d{7,8})$|([1][3,4,5,6,7,8,9][0-9]{9})/, message: '请正确输入联系电话' }],
|
||||
<Input placeholder="请输入联系电话" onBlur={() => { verify("phone") }} className={editable ? "" : "disabledInput"} disabled={editable ? false : true} />
|
||||
)}
|
||||
{helper('邮箱地址',
|
||||
|
@ -426,28 +426,28 @@ function Apply(props) {
|
|||
'请以图片的形式上传学生证明,大小不超过5M,格式为png、jpg、jpeg',
|
||||
'proveAttachmentId',
|
||||
[{ required: true, message: "请正确上传学生证明" }],
|
||||
userApplyInfo && userApplyInfo.proveAttachmentId ? <div className='projectLogo'><img src={`${getUrl()}/api/attachments/${userApplyInfo.proveAttachmentId}`} alt='' /></div>
|
||||
: <Upload
|
||||
listType="picture-card"
|
||||
className="avatar-uploader"
|
||||
showUploadList={false}
|
||||
action={getUploadActionUrl()}
|
||||
accept=".png,.jpg,.jpeg"
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{imageUrl ? <img src={imageUrl} alt="avatar" style={{ maxWidth: '100px', maxHeight: '100px' }} /> : <div>
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
className="avatar-uploader"
|
||||
showUploadList={false}
|
||||
action={getUploadActionUrl()}
|
||||
accept=".png,.jpg,.jpeg"
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{imageUrl ? <img src={imageUrl} alt="avatar" style={{ maxWidth: '100px', maxHeight: '100px' }} /> : userApplyInfo && userApplyInfo.proveAttachmentId ?
|
||||
<div><img src={`${getUrl()}/api/attachments/${userApplyInfo.proveAttachmentId}`} alt='' /></div> : <div>
|
||||
<i className='iconfont icon-tianjiadaohang font-30'></i>
|
||||
<div className="ant-upload-text font-13">请上传学生证明</div>
|
||||
</div>}
|
||||
</Upload>
|
||||
</Upload>
|
||||
)}</div>
|
||||
|
||||
{
|
||||
myTaskList.map((item, i) => {
|
||||
return (
|
||||
<Fragment key={item.taskId + '' + i}>
|
||||
<h4 className="item-tit">课题信息(<span className="item-tit-num">{i + 1}</span>/2) {myTaskList.length > 1 && <span className="delete"><i className="iconfont icon-shanchu mr5" onClick={() => { deleteTask(i) }}></i>删除</span>}</h4>
|
||||
<h4 className="item-tit">课题信息(<span className="item-tit-num">{i + 1}</span>/2) {myTaskList.length > 1 && <span className="delete" onClick={() => { deleteTask(i) }}><i className="iconfont icon-shanchu mr5"></i>删除</span>}</h4>
|
||||
{helper('课题名称',
|
||||
'',
|
||||
'taskId' + i,
|
||||
|
@ -465,7 +465,7 @@ function Apply(props) {
|
|||
</Select>
|
||||
)}
|
||||
<div className='introArea'>{helper('自荐书',
|
||||
<div className="memoExtra">自荐书示例:<span >https://forum.gitlink.org.cn/forums/7299/detail</span></div>,
|
||||
<div className="memoExtra">自荐书示例:<a href="https://forum.gitlink.org.cn/forums/7299/detail" target="_black">https://forum.gitlink.org.cn/forums/7299/detail</a></div>,
|
||||
'memo' + i,
|
||||
[{ required: true, message: "请正确输入自荐书" },
|
||||
{ max: 500, message: '超出限制长度500位字符,请重新编辑' }],
|
||||
|
|
|
@ -293,7 +293,7 @@
|
|||
.memoExtra {
|
||||
margin-top: 12px;
|
||||
margin-bottom: -10px;
|
||||
span {
|
||||
a {
|
||||
color: #466aff;
|
||||
}
|
||||
}
|
||||
|
@ -312,4 +312,26 @@
|
|||
border: 1px solid #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 0px 12px rgba(203, 220, 255, 0.47);
|
||||
|
||||
.ant-select-dropdown-menu-item{
|
||||
&:hover{
|
||||
background-color: #e9efff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.glcc_cascader{
|
||||
.ant-cascader-menu{
|
||||
width: 240px;
|
||||
|
||||
&::-webkit-scrollbar-track{
|
||||
background-color: #E2E9FF;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb{
|
||||
background-color: #BCCCFF;
|
||||
}
|
||||
}
|
||||
.ant-cascader-menu:first-child{
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,6 +226,7 @@ export function TPMIndexHOC(WrappedComponent) {
|
|||
this.setState({
|
||||
showNotice:false
|
||||
})
|
||||
this.getAppdatausr();
|
||||
}
|
||||
|
||||
showCompeleteDialog=()=>{
|
||||
|
|