diff --git a/src/forge/Order/Detail.js b/src/forge/Order/Detail.js index e13fa4ebf..e76c24451 100644 --- a/src/forge/Order/Detail.js +++ b/src/forge/Order/Detail.js @@ -69,14 +69,6 @@ class Detail extends Component { data: result.data, isSpins: false }); - const {description} = result.data; - const md_content = description; - // 所有的一级目录(包含其子目录) - const menuTree1 = md_content.split('\n-'); - console.log('所有的一级目录(包含其子目录)', menuTree1); - console.log('\n分割', menuTree1[0].split('\n')[6].split('\t')); - const menuTree2 = menuTree1[0].split('\n\t').filter(i=>{return i.indexOf('\t') === -1}); - console.log('二级目录', menuTree2); } }) .catch((error) => { diff --git a/src/forge/Wiki/Index.jsx b/src/forge/Wiki/Index.jsx index 4beec5101..fcff29cf1 100644 --- a/src/forge/Wiki/Index.jsx +++ b/src/forge/Wiki/Index.jsx @@ -39,6 +39,8 @@ export default (props) => { const [menuName, setMenuName] = useState(undefined); const [addMenuError, setAddMenuError] = useState(undefined); const [sidebar, setSidebar] = useState(undefined); + // 改变了目录顺序 + const [reloadBySort, setReloadBySort] = useState(undefined); useEffect(()=>{ if(projectDetail){ @@ -72,9 +74,13 @@ export default (props) => { setFileList(menuList); setFileListInit(menuList); let firstWikiNode = undefined; + // if(!pathname.endsWith('/wiki')){ + // firstWikiNode = findNodeByKey(menuList, pathname.split('/').pop()) + // } + const arr = pathname.split('/'); if(!pathname.endsWith('/wiki')){ - firstWikiNode = findNodeByKey(menuList, pathname.split('/').pop()) - }else{ + firstWikiNode = findNodeByName(menuList, arr[arr.length-2]); + } else{ // 找到目录树中第一个[[页面]] firstWikiNode = findFirstWiki(menuList); } @@ -84,6 +90,7 @@ export default (props) => { ...firstWiki, key: firstWikiNode.key }) + history.push(`/${owner}/${projectsId}/wiki/${title}/${firstWikiNode.key}`); } else { setFileArr([]); setFileArrInit([]); @@ -107,6 +114,40 @@ export default (props) => { }); }, [project, checkItem]); + // 监听reloadBySort的变化,修改路由 + // useEffect(()=>{ + // console.log('reloadBySort', reloadBySort, fileList); + // if(reloadBySort){ + // const node = findNodeByName(fileList, reloadBySort); + // const firstWiki = fileArrInit.filter(item => { return node.title.indexOf(item.name) !== -1})[0]; + // setCheckItem({ + // ...checkItem, + // key: node.key + // }) + // console.log('node', node, { + // ...checkItem, + // key: node.key + // }); + // history.push(`/${owner}/${projectsId}/wiki/${reloadBySort}/${node.key}`); + // setReloadBySort(undefined); + // } + + // }, [reloadBySort, fileList]) + + function findNodeByName(list, name){ + for (let index = 0; index < list.length; index++) { + const element = list[index]; + if (element.title.indexOf(name) !== -1) { + return element; + }else if (element.children.length) { + let result = findNodeByName(element.children, name); + if (result) { + return result; + } + } + } + } + // 初始化页面:递归menulist找到第一个页面 function findFirstWiki(list){ for (let index = 0; index < list.length; index++) { @@ -255,10 +296,10 @@ export default (props) => { const uploadProps = { name: 'multipartFile', withCredentials: true, - action: `${httpUrl}/api/wikiExport/uploadWiki/${owner}/${projectsId}/${project && project.id}?token=${sessionStorage.taskToken}`, //?token=${sessionStorage.taskToken} + action: `${httpUrl}/api/wikiExport/uploadWiki/${owner}/${projectsId}/${project && project.id}`, //?token=${sessionStorage.taskToken} showUploadList: false, headers: { - Authorization: cookie.load(TokenKey) || sessionStorage.taskToken, + Authorization: cookie.load(TokenKey), }, beforeUpload: beforeUpload, onChange(info) { @@ -291,7 +332,7 @@ export default (props) => { } return ( - < Spin spinning={!fileArrInit} className="opacitySpin"> + {fileArrInit && fileArrInit.length ?
@@ -333,7 +374,7 @@ export default (props) => { /> {/* 读sidebar转换成目录树 */} - +
@@ -368,7 +409,7 @@ export default (props) => { : } - {setVisible(false);setAddMenuError(undefined)}} onOk={addMenu} className="wikiAddMenu myself-modal" width={450} centered> + {setVisible(false);setAddMenuError(undefined);setMenuName(undefined);}} onOk={addMenu} className="wikiAddMenu myself-modal" width={450} centered>
请输入目录名称:
{setMenuName(e.target.value);setAddMenuError(undefined)}} maxLength={30}>
{addMenuError}
diff --git a/src/forge/Wiki/api.js b/src/forge/Wiki/api.js index 82adcf46a..8a48da25f 100644 --- a/src/forge/Wiki/api.js +++ b/src/forge/Wiki/api.js @@ -137,20 +137,6 @@ export function markdownToTree(markdownText){ } } }) - // 找到所有的一级目录以及其子目录,使用\n- 会找不到一级[[页面]] - let oneMenuAndChildren = []; - markdownText.split('\n- ').map(item=>{ - if(item.includes('\n[[')){ - const list = item.split('\n[[').map((item, index)=>index ? `[[${item}` : item); - oneMenuAndChildren = oneMenuAndChildren.concat(list); - }else{ - item && oneMenuAndChildren.push(item); - } - }) - // 给每一个节点赋值一级目录以及其子目录的md内容,后续对子节点进行操作时,对md内容整个替换 - oneMenuAndChildren.map((item, index)=>{ - assignmentNode(root.children[index], item); - }) return root.children; } @@ -169,13 +155,20 @@ export function findNodeByKey(list, key){ return undefined; } -// 给每个子节点赋值 整个层级的md内容 -function assignmentNode(root, value){ - const val = value.startsWith('[[') || value.startsWith('- ') ? value : `- ${value}` - if(root){ - root.node = val; - root.children.length && root.children.map(item=>{assignmentNode(item, val)}) +// 找到children中有相同key的数组 +export function findNodeByChildrenKey(list, key){ + for (let index = 0; index < list.length; index++) { + const element = list[index]; + if (element.key == key) { + return list; + }else if (element.children.length) { + let result = findNodeByChildrenKey(element.children, key); + if (result) { + return result; + } + } } + return []; } // 目录结构转md内容 diff --git a/src/forge/Wiki/components/sidebar/index.jsx b/src/forge/Wiki/components/sidebar/index.jsx index 74239d122..a6b8ecaf6 100644 --- a/src/forge/Wiki/components/sidebar/index.jsx +++ b/src/forge/Wiki/components/sidebar/index.jsx @@ -3,23 +3,28 @@ import { Tree, Dropdown, Menu, message, Modal, Input } from 'antd'; import DelModal from '../../components/ModalFun'; import './index.scss'; import '../../components/ModalFun/index.scss'; -import { deleteWiki, findNodeByKey, treeToMd, updateWiki } from '../../api'; +import { deleteWiki, findNodeByChildrenKey, findNodeByKey, treeToMd, updateWiki } from '../../api'; import { useEffect } from 'react'; import { Base64 } from 'js-base64'; const {DirectoryTree, TreeNode} = Tree; // wiki目录树 export default function Sidebar(props) { - const {fileList, changeitem, owner, projectsId, project, setReload, sidebar, history} = props; + const {fileList, changeitem, owner, projectsId, project, setReload, sidebar, history, setReloadBySort} = props; + const {location:{pathname}} = history; + const [initMenuList, setInitMenuList] = useState(undefined); const [menuList, setMenuList] = useState(undefined); const [actionVisible, setActionVisible] = useState(undefined); const [visible, setVisible] = useState(false); const [menuName, setMenuName] = useState(undefined); const [addMenuError, setAddMenuError] = useState(undefined); + // 重命名目录名称 + const [isEditName, setIsEditName] = useState(undefined); let key = 1; useEffect(()=>{ setMenuList(fileList); + setInitMenuList(fileList); }, [fileList]) const menu = (title, isFile, item, level) =>{ @@ -34,6 +39,11 @@ export default function Sidebar(props) { 添加子目录 } + + { updateName(e, item) }}> + 重命名 + + { deleteFileModal(e, title, isFile, item) }}> 删除 @@ -77,6 +87,18 @@ export default function Sidebar(props) { }); } + // 遍历list,找到相同的key callback + const loop = (data, key, callback) => { + data.forEach((item, index, arr) => { + if (item.key === key) { + return callback(item, index, arr); + } + if (item.children) { + return loop(item.children, key, callback); + } + }); + }; + function selectTree(keys,event){ let {title, key} = event.node.props.dataRef; title = title.trim() @@ -183,7 +205,7 @@ export default function Sidebar(props) { }) } - // 修改此仓库的sidebar文件 type 1删除 3添加子目录 + // 修改此仓库的sidebar文件 type 1删除 2拖拽 3添加子目录 4目录重命名 function updateSidebar(content, type, addWikiName){ updateWiki({ owner, @@ -198,10 +220,19 @@ export default function Sidebar(props) { setReload(Math.random()); if(type === 1){ message.success('删除成功'); - }else{ + }else if(type === 3){ setMenuName(undefined); setVisible(false); message.success('新增成功'); + }else if(type === 4){ + setIsEditName(false); + setMenuName(undefined); + setVisible(false); + message.success('重命名成功'); + }else{ + // const arr = pathname.split('/'); + // setReloadBySort(arr[arr.length-2]); + console.log('修改文件目录顺序成功'); } } }); @@ -213,8 +244,19 @@ export default function Sidebar(props) { history.push(`/${owner}/${projectsId}/wiki/add?key=${item.key}`) } - // 新增子目录 - async function addMenu(){ + // 重命名目录文件 + function updateName(e, item){ + e.stopPropagation(); + setVisible(item); + setIsEditName(true); + let title = item.title.trim(); + const isFile = title.startsWith('[[') && title.endsWith(']]'); + title = isFile ? title.substring(2,title.length-2) : title.substring(2, title.length); + setMenuName(title); + } + + // 新增子目录 或者 重命名目录 + function submit(){ if(!menuName){ setAddMenuError('请输入目录名称'); return; @@ -224,21 +266,36 @@ export default function Sidebar(props) { setAddMenuError('不能有特殊字符'); return; } - // 校验同级目录中是否有相同名称 - const {children, node, title, key} = visible; - const mList = children.filter(item=>!item.title.trim().startsWith('[[')).map(i=>i.title.trim()) - if(mList.includes(`- ${menuName}`)){ - setAddMenuError('不能与已有文件标题相同'); - return; + if(!isEditName){ + // 校验同级目录中是否有相同名称 + const {children, node, title, key} = visible; + const mList = children.filter(item=>!item.title.trim().startsWith('[[')).map(i=>i.title.trim()) + if(mList.includes(`- ${menuName}`)){ + setAddMenuError('不能与已有目录名称相同'); + return; + } + const newList = menuList; + addChildrenByKey(newList, key, menuName); + updateSidebar(treeToMd(newList), 3) + }else{ + // 编辑sidebar + const {children, node, title, key} = visible; + const list = findNodeByChildrenKey(menuList, key) || []; + if(title.trim() === `- ${menuName}`){ + setAddMenuError("请修改目录名称"); + return + } + if(list.map(item=>item.title.trim()).includes(`- ${menuName}`)){ + message.error("不能与同级目录名称相同"); + }else{ + const newMenuList = JSON.parse(JSON.stringify(menuList)) + loop(newMenuList, key, (item)=>{ + const {title} = item; + item.title = `${title.substring(0, title.indexOf('- '))}- ${menuName}` + }) + updateSidebar(treeToMd(newMenuList), 4) + } } - - const newList = menuList; - addChildrenByKey(newList, key, menuName); - updateSidebar(treeToMd(newList), 3) - // const isFindEnd = await addMenuFindKey(newList, key, menuName, title); - // if(isFindEnd){ - // updateSidebar(treeToMd(newList), 3) - // } } // 递归menuList 创建子目录 @@ -261,32 +318,120 @@ export default function Sidebar(props) { } } - // 递归menuList,nodeTitle 增加子节点的节点名称 - // async function addMenuFindKey(list, key, name, nodeTitle){ - // let bool = false; - // await list.map(item=>{ - // if(item.key === key){ - // item.children.push({ - // title: `\t${nodeTitle.substring(0, nodeTitle.indexOf('- '))}- ${name}`, - // children: [] - // }) - // bool = true; - // }else{ - // addMenuFindKey(item.children, key, name, nodeTitle) - // } - // }) - // return true; - // } + + function onDrop(info){ + // dragNode: 拖拽的节点 node: 放入的节点 + const dropKey = info.node.props.dataRef.key; + const dragKey = info.dragNode.props.dataRef.key; + const dropPos = info.node.props.pos.split('-'); + const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]); + // dropPosition 0元素之上 1元素之下 -1元素之上 + + function upTitle(list, title){ + const kongGe = title.substring(0, title.indexOf('- ') === -1 ? title.indexOf('[[') : title.indexOf('- ')); + list.map(item=>{ + item.title = `\t${kongGe}${item.title.trim()}`; + if(item.children){ + return upTitle(item.children, item.title); + } + }) + } + + const data = JSON.parse(JSON.stringify(menuList)); + + // Find dragObject + let dragObj; + loop(data, dragKey, (item, index, arr) => { + arr.splice(index, 1); + dragObj = item; + }); + // 如果拖拽的是目录,那么需要遍历所有的子节点,改变\t个数 + if(dragObj.title.indexOf('- ') !== -1){ + // 放入的节点标题 + const title = info.node.props.dataRef.title; + const addBool = !info.dropToGap || ((info.node.props.children || []).length > 0 && dropPosition === 1) + upTitle(dragObj.children, addBool ? `\t${title}` : title); + } + + // 是否要保存sidebar文件 + let bool = false; + + // dropToGap: true拖拽在节点中间 false拖拽到节点之上 + if (!info.dropToGap) { + // 追加到尾部 + loop(data, dropKey, (item, index, arr) => { + const {title} = item; + if(title.indexOf('- ') === -1){ + return; + } + const childrenName = item.children.map(item=>item.title.trim()); + if(childrenName.includes(dragObj.title.trim())){ + message.error('不能与同级目录名称相同'); + return; + } + dragObj.title = `\t${title.substring(0, title.indexOf('- '))}${dragObj.title.trim()}`; + item.children = item.children || []; + item.children.push(dragObj); + bool = true; + }); + } else if ( + (info.node.props.children || []).length > 0 && // Has children + dropPosition === 1 // On the bottom gap + ) { + // 拖拽到目录节点下 + loop(data, dropKey, item => { + const childrenName = item.children.map(item=>item.title.trim()) + if(childrenName.includes(dragObj.title.trim())){ + message.error('不能与同级目录名称相同'); + return; + } + const {title} = item; + dragObj.title = `\t${title.substring(0, title.indexOf('- '))}${dragObj.title.trim()}`; + item.children = item.children || []; + item.children.unshift(dragObj); + }); + bool = true; + } else { + let ar; + let i; + loop(data, dropKey, (item, index, arr) => { + ar = arr; + i = index; + }); + const childrenName = ar.map(item=>item.title.trim()) + if(childrenName.includes(dragObj.title.trim())){ + message.error('不能与同级目录名称相同'); + return; + } + dragObj.title = `${ar[i].title.substring(0, ar[i].title.indexOf('- '))}${dragObj.title.trim()}`; + if (dropPosition === -1) { + ar.splice(i, 0, dragObj); + } else { + ar.splice(i + 1, 0, dragObj); + } + bool = true; + } + bool && updateSidebar(treeToMd(data), 2); + setMenuList(bool ? data : initMenuList); + } + + // modal cancel + function onCancel(){ + setVisible(false); + setAddMenuError(undefined); + setIsEditName(false); + setMenuName(undefined); + } return(
- + {menuList && renderTreeNodes(menuList)} {/* 新增子目录弹窗 */} - {setVisible(false);setAddMenuError(undefined)}} onOk={addMenu} className="wikiAddMenu myself-modal" width={450} centered> -
请输入目录名称:
+ +
目录名称:
{setMenuName(e.target.value);setAddMenuError(undefined)}} maxLength={30}>
{addMenuError}
diff --git a/src/forge/Wiki/fetch.js b/src/forge/Wiki/fetch.js index ec3abf870..7faebef63 100644 --- a/src/forge/Wiki/fetch.js +++ b/src/forge/Wiki/fetch.js @@ -1,13 +1,9 @@ - import javaFetch from '../javaFetch'; - let settings = JSON.parse(localStorage.chromesetting); let actionUrl = settings && settings.common.wiki; const service = javaFetch(actionUrl); export const httpUrl = actionUrl; export default service; - - - +export const TokenKey = 'autologin_trustie'; \ No newline at end of file