merge 服务-save
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1651041108151') format('woff2'),
|
||||
url('iconfont.woff?t=1651041108151') format('woff'),
|
||||
url('iconfont.ttf?t=1651041108151') format('truetype');
|
||||
src: url('iconfont.woff2?t=1652151013948') format('woff2'),
|
||||
url('iconfont.woff?t=1652151013948') format('woff'),
|
||||
url('iconfont.ttf?t=1652151013948') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,14 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-zanwushuju:before {
|
||||
content: "\e928";
|
||||
}
|
||||
|
||||
.icon-fuwuicon:before {
|
||||
content: "\e929";
|
||||
}
|
||||
|
||||
.icon-personal-center:before {
|
||||
content: "\e927";
|
||||
}
|
||||
|
|
|
@ -5,6 +5,20 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "29467269",
|
||||
"name": "暂无数据",
|
||||
"font_class": "zanwushuju",
|
||||
"unicode": "e928",
|
||||
"unicode_decimal": 59688
|
||||
},
|
||||
{
|
||||
"icon_id": "29467272",
|
||||
"name": "服务icon",
|
||||
"font_class": "fuwuicon",
|
||||
"unicode": "e929",
|
||||
"unicode_decimal": 59689
|
||||
},
|
||||
{
|
||||
"icon_id": "29206429",
|
||||
"name": "personal-center",
|
||||
|
|
|
@ -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;
|
||||
|
@ -652,6 +658,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={
|
||||
|
|
|
@ -305,7 +305,7 @@
|
|||
font-size: 14px;
|
||||
height: 36px;
|
||||
line-height: 24px;
|
||||
display: block;
|
||||
display: flex;
|
||||
color: #000!important;
|
||||
&> span.num{
|
||||
line-height: 24px;
|
||||
|
|
|
@ -117,6 +117,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" : ""}>
|
||||
|
|
|
@ -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,24 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
|
||||
function Main(props){
|
||||
const { owner , projectsId } = props.match.params;
|
||||
return(
|
||||
<div>
|
||||
<ul className="serverlist">
|
||||
<li>
|
||||
<span className="servername">
|
||||
<img src={require('./img/logo.png')} alt=""/>
|
||||
<Link to={`/${owner}/${projectsId}/server/1`}>重晴鸟代码溯源系统</Link>
|
||||
</span>
|
||||
<p className="task-hide-2 serverdesc">支持软件源代码的溯源分析、自主度评估、开源漏洞检测、开源许可证合规性分析等</p>
|
||||
<span className="serverbtn">
|
||||
<Link to={`/${owner}/${projectsId}/server/1`} className="btnhover">查看详情</Link>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Main;
|
|
@ -0,0 +1,60 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Modal , Checkbox } from 'antd';
|
||||
|
||||
|
||||
function AgreementModal({ visible , onCancel , onOk }){
|
||||
const [ agree , setAgree ] = useState(false);
|
||||
function changeAgree(e){
|
||||
setAgree(e.target.checked);
|
||||
}
|
||||
// 不同意
|
||||
function unAgree(){
|
||||
setAgree(false);
|
||||
onCancel();
|
||||
}
|
||||
|
||||
// 同意协议
|
||||
function agreeFunc(){
|
||||
agree && onOk();
|
||||
setAgree(false);
|
||||
}
|
||||
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,122 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import DataEmpty from './dataEmpty';
|
||||
import AgreementModal from './agreementModal';
|
||||
import DetectionModal from './detectionModal';
|
||||
import { Table } from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
const source=[
|
||||
{name:"maste2988989898984qwerrfccdr",status:"failure",time:"2022-05-11 17:21"},
|
||||
{name:"maste2988989898984qwerrfccdr",status:"success",time:"2022-05-11 17:21"},
|
||||
{name:"maste2988989898984qwerrfccdr",status:"50",time:"2022-05-11 17:21"},
|
||||
{name:"maste2988989898984qwerrfccdr",status:"80",time:"2022-05-11 17:21"}
|
||||
]
|
||||
function Data(props){
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ detectionVisible , setDetectionVisible ] = useState(false);
|
||||
const [ dataSource , setDataSource ] = useState(source);
|
||||
const [ page , setPage ] = useState(1);
|
||||
const limit = 15;
|
||||
const { owner , projectsId } = props.match.params;
|
||||
|
||||
function onOk(){
|
||||
setVisible(false);
|
||||
setDetectionVisible(true);
|
||||
}
|
||||
|
||||
function onDetectionOk(){
|
||||
setDetectionVisible(false);
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
const url = `/traces/${owner}/${projectsId}/task_results.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
page,limit
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
|
||||
}
|
||||
}).catch(error=>{})
|
||||
},[])
|
||||
|
||||
const columns=[
|
||||
{
|
||||
title:"序号",
|
||||
dataIndex:"number",
|
||||
key:"number",
|
||||
width:"7%",
|
||||
align:"center",
|
||||
render: (k,e,e1) => {return e1+1}
|
||||
},
|
||||
{
|
||||
title:"分支名称",
|
||||
dataIndex:"name",
|
||||
key:"name",
|
||||
width:"30%",
|
||||
align:"left",
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title:"检测状态",
|
||||
dataIndex:"status",
|
||||
key:"status",
|
||||
align:"left",
|
||||
render: (k,e,e1) => {
|
||||
return (
|
||||
k === "failure" ?
|
||||
<span className="failure">失败</span>
|
||||
: k==="success" ?
|
||||
<span className="success">成功</span>
|
||||
:
|
||||
<div className="running"><span style={{width:`${k}%`}}>{k}%</span></div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title:"检测时间",
|
||||
dataIndex:"time",
|
||||
key:"time",
|
||||
align:"left",
|
||||
},
|
||||
{
|
||||
title:"操作",
|
||||
dataIndex:"operation",
|
||||
key:"operation",
|
||||
align:"center",
|
||||
width:"30%",
|
||||
render: (k,e,e1) => {
|
||||
return(
|
||||
<div className="operationBtns">
|
||||
<a>重新扫描</a>
|
||||
<a>查看<i className="iconfont icon-sanjiaoxing-down"></i></a>
|
||||
<a>下载报告</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
return(
|
||||
<div>
|
||||
<AgreementModal visible={visible} onCancel={()=>setVisible(false)} onOk={onOk}/>
|
||||
<DetectionModal
|
||||
visible={detectionVisible}
|
||||
onCancel={()=>setDetectionVisible(false)}
|
||||
onOk={onDetectionOk}
|
||||
owner={owner}
|
||||
projectsId={projectsId}
|
||||
/>
|
||||
<div className="servertitle">
|
||||
<span className="systitle">重晴鸟代码溯源系统</span>
|
||||
<a className="btnhover" onClick={()=>setVisible(true)}>新建分析</a>
|
||||
</div>
|
||||
<div>
|
||||
<Table className="dataTable" columns={columns} dataSource={dataSource} pagination={false}/>
|
||||
</div>
|
||||
<DataEmpty />
|
||||
</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,134 @@
|
|||
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 }){
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
||||
const [ check , setCheck ] = useState(false);
|
||||
const [ branch , setBranch ] = useState("");
|
||||
const [ branchList , setBranchList ] = useState([]);
|
||||
|
||||
|
||||
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(){
|
||||
if(check) {
|
||||
setCheck(false);
|
||||
} else{
|
||||
onCancel();
|
||||
}
|
||||
}
|
||||
|
||||
// 开始检测
|
||||
function onOkFunc(){
|
||||
validateFields((error,values)=>{
|
||||
if(!error){
|
||||
setCheck(true);
|
||||
setBranch(values.branch);
|
||||
// onOk();
|
||||
}
|
||||
})
|
||||
}
|
||||
return(
|
||||
<Modal
|
||||
visible={visible}
|
||||
title=""
|
||||
onCancel={onCancel}
|
||||
className="agreementModal"
|
||||
width="635px"
|
||||
footer={
|
||||
<div className="agreeBtn">
|
||||
<a onClick={onCancelFunc}>取消</a>
|
||||
{ !check && <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>5</span></p>
|
||||
}
|
||||
</div>
|
||||
<div className="formDiv">
|
||||
<Form {...layout}>
|
||||
{
|
||||
!check &&
|
||||
<Form.Item label="检测分支" colon={false} labelAlign={"left"}>
|
||||
{getFieldDecorator("branch",{
|
||||
rules:[{required:true,message:"请选择要检测的分支"}]
|
||||
})(
|
||||
<Select placeholder="请选择仓库分支" 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 &&
|
||||
<div>
|
||||
<span>检测分支</span>
|
||||
<p>{branch}</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,390 @@
|
|||
.panels{
|
||||
width: 1200px;
|
||||
margin:20px auto;
|
||||
}
|
||||
.btnhover{
|
||||
background-color: #466aff;
|
||||
color: #fff!important;
|
||||
&:hover{
|
||||
background-color: rgba(26, 71, 255, 1);
|
||||
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{
|
||||
.ant-table-thead > tr > th{
|
||||
background-color: #fff;
|
||||
div{
|
||||
color: rgba(51, 51, 51, 1);
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
.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{
|
||||
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);
|
||||
}
|
||||
}
|
||||
.operationBtns{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
a{
|
||||
margin:0px 14px;
|
||||
position: relative;
|
||||
color: rgba(70, 106, 255, 1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 26px;
|
||||
i{
|
||||
width: 13px;
|
||||
}
|
||||
&::before{
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 12px;
|
||||
top:7px;
|
||||
background-color: rgba(213, 213, 213, 1);
|
||||
left: -14px;
|
||||
}
|
||||
&:first-child::before{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,7 +17,8 @@ const menu = [
|
|||
{name:"引擎 (Engine)",index:"devops"},
|
||||
// {name:"资源库",index:"resources"},
|
||||
{name:"里程碑",index:"versions"},
|
||||
// {name:"维基 (Wiki)",index:"wiki"},
|
||||
{name:"维基 (Wiki)",index:"wiki"},
|
||||
{name:"服务",index:"services"},
|
||||
{name:"动态",index:"activity"},
|
||||
]
|
||||
class Setting extends Component {
|
||||
|
|