diff --git a/public/css/edu-purge.css b/public/css/edu-purge.css index 0d146204..9877c4ea 100644 --- a/public/css/edu-purge.css +++ b/public/css/edu-purge.css @@ -3971,9 +3971,12 @@ html>body #ajax-indicator { display: block; height: 100%; width: 100%; - color: #333; + color: #fff; font-size: 16px; } +.head-right i{ + color: #fff!important; +} .head-nav ul#header-nav li a:hover,.head-nav ul#header-nav li.active a { color: #5091FF; diff --git a/src/App.js b/src/App.js index 3072aca5..5b745a70 100644 --- a/src/App.js +++ b/src/App.js @@ -322,6 +322,13 @@ class App extends Component { {/* 查询 */} + ( + + ) + } + /> ( diff --git a/src/forge/Component/HeadSearch.jsx b/src/forge/Component/HeadSearch.jsx index fb7c9f25..10b829a2 100644 --- a/src/forge/Component/HeadSearch.jsx +++ b/src/forge/Component/HeadSearch.jsx @@ -32,7 +32,7 @@ export default ({history}) => { /> : - { + { setOpenSearch(true) }} /> } diff --git a/src/forge/Head/Footer.jsx b/src/forge/Head/Footer.jsx index 52c06858..8a69c2ad 100644 --- a/src/forge/Head/Footer.jsx +++ b/src/forge/Head/Footer.jsx @@ -19,7 +19,7 @@ function Footer(){ return(
-
+
{value && showhtml(value)} {/*
diff --git a/src/forge/Head/Header.js b/src/forge/Head/Header.js index ac139351..622eef3c 100644 --- a/src/forge/Head/Header.js +++ b/src/forge/Head/Header.js @@ -433,7 +433,7 @@ class NewHeader extends Component { { current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)? - + :"" } @@ -448,7 +448,7 @@ class NewHeader extends Component { > {current_user && - + } @@ -457,10 +457,10 @@ class NewHeader extends Component {
{!user || (user && !user.login) ? - this.educoderlogin()} className="mr5 color-grey-6">登录 + this.educoderlogin()} className="mr5 color-white">登录 { settings && settings.common && settings.common.register && - 注册 + 注册 } : diff --git a/src/forge/Head/NoticeContent.jsx b/src/forge/Head/NoticeContent.jsx index 634a7adc..39546707 100644 --- a/src/forge/Head/NoticeContent.jsx +++ b/src/forge/Head/NoticeContent.jsx @@ -224,7 +224,7 @@ function NoticeContent({ visible, showNotification, resetUserInfo, current_user:
- " + (item.sender ? item.sender.name : '') + "   " + item.content + " 中@我" }}> + {item.time_ago}
diff --git a/src/forge/Images/taskbar.png b/src/forge/Images/taskbar.png new file mode 100644 index 00000000..91ceec7f Binary files /dev/null and b/src/forge/Images/taskbar.png differ diff --git a/src/forge/Index.js b/src/forge/Index.js index c2e36916..a3770fcc 100644 --- a/src/forge/Index.js +++ b/src/forge/Index.js @@ -22,6 +22,11 @@ const ProjectIndex = Loadable({ loading: Loading, }); +const ProjectHome = Loadable({ + loader: () => import("./Main/projecthome/Index"), + loading: Loading, +}); + // 项目详情放在用户和组织下作为二级菜单存在 // const ProjectDetail = Loadable({ // loader: () => import("./Main/Detail"), @@ -67,16 +72,22 @@ class Index extends Component { )} > */} ( )} > + ( + + )} + > ( - + )} > diff --git a/src/forge/Main/CoderDepot.jsx b/src/forge/Main/CoderDepot.jsx index f50c134a..bfd6105a 100644 --- a/src/forge/Main/CoderDepot.jsx +++ b/src/forge/Main/CoderDepot.jsx @@ -138,7 +138,7 @@ function CoderDepot(props){ if(result && result.data){ const release = { "list":result.data.releases, - "total_count":result.data.releases.length + "total_count":result.data.releases && result.data.releases.length } setReleaseVersions(release); } diff --git a/src/forge/Main/CoderDepotReadme.jsx b/src/forge/Main/CoderDepotReadme.jsx index 315f7080..438b2d64 100644 --- a/src/forge/Main/CoderDepotReadme.jsx +++ b/src/forge/Main/CoderDepotReadme.jsx @@ -41,7 +41,7 @@ function CoderDepotReadme({ operate , history , readme , ChangeFile }){ return(
- +
diff --git a/src/forge/Main/Detail.js b/src/forge/Main/Detail.js index 96b14b17..66822ddb 100644 --- a/src/forge/Main/Detail.js +++ b/src/forge/Main/Detail.js @@ -509,11 +509,6 @@ class Detail extends Component { this.textFunc(projectDetail.forked_from_project_id, projectDetail.fork_info) : "" } - { - projectDetail && projectDetail.type && projectDetail.type !== 0 ? - 导入于 {projectDetail.mirror_url} - : "" - }
diff --git a/src/forge/Main/Index.js b/src/forge/Main/Index.js index 3b1f66db..b82db46e 100644 --- a/src/forge/Main/Index.js +++ b/src/forge/Main/Index.js @@ -50,7 +50,7 @@ class Index extends Component { this.getCategory(); - this.getRecommand(); + // this.getRecommand(); this.getLanguage(); @@ -304,9 +304,9 @@ class Index extends Component { return (
-

+ {/*

-

+

*/} {/* { recommendOriList && recommendOriList.length>0? @@ -320,7 +320,7 @@ class Index extends Component { :"" } */} - { + {/* { recommendList && recommendList.length>0 && 5 ? "recommandProjects":"recommandProjects mb20"}> { @@ -341,7 +341,7 @@ class Index extends Component { }) } - } + } */}
    diff --git a/src/forge/Main/IndexItem.js b/src/forge/Main/IndexItem.js index 0cba9123..4ddd7633 100644 --- a/src/forge/Main/IndexItem.js +++ b/src/forge/Main/IndexItem.js @@ -52,12 +52,6 @@ class IndexItem extends Component { :"" } - { - item.type && item.type === 1 ? - - - :"" - } { diff --git a/src/forge/Main/img/index/banner.png b/src/forge/Main/img/index/banner.png new file mode 100644 index 00000000..101be0a5 Binary files /dev/null and b/src/forge/Main/img/index/banner.png differ diff --git a/src/forge/Main/img/index/box.png b/src/forge/Main/img/index/box.png new file mode 100644 index 00000000..3dbddbef Binary files /dev/null and b/src/forge/Main/img/index/box.png differ diff --git a/src/forge/Main/img/index/data.png b/src/forge/Main/img/index/data.png new file mode 100644 index 00000000..6b5b3347 Binary files /dev/null and b/src/forge/Main/img/index/data.png differ diff --git a/src/forge/Main/img/index/earth.png b/src/forge/Main/img/index/earth.png new file mode 100644 index 00000000..eca8dafb Binary files /dev/null and b/src/forge/Main/img/index/earth.png differ diff --git a/src/forge/Main/img/index/eye.png b/src/forge/Main/img/index/eye.png new file mode 100644 index 00000000..e7563add Binary files /dev/null and b/src/forge/Main/img/index/eye.png differ diff --git a/src/forge/Main/img/index/hot.png b/src/forge/Main/img/index/hot.png new file mode 100644 index 00000000..0304899d Binary files /dev/null and b/src/forge/Main/img/index/hot.png differ diff --git a/src/forge/Main/img/index/hotAuthor.png b/src/forge/Main/img/index/hotAuthor.png new file mode 100644 index 00000000..62d01a74 Binary files /dev/null and b/src/forge/Main/img/index/hotAuthor.png differ diff --git a/src/forge/Main/img/index/icon.png b/src/forge/Main/img/index/icon.png new file mode 100644 index 00000000..2bfa60dd Binary files /dev/null and b/src/forge/Main/img/index/icon.png differ diff --git a/src/forge/Main/img/index/month.png b/src/forge/Main/img/index/month.png new file mode 100644 index 00000000..3b0b909f Binary files /dev/null and b/src/forge/Main/img/index/month.png differ diff --git a/src/forge/Main/img/index/more.png b/src/forge/Main/img/index/more.png new file mode 100644 index 00000000..1ae51d03 Binary files /dev/null and b/src/forge/Main/img/index/more.png differ diff --git a/src/forge/Main/img/index/typebg.png b/src/forge/Main/img/index/typebg.png new file mode 100644 index 00000000..e1d748ed Binary files /dev/null and b/src/forge/Main/img/index/typebg.png differ diff --git a/src/forge/Main/img/index/unit/feiteng.png b/src/forge/Main/img/index/unit/feiteng.png new file mode 100644 index 00000000..b4190d4e Binary files /dev/null and b/src/forge/Main/img/index/unit/feiteng.png differ diff --git a/src/forge/Main/img/index/unit/huake.png b/src/forge/Main/img/index/unit/huake.png new file mode 100644 index 00000000..56863862 Binary files /dev/null and b/src/forge/Main/img/index/unit/huake.png differ diff --git a/src/forge/Main/img/index/unit/huawei.png b/src/forge/Main/img/index/unit/huawei.png new file mode 100644 index 00000000..4374a68c Binary files /dev/null and b/src/forge/Main/img/index/unit/huawei.png differ diff --git a/src/forge/Main/img/index/unit/jijinhui.png b/src/forge/Main/img/index/unit/jijinhui.png new file mode 100644 index 00000000..c7fc91a6 Binary files /dev/null and b/src/forge/Main/img/index/unit/jijinhui.png differ diff --git a/src/forge/Main/img/index/unit/langchao.png b/src/forge/Main/img/index/unit/langchao.png new file mode 100644 index 00000000..46a1d70c Binary files /dev/null and b/src/forge/Main/img/index/unit/langchao.png differ diff --git a/src/forge/Main/img/index/unit/mulan.png b/src/forge/Main/img/index/unit/mulan.png new file mode 100644 index 00000000..8e700754 Binary files /dev/null and b/src/forge/Main/img/index/unit/mulan.png differ diff --git a/src/forge/Main/img/index/unit/xigongye.png b/src/forge/Main/img/index/unit/xigongye.png new file mode 100644 index 00000000..7ec29810 Binary files /dev/null and b/src/forge/Main/img/index/unit/xigongye.png differ diff --git a/src/forge/Main/img/index/unit/xiuos.png b/src/forge/Main/img/index/unit/xiuos.png new file mode 100644 index 00000000..cc9d7422 Binary files /dev/null and b/src/forge/Main/img/index/unit/xiuos.png differ diff --git a/src/forge/Main/img/index/week.png b/src/forge/Main/img/index/week.png new file mode 100644 index 00000000..c967f424 Binary files /dev/null and b/src/forge/Main/img/index/week.png differ diff --git a/src/forge/Main/projecthome/Index.jsx b/src/forge/Main/projecthome/Index.jsx new file mode 100644 index 00000000..37e72cd1 --- /dev/null +++ b/src/forge/Main/projecthome/Index.jsx @@ -0,0 +1,126 @@ +import React , { useEffect , useState } from 'react'; +import './Index.scss'; +import SubBanner from './SubBanner'; +import SubUnitBanner from './SubUnitBanner'; +import Icon from '../img/index/icon.png'; +import { Link } from 'react-router-dom'; +import { Spin } from 'antd'; +import SubList from './SubList'; +import more from '../img/index/more.png'; +import axios from 'axios'; +import { getImageUrl } from 'educoder'; +import Nodata from '../../Nodata'; + +const LIMIT = 20; +function Index() { + + const [ cateList , setCateList ] = useState(undefined); + const [ projectsList , setProjectsList ] = useState(undefined); + const [ cateID, setCateID ] = useState(undefined); + const [ isSpin, setIsSpin ] = useState(true); + + useEffect(()=>{ + getCate(); + },[]) + + useEffect(()=>{ + setIsSpin(true); + getProject(); + },[cateID]) + + function getCate() { + const url = `/project_categories/pinned_index.json`; + axios.get(url).then(result=>{ + if(result && result.data){ + setCateList(result.data.project_categories); + } + }).catch(error=>{}) + } + + function getProject() { + const url = `/projects.json`; + axios.get(url,{ + params:{ + pinned:"d", + category_id:cateID, + limit:LIMIT + } + }).then(result=>{ + if(result && result.data){ + setProjectsList(result.data.projects); + setIsSpin(false); + } + }).catch(error=>{}) + } + + return( +
    + + +
    +
    + +
    +
    + 开源项目 + 更多 +
    + +
    + { + projectsList && projectsList.length > 0 ? +
    + { + projectsList.map((i,k)=>{ + return( +
  • + +
    +
    + {i.author && i.author.name}/{i.name} + {i.praises_count > 0 ? {i.praises_count} :"" } + {i.forked_count > 0 ? {i.forked_count}:""} +
    +
    + {i.description} +
    +
    + {i.category && i.category.id ? {i.category.name} :"" } + {i.language && i.language.id ? {i.language.name} :""} + 更新于{i.time_ago} +
    +
    +
  • + ) + }) + } +
    + :"" + } + { + projectsList && projectsList.length === 0 && + } +
    +
    +
    + 查看更多开源项目 +
    +
    +
    + +
    +
    + ) +} +export default Index; \ No newline at end of file diff --git a/src/forge/Main/projecthome/Index.scss b/src/forge/Main/projecthome/Index.scss new file mode 100644 index 00000000..ef733067 --- /dev/null +++ b/src/forge/Main/projecthome/Index.scss @@ -0,0 +1,553 @@ +.banners{ + background: url('../img/index/banner.png') no-repeat top; + min-height: 516px; + background-size: cover; + background-color: #0C2A5B; + .bannersCenter{ + padding-top: 30px; + max-width: 1200px; + margin: 0px auto; + position: relative; + height: 516px; + } + .bTitle{ + height: 30px; + line-height: 30px; + font-size: 30px; + font-weight: 500; + color: #FFFFFF; + margin-bottom: 20px!important; + text-align: center; + span{ + background: linear-gradient(to right,#289AF6 0%, #9E84FF 40%, #FFB03B 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + } + .bSubTitle{ + text-align: center; + height: 30px; + line-height: 30px; + font-size: 16px; + font-weight: 400; + color: #FFFFFF; + } + .bannerBox{ + background: url('../img/index/box.png') no-repeat; + background-size: 100% 100%; + height: 240px; + width: 380px; + margin:0px auto; + padding:25px 30px 34px; + .bannersProject{ + position: relative; + .slick-list{ + width: 100%; + overflow: hidden; + } + .slick-track{ + display: flex; + li{ + padding:15px 20px; + .projectinfos{ + display: flex; + align-items: center; + width: 100%; + margin-bottom: 13px; + img{ + width: 32px; + height: 32px; + margin-right: 7px; + border-radius: 50%; + } + .name{ + height: 28px; + line-height: 28px; + font-size: 20px; + font-weight: 500; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + max-width: 250px; + color: #25EBFF; + a{ + color: #25EBFF!important; + } + } + .company{ + height: 20px; + line-height: 20px; + font-size: 14px; + font-weight: 400; + color: #FFFFFF; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + max-width: 250px; + a{ + color: #FFFFFF!important; + } + } + } + .desc{ + height: 40px; + font-size: 13px; + font-weight: 400; + color: #FFFFFF; + line-height: 20px; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + } + .infoData{ + display: flex; + margin-top: 16px; + justify-content: space-around; + &>span{ + display: flex; + align-items: center; + &>span{ + color: #FFB729; + font-size: 15px; + font-weight: 400; + } + } + img{ + width: 16px; + margin-right: 4px; + } + } + } + } + } + } + .airBubble{ + &>div{ + position: absolute; + height: 410px; + width: 415px; + bottom: 0px; + &.right{ + right: 0px; + } + &.left{ + left: 0px; + } + &.right div, &.left div{ + position: relative; + width: 100%; + height: 100%; + span{ + position: absolute; + border-radius: 50%; + background: linear-gradient(124deg, rgba(255, 255, 255, 0.1) 0%, rgba(5, 200, 220, 0.04) 50%, rgba(5, 200, 220, 0.03) 100%); + box-shadow: 0px 0px 7px 3px rgba(0, 154, 255, 0.19); + border: 1px solid rgba(0, 154, 255, 0.19); + font-size: 14px; + font-weight: 400; + line-height: 17px; + display: flex; + align-items: center; + word-break: break-all; + text-align: center; + padding:5px; + animation: zoomin 1.3s infinite alternate; + &:hover{ + animation:none + } + } + } + &.right span:nth-child(4) a,&.left span:nth-child(1) a,&.left span:nth-child(2) a{ + color: #25EBFF!important; + } + &.right span:nth-child(1) a,&.left span:nth-child(5) a{ + color: #CD8AFF!important; + } + &.right span:nth-child(3) a,&.right span:nth-child(5) a,&.left span:nth-child(6) a{ + color: #FF6125!important; + } + &.left span:nth-child(3) a{ + color: #FF8425!important; + } + &.right span:nth-child(2) a,&.left span:nth-child(4) a{ + color: #8CC2FF!important; + } + &.right span:nth-child(1){ + right: 0px; + height: 120px; + width: 120px; + } + &.right span:nth-child(2){ + right: 160px; + height: 72px; + width: 72px; + bottom: 220px; + padding:0px; + animation-delay: 0.2s; + } + &.right span:nth-child(3){ + right: 300px; + height: 94px; + width: 94px; + bottom: 99px; + padding:8px; + animation-delay: 0.3s; + } + &.right span:nth-child(4){ + right: 156px; + height: 100px; + width: 100px; + bottom: 39px; + font-size: 12px; + animation-delay: 0.2s; + } + &.right span:nth-child(5){ + right: 10px; + height: 94px; + width: 94px; + bottom: 97px; + animation-delay: 0.4s; + } + &.left span:nth-child(1){ + left: 80px; + height: 110px; + width: 110px; + padding:8px; + animation-delay: 0.1s; + } + &.left span:nth-child(2){ + right: 60px; + height: 96px; + width: 96px; + top: 85px; + font-size: 13px; + animation-delay: 0.2s; + } + &.left span:nth-child(3){ + left: 0px; + height: 86px; + width: 86px; + top: 145px; + font-size: 13px; + animation-delay: 0.3s; + } + &.left span:nth-child(4){ + left: 164px; + height: 70px; + width: 70px; + bottom: 158px; + font-size: 12px; + font-size: 12px; + animation-delay: 0.3s; + } + &.left span:nth-child(5){ + left: 35px; + height: 102px; + width: 102px; + bottom: 32px; + font-size: 13px; + animation-delay: 0.4s; + } + &.left span:nth-child(6){ + right: 10px; + height: 114px; + width: 114px; + bottom: 26px; + padding:8px; + } + } + } +} +@keyframes zoomin{ + 0%{-webkit-transform:scale(1.05);transform:scale(1.05)} + 100%{-webkit-transform:scale(0.8);transform:scale(0.8)} +} +@-webkit-keyframes zoomin{ + 0%{-webkit-transform:scale(1.05);transform:scale(1.05)} + 100%{-webkit-transform:scale(0.8);transform:scale(0.8)} +} +.unitBanner{ + padding:29px 0px; + background: #F9F9F9; + .unitContent{ + max-width: 1200px; + margin:0px auto; + .unitTitle{ + height: 28px; + line-height: 28px; + font-size: 20px; + font-weight: 500; + color: #1E1E1E; + display: flex; + align-items: center; + img{ + margin-left: 9px; + } + } + .unitSlider{ + padding:30px 0px 10px; + .slick-list{ + width: 100%; + height: 56px; + overflow: hidden; + .slickline{ + display: flex!important; + align-items: center; + justify-content: space-between; + } + } + } + } +} +.dataPanel{ + width: 1200px; + display: flex; + justify-content: space-between; + padding:30px 0px 60px; + margin:0px auto; + .left{ + width: 850px; + box-shadow: 0px 0px 4px 5px rgba(0, 0, 0, 0.02); + display: flex; + .leftTypes{ + width: 220px; + height: 1576px; + background: url('../img/index/typebg.png'); + background-size: 100% 100%; + box-shadow: 0px 0px 4px 5px rgba(0, 0, 0, 0.02); + padding:12px 0px; + a{ + padding:0px 20px; + height: 44px; + margin-top: 10px; + font-size: 16px; + font-weight: 500; + color: #333333; + display: flex; + align-items: center; + cursor: pointer; + &:hover{ + background-color: #F5F5F5; + } + &.active{ + background: linear-gradient(to right,#07228F , #466AFF); + color: #fff!important; + } + img{ + margin-right: 12px; + width: 28px; + } + } + } + .leftLists{ + flex:1; + .leftTitles{ + height: 60px; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid rgba(153, 153, 153, 0.16); + padding:0px 20px; + span{ + font-size: 18px; + font-weight: 500; + color: #000000; + } + a{ + color: #466AFF!important; + } + } + .leftlistItem{ + padding:0px 20px; + li{ + border-bottom: 1px solid rgba(153, 153, 153, 0.16); + display: flex; + align-items: flex-start; + padding:20px 0px ; + &>a img{ + width: 32px; + height: 32px; + border-radius: 50%; + margin-right: 10px; + } + .itemTitle{ + flex:1; + .item-title-infos{ + height: 22px; + display: flex; + align-items: center; + .infotitle{ + flex:1; + height: 21px; + font-size: 15px; + font-weight: 600; + line-height: 21px; + color: #333!important; + &:hover{ + color: #466AFF!important; + } + } + span{ + margin-left:20px ; + color: #333; + i{ + color: #666; + } + } + } + .item-desc{ + font-size: 14px; + font-weight: 400; + color: #414141; + line-height: 24px; + max-width: 548px; + margin: 5px 0px; + } + .item-data{ + font-size: 13px; + font-weight: 400; + color: #7D7D7D; + height: 20px; + line-height: 20px; + display: flex; + align-items: flex-end; + .category{ + position: relative; + padding-left: 11px; + margin-right: 10px; + &::before{ + position: absolute; + content: ""; + width: 6px; + height: 6px; + border-radius: 50%; + background-color: #466AFF; + top: 7px; + left: 0px; + } + } + .language{ + position: relative; + padding-left: 11px; + &::before{ + position: absolute; + content: ""; + width: 1px; + height: 10px; + border-radius: 50%; + border-left: 1px solid #9e9e9e; + bottom: 4px; + left: 0px; + } + } + } + } + } + } + } + .left-bottom-btn{ + display: flex; + justify-content: center; + padding:18px 0px; + a{ + height: 38px; + line-height: 36px; + border-radius: 8px; + border: 1px solid #466AFF; + color: #466AFF; + font-size: 16px; + padding:0px 20px; + img{ + height: 16px; + margin-top: -1px; + margin-left: 8px; + } + } + } + } + .right{ + width: 330px; + &>div{ + box-shadow: 0px 0px 4px 5px rgba(0, 0, 0, 0.02); + margin-bottom: 20px; + } + .partTitle{ + padding:15px; + background: #F6F9FF; + font-size: 18px; + color: #000000; + font-weight: 500; + margin-bottom: 10px; + img{ + width: 33px; + margin-right: 6px; + } + } + .righthotAuthor{ + padding-bottom: 15px; + li{ + padding-left: 15px; + &>div{ + display: flex; + align-items: flex-start; + padding:10px 15px 10px 0px; + border-bottom: 1px solid rgba(153, 153, 153, 0.1); + img{ + width: 32px; + height: 32px; + border-radius: 50%; + margin-right: 8px; + margin-top: 3px; + } + } + &:hover{ + background-color: #F3F3F3; + } + &:last-child > div{ + border-bottom: none; + } + } + } + .hotProjects{ + li{ + padding:10px 15px; + margin-bottom: 10px; + &:hover{ + background-color: #F3F3F3; + } + .mInfos{ + display: flex; + align-items: center; + height: 20px; + .num{ + width: 18px; + height: 18px; + background: #466AFF; + border-radius: 2px; + color: #fff; + text-align: center; + line-height: 18px; + margin-right: 8px; + } + .name{ + flex:1; + font-size: 15px; + } + } + .sInfos{ + background: #F7F8F9; + padding:5px; + font-size: 13px; + font-weight: 400; + color: #666666; + line-height: 22px; + word-break: break-all; + margin-top: 10px; + } + } + } + } +} \ No newline at end of file diff --git a/src/forge/Main/projecthome/SubBanner.jsx b/src/forge/Main/projecthome/SubBanner.jsx new file mode 100644 index 00000000..7e8c1a63 --- /dev/null +++ b/src/forge/Main/projecthome/SubBanner.jsx @@ -0,0 +1,115 @@ +import React , { useEffect , useState } from 'react'; +import Slider from 'react-slick'; +import { Link } from 'react-router-dom'; +import { getImageUrl } from 'educoder'; +import Eye from '../img/index/eye.png'; +import Data from '../img/index/data.png'; +import Earth from '../img/index/earth.png'; +import Imgs from '../img/tree.png'; +import axios from 'axios'; + +// const list =[ +// {img:Imgs,name:"矽璓工业物联操作系统XiUOS",company:"泛在操作系统实验室",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"openGauss-operator",company:"华为技术有限公司",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"PaddleDetection 2.0",company:"TrustieMirrors",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"skyline",company:"浪潮信息",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"BitXHub",company:"开放原子开源基金会",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"Device Model",company:"openDACS",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"Gitlink",company:"Gitlink",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"openEuler-datenlord",company:"华为技术有限公司",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"OpenAtom XuperChain",company:"开放原子开源基金会",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"xuos-web",company:"泛在操作系统实验室",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// {img:Imgs,name:"CrowdOS开源项目开发",company:"西北工业大学",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"}, +// ] +const settings={ + dots: false, + infinite: true, + speed: 1000, + slidesToShow: 1, + slidesToScroll: 1, + autoplay:true, + arrows:false, + adaptiveHeight:true +} + +function SubBanner() { + + const [ list , setList ] = useState(undefined); + + useEffect(()=>{ + getList(); + },[]) + + function getList() { + const url = `/projects/banner_recommend.json`; + axios.get(url).then(result=>{ + if(result && result.data){ + setList(result.data.projects); + } + }).catch(error=>{}) + } + return( +
    +
    +

    新一代开源创新服务平台

    +

    Gitlink(确实开源)-CCF官网指定的产学研融合面向软件开源创新的开源社区

    +
    + { + list && list.length > 0 ? + + { + list.map((i,k)=>{ + return( +
  • +
    + +
    +

    {i.name}

    +

    {i.author && i.author.name}

    +
    +
    +

    {i.description}

    +
    + {i.visits} + {i.category && i.category.id && {i.category.name}} + {i.language && i.language.id && {i.language.name}} +
    +
  • + ) + }) + } +
    + :"" + } +
    +
    +
    +
    + { + list && list.length > 0 && list.map((i,k)=>{ + return( + k%2 === 0? {i.author && i.author.name}/{i.name} : "" + ) + }) + } +
    +
    + +
    +
    + { + list && list.length > 0 && list.map((i,k)=>{ + return( + k%2 > 0 ? {i.author && i.author.name}/{i.name} : "" + ) + }) + } +
    +
    + +
    +
    +
    + ) +} +export default SubBanner diff --git a/src/forge/Main/projecthome/SubList.jsx b/src/forge/Main/projecthome/SubList.jsx new file mode 100644 index 00000000..56510392 --- /dev/null +++ b/src/forge/Main/projecthome/SubList.jsx @@ -0,0 +1,138 @@ +import React , { useEffect , useState } from 'react'; +import hotAuthor from '../img/index/hotAuthor.png'; +import week from '../img/index/week.png'; +import month from '../img/index/month.png'; +import { Link } from 'react-router-dom'; +import axios from 'axios'; +import { getImageUrl } from 'educoder'; + + +function SubList() { + + const [ weekList ,setWeekList ] = useState(undefined); + const [ monthList ,setMonthList ] = useState(undefined); + const [ authorList ,setAuthorList ] = useState(undefined); + + useEffect(()=>{ + getList(7); + getList(30); + getAuthorList(7); + },[]) + + function getList(time){ + const url = `/project_rank.json`; + axios.get(url,{ + params:{ + time + } + }).then(result=>{ + if(result && result.data){ + time === 7 ? setWeekList(result.data.projects) : setMonthList(result.data.projects); + } + }).catch(error=>{}) + } + function getAuthorList(time){ + const url = `/user_rank.json`; + axios.get(url,{ + params:{ + time + } + }).then(result=>{ + if(result && result.data){ + setAuthorList(result.data.users); + } + }).catch(error=>{}) + } + + return( +
    + { + authorList && authorList.length > 0? +
    +
    本周热门开发者
    +
    + { + authorList.map((i,k)=>{ + return( +
  • +
    + +
    + {i.name} +

    + {i.project && i.project.name} +

    +
    +
    +
  • + ) + }) + } +
    +
    + :"" + } + + { + weekList && weekList.length > 0 ? +
    +
    本周热门项目
    +
    + { + weekList.map((i,k)=>{ + return( +
  • +
    + {k+1} + {i.owner && i.owner.name}/{i.name} + + {i.praises} + +
    + {i.description && +
    + {i.description} +
    + } +
  • + ) + }) + } +
    +
    + :"" + } + { + monthList && monthList.length > 0? +
    +
    本月热门项目
    +
    + { + monthList.map((i,k)=>{ + return( +
  • +
    + {k+1} + {i.owner && i.owner.name}/{i.name} + + {i.praises} + +
    + {i.description && +
    + {i.description} +
    + } +
  • + ) + }) + } +
    +
    + :"" + } + +
    + ) +} +export default SubList; \ No newline at end of file diff --git a/src/forge/Main/projecthome/SubUnitBanner.jsx b/src/forge/Main/projecthome/SubUnitBanner.jsx new file mode 100644 index 00000000..f3ba16a5 --- /dev/null +++ b/src/forge/Main/projecthome/SubUnitBanner.jsx @@ -0,0 +1,84 @@ +import React , { useEffect , useState } from 'react'; +import Hot from '../img/index/hot.png'; +import Slider from "react-slick"; +import huawei from '../img/index/unit/huawei.png'; +import langchao from '../img/index/unit/langchao.png'; +import jijinhui from '../img/index/unit/jijinhui.png'; +import mulan from '../img/index/unit/mulan.png'; +import xigongye from '../img/index/unit/xigongye.png'; +import feiteng from '../img/index/unit/feiteng.png'; +import xiuos from '../img/index/unit/xiuos.png'; +import huake from '../img/index/unit/huake.png'; +import axios from 'axios'; +import { Link } from 'react-router-dom'; +import { getImageUrl } from 'educoder'; + +const settings = { + dots: false, + infinite: true, + slidesToShow: 1, + slidesToScroll: 1, + vertical: true, + verticalSwiping: true, + autoplay:true, + arrows:false +}; +const group_size = 6; +function SubUnitBanner() { + + const [ list , setlist ] = useState(undefined); + + useEffect(()=>{ + getRecommandOrz(); + },[]) + + function getRecommandOrz(params) { + const url = `/organizations/recommend.json`; + axios.get(url,{ + params:{ + group_size + } + }).then(result=>{ + if(result){ + setlist(result.data.organizations) + } + }).catch(error=>{}) + } + return( + list && list.length > 0 ? +
    +
    +
    + 精选开源组织 + +
    + + { + list.map((i,k)=>{ + return( +
    + { + i.map((j,k1)=>{ + return( + + ) + }) + } +
    + ) + }) + } + {/*
    + + + + +
    */} +
    +
    +
    + :"" + + ) +} +export default SubUnitBanner; \ No newline at end of file diff --git a/src/forge/Main/sub/DetailBanner.jsx b/src/forge/Main/sub/DetailBanner.jsx index 22a5ce41..bb298aa1 100644 --- a/src/forge/Main/sub/DetailBanner.jsx +++ b/src/forge/Main/sub/DetailBanner.jsx @@ -48,7 +48,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa item.menu_name === "issues" &&
  • - + 易修(Issue) @@ -61,7 +61,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
  • - 合并请求 + 合并请求(PR) {projectDetail && projectDetail.pull_requests_count ? {numFormat(projectDetail.pull_requests_count)} : ""}
  • :"" @@ -71,7 +71,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
  • - Wiki + 维基(Wiki)
  • } @@ -80,7 +80,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
  • {/* */} - 工作流(beta版) + 引擎(Engine) {projectDetail && projectDetail.ops_count ? {projectDetail.ops_count} : ""}
  • diff --git a/src/forge/Main/sub/ReadmeCatelogue.jsx b/src/forge/Main/sub/ReadmeCatelogue.jsx index 6dab7d79..754f3cc2 100644 --- a/src/forge/Main/sub/ReadmeCatelogue.jsx +++ b/src/forge/Main/sub/ReadmeCatelogue.jsx @@ -36,7 +36,7 @@ function ReadmeCatelogue({ menuList , hash }) { { menu && menu.length>0?
    - + { menu.map((item,key)=>{ return( diff --git a/src/forge/Merge/Files.jsx b/src/forge/Merge/Files.jsx index b4cf5b48..6661c1d3 100644 --- a/src/forge/Merge/Files.jsx +++ b/src/forge/Merge/Files.jsx @@ -18,7 +18,7 @@ function Files({ data,history,owner,projectsId , parentsSha }){ useEffect(()=>{ document.addEventListener('click',()=>{setIsOpen(false)}) - }) + },[]) function showDown(flag,index,isBin){ if(!isBin){ diff --git a/src/forge/Merge/MergeItem.js b/src/forge/Merge/MergeItem.js index 61477c14..3e88eeb9 100644 --- a/src/forge/Merge/MergeItem.js +++ b/src/forge/Merge/MergeItem.js @@ -112,9 +112,9 @@ class MergeItem extends Component { to={`/${item.is_original ? item.fork_project_user : owner}/${ item.is_original ? item.fork_project_identifier : projectsId }/tree/${turnbar(item.pull_request_head)}`} className="maxW200px task-hide ver-middle" style={{maxWidth:"200px"}} > - {item.is_original - ? item.fork_project_user - : project_author_name} + {item.is_fork + ? item.pull_request_base + : item.author_name} :{item.pull_request_head} @@ -136,8 +136,8 @@ class MergeItem extends Component { to={`/${owner}/${projectsId}/tree/${turnbar(item.pull_request_base)}`} className="maxW200px task-hide ver-middle" style={{maxWidth:"200px"}} > - {/* {item.is_fork ? item.pull_request_base : `${item.author_name}:${item.pull_request_base}`} */} - {project_author_name}:{item.pull_request_base} + {item.is_fork ? item.pull_request_base : `${item.author_name}:${item.pull_request_base}`} + {/* {project_author_name}:{item.pull_request_base} */} } diff --git a/src/forge/Merge/MessageCount.js b/src/forge/Merge/MessageCount.js index 6d01e8a3..d7f665dd 100644 --- a/src/forge/Merge/MessageCount.js +++ b/src/forge/Merge/MessageCount.js @@ -365,10 +365,10 @@ class MessageCount extends Component {
    - {data.pull_request.is_original ? data.pull_request.fork_project_user : data.issue.project_author_name}: {data.pull_request && data.pull_request.head} + {data.pull_request.is_fork ? data.pull_request_base.fork_project_user : data.issue.author_name}: {data.pull_request && data.pull_request.head} @@ -383,7 +383,7 @@ class MessageCount extends Component { to={`/${owner}/${projectsId}/tree/${data.pull_request.base}`} className="ver-middle task-hide" style={{maxWidth:"200px"}} title={`${data.issue.project_author_name}:${data.pull_request.base}`} > - {data.issue.project_author_name}:{data.pull_request.base} + {data.issue.author_name}:{data.pull_request.base}
    diff --git a/src/forge/Merge/UpdateMerge.js b/src/forge/Merge/UpdateMerge.js index 8918db6e..8af84941 100644 --- a/src/forge/Merge/UpdateMerge.js +++ b/src/forge/Merge/UpdateMerge.js @@ -54,7 +54,7 @@ class UpdateMerge extends Component { const { data, isSpin, pull, merge } = this.state; return (
    -
    +
    {" "} {data ? ( diff --git a/src/forge/Merge/merge.css b/src/forge/Merge/merge.css index d61543b4..0ac43c7d 100644 --- a/src/forge/Merge/merge.css +++ b/src/forge/Merge/merge.css @@ -222,4 +222,8 @@ form .ant-cascader-picker, form .ant-select { .overlihide li{ max-width: 450px; + } + /* 距离底部加大 @列表被遮挡 */ + .updateMerge{ + margin: 30px auto 60px; } \ No newline at end of file diff --git a/src/forge/Merge/merge_form.js b/src/forge/Merge/merge_form.js index e6378139..d050116f 100644 --- a/src/forge/Merge/merge_form.js +++ b/src/forge/Merge/merge_form.js @@ -25,6 +25,7 @@ class MergeForm extends Component { issue_tags: undefined, issue_versions: undefined, issue_priories: undefined, + atWhoLoginList:undefined }; } @@ -146,7 +147,7 @@ class MergeForm extends Component { } else { values.issue_tag_ids = []; } - const { desc } = this.state; + const { desc , atWhoLoginList } = this.state; if (merge_type === "new") { let url = `/${owner}/${projectsId}/pulls.json`; axios.post(url, { @@ -158,7 +159,8 @@ class MergeForm extends Component { fork_project_id: data && data.fork_project_id, merge_user_login: data && data.merge_user_login, files_count, - commits_count + commits_count, + receivers_login:atWhoLoginList, }) .then((result) => { if (result) { @@ -189,6 +191,7 @@ class MergeForm extends Component { body: desc, head: pull, base: merge, + receivers_login:atWhoLoginList, }) .then((result) => { if (result) { @@ -225,6 +228,13 @@ class MergeForm extends Component { }); }; + //合并请求中at谁列表(存储:login) + changeAtWhoLoginList = (loginList) =>{ + this.setState({ + atWhoLoginList:loginList, + }); + }; + render() { const { merge_type } = this.props; const { getFieldDecorator } = this.props.form; @@ -273,6 +283,10 @@ class MergeForm extends Component { mdID={"merge-new-description"} initValue={desc} onChange={this.onContentChange} + isCanAtme = {true} + changeAtWhoLoginList = {this.changeAtWhoLoginList} + owner = {owner} + projectsId = {projectsId} >

    {get_attachments && get_attachments.length > 0 ? ( diff --git a/src/forge/SecuritySetting/notice/myNotice/Index.jsx b/src/forge/SecuritySetting/notice/myNotice/Index.jsx index 22660691..3d495722 100644 --- a/src/forge/SecuritySetting/notice/myNotice/Index.jsx +++ b/src/forge/SecuritySetting/notice/myNotice/Index.jsx @@ -17,7 +17,7 @@ function MyNotice(props) { const [selectedNum, setSelectedNum] = useState(0);//@我批量删除选择消息条数 const [isBatchDelete, setIsBatchDelete] = useState(false);//@我是否批量删除 const [batchDeleteCheckedAll, setBatchDeleteCheckAll] = useState(false);//@我批量删除--全选 - + const [messageType, setMessageType] = useState(undefined); const [noticeUnreadCount, setNoticeUnreadCount] = useState();//未读系统通知数量 // const [letterUnreadCount, setLetterUnreadCount] = useState(0);//未读私信数量 const [atUnreadCount, setAtUnreadCount] = useState();//未读@我数量 @@ -65,6 +65,7 @@ function MyNotice(props) { setAtUnreadCount(response.data.unread_atme); setMessageList(response.data.messages); setMessTotalCount(response.data.total_count); + setMessageType(response.data.type); } }); } @@ -203,7 +204,46 @@ function MyNotice(props) {
    } - {messageList && messageList.map(item => { + {/* 系统消息 */} + {messageType === "notification" && messageList && messageList.map(item =>{ + return ( +
    +
    + {item.status === 1 ? : } + + {turnToMess(item)}} dangerouslySetInnerHTML={{__html: item.content}}> +
    +
    + {item.time_ago} + {item.status === 1 && readNotice([item.id])}>标记为已读} +
    +
    + ) + })} + + {/* @我消息 */} + {messageType === "atme" && messageList && messageList.map(item =>{ + return ( +
    +
    + + {item.sender && {window.open(`/${item.sender && item.sender.login}`);}}/>} +
    {turnToMess(item)}}> + {item.status === 1 ? : } + {item.sender && } +
    +
    +
    + {item.time_ago} + {!isBatchDelete && item.status === 1 && readNotice([item.id])}>标记为已读}    + {!isBatchDelete && deleteNotice([item.id])}>删除} +
    +
    + ) + })} + + {false && messageList && messageList.map(item => { + console.log('item',item); // 系统消息 if (noticeType === "0") { // 消息类别 @@ -229,7 +269,7 @@ function MyNotice(props) { {item.sender && {window.open(`/${item.sender && item.sender.login}`);}}/>}
    {turnToMess(item)}}> {item.status === 1 ? : } - {item.sender && " + item.sender.name+ " "+ item.content +" 中@我"}}>} + {item.sender && " + item.sender.name+ " "+ item.content}}>}
    diff --git a/src/forge/Settings/Setting.js b/src/forge/Settings/Setting.js index deccb3da..e7fc4d96 100644 --- a/src/forge/Settings/Setting.js +++ b/src/forge/Settings/Setting.js @@ -13,9 +13,9 @@ const menu = [ {name:"主页",index:"home"}, {name:"代码库",index:"code"}, {name:"易修 (Issue)",index:"issues"}, - {name:"合并请求",index:"pulls"}, - {name:"Wiki",index:"wiki"}, - {name:"工作流(beta版)",index:"devops"}, + {name:"合并请求 (PR)",index:"pulls"}, + {name:"维基 (Wiki)",index:"wiki"}, + {name:"引擎 (Engine)",index:"devops"}, // {name:"资源库",index:"resources"}, {name:"里程碑",index:"versions"}, {name:"动态",index:"activity"}, @@ -267,6 +267,11 @@ class Setting extends Component { }, ], })()} + { + projectDetail && projectDetail.type && projectDetail.type !== 0 ? + 该项目导入于 {projectDetail.mirror_url} + : "" + }
    可见性 diff --git a/src/forge/Team/Group/GroupDetails.jsx b/src/forge/Team/Group/GroupDetails.jsx index ba569386..1122ce72 100644 --- a/src/forge/Team/Group/GroupDetails.jsx +++ b/src/forge/Team/Group/GroupDetails.jsx @@ -117,8 +117,8 @@ export default ((props) => {
    {group.description ? group.description : "暂无描述"}
    -

    管理员团队对 所有仓库 具有操作权限,且对组织具有 管理员权限

    -

    此外,该团队拥有了 创建仓库 的权限:成员可以在组织中创建新的仓库。

    +

    组织的Owner团队拥有更改组织设置,在组织内新建仓库,新建组织团队等权限。

    +

    此外,Owner团队成员对当前组织下所有项目均具有仓库管理员权限,组织下其他团队的权限可由Owner团队成员自由制定。

    {group.is_admin ? : ""}
    diff --git a/src/forge/Team/ListItem.jsx b/src/forge/Team/ListItem.jsx index a908f80b..ab9d64f2 100644 --- a/src/forge/Team/ListItem.jsx +++ b/src/forge/Team/ListItem.jsx @@ -10,14 +10,10 @@ function ListItem({item,key,OIdentifier}) { {item.name} { item.forked_from_project_id && } { - item.type && item.type !== 0 ? - item.type === 2 ? + item.type && item.type === 2 ? - : - - - :"" + :"" } diff --git a/src/forge/UsersList/fork_users.js b/src/forge/UsersList/fork_users.js index 23cd5bea..a3d9c2a2 100644 --- a/src/forge/UsersList/fork_users.js +++ b/src/forge/UsersList/fork_users.js @@ -27,7 +27,7 @@ class ForkUsers extends Component { }); const { projectsId , owner } = this.props.match.params; - const url = `/${owner}/${projectsId}/members.json`; + const url = `/${owner}/${projectsId}/forks.json`; axios .get(url, { params: { diff --git a/src/forge/comments/comments.js b/src/forge/comments/comments.js index dca7581f..fb19e1da 100644 --- a/src/forge/comments/comments.js +++ b/src/forge/comments/comments.js @@ -30,6 +30,7 @@ class comments extends Component { reply_id: undefined, reply_content: undefined, new_journal_id: undefined, + atWhoLoginList:undefined }; } @@ -51,6 +52,7 @@ class comments extends Component { }); return; } + this.props.form.validateFieldsAndScroll((err, values) => { if (!err) { const { @@ -60,10 +62,12 @@ class comments extends Component { orderId, reply_id, is_reply, + atWhoLoginList, } = this.state; - const url = `/issues/${orderId}/journals.json`; + + const url = `/issues/${orderId}/journals.json`; axios .post(url, { ...values, @@ -71,6 +75,7 @@ class comments extends Component { issue_id: orderId, attachment_ids: fileList, parent_id: reply_id, + receivers_login:atWhoLoginList, }) .then((result) => { if (result && result.data.status === 0) { @@ -248,18 +253,29 @@ class comments extends Component { onContentChange = (value) => { if (value) { this.setState({ - content: value, quillFlag: false, }); } + this.setState({ + content: value, + }); }; replyContentChange = (value) => { if (value) { this.setState({ - reply_content: value, quillFlag: false, }); } + this.setState({ + reply_content: value, + }); + }; + + //评论中at谁列表(存储:login) + changeAtWhoLoginList = (loginList) =>{ + this.setState({ + atWhoLoginList:loginList, + }); }; onRef = (ref) => { @@ -308,6 +324,7 @@ class comments extends Component { new_journal_id, } = this.state; const { current_user, only_show_content } = this.props; + const { projectsId ,owner } = this.props.match.params; const new_comment = (is_reply, item_id) => { return ( @@ -339,6 +356,10 @@ class comments extends Component { onChange={ is_reply ? this.replyContentChange : this.onContentChange } + isCanAtme = {true} + changeAtWhoLoginList = {this.changeAtWhoLoginList} + owner = {owner} + projectsId = {projectsId} >

    {quillFlag && 请输入评论内容} diff --git a/src/forge/css/index.scss b/src/forge/css/index.scss index a19619d7..579508f0 100644 --- a/src/forge/css/index.scss +++ b/src/forge/css/index.scss @@ -4,6 +4,13 @@ ul,ol,dl{ .newMain{ background-color: #fff; } +.newTable{ + background-color: #F0F5FF; + .newImages{ + background-image: url('../../forge/Images/taskbar.png'); + height: 364px; + } +} .color-black{ color: #333; } diff --git a/src/modules/403/Shixunauthority.js b/src/modules/403/Shixunauthority.js index a16ef32a..435d818b 100644 --- a/src/modules/403/Shixunauthority.js +++ b/src/modules/403/Shixunauthority.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { Component, useReducer } from 'react'; import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom"; @@ -11,20 +11,29 @@ import { TPMIndexHOC } from '../tpm/TPMIndexHOC'; import { SnackbarHOC,getImageUrl } from 'educoder'; class Shixunauthority extends Component { + constructor(props) { + super(props); + } render() { + console.log(this.props); + const { current_user } = this.props; return ( -

    -
    +
    +
    {/*mt100 mb100*/} -

    - 您可以稍后尝试 返回首页 - ,或者  +

    +

    您尚未被授权访问此页面,请先获取相关权限

    + 您可尝试 + {(!current_user || !current_user.login) && ( +

    您可尝试登录

    + )} + 返回首页,也可以通过 QQ反馈>> -

    + href="https://qm.qq.com/cgi-bin/qm/qr?k=YVGUhY7uK8ovpyd7tG_lHe2qGZ63LOij&jump_from=webapi" + className="color-blue">QQ向我们反馈 +

    {/*
    */} {/**/} @@ -33,5 +42,4 @@ class Shixunauthority extends Component { ); } } - export default SnackbarHOC() (TPMIndexHOC ( Shixunauthority )); diff --git a/src/modules/404/Shixunnopage.js b/src/modules/404/Shixunnopage.js index af1ad958..508255dd 100644 --- a/src/modules/404/Shixunnopage.js +++ b/src/modules/404/Shixunnopage.js @@ -11,19 +11,29 @@ import { TPMIndexHOC } from '../tpm/TPMIndexHOC'; import { SnackbarHOC,getImageUrl } from 'educoder'; class http500 extends Component { + constructor(props) { + super(props); + } render() { + console.log(this.props); + const { current_user } = this.props; return ( -
    -
    +
    +
    {/*mt100 mb100*/} -

    - 您可以稍后尝试  +

    你访问的页面不存在

    + 您可尝试 + {(!current_user || !current_user.login) && ( +

    您可尝试登录

    + )} + 返回首页 - ,或者  + ,也可通过 QQ反馈>> + href="https://qm.qq.com/cgi-bin/qm/qr?k=YVGUhY7uK8ovpyd7tG_lHe2qGZ63LOij&jump_from=webapi" + className="color-blue">QQ向我们反馈

    {/*
    */} diff --git a/src/modules/500/http500.js b/src/modules/500/http500.js index 89e1baa5..96ef9474 100644 --- a/src/modules/500/http500.js +++ b/src/modules/500/http500.js @@ -13,17 +13,18 @@ import { SnackbarHOC,getImageUrl } from 'educoder'; class Shixunnopage extends Component { render() { return ( -
    +
    {/*mt100 mb100*/} -

    - 您可以稍后尝试  +

    服务器异常,请稍后重试

    + 您可尝试刷新页面返回首页 - ,或者  + ,也可以通过 QQ反馈>> + href="https://qm.qq.com/cgi-bin/qm/qr?k=YVGUhY7uK8ovpyd7tG_lHe2qGZ63LOij&jump_from=webapi" + className="color-blue">QQ向我们反馈

    {/*
    */} diff --git a/src/modules/login/EducoderLogin.js b/src/modules/login/EducoderLogin.js index 9a552673..c687f5f5 100644 --- a/src/modules/login/EducoderLogin.js +++ b/src/modules/login/EducoderLogin.js @@ -153,21 +153,21 @@ class EducoderLogin extends Component { justifyContent: "center", width: "100%", }}> -
    © {moment().year()} EduCoder湘ICP备17009477号Trustie   &   IntelliDE inside.
    +
    © {moment().year()} GitLink | 确实开源京ICP备13000930号GitLink   &   IntelliDE inside.
    : this.props.mygetHelmetapi===undefined||this.props.mygetHelmetapi.main_site===null|| this.props.mygetHelmetapi.main_site===undefined?
    -
    © {moment().year()} EduCoder湘ICP备17009477号Trustie   &   IntelliDE inside.
    +
    © {moment().year()} GitLink | 确实开源京ICP备13000930号GitLink   &   IntelliDE inside.
    :this.props.mygetHelmetapi.main_site===true?
    -
    © {moment().year()} EduCoder湘ICP备17009477号Trustie   &   IntelliDE inside.
    +
    © {moment().year()} GitLink | 确实开源京ICP备13000930号GitLink   &   IntelliDE inside.
    :"" } diff --git a/src/modules/login/Trialapplication.js b/src/modules/login/Trialapplication.js index 5cb18166..4f23406e 100644 --- a/src/modules/login/Trialapplication.js +++ b/src/modules/login/Trialapplication.js @@ -142,12 +142,12 @@ class Trialapplication extends Component { if (this.state.Phonenumberisnotcobool === false) { if (this.state.login.length === 0) { this.setState({ - Phonenumberisnotco: "请输入正确的手机号或邮箱", + Phonenumberisnotco: "请输入正确的邮箱账号", }) return } else { this.setState({ - Phonenumberisnotco: "请输入正确的手机号或邮箱", + Phonenumberisnotco: "请输入正确的邮箱账号", }) } return; diff --git a/src/modules/login/Trialapplicationysl.js b/src/modules/login/Trialapplicationysl.js index 25522e86..68c4a244 100644 --- a/src/modules/login/Trialapplicationysl.js +++ b/src/modules/login/Trialapplicationysl.js @@ -158,12 +158,12 @@ class Trialapplicationysl extends Component { if (this.state.Phonenumberisnotcobool === false) { if (this.state.login.length === 0) { this.setState({ - Phonenumberisnotco: "请输入正确的手机号或邮箱", + Phonenumberisnotco: "请输入正确的邮箱账号", }) return } else { this.setState({ - Phonenumberisnotco: "请输入正确的手机号或邮箱", + Phonenumberisnotco: "请输入正确的邮箱账号", }) } return; diff --git a/src/modules/tpm/TPMIndex.css b/src/modules/tpm/TPMIndex.css index bdd6d36a..8d513feb 100644 --- a/src/modules/tpm/TPMIndex.css +++ b/src/modules/tpm/TPMIndex.css @@ -28,13 +28,14 @@ body>.-task-title { height:70px; min-width: 1200px; z-index: 1000; - background:rgba(255,255,255,1); + box-shadow: 0px 2px 4px 0px rgb(0 0 0 / 50%); position: fixed; - box-shadow: 0px 0px 14px rgb(0 0 0 / 10%); + background-image: linear-gradient(to right, #0F141F, #0C2A5B,#101417); + color: #fff; } .headerContent{ - width:1200px; margin:0px auto; + padding:0px 30px; display: flex; align-items: center; height: 100%; diff --git a/src/modules/tpm/challengesnew/css/newquestion.css b/src/modules/tpm/challengesnew/css/newquestion.css index 444ca8d1..eb1a67eb 100644 --- a/src/modules/tpm/challengesnew/css/newquestion.css +++ b/src/modules/tpm/challengesnew/css/newquestion.css @@ -4,4 +4,39 @@ .Permanentban{ color:#5091FF !important; border-color: #5091FF !important; +} + +/*md编辑器中输入@弹出可选人列表样式*/ +.at_who_list{ + position: absolute; + z-index: 100; + width: 180px; + max-height: 160px; + background: #FFFFFF; + box-shadow: 0px 4px 8px 2px rgba(212, 212, 212, 0.5); + border-radius: 4px; + overflow-y: scroll; + cursor: pointer; +} +.at_who{ + height: 40px; + display: flex; + flex-direction: row; + align-items: center; + border-bottom: 1px solid rgba(212, 212, 212, 0.5); + padding: 0 4px; +} +.at_who.active{ + background: #F3F4F6; +} +.at_who img{ + width:30px; + height:30px; + border-radius:50%; + margin-right: 10px; +} +.at_who span{ + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } \ No newline at end of file diff --git a/src/modules/tpm/challengesnew/tpm-md-editor.js b/src/modules/tpm/challengesnew/tpm-md-editor.js index e1c06eda..46c01ec3 100644 --- a/src/modules/tpm/challengesnew/tpm-md-editor.js +++ b/src/modules/tpm/challengesnew/tpm-md-editor.js @@ -1,11 +1,12 @@ - import React, { Fragment, useEffect, useRef, useState } from 'react'; import { getUploadActionUrl, getUrl } from 'educoder'; import ResizeObserver from 'resize-observer-polyfill'; - +import { getImageUrl } from 'educoder'; +import axios from 'axios'; import '../../courses/css/Courses.css'; import './css/TPMchallengesnew.css'; import 'codemirror/lib/codemirror.css'; +import './css/newquestion.css'; const $ = window.$ const mdIcons = ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "inline-latex", "latex", '|', "image", "table", '|', "line-break", "watch", "clear"]; @@ -39,7 +40,6 @@ function md_rec_data(k, mdu, id) { } window.md_rec_data = md_rec_data; - function md_elocalStorage(editor, mdu, id) { let oc = window.sessionStorage.getItem('content' + mdu) if (oc !== null && oc !== editor.getValue()) { @@ -74,16 +74,38 @@ function md_elocalStorage(editor, mdu, id) { return tid } - -export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch, showNullButton = false, showResizeBar = false, startInit = true , forMember = true }) => { - +export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch, showNullButton = false, showResizeBar = false, startInit = true , forMember = true , isCanAtme = false , changeAtWhoLoginList, owner, projectsId }) => { + const editorEl = useRef(); const resizeBarEl = useRef(); const [editorInstance, setEditorInstance] = useState(); + const [atWhoVisible, setAtWhoVisible] = useState(false); + const [atWhoLoginListState, setAtWhoLoginListState] = useState([]); + //调用member.json接口获取到的用户列表 + const [users, setUsers] = useState([]); + //可以@的全部用户 + const [allUsers, setAllUsers] = useState([]); + const atWhoLoginList = useRef([]); + const atWhoVisibleRef = useRef(false); const containerId = `mdEditor_${mdID}`; const editorBodyId = `mdEditors_${mdID}`; const tipId = `e_tips_mdEditor_${mdID}`; + useEffect(()=>{ + //请求members接口获取全部可@列表 + isCanAtme && axios.get(`/${owner}/${projectsId}/members.json`).then(response=>{ + if(response.data.total_count !== 0){ + setAllUsers(response.data.users); + setUsers(response.data.users); + } + }) + //点击其他地方关闭弹框 + document.addEventListener('click',()=>{ + atWhoVisibleRef.current = false; + setAtWhoVisible(false); + }) + },[]) + function onLayout() { let ro; if (editorEl.current) { @@ -101,6 +123,96 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla return ro; } + function selectAtWho(username){ + atWhoVisibleRef.current = false; + setAtWhoVisible(false); + const cm = editorInstance.cm; + //获取鼠标所在行的行数和ch + const cursor = cm.doc.getCursor(); + const line = cursor.line;//行 + const ch = cursor.ch;//列 + const startIndex = cm.getRange({line,ch:0},{line,ch}).lastIndexOf("@"); + let selectUserLogin = undefined; + users.map((item)=>{ + item.username === username && (selectUserLogin = item.login); + }) + //替换内容 + cm.replaceRange("[@"+username+"]"+`(/${selectUserLogin}) `,{line,ch:startIndex},{line,ch}); + //鼠标聚焦 + cm.focus(); + //将此user的login存储到atWhoLoginList集合中 + const list = new Set(atWhoLoginList.current); + list.add(selectUserLogin); + atWhoLoginList.current = Array.from(list); + setAtWhoLoginListState(Array.from(list)); + } + + function onMouseOver(key){ + document.getElementsByClassName("at_who active")[0] && (document.getElementsByClassName("at_who active")[0].className="at_who"); + document.getElementsByClassName("at_who")[key] && (document.getElementsByClassName("at_who")[key].className="at_who active"); + } + + //markdown编辑器中输入的键盘监听事件 + function mdKeyDown(e){ + if (e.shiftKey && e.code === "Digit2") { + // 输入@键后在对应的位置显示可选的项目成员 + atWhoVisibleRef.current = true; + setAtWhoVisible(true); + //获取光标位置 + const cssStyle = document.getElementsByClassName("CodeMirror cm-s-default CodeMirror-wrap")[0].firstChild.style; + //设置弹框位置 + const newTop = placeholder === "添加评论..." ? 159: placeholder === "请输入合并请求的描述..." ? 172:62; + const newLeft = placeholder === "添加评论..." ? 80: 20; + document.getElementById("at_who_list").style.top = parseInt(cssStyle.getPropertyValue("top").replace("px","")) + newTop +"px"; + document.getElementById("at_who_list").style.left = parseInt(cssStyle.getPropertyValue("left").replace("px",""))+newLeft+"px"; + } + //处理本来@了某人 -> 删掉 -> 撤回 的情况 + if(e.ctrlKey && e.code === "KeyZ" && allUsers.length != 0){ + const codemirror = editorInstance.cm; + let value = codemirror.getValue(); + //处理初始内容就自带@谁的情况 + if(initValue){ + const del = []; + allUsers.map(item=>{ + if(initValue.indexOf(item.username)!=-1 && initValue.charAt(initValue.indexOf(item.username)-1) === "@" && initValue.indexOf(`@${item.username}`)===value.indexOf(`@${item.username}`)){ + //初始内容中有符合@+名字的格式并且当前内容未删除初始内容 + del[del.length] = `[@${item.username}](/${item.login})`; + } + }) + del.length!=0 && del.map(str=>{ + value = value.replace(str,""); + }) + } + //判断value是否包含@符号 + value.indexOf("@") != -1 && allUsers.map(item =>{ + if(value.indexOf(item.username)!=-1 && value.charAt(value.indexOf(item.username)-1) ==="@"){ + //将此user的login存储到atWhoLoginList集合中 + const list = new Set(atWhoLoginList.current); + list.add(item.login); + atWhoLoginList.current = Array.from(list); + setAtWhoLoginListState(Array.from(list)); + } + }) + } + } + + useEffect(()=>{ + changeAtWhoLoginList && changeAtWhoLoginList(atWhoLoginListState); + },[atWhoLoginListState]) + + const atWhoList = ( +
    + {users && users.map((item,key)=>{ + return( +
    {selectAtWho(item.username)}} onMouseOver={()=>{onMouseOver(key)}}> + {item.image_url && } + {item.username} +
    + ) + })} +
    + ) + useEffect(() => { if (editorInstance) { return @@ -183,6 +295,69 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla const cmEl = editorInstance && editorInstance.cm + useEffect(()=>{ + if(atWhoVisibleRef.current){ + // 添加上下键、enter键监听事件 + cmEl.addKeyMap({ + 'Up':()=>{ + const atWhoListDiv = document.getElementById("at_who_list"); + const atWhoDivs = document.getElementsByClassName("at_who"); + let index; + for(let i = 0; i0){ + index <=atWhoDivs.length-4 && (atWhoListDiv.scrollTop -=40) + atWhoDivs[index].className = "at_who"; + atWhoDivs[index-1].className = "at_who active"; + } + }, + 'Down':()=>{ + const atWhoListDiv = document.getElementById("at_who_list"); + const atWhoDivs = document.getElementsByClassName("at_who"); + let index; + for(let i = 0; i=3 && (atWhoListDiv.scrollTop +=40) + atWhoDivs[index].className = "at_who"; + atWhoDivs[index+1].className = "at_who active"; + } + }, + 'Enter':()=>{ + //找到classname为at_who active的div,执行click事件 + if(document.getElementsByClassName("at_who active")[0]){ + document.getElementsByClassName("at_who active")[0].click() + }else{ + const cm = editorInstance.cm; + const cursor = cm.doc.getCursor(); + const line = cursor.line;//行 + const ch = cursor.ch;//列 + //添加换行 + cm.replaceRange("\n",{line,ch},{line,ch}); + setAtWhoVisible(false); + atWhoVisibleRef.current = false; + } + } + }) + } else { + //移除上下、enter键监听 + cmEl && cmEl.removeKeyMap(); + } + },[atWhoVisible]) + + useEffect(()=>{ + //当users数组发生变化时改变框的位置 + if(atWhoVisibleRef.current && users){ + //获取光标位置 + const cssStyle = document.getElementsByClassName("CodeMirror cm-s-default CodeMirror-wrap")[0].firstChild.style; + //设置弹框位置 + const newLeft = placeholder === "添加评论..."? 80: 10; + document.getElementById("at_who_list").style.left = (parseInt(cssStyle.getPropertyValue("left").replace("px",""))+newLeft)+"px"; + } + },[users]) + useEffect(() => { if (cmEl) { let tid = null @@ -198,19 +373,138 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla if (!noStorage) { tid = md_elocalStorage(editorInstance, `MDEditor__${containerId}`, containerId) } - if (onChange) { - editorInstance.cm.on('change', (cm) => { - // if(forMember){ - // document.onkeydown = (e) => { - // if (e.key === "@") { - // // 输入@键后在对应的位置显示可选的项目成员 - - // } - // }; - // } - onChange(cm.getValue()) - }) - } + //isCanAtme:只有issue和合并请求以及评论部分可以@他人操作 + //绑定@事件 + isCanAtme && editorInstance.cm.on("focus", () => { + document.addEventListener("keydown", mdKeyDown); + }); + isCanAtme && editorInstance.cm.on("blur", () => { + document.removeEventListener("keydown",mdKeyDown); + }); + editorInstance.cm.on("change", (cm) => { + //调用父组件的onchange方法,将输入内容传入父级组件 + onChange && onChange(cm.getValue()); + if(atWhoVisibleRef.current){ + //搜索用户(弹框之后用户输入用户名信息) + const cur = cm.doc.getCursor(); + const line = cur.line; + const ch = cur.ch; + let rangeCont = cmEl.getRange({line,ch:0},{line,ch}); + //处理已经弹出列表框,但用户删除@符号 + if(rangeCont.indexOf("@")===-1){ + setAtWhoVisible(false); + atWhoVisibleRef.current = false; + }else{ + rangeCont = rangeCont.substring(rangeCont.lastIndexOf("@")+1); + rangeCont ? axios.get(`/${owner}/${projectsId}/members.json`,{ + params: { + search: rangeCont, + }, + }).then(response=>{ + if(response && response.data && response.data.total_count !== 0){ + setUsers(response.data.users); + }else{ + setUsers(undefined); + } + }):setUsers(allUsers) + } + } + + //当内容发生改变并且有已@列表时 + if(atWhoLoginList.current.length != 0){ + const codemirror = editorInstance.cm; + //startValue:触发change方法时的内容,value:处理了初始内容带@用户的情况 + let startValue = codemirror.getValue(); + let value = codemirror.getValue(); + //处理初始内容就自带@谁的情况 + if(initValue){ + const del = []; + allUsers.map(item=>{ + if(initValue.indexOf(item.username)!=-1 && initValue.charAt(initValue.indexOf(item.username)-1) === "@" && initValue.indexOf(`@${item.username}`)===value.indexOf(`@${item.username}`)){ + //初始内容中有符合@+名字的格式并且当前内容未删除初始内容 + del[del.length] = `[@${item.username}](/${item.login})`; + } + }) + del.length!=0 && del.map(str=>{ + value = value.replace(str,""); + }) + } + //以username为主键,login为value的map集合 + let atWhoMap = new Map(); + Array.from(atWhoLoginList.current).map(item=>{ + allUsers.map(i=>{ + if(i.login === item){ + atWhoMap.set(i.username,i.login); + } + }) + }); + const cursor = codemirror.doc.getCursor(); + const line = cursor.line; + const ch = cursor.ch; + //处理全部内容中不包含“@”的情况 + if(value.indexOf("@") === -1){ + //markdown嵌套的链接删掉 + // Array.from(atWhoMap.keys()).map(username=>{ + // startValue = startValue.replaceAll(`[${username}](/${atWhoMap.get(username)}) `,username); + // }) + //替换全部内容 + // codemirror.setValue(startValue); + //全部内容已经有要@的列表,但是没有@符号 -> 清空@集合 + atWhoLoginList.current = []; + setAtWhoLoginListState([]); + } + + //截取第一个字符到光标的内容 + const curAfterCont = codemirror.getRange({line,ch:0},{line,ch}); + const content = codemirror.getLine(line); + //处理光标所在行 有“@”的情况 + if(content && content.indexOf("@") !== -1){ + Array.from(atWhoMap.keys()).map(username=>{ + //判断content是不是以列表中的某个username结尾 + const userCont = `[@${username}](/${atWhoMap.get(username)})`; + //删除空格->选中@用户区域 + if(curAfterCont.endsWith(userCont)){ + codemirror.setSelection({line,ch:curAfterCont.lastIndexOf("@")-1},{line,ch}); + } + //处理已经有@列表但是value中不包含完整[@用户名](/login)的情况 + if(value.indexOf(userCont)===-1){ + // //markdown嵌套的链接删掉,删[]、()的情况不用处理,markdown会自动认为不是链接 + // //找到[和)的index,将区域内容替换成[]包裹的内容 + // //光标之后的内容 + // const curLeterCont = codemirror.getRange({line,ch},{line,ch:content.length}); + // console.log('光标之后的内容curLeterCont',curLeterCont); + // //删除用户名 -> ]在curLeterCont中 + // //删除login -> ]在curAfterCont中 + // const a = curAfterCont.lastIndexOf('['); + // const b = curLeterCont.indexOf(')') + // const c = curLeterCont.indexOf(']') === -1 ? curAfterCont.lastIndexOf(']') : curLeterCont.indexOf(']')+curAfterCont.length; + // console.log('[',a,')',b,']',c); + // const newCont = codemirror.getRange({line,ch:a+1},{line,ch:c}); + // console.log('newCont',newCont); + // codemirror.replaceRange(newCont,{line,ch:a-1},{line,ch:b+curAfterCont.length+1}) + + //符合情况->踢掉这个人 不给他发消息 + const list = new Set(atWhoLoginList.current); + list.delete(atWhoMap.get(username)); + atWhoLoginList.current = Array.from(list); + setAtWhoLoginListState(Array.from(list)); + } + }) + }else{ + //处理所在行没有“@”的情况 + Array.from(atWhoMap.keys()).map(username=>{ + const userCont = `[@${username}](/${atWhoMap.get(username)})`; + if(value.indexOf(userCont)===-1){ + //符合情况->踢掉这个人 不给他发消息 + const list = new Set(atWhoLoginList.current); + list.delete(atWhoMap.get(username)); + atWhoLoginList.current = Array.from(list); + setAtWhoLoginListState(Array.from(list)); + } + }) + } + } + }); ro = onLayout() return () => { if (!noStorage) { @@ -271,7 +565,8 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla return ( -
    + {atWhoVisible && atWhoList} +
    diff --git a/src/modules/user/FindPasswordComponent.js b/src/modules/user/FindPasswordComponent.js index 85f0285a..c753c66e 100644 --- a/src/modules/user/FindPasswordComponent.js +++ b/src/modules/user/FindPasswordComponent.js @@ -699,7 +699,7 @@ class LoginRegisterComponent extends Component { {/*onBlur={(e) => this.inputOnBlur(e)}*/} this.inputOnBlurzhuche(e)} onChange={this.loginInputonChange} style={{marginTop: '10px', height: "38px"}}> { diff --git a/src/modules/user/LoginRegisterComponent.js b/src/modules/user/LoginRegisterComponent.js index db369458..f3258174 100644 --- a/src/modules/user/LoginRegisterComponent.js +++ b/src/modules/user/LoginRegisterComponent.js @@ -7,6 +7,7 @@ import axios from 'axios'; import CheckInputysl1 from './CheckInputysl'; import CheckInputysl2 from './CheckInputysl'; import Notcompletedysl from './Notcompletedysl'; +import Educoder from '../login/educoder.png'; import './common.css' import './commontwo.css' const { TabPane } = Tabs; @@ -1039,7 +1040,7 @@ class LoginRegisterComponent extends Component { } - this.postLogin()} size={"large"}>登录 - {this.props.mygetHelmetapi&&this.props.mygetHelmetapi.main_site===true?this.state.isphone===true?

    - - ———————— 快速登录 ———————— -

    -

    :

    - ———————— 快速登录 ———————— -

    -

    :""} +

    + ———————— 快速登录 ———————— +

    + + educoder登录 + +
    +

    } @@ -1115,7 +1102,7 @@ class LoginRegisterComponent extends Component { { weixinlogin===false&&parseInt(tab[0])==1 &&
    - 我已阅读并同意 - 《服务协议条款》 + 《服务协议条款》 :""} - {this.props.mygetHelmetapi&&this.props.mygetHelmetapi.main_site===true?this.state.isphone===true?

    - - ———————— 快速登录 ———————— -

    -

    :

    - ———————— 快速登录 ———————— -

    -

    :"" - } +

    + ———————— 快速登录 ———————— +

    + + educoder登录 + +
    +

    }