Merge pull request '云际专区代码' (#617) from jhnine/forgeplus-react:gitlink_server into gitlink_server

This commit is contained in:
durian 2024-01-30 10:21:15 +08:00
commit c6d6d7bb1c
20 changed files with 791 additions and 43 deletions

View File

@ -0,0 +1,58 @@
.partner_jcc{
.grow_path {
height: 100px;
display: flex;
justify-content: space-around;
align-items: center;
.grow_path_item {
z-index: 10;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
align-self: self-start;
cursor: pointer;
transition: 1s;
.grow_path_type {
width: 82px;
height: 58px;
// color: black;
font-size: 15px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
}
.dot {
width:28px;
height:28px;
background-color:#ffffff;
border:7px solid;
border-color:#0d8dfd52;
border-radius: 50%;
transition: .5s;
}
}
.line {
height: 0px;
width: 1200px;
border-bottom: solid 1px #ddd;
transform: translate(0, -87px);
}
.zone_part_lists{
margin-top: 40px;
li {
max-height: 414px;
overflow-y: auto;
align-items: flex-start;
}
}
.type_active{
border-color: #0d8ffd !important;
}
::-webkit-scrollbar
{
display: none;
}
}

View File

@ -0,0 +1,81 @@
import React , { useEffect } from 'react';
import { useState } from 'react';
import './index.scss'
function Partner(props) {
const [ topics ,setTopics ] = useState(undefined);
const [ moreTypes ,setMoreTypes ] = useState(false);
const [ currentPartner ,setPartner] = useState(undefined);
const { id, partnerList } = props;
useEffect(()=>{
getUnit(partnerList);
},[id])
function getUnit(array){
const newArray = array
setMoreTypes(array.length > 1)
while(newArray[1] && newArray[1].length + newArray[0].length <= 5) {
newArray[0] = [...newArray[0], ...newArray.splice(1, 1)[0]]
}
setTopics(newArray)
setPartner(newArray[0][0].typeName)
}
return(
<div className='partner_jcc boxmain pt60 pb60'>
{
moreTypes &&
<div className="grow_path">
{
topics && topics.length>0 ?
topics.map((i, k) => {
return (
<div className="grow_path_item" key={ k } onClick={()=> setPartner(i[0].typeName)}>
<div className={`dot ${i[0].typeName === currentPartner ? 'type_active' : ''}`}></div>
<div className="grow_path_type">
{ i[0].typeName }
</div>
</div>
)
})
:
""
}
</div>
}
{
moreTypes && <div className="line"></div>
}
<ul className="zone_part_lists">
{
topics && topics.length>0 ?
topics.map((i, k)=>{
return(
<li key={ k } >
{
i[0].typeName === currentPartner ?
i.map((j,k1)=>{
return(
<div className="zone_part_item" key={ k1 }>
{
j.link ? <a key={ k1 } href={ j.link } target="_blank" ><img src={j.logo} alt=""/></a>
:
<div><img src={j.logo} alt=""/></div>
}
</div>
)
})
:
""
}
</li>
)
})
:
""
}
</ul>
</div>
)
}
export default Partner;

View File

@ -1,9 +1,234 @@
import React, { } from 'react';
import './index.scss';
import React,{ useState, useRef, useEffect } from 'react';
import { httpUrl } from '../../fetch';
import img1 from '../../img/img1.png';
function HomePage(props) {
return (
<div>云际计算社区首页自定义</div>
)
import visionFw from '../../img/vision-fw.png';
import visionYj from '../../img/vision-yj.png';
import visionZy from '../../img/vision-zy.png';
import visionJz from '../../img/vision-jz.png';
import guideArrow from '../../img/guideArrow1.png';
import { Link } from 'react-router-dom';
import shijian from '../../img/shijian.png';
import axios from 'axios';
import Projects from '../../Component/projects';
import PartnerJcc from './Component/partnerJcc';
import '../../indexZone1.scss'
import './index.scss'
import { Popover, Tabs } from 'antd';
let tabTimer = undefined;
function HeaderPageJCC(props){
const [ projectList , setProjectList ] = useState(undefined);
const [ personList , setPersonList ] = useState(undefined);
const [ newsList, setNewsList ] = useState(undefined);
const [ partnerList, setParterList ] = useState(undefined);
const { deptId } = props.match.params;
const { data, id, history } = props;
const [ activeKey, setActiveKey ] = useState(undefined);
const vision = [
{imageUrl: visionFw, title: '服务无边界'},
{imageUrl: visionYj, title: '云间有协作'},
{imageUrl: visionZy, title: '资源易共享'},
{imageUrl: visionJz, title: '价值可交换'}
]
useEffect(()=>{
if(id){
getProjectList();
getNewsList();
getPersonList();
getPartnerList();
}
return componentWillUnmount;
},[id])
function componentWillUnmount() {
clearInterval(tabTimer)
}
function getPersonList(){
const url = `${httpUrl}/zone/open/${id}/member/homePageList`;
axios.get(url).then(result=>{
if(result){
setPersonList(result.data.rows);
}
}).catch(error=>{})
}
function getNewsList(){
const url = `${httpUrl}/cms/doc/open/zone/${id}/homePageDocList`;
axios.get(url).then(result=>{
if(result){
setNewsList(result.data.rows);
clearInterval(tabTimer)
tabTimer = setInterval(() => {
handle(result.data.rows && result.data.rows[0].id, result.data.rows)
}, 4000)
}
}).catch(error=>{})
}
function getProjectList(){
const url = `${httpUrl}/zone/open/${id}/project/list`;
axios.get(url,{params:{
isHomepage:1
}}).then(result=>{
if(result){
if (result.data.rows.length < 3) {
setProjectList(result.data.rows)
} else {
setProjectList([...result.data.rows, {}]);
}
}
}).catch(console.error())
}
function getPartnerList(){
const url = `${httpUrl}/zone/open/${id}/partners/list`;
axios.get(url).then(result=>{
if(result){
const array = result.data.rows;
const newArray = [];
for(let i in array) {
let e = array[i]
if (e.zonePartnersList && e.zonePartnersList.length > 0) {
e.zonePartnersList[0].typeName = e.typeName;
}
if ( e.zonePartnersList.length > 0 ) {
newArray.push(e.zonePartnersList);
}
}
setParterList(newArray);
}
}).catch(error=>{})
}
function handle(value, rows){
// id
let idList = rows ? rows.map(obj => obj.id) : []
// tab
let tabs = document.querySelectorAll('.zone_news .ant-tabs-tab')
const tabIndex = idList.indexOf(Number(value))
if(tabIndex !== -1 ){
if(tabIndex !== idList.length -1){
tabs[tabIndex + 1].click()
}else{
tabs[0].click()
}
}
}
function handleTabChange(key) {
setTimeout(()=>{
setActiveKey(key)
},100)
clearInterval(tabTimer)
tabTimer = setInterval(() => {
handle(key, newsList)
}, 4000)
}
return(
<div className="zone_jcc_box">
{
//
data && (data.introductionTitle || data.introductionContent || data.introductionImage) &&
<div className="boxmain zone_infos mb30">
<div className="zone_infos_desc">
{data && <p className="in_title tleft">{data.firstTitle}</p>}
<p className="z_name">{data.introductionTitle}</p>
<p className="z_desc task-hide-2" dangerouslySetInnerHTML={{ __html: data.introductionContent }} ></p>
</div>
{
data.introductionImage &&
<img src={data.introductionImage} alt="" width="600px" height="361px"/>
}
</div>
}
<div className="zone_vision pt40 pb100">
<p className="in_title mb40">宗旨及愿景</p>
<div className='boxmain'>
{
vision.map((i, k) => {
return (
<div className="vision_item" key={ k }>
<div className="vision_icon">
<img src={i.imageUrl} alt="" />
</div>
<p className="vision_title">{ i.title }</p>
</div>
)
})
}
</div>
</div>
{
//
data && data.cmsShow === 1 && newsList && newsList.length>0 &&
<div className="zone_news">
<div className="boxmain" style={{display:"flex"}}>
<p className="news_title">{ data.homepageCmsTitle }</p>
<Tabs className='news_tab' tabPosition="left" onChange={handleTabChange} >
{
newsList.map((i,k)=>{
return(
<Tabs.TabPane tab={i.name} key={i.id}>
<div className='tab-content'>
<Link to={`/zone/${deptId}/newdetail/${i.id}`}><div className='title'>{i.name}</div>
<p><img src={shijian} alt="" className="mr3 photo" />{i.publishTime}</p>
<p className='new_desc'>{i.summary || '-'}</p>
<img src={newsList[k].headImg || img1} alt="" height="260px" style={{width:"100%",objectFit:"cover"}}/></Link>
</div>
</Tabs.TabPane>
)
})
}
</Tabs>
</div>
</div>
}
{
//
data && data.projectShow === 1 && projectList && projectList.length > 0 &&
<div className="zone_projects pt50 pb30">
<p className="in_title mb40">{ data.homepageProjectTitle }</p>
<Projects projectList={projectList}></Projects>
</div>
}
{
//
data && data.memberShow === 1 && personList && personList.length > 0 &&
<div className="zone_contributor">
<p className="in_title">{ data.homepageMemberTitle }</p>
{
<ul className="boxmain zone_c_lists">
{
personList.map((i,k)=>{
return(
<li key={k}>
<Popover overlayClassName="zone_popover" content={i.introduction || "暂无~"} title={i.name} trigger="hover">
<Link to={`/${i.login}`}><img src={i.imageUrl} alt="" /></Link>
</Popover>
</li>
)
})
}
</ul>
}
</div>
}
{
//
data && data.partnersShow === 1 && partnerList && partnerList.length > 0 &&
<div className="zone_parter">
<p className="in_title">{ data.homepagePartnersTitle }</p>
<PartnerJcc id={ id } partnerList={ partnerList }></PartnerJcc>
</div>
}
</div>
)
}
export default HomePage;
export default HeaderPageJCC;

View File

@ -0,0 +1,361 @@
@import '../../theme.scss';
.zone_jcc_box{
background-color: #f7f7f7;
padding-top:70px;
.zone_infos{
display: flex;
align-items: center;
margin-top: 54px;
padding:27px 24px;
position: relative;
&>img{
position: absolute;
right: 0;
top: 0;
border-radius: 4px;
object-fit: contain;
}
.zone_infos_desc{
position: relative;
padding:0px 34px 0px 10px;
flex: 1;
.tleft{
text-align: left;
margin-bottom: 25px !important;
}
.z_name{
color:#1f2329;
font-size:26px;
height: 28px;
line-height: 28px;
margin-bottom: 28px!important;
font-size: 20px;
}
.z_desc{
color:#3d485d;
font-size:14px;
line-height:32px;
word-break: break-all;
-webkit-line-clamp: 4;
white-space: pre-wrap;
background: white;
padding: 50px 250px 50px 50px;
margin-right: 350px;
color: inherit;
}
}
}
.zone_vision {
background-color: #ffffff;
.boxmain {
display: flex;
justify-content: space-between;
}
.vision_item {
width: 244px;
display: flex;
align-items: center;
flex-direction: column;
.vision_icon {
height: 162px;
width: 162px;
background-image: url(../../img/visionBack.png);
background-size: 100% 100%;
position: relative;
img {
width: 50%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
.vision_icon:hover {
background-image: url(../../img/visionBackActive.png);
}
.vision_title {
font-weight:700;
color:#1f2329;
font-size:17px;
line-height:27px;
text-align:center;
margin-top: 39px;
margin-top: 0;
font-weight: 600;
}
.vision_content {
margin-top: 21px;
color:#4c5876;
font-size:14px;
line-height:27px;
text-align:center;
}
}
}
.zone_news{
height: 30.2vw;
min-height: 475px;
background-color: #273144;
background-image: url(../../img/bgJccNews.png);
background-repeat: no-repeat;
background-size: cover;
.boxmain {
width: 1200px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
.news_title {
height: 44px;
font-weight: 500;
color: #ffffff;
font-size: 32px;
text-align: center;
}
.photo {
margin-bottom: 3px;
margin-right: 5px;
}
.news_tab{
color: #fff;
height: 380px;
.ant-tabs-bar{
background-color: rgba(33, 84, 118, 0.5);
}
.ant-tabs-left-bar {
border-right-color: transparent !important;
}
.ant-tabs-nav-container{
font-size: 18px;
}
.ant-tabs-left-bar .ant-tabs-tab, .ant-tabs-right-bar .ant-tabs-tab {
padding: 34px 24px;
margin: 0;
text-align: left;
width: 260px;
overflow-x: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ant-tabs-left-content {
padding-left: 100px;
border-left-color: transparent !important;
}
.ant-tabs-tab-active{
background-color: #04BBF7;
color: white;
}
.ant-tabs-nav .ant-tabs-tab:active {
color: white;
}
.ant-tabs-ink-bar{
display: none !important;
}
.ant-tabs-nav .ant-tabs-tab:hover {
color: white;
}
.tab-content{
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.title{
font-size: 20px;
margin: 10px 0;
}
a:link, a:visited {
color: white;
}
.new_desc{
height: 48px;
font-size: 15px;
word-break: break-all;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
margin-top: 10px;
}
}
}
.zone_projects{
background-image:linear-gradient(180deg,#f1f4fa 0%,#ffffff 100%);
.right_arraw {
width: 48px;
height: 48px;
right: 0;
}
.left_arraw {
width: 48px;
height: 48px;
left: 0;
z-index: 100;
}
.slick-track {
display: flex;
align-items: center;
height: 435px;
.slick-slide {
height: auto;
}
}
.less_three_project {
display: flex;
justify-content: center;
.container {
.zone_p_item {
background: #fefefe;
}
margin: 10px;
}
}
.not_three_project {
.slick-track {
.slick-slide[aria-hidden="true"] {
opacity: 0;
}
}
}
.slick-current {
z-index: 100;
}
.slick-current .zone_p_item {
width:364px;
height:395px;
background:#fefefe;
}
.zone_p_item {
width: 364px;
height: 320px;
border-radius:16px;
padding: 42px 42px 35px 42px;
box-shadow:0px 0px 20px rgba(35, 54, 185, 0.06);
background: url(../../img/projectBg.png) no-repeat;
background-size: 100% 100%;
border-color:#ffffff;
transition: 0.3s;
display: flex;
flex-direction: column;
align-items: center;
.info_img {
width:74px;
height: 74px;
border-radius: 50%;
}
.z_p_title {
font-weight: 700;
color: #1f2329;
font-size: 16px;
text-align: center;
margin-top: 10px;
cursor: pointer;
width: 90%;
}
.z_p_desc{
margin-top: 18px;
color:#4c5876;
font-size:14px;
line-height:22px;
word-break: break-all;
-webkit-line-clamp: 5
}
}
.zone_p_item:hover {
.z_p_title {
color: #07a583;
}
}
}
.zone_contributor{
min-height: 466px;
background-color: #F7F9FC;
padding:44px 0px 30px;
.container {
height: 220px;
}
.zone_c_lists{
display: flex;
align-items: center;
margin-top: 50px;
flex-wrap: wrap;
li{
// background-image: url(./img/contributebg.png);
box-shadow:0px 0px 15px rgba(49,61,113,0.06);
background-size: 100% 100%;
width:80px;
height: 80px;
border:1px solid #fff;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 50%;
margin-bottom: 40px!important;
margin-right: 40px;
& img{
width: 80px;
height: 80px;
border-radius: 50%;
margin-bottom: 16px;
}
}
.slick-track {
display: flex;
}
.c_item {
margin-top: 40px;
margin-left: 10px;
width: 380px;
height: 165px;
background-image: url(../../img/cbg.png);
background-size: 100% 100%;
position: relative;
background-color:#f6f7fa;
border:2px solid;
border-color:#ffffff;
border-radius:4px;
box-shadow:0px 0px 10px rgba(7, 70, 165, 0.11);
padding: 30px 35px;
img {
position: absolute;
width:80px;
height:80px;
border-radius: 50%;
border: solid 2px #ffffff;
right: 27px;
top: -40px;
object-fit: cover;
}
.c_name {
color: #000000;
font-size: 16px;
text-align: center;
max-width: 240px;
}
.c_desc {
color: #4c5876;
font-size: 15px;
line-height: 26px;
}
}
.c_item:hover {
box-shadow:0px 0px 35px rgba(7, 70, 165, 0.11);
}
}
}
}
.zone_popover{
width: 300px;
:global{
.ant-popover-title{
font-weight: 600;
}
.ant-popover-content{
width: 300px;
}
}
}

View File

@ -48,7 +48,7 @@ function HeaderPage(props){
}
}).catch(console.error())
}
function getPartner(){
getPartnerList(id).then(result => {
if(result){
@ -170,7 +170,7 @@ function HeaderPage(props){
}
</div>
}
{
//

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -77,6 +77,10 @@ function List(props){
}else{
Init();
}
// issue
if (props.location.state && props.location.state.issue) {
chooseTagFunc(props.location.state.issue)
}
},[])
useEffect(()=>{

View File

@ -189,6 +189,12 @@ function Sign(props){
c && setDefaultColor(`#${c}`);
setEdit(true);
}
// issue
function toIssues(issue) {
props.history.push({ pathname: `/${owner}/${projectsId}/issues`, state: { issue: issue } });
}
return(
<div>
<DelBox
@ -236,11 +242,11 @@ function Sign(props){
<p>
<span className="square mr10" style={{backgroundColor:`${i.color}`}}></span>
<i className="iconfont icon-biaoji mr3 font-12 " style={{color:`${i.color}`}}></i>
<span className="task-hide" title={i.name} style={{maxWidth:210}}>{i.name}</span>
<span className="task-hide color-blue pointer" title={i.name} style={{maxWidth:210}} onClick={() => toIssues(i) }>{i.name}</span>
</p>
<p style={{flex:2}} className="task-hide">{i.description}</p>
<p>
<span>{i.issues_count || 0} 疑修</span>
<span><span className="task-hide color-blue pointer" onClick={() => toIssues(i) } >{i.issues_count || 0} </span> 疑修</span>
{/* <span className="line">{i.pull_requests_count || 0} 合并请求</span> */}
</p>
<p>

View File

@ -511,9 +511,9 @@ function CoderDepot(props){
}
{
checkIfLogin && checkIfLogin()?
<a className='newBtn' onClick={()=>eventTrack(`/${owner}/${projectsId}/webIDE/tree/${branchName||defaultBranch}`)}>Web IDE <div className='newBtnImg'></div></a>
<a className='newBtn' onClick={()=>eventTrack(`/${owner}/${projectsId}/webIDE/tree/${branchName||defaultBranch}`)}>Web IDE</a>
:
<a className='newBtn' onClick={()=>{showLoginDialog(`/${owner}/${projectsId}`)}}>Web IDE <div className='newBtnImg'></div></a>
<a className='newBtn' onClick={()=>{showLoginDialog(`/${owner}/${projectsId}`)}}>Web IDE</a>
}
<Dropdown overlay={downloadMenu} placement="bottomRight" trigger={['click']}>

View File

@ -98,7 +98,7 @@ function DetailBanner({ history,list , owner , projectsId ,showNotification , ur
<li className={pathname==="devops" ? "active" : ""}>
{/* <Link to={{ pathname: `/${owner}/${projectsId}/devops${open_devops ? `/dispose`:""}`, state }}> */}
<Link className='newTab' to={{ pathname: `/${owner}/${projectsId}/devops`, state:{...state,open_devops} }}>
<i className="iconfont icon-gongzuoliuicon font-13 mr5 color-grey-3"></i>引擎(Engine)<div className='newBtnImg'></div>
<i className="iconfont icon-gongzuoliuicon font-13 mr5 color-grey-3"></i>引擎(Engine)
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
</Link>
</li>
@ -138,7 +138,7 @@ function DetailBanner({ history,list , owner , projectsId ,showNotification , ur
<li className={pathname === "server" ? "active" : ""}>
<Link className='newTab' to={{ pathname: `/${owner}/${projectsId}/service`, state }}>
<i className={"iconfont icon-fuwuicon color-grey-3 mr5 font-15"} style={{marginTop:"1px"}}></i>
<span>服务</span><div className='newBtnImg'></div>
<span>服务</span>
</Link>
</li>
}

View File

@ -18,7 +18,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
let wikiName = ''
let key = '';
if (!pathname.endsWith('/wiki/add')) {
wikiName = pathname.split('/')[4];
wikiName = decodeURI(pathname.split('/')[4]);
key = pathname.split('/')[5];
}else{
key = search.split('=').pop();
@ -116,6 +116,12 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
};
validateFields((err, values) => {
if (!err) {
let regEn = /[\\/:*?"<>|[\]-]/g;
if (regEn.test(values.title)) {
message.error('文件名不能有特殊字符: \\ / : * ? \" < > | [ \] -');
setOperateFlag(false);
return;
}
const {md_content, title} = values;
if (wikiName && search!== "?copy") {
updateWiki({
@ -124,7 +130,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
projectId: project.id,
pageName: wikiName,
title,
message: '',
commit_message: '',
content_base64: Base64.encode(md_content)
}).then(res => dealRes(res, title));
} else {
@ -217,7 +223,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
projectId: project.id,
pageName: '_Sidebar',
title: '_Sidebar',
message: '',
commit_message: '',
content_base64: Base64.encode(content)
}).then(res => {
if (res && res.message === "200") {
@ -327,7 +333,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
"title",
[
{ required: true, message: "请输入标题" },
{ pattern: /^(?!-).*$/, message: '不能以-开头' }
// { pattern: /[^`\[\]\/:*?''<>|%-+_]/g, message: '' }
],
<Input
placeholder={"请输入标题"}

View File

@ -115,7 +115,7 @@ export default (props) => {
project && checkItem.name && getWiki({
owner: owner,
repo: projectsId,
pageName: checkItem.sub_url,
pageName: checkItem.name,
projectId: project.id
}).then(res => {
if (res && res.message === "200") {
@ -190,6 +190,11 @@ export default (props) => {
setAddMenuError("不能仅输入空格");
return;
}
const regEn = /[\\/:*?"<>|[\]-]/g;
if (regEn.test(menuName)) {
setAddMenuError("不能有特殊字符: \\ / : * ? \" < > | [ \] -");
return;
}
//
const oneMenuList = fileList.filter(item=>!item.title.trim().startsWith('[[')).map(i=>i.title.trim())
if(oneMenuList.includes(`- ${menuName}`)){
@ -210,7 +215,7 @@ export default (props) => {
projectId: project.id,
pageName: '_Sidebar',
title: '_Sidebar',
message: '',
commit_message: '',
content_base64: Base64.encode(treeToMd(sidebarList))
}).then(res => {
if (res && res.message === "200") {
@ -228,7 +233,7 @@ export default (props) => {
}
function goEdit(params) {
history.push(`/${owner}/${projectsId}/wiki/${encodeURI(checkItem.sub_url)}/${checkItem.key}/edit${params}`);
history.push(`/${owner}/${projectsId}/wiki/${encodeURI(checkItem.name)}/${checkItem.key}/edit${params}`);
}
function preview() {

View File

@ -63,7 +63,7 @@ export default (props) => {
projectsId && checkItem.name && getWiki({
owner: owner,
repo: projectsId,
pageName: checkItem.sub_url,
pageName: checkItem.name,
projectId: projectId,
}).then(res => {
if (res && res.message === "200") {

View File

@ -116,16 +116,13 @@ export function markdownToTree(markdownText){
lines.map((item, index) =>{
const title = item.trim();
const isFile = title.startsWith('[[') && title.endsWith(']]');
const titleStr = isFile ? title.substring(2, title.length - 2) : title.substring(2, title.length)
const node = {
// 带空格+[[]]或者- 标识
title: item,
children: [],
key: undefined,
// 纯内容
titleStr,
// 编码后的title,获取wiki内容用title_sub
title_sub: encodeURIComponent(titleStr),
titleStr: isFile ? title.substring(2, title.length - 2) : title.substring(2, title.length),
// 是否是wiki文件
isFile: isFile
}

View File

@ -163,7 +163,7 @@ export default function Sidebar(props) {
const {node, children, key} = item;
if(isFile){
//
deleteWiki({owner: owner, repo: projectsId, projectId: project.id, pageName: item.title_sub}).then(res => {
deleteWiki({owner: owner, repo: projectsId, projectId: project.id, pageName: title}).then(res => {
if(res && res.message === "204"){
// key
const menuListByDel = findSameKeyByDel(menuList, key);
@ -267,7 +267,7 @@ export default function Sidebar(props) {
projectId: project.id,
pageName: '_Sidebar',
title: '_Sidebar',
message: '',
commit_message: '',
content_base64: Base64.encode(content)
}).then(res => {
if (res && res.message === "200") {
@ -303,18 +303,20 @@ export default function Sidebar(props) {
e.stopPropagation();
setVisible(item);
setIsEditName(type);
const {titleStr, title_sub} = item;
let title = item.title.trim();
const isFile = title.startsWith('[[') && title.endsWith(']]');
title = isFile ? title.substring(2,title.length-2) : title.substring(2, title.length);
type === 2 && getWiki({
owner: owner,
repo: projectsId,
pageName: title_sub,
pageName: title,
projectId: project.id
}).then(res => {
if (res && res.message === "200") {
setWikiContent(res.data.md_content);
}
})
setMenuName(titleStr);
setMenuName(title);
}
//
@ -327,8 +329,9 @@ export default function Sidebar(props) {
setAddMenuError("不能仅输入空格");
return;
}
if (isEditName === 2 && /^-/.test(menuName)) {
setAddMenuError('不能以-开头');
const regEn = /[\\/:*?"<>|[\]-]/g;
if (regEn.test(menuName)) {
setAddMenuError('不能有特殊字符: \\ / : * ? \" < > | [ \] -');
return;
}
if(!isEditName){
@ -353,15 +356,14 @@ export default function Sidebar(props) {
}else{
// isEditName 1 2
const titleToJudge = isEditName === 2 ? `[[${menuName}]]` : `- ${menuName}`;
const {key, titleStr, title_sub} = visible;
//
if(titleStr === menuName){
const {title, key} = visible;
if(title.trim() === titleToJudge){
setAddMenuError("请修改名称");
return
}
//
const list = findBrotherNodesByKey(menuList, key) || [];
if(list.map(item=>item.titleStr).includes(menuName)){
if(list.map(item=>item.title.trim()).includes(titleToJudge)){
setAddMenuError("不能与同级目录名称相同");
return
}
@ -379,16 +381,17 @@ export default function Sidebar(props) {
})
if(isEditName === 2){
// -> wiki
const oldTitle = title.substring(title.indexOf('[[')+2, title.indexOf(']]'))
updateWiki({
owner,
repo: projectsId,
projectId: project.id,
//
pageName: title_sub,
pageName: oldTitle,
//
title: menuName,
content_base64: wikiContent,
message: '',
commit_message: '',
}).then(res=>{
if(res && res.message === '200'){
// wikisidebar

View File

@ -59,8 +59,10 @@ export default function UploadWiki(props) {
message.error('只能上传md、txt文件');
return false;
}
if (/^-/.test(file.name)) {
message.error('文件名不能以-开头');
let regEn = /[\\/:*?"<>|[\]-]/g;
if (regEn.test(file.name)) {
message.error('文件名不能有特殊字符: \\ / : * ? \" < > | [ \] -');
return false;
}
@ -84,7 +86,7 @@ export default function UploadWiki(props) {
projectId: project.id,
pageName: '_Sidebar',
title: '_Sidebar',
message: '',
commit_message: '',
content_base64: Base64.encode(treeToMd(sidebarList))
}).then(res => {
if (res && res.message === "200") {