提交 4069d643 authored 作者: 王鹏飞's avatar 王鹏飞

feat: 添加侧边栏宽度调整功能

上级 b978b149
import { useState, useEffect, useRef } from 'react'
import { useState, useEffect, useRef, useCallback } from 'react'
import { Button, Row, Col, Descriptions, Tree, Dropdown, Modal, Spin, App } from 'antd'
import { EllipsisOutlined, DiffOutlined, MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
import WangEditorCustomer from '@/common/wangeditor-customer'
......@@ -18,7 +18,7 @@ import {
findFirstNotHasChildren,
findParentLevelOne,
findTreeToIndex,
findNodeById
findNodeById,
} from '@/utils/common'
import { getAllList, getInfoByChapterId, sectionEdit, chapterDel, dragOrder } from './request'
import './index.less'
......@@ -30,7 +30,7 @@ const Examine = () => {
const id = get(location, 'state.id', '')
const isAdminOrCreator = get(location, 'state.isAdminOrCreator', false)
const { treeChapter, userInfo } = useSelector(state => state.user)
const { treeChapter, userInfo } = useSelector((state) => state.user)
const navigate = useNavigate()
const dispatch = useDispatch()
......@@ -44,6 +44,9 @@ const Examine = () => {
const [nowTitle, setNowTitle] = useState('')
// 编辑操作
const [isCollapse, setisCollapse] = useState(false)
const [sidebarWidth, setSidebarWidth] = useState(280)
const isResizing = useRef(false)
const sidebarRef = useRef(null)
const [editKey, setEditKey] = useState(null)
const [parentId, setParentId] = useState(null)
const [editValue, setEditValue] = useState('')
......@@ -60,6 +63,38 @@ const Examine = () => {
// 关联知识图谱
const [bindKnowledgeGraphIsOpen, setBindKnowledgeGraphIsOpen] = useState(false)
// 拖拽改变侧边栏宽度
const handleMouseDown = useCallback(
(e) => {
e.preventDefault()
isResizing.current = true
document.body.style.cursor = 'col-resize'
document.body.style.userSelect = 'none'
const startX = e.clientX
const startWidth = sidebarWidth
const handleMouseMove = (e) => {
if (!isResizing.current) return
const delta = e.clientX - startX
const newWidth = Math.min(Math.max(startWidth + delta, 200), 600)
setSidebarWidth(newWidth)
}
const handleMouseUp = () => {
isResizing.current = false
document.body.style.cursor = ''
document.body.style.userSelect = ''
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
}
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
},
[sidebarWidth],
)
// 编辑器内容
const editorRef = useRef()
const saveInterRef = useRef()
......@@ -81,7 +116,7 @@ const Examine = () => {
return
}
const uniqueBookList = [...new Set(data.map(item => item.book_id))][0]
const uniqueBookList = [...new Set(data.map((item) => item.book_id))][0]
setBookId(uniqueBookList)
const arr = convertToAntdTreeData(data, 'name')
setGData(arr)
......@@ -123,9 +158,9 @@ const Examine = () => {
setNowTitle(title)
}
// 递归函数,获取所有节点的key
const getAllNodeKeys = nodes => {
const getAllNodeKeys = (nodes) => {
let keys = []
nodes.forEach(node => {
nodes.forEach((node) => {
keys.push(node.key)
if (node.children && node.children.length > 0) {
keys = keys.concat(getAllNodeKeys(node.children))
......@@ -153,7 +188,7 @@ const Examine = () => {
setLoading(false)
}
const onExpand = expandedKeys => {
const onExpand = (expandedKeys) => {
setExpandedKeys(expandedKeys)
}
const handleSelect = async (selectedKeys, info) => {
......@@ -205,7 +240,7 @@ const Examine = () => {
const data = await sectionEdit({
id: contentId,
content: contentHtml,
word_count
word_count,
})
if (data) {
if ((data.code && data.code === 3000) || data.code === '3000') {
......@@ -233,7 +268,7 @@ const Examine = () => {
setParentId(-1)
}
const delChapter = async node => {
const delChapter = async (node) => {
const childInKey = findParentLevelOne(gData, 'key', node.key)
let current = null
if (childInKey && childInKey.children && childInKey.children.length > 0) {
......@@ -296,11 +331,11 @@ const Examine = () => {
label: '一键AI',
children: [
{ key: '61', label: '一键AI创作课件', disabled: true },
{ key: '62', label: '一键AI创作教案', disabled: true }
]
{ key: '62', label: '一键AI创作教案', disabled: true },
],
},
{ key: '3', label: '编辑' },
{ key: '4', label: '删除' }
{ key: '4', label: '删除' },
]
if (!isAdminOrCreator) {
chapterMenuItems = [{ key: '1', label: '展开全部' }]
......@@ -330,7 +365,7 @@ const Examine = () => {
content: `确认删除子节【${node.title}】?`,
onOk() {
delChapter(node)
}
},
})
} else if (e.key == 5) {
setEditChapterEditorsIsOpen(true)
......@@ -340,18 +375,18 @@ const Examine = () => {
}
// 章节名称
const chapterTitleRender = node => {
const chapterTitleRender = (node) => {
return (
<div className="chapter-tree-item">
<p className="title">{node.title}</p>
<Dropdown trigger={['click']} menu={{ items: chapterMenuItems, onClick: e => handleMenuClick(e, node) }}>
<EllipsisOutlined onClick={e => e.stopPropagation()} />
<Dropdown trigger={['click']} menu={{ items: chapterMenuItems, onClick: (e) => handleMenuClick(e, node) }}>
<EllipsisOutlined onClick={(e) => e.stopPropagation()} />
</Dropdown>
</div>
)
}
const onDrop = async info => {
const onDrop = async (info) => {
const dropToGap = info.dropToGap // true 为同级或最大级 false 为子级
const nowDropNode = info.dragNode.key
const sideDropNode = info.node.key
......@@ -369,7 +404,7 @@ const Examine = () => {
book_id: id,
drag_node: nowDropNode,
position_node: sideDropNode,
drop_type: 'after'
drop_type: 'after',
})
} else {
if (dragOverGapTop) {
......@@ -378,14 +413,14 @@ const Examine = () => {
book_id: id,
drag_node: nowDropNode,
position_node: sideDropNode,
drop_type: 'before'
drop_type: 'before',
})
} else if (dragOverGapBottom) {
data = await dragOrder({
book_id: id,
drag_node: nowDropNode,
position_node: sideDropNode,
drop_type: 'after'
drop_type: 'after',
})
}
}
......@@ -395,7 +430,7 @@ const Examine = () => {
book_id: id,
drag_node: nowDropNode,
position_node: sideDropNode,
drop_type: 'inner'
drop_type: 'inner',
})
}
if (data) {
......@@ -406,8 +441,11 @@ const Examine = () => {
return (
<div className="examine">
<div className="content-box">
<Row gutter={10} style={{ height: '100%' }} className="book-content-row">
<Col span={isCollapse ? 1 : 4} className="book-content-tree">
<div className="book-content-row">
<div
ref={sidebarRef}
className="book-content-tree"
style={{ width: isCollapse ? 50 : sidebarWidth, minWidth: isCollapse ? 50 : 200, flexShrink: 0 }}>
<div className="border">
{!isCollapse ? (
<>
......@@ -431,8 +469,8 @@ const Examine = () => {
onClick={() => setisCollapse(true)}></Button>
</Col>
</Row>
)
}
),
},
]}
/>
{gData && gData.length > 0 && (
......@@ -450,7 +488,7 @@ const Examine = () => {
disabled={loading}
treeData={gData}
onExpand={onExpand}
titleRender={nodeData => chapterTitleRender(nodeData)}
titleRender={(nodeData) => chapterTitleRender(nodeData)}
/>
)}
</>
......@@ -470,14 +508,15 @@ const Examine = () => {
onClick={() => setisCollapse(false)}></Button>
</Col>
</Row>
)
}
),
},
]}
/>
)}
</div>
</Col>
<Col span={isCollapse ? 23 : 20} className="book-content-tree">
</div>
{!isCollapse && <div className="resize-handle" onMouseDown={handleMouseDown} />}
<div className="book-content-editor" style={{ flex: 1, minWidth: 0 }}>
<div className="editor-right">
<Spin spinning={loading}>
<WangEditorCustomer
......@@ -494,8 +533,8 @@ const Examine = () => {
/>
</Spin>
</div>
</Col>
</Row>
</div>
</div>
</div>
<Modal
......@@ -509,7 +548,7 @@ const Examine = () => {
closeIcon={false} // 添加这一行以隐藏关闭按钮
onCancel={() => setEditKey(false)}
classNames={{
wrapper: 'chapter-title-modal'
wrapper: 'chapter-title-modal',
}}>
<EditChapterTitle
setEditKey={setEditKey}
......
......@@ -7,9 +7,46 @@
.book-content-row {
height: 100%;
overflow: hidden;
display: flex;
gap: 0;
.book-content-tree {
height: 100%;
overflow: hidden;
transition: width 0s;
}
.book-content-editor {
height: 100%;
overflow: hidden;
}
}
.resize-handle {
width: 6px;
cursor: col-resize;
background: transparent;
position: relative;
flex-shrink: 0;
z-index: 10;
transition: background 0.2s;
&:hover,
&:active {
background: #1890ff;
border-radius: 3px;
}
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 2px;
height: 30px;
background: #d9d9d9;
border-radius: 1px;
transition: background 0.2s;
}
&:hover::after,
&:active::after {
background: #fff;
}
}
.ant-descriptions-item-label {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论