diff --git a/public/css/iconfont.css b/public/css/iconfont.css index af04c62b..2aa4e5fe 100644 --- a/public/css/iconfont.css +++ b/public/css/iconfont.css @@ -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 { diff --git a/public/css/iconfont.ttf b/public/css/iconfont.ttf index 50b785fc..aaf41b74 100644 Binary files a/public/css/iconfont.ttf and b/public/css/iconfont.ttf differ diff --git a/public/css/iconfont.woff b/public/css/iconfont.woff index af3a98f6..7ad90ffb 100644 Binary files a/public/css/iconfont.woff and b/public/css/iconfont.woff differ diff --git a/public/css/iconfont.woff2 b/public/css/iconfont.woff2 index c8ead9b9..f45e4e1d 100644 Binary files a/public/css/iconfont.woff2 and b/public/css/iconfont.woff2 differ diff --git a/public/index.html b/public/index.html index 9489fe42..bb947662 100755 --- a/public/index.html +++ b/public/index.html @@ -7,6 +7,7 @@ + diff --git a/src/AppConfig.js b/src/AppConfig.js index b4107e46..cd3aca3d 100644 --- a/src/AppConfig.js +++ b/src/AppConfig.js @@ -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) { diff --git a/src/forge/Component/NoticeModal/SystemNotice.jsx b/src/forge/Component/NoticeModal/SystemNotice.jsx index c95a8030..78619f18 100644 --- a/src/forge/Component/NoticeModal/SystemNotice.jsx +++ b/src/forge/Component/NoticeModal/SystemNotice.jsx @@ -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(); diff --git a/src/forge/Main/Detail.js b/src/forge/Main/Detail.js index ceebddc8..60b2fc3b 100644 --- a/src/forge/Main/Detail.js +++ b/src/forge/Main/Detail.js @@ -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 { : + {/* 服务 */} + () + } + > {/* 资源 */} a{ position: relative; font-size: 14px; height: 36px; line-height: 24px; - display: block; + display: flex; color: #000!important; &> span.num{ line-height: 24px; diff --git a/src/forge/Main/sub/DetailBanner.jsx b/src/forge/Main/sub/DetailBanner.jsx index f03f14ba..8a0472ce 100644 --- a/src/forge/Main/sub/DetailBanner.jsx +++ b/src/forge/Main/sub/DetailBanner.jsx @@ -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 } + { + item.menu_name === "services" && +
  • + + + 服务 + +
  • + } { item.menu_name === "activity" &&
  • diff --git a/src/forge/Server/Index.jsx b/src/forge/Server/Index.jsx new file mode 100644 index 00000000..cdcb8bbc --- /dev/null +++ b/src/forge/Server/Index.jsx @@ -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( +
    + + () + } + > + () + } + > + +
    + ) +} +export default ServerIndex; \ No newline at end of file diff --git a/src/forge/Server/List.jsx b/src/forge/Server/List.jsx new file mode 100644 index 00000000..3e49e815 --- /dev/null +++ b/src/forge/Server/List.jsx @@ -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( +
    + setVisible(false)} onOk={onOk}/> + +
    + ) +} +export default Main; \ No newline at end of file diff --git a/src/forge/Server/agreementModal.jsx b/src/forge/Server/agreementModal.jsx new file mode 100644 index 00000000..2e7a91b3 --- /dev/null +++ b/src/forge/Server/agreementModal.jsx @@ -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( + + 不同意 + 同意协议 + + } + > +
    +
    +

    在使用本系统前,请您务必仔细阅读下列条款: 本系统的资料、信息及其他内容均由国家超级计算无锡中心、中国科学院计算技术研究所、清华大学和北京大学提供,任何人进入本系统、阅读本系统所载任何内容、从本系统下载任何资料或使用本系统提供的任何资料,即表示同意遵守这些条款。如果您不同意遵守这些条款,请勿继续使用本系统。提供方有权对这些条款不时进行更新,前述更新之后的条款将在本系统进行公布,并自公布之日起生效。

    +

    版权声明

    +

    本系统所提供任何内容,包括但不限于数据、文字、图表或图象,其所有权、著作权及其他权利均由提供方享有。前述权利受中华人民共和国的法律、法规、规章、规范性法律文件及相关国际条约的保护;对前述权利的任何侵犯行为均有可能导致民事、行政或刑事责任,一切后果均由侵权行为人承担。未经提供方事先书面许可,您不得以任何方式复制、修改、传播、出版、转载或展示本系统的任何内容。

    +

    本系统采用但非本系统原创的所有内容,其版权归版权所有人所有;转载的部分内容源自其他系统,因无法和版权权利人联系,如果您是前述内容的版权权利人,请与我们联系并提供证明材料和详实说明,我们将及时加注版权信息;如果您提出异议,我们将立即撤除任何涉及版权问题的内容。对于独家授权本系统提供的任何内容,如您需要转载,应当事先得到本系统和版权所有人的同意。

    +

    引用本系统内容

    +

    1. 在遵守国家法律以及本协议的情况下,您可以出于非商业目的浏览、下载本系统的内容。如出于商业目的使用(如:拷贝、下载、存储、通过硬盘拷贝或电子抓取系统发送、转换、演示、传播、出版本系统的任何内容,或创造与前述内容有关的演绎作品或衍生产品),则必须事先经过提供方的书面许可,并在使用时注明来源和版权标记。

    +

    2. 如果您需要使用本系统包含的由任何其他主体提供的内容,请直接与版权权利人联系。

    +

    免责条款

    +

    对本系统的内容,我们已尽最大努力审核,但对于内容的正确性、完整性、及时性、有效性、稳定性、可用性、不侵犯他人权利等方面,不提供任何形式(无论明示或默示)的保证。我们不保证服务器的稳定性,任何由于黑客入侵或攻击、计算机病毒侵入或发作、因政府管制而造成的暂时性关闭等影响网络正常经营的不可抗力而造成的资料泄露、丢失、被盗用或被篡改等,本系统均得免责。我们不保证您在任何时候均可浏览、阅读、使用本系统;不保证本系统的内容不存在打印、复制及其他输入方面的错误。提供方有权随时更改本系统任何内容。 在任何情况下,对于无法进入本系统或无法使用本系统内容而导致的任何直接的、间接的、附带的、给第三人造成的损失(包括但不限于,利润损失、信息数据丢失、财产毁坏损失),提供方均不承担任何责任。 本系统提供的站外链接仅为用户提供方便,但链接的系统不属于本系统的控制范围或管理范畴,故提供方对链接系统所传送或登载的任何形式的内容不承担任何责任。 任何用户在本系统发表的商业信息、个人信息、留言以及其他信息,均不代表本系统以及提供方的立场,且与本系统与提供方无关,相关责任由作者完全承担;本系统有权对上述商业信息、个人信息、留言以及其他信息随时进行删除。

    +

    本系统支持用户在使用本系统系统过程中的合法经营行为,但因用户的作为或不作为所造成的后果概由用户自行承担。

    +

    隐私保护声明

    +

    本系统承诺按照相关法律的规定、本系统的隐私政策,保护本系统收集的用户个人信息。我们建议您认真阅读本隐私保护声明。

    +

    适用法律与争议解决

    +

    因本公告或使用本系统所发生的争议适用中华人民共和国法律。因本公告或使用本系统发生争议,应当协商解决,协商不成的,由本公司所在地人民法院受理解决。

    +

    终止协议或退出服务

    +

    如果您希望不再使用本系统提供的服务,或者您不同意上述条款及更新内容,您可以选择终止协议或者退出服务具体请联系客服人员。

    +
    + 我已阅读并同意《用户协议及声明条款》 +
    +
    + ) +} +export default AgreementModal; \ No newline at end of file diff --git a/src/forge/Server/data.jsx b/src/forge/Server/data.jsx new file mode 100644 index 00000000..5bf540cd --- /dev/null +++ b/src/forge/Server/data.jsx @@ -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( +
    + setDetectionVisible(false)} + onOk={onDetectionOk} + owner={owner} + projectsId={projectsId} + relayCount={relayCount} + repeatId={repeatId} + repeatBranch={repeatBranch} + /> +
    + 重晴鸟代码溯源系统 + { isManager && 新建分析 } +
    + +
    + { + dataSource && dataSource.length >0 && +
    +
      +
    • + 序号 + 分支名称 + 检测状态 + 检测时间 + { isManager && 操作 } +
    • + { + dataSource.map((e,key)=>{ + return( +
      +
    • + {key + 1 } + {e.branch_tag} + + { + e.detect_status === "fail" ? + 失败 + : e.detect_status==="detecting" ? +
      + + {e.detect_process}% +
      + : + 成功 + } +
      + {e.detect_startdate} + { + isManager && + +
      + { + e.detect_status ==="detecting" ? + 重新扫描 + : + repeatCheck(e.project_id,e.branch_tag)}>重新扫描 + } + {/* { + (e.detect_status ==="fail" || e.detect_status ==="detecting") ? + 查看 + : + 查看 + } */} + { + (e.detect_status ==="fail" || e.detect_status ==="detecting") ? + 下载报告 + : + handleDownExcel(e.task_id)}>下载报告 + } +
      +
      + } +
    • + {false && } +
      + ) + }) + } +
    +
    + } + { + (dataSource === null || (dataSource && dataSource.length === 0)) && + + } +
    +
    +
    + ) +} +export default Data; \ No newline at end of file diff --git a/src/forge/Server/dataEmpty.jsx b/src/forge/Server/dataEmpty.jsx new file mode 100644 index 00000000..b6ecf4f6 --- /dev/null +++ b/src/forge/Server/dataEmpty.jsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { Divider} from 'antd'; + + +function DataEmpty(props){ + return( +
    +
    + + 暂无数据 +

    重睛鸟代码溯源及安全审查系统是一款完全自主、面向主流语言的代码审查大数据平台。主要功能包含软件源代码的溯源分析、自主度评估、开源漏洞检测、开源许可证合规性分析,支持分析结果多层次可视化展示等,可用于提高软件代码的可控性与安全性。

    + +

    对每个仓库,可进行代码检测总次数仅为 5

    +
    +
    + ) +} +export default DataEmpty; \ No newline at end of file diff --git a/src/forge/Server/detectionModal.jsx b/src/forge/Server/detectionModal.jsx new file mode 100644 index 00000000..5e9acef2 --- /dev/null +++ b/src/forge/Server/detectionModal.jsx @@ -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( + + 取消 + { !check && relayCount !== 0 && 开始检测 } + + } + > +
    +
    +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    + { + check ? +

    正在开启检测,请等待...

    + : +

    剩余扫描次数{relayCount}

    + } +
    +
    +
    + { + !check && !repeatBranch && + + {getFieldDecorator("branch",{ + rules:[{required:true,message:"请选择要检测的分支"}] + })( + + )} + + } +
    + { + ((check && branch) || repeatBranch) && +
    + 检测分支 +

    {branch || repeatBranch}

    +
    + } +
    + 检测类型 +

    快速-组件级

    +
    +
    + 检测参数 +
    +

    解析层级:2

    +

    最小解析文件行数:10

    +

    许可证检测类型:开源软件

    + 文件相似阈值 +
      +
    • 行数:20
    • +
    • 相似比例:50%
    • +
    +
    +
    +
    +
    +
    +
    +
    + ) +} +export default Form.create()(forwardRef(DetectionModal)); \ No newline at end of file diff --git a/src/forge/Server/img/1.png b/src/forge/Server/img/1.png new file mode 100644 index 00000000..f68e8d95 Binary files /dev/null and b/src/forge/Server/img/1.png differ diff --git a/src/forge/Server/img/2.png b/src/forge/Server/img/2.png new file mode 100644 index 00000000..2643e352 Binary files /dev/null and b/src/forge/Server/img/2.png differ diff --git a/src/forge/Server/img/3.png b/src/forge/Server/img/3.png new file mode 100644 index 00000000..93987fcc Binary files /dev/null and b/src/forge/Server/img/3.png differ diff --git a/src/forge/Server/img/4.png b/src/forge/Server/img/4.png new file mode 100644 index 00000000..0374f991 Binary files /dev/null and b/src/forge/Server/img/4.png differ diff --git a/src/forge/Server/img/5.png b/src/forge/Server/img/5.png new file mode 100644 index 00000000..921b8c33 Binary files /dev/null and b/src/forge/Server/img/5.png differ diff --git a/src/forge/Server/img/6.png b/src/forge/Server/img/6.png new file mode 100644 index 00000000..31894e40 Binary files /dev/null and b/src/forge/Server/img/6.png differ diff --git a/src/forge/Server/img/7.png b/src/forge/Server/img/7.png new file mode 100644 index 00000000..2c2c3972 Binary files /dev/null and b/src/forge/Server/img/7.png differ diff --git a/src/forge/Server/img/bg.png b/src/forge/Server/img/bg.png new file mode 100644 index 00000000..ac89dfef Binary files /dev/null and b/src/forge/Server/img/bg.png differ diff --git a/src/forge/Server/img/detectionBG.png b/src/forge/Server/img/detectionBG.png new file mode 100644 index 00000000..d79ab961 Binary files /dev/null and b/src/forge/Server/img/detectionBG.png differ diff --git a/src/forge/Server/img/logo.png b/src/forge/Server/img/logo.png new file mode 100644 index 00000000..4bebd9fc Binary files /dev/null and b/src/forge/Server/img/logo.png differ diff --git a/src/forge/Server/img/modaltitle.png b/src/forge/Server/img/modaltitle.png new file mode 100644 index 00000000..81179304 Binary files /dev/null and b/src/forge/Server/img/modaltitle.png differ diff --git a/src/forge/Server/img/nullicon.png b/src/forge/Server/img/nullicon.png new file mode 100644 index 00000000..6801601d Binary files /dev/null and b/src/forge/Server/img/nullicon.png differ diff --git a/src/forge/Server/index.scss b/src/forge/Server/index.scss new file mode 100644 index 00000000..a0de01e4 --- /dev/null +++ b/src/forge/Server/index.scss @@ -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; + } + } + } +} \ No newline at end of file diff --git a/src/forge/Settings/Setting.js b/src/forge/Settings/Setting.js index 5e02796c..db6263b6 100644 --- a/src/forge/Settings/Setting.js +++ b/src/forge/Settings/Setting.js @@ -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 { diff --git a/src/forge/users/Infos.js b/src/forge/users/Infos.js index d5d54706..13d78239 100644 --- a/src/forge/users/Infos.js +++ b/src/forge/users/Infos.js @@ -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 (
    { diff --git a/src/modules/tpm/TPMIndexHOC.js b/src/modules/tpm/TPMIndexHOC.js index b675fb35..1fdf5f2a 100644 --- a/src/modules/tpm/TPMIndexHOC.js +++ b/src/modules/tpm/TPMIndexHOC.js @@ -226,6 +226,7 @@ export function TPMIndexHOC(WrappedComponent) { this.setState({ showNotice:false }) + this.getAppdatausr(); } showCompeleteDialog=()=>{