diff --git a/src/assets/add.svg b/src/assets/add.svg new file mode 100644 index 0000000..c0e899c --- /dev/null +++ b/src/assets/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/default.scss b/src/assets/default.scss index 032f0d1..ad5d6ab 100644 --- a/src/assets/default.scss +++ b/src/assets/default.scss @@ -3,14 +3,17 @@ src: local("Apple Color Emojiji"), local("Segoe UI Emoji"), local("Segoe UI Symbol"), local("Noto Color Emoji"); unicode-range: U+1F000-1F644, U+203C-3299; } + //无线字体: body { font-family: system-ui, —apple-system, Segoe UI, Rototo, Emoji, Helvetica, Arial, sans-serif; } + //衬线字体: @mixin font-serif { font-family: Georgia, Cambria, "Times New Roman", Times, serif; } + //等宽字体 @mixin font-mono { font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; @@ -18,33 +21,50 @@ body { //以上字体总结 来源于B站Up:zhangxinxu https://www.bilibili.com/video/BV1b54y1Z7pu/?spm_id_from=333.337.search-card.all.click&vd_source=2f8cd1eff8d87be6af7bdcbccbd60ade -@mixin widthAuto{ +@mixin widthAuto { /*div宽度适应文字*/ - width:fit-content; - width:-webkit-fit-content; - width:-moz-fit-content; + width: fit-content; + width: -webkit-fit-content; + width: -moz-fit-content; } -@mixin noSelect{ + +@mixin noSelect { /*无法选中*/ - -webkit-touch-callout:none; - -webkit-user-select:none; - -khtml-user-select:none; - -moz-user-select:none; - -ms-user-select:none; - user-select:none; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + //浸水模糊效果 -@mixin beautifulBlurWhite{ +@mixin beautifulBlurWhite { background-color: rgba(255, 255, 255, 0.8); backdrop-filter: blur(20px) saturate(5); } + //浸水模糊效果 -@mixin beautifulBlur{ +@mixin beautifulBlur { backdrop-filter: blur(20px) saturate(1); } + //壁纸适应效果 -@mixin autoBackgroundImg{ +@mixin autoBackgroundImg { background-position: center; background-repeat: no-repeat; background-size: cover; +} + +@mixin autoHide { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +@mixin threeLineHide { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; } \ No newline at end of file diff --git a/src/assets/setting.svg b/src/assets/setting.svg new file mode 100644 index 0000000..c328b68 --- /dev/null +++ b/src/assets/setting.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/components/DirectoryStructureTree/index.jsx b/src/components/DirectoryStructureTree/index.jsx index 4e45da5..4406da4 100644 --- a/src/components/DirectoryStructureTree/index.jsx +++ b/src/components/DirectoryStructureTree/index.jsx @@ -1,14 +1,60 @@ // Nie 2023/2/8 import css from './index.module.scss' -export default function DirectoryStructureTree(props){ +import svgSetting from '@/assets/setting.svg' +import svgAdd from '@/assets/add.svg' +import {defaultStore} from "@/store/index.js"; +import {useEffect, useState} from "react"; +import {autorun} from "mobx"; + +export default function DirectoryStructureTree(props) { + const [chooseId, setChooseId] = useState(null) + function handleSetting(e, id) { + e.stopPropagation(); + defaultStore.setSettingMenuId(id) + } + + function handleCreate(e, id) { + e.stopPropagation(); + defaultStore.setNewMenuChildren(id) + } + + function handleChoose(e, id){ + e.stopPropagation(); + defaultStore.setChooseMenuId(id) + } + useEffect(() => { + const a = autorun(() => { + if(defaultStore.menuId == chooseId) return + console.log(defaultStore.menuId) + setChooseId(defaultStore.menuId) + }) + return () => { + a() + } + }) + + + return props.tree.map((item, index) => { - if(item.children && Array.isArray(item.children)){ + if (item.children && Array.isArray(item.children)) { return
-
{item.name}
+
handleChoose(e, item.id)}> +
{item.name}
+
+ handleCreate(e, item.id)}/> handleSetting(e, item.id)}/> +
+
{DirectoryStructureTree({tree: item.children})}
- }else{ - return
{item.name}
+ } else { + return
+
handleChoose(e, item.id)}> +
{item.name}
+
handleCreate(e, item.id)}/> handleSetting(e, item.id)}/>
+
+
} }) } \ No newline at end of file diff --git a/src/components/DirectoryStructureTree/index.module.scss b/src/components/DirectoryStructureTree/index.module.scss index c648cde..c425806 100644 --- a/src/components/DirectoryStructureTree/index.module.scss +++ b/src/components/DirectoryStructureTree/index.module.scss @@ -1,7 +1,47 @@ -.directoryStructureTree{ +@import '@/assets/default.scss'; +.directoryStructureTree { position: relative; line-height: 1.5em; border-radius: 10px; - margin: 1em; + margin: 0.5rem 0; + padding-left: 0.5rem; cursor: pointer; + + & > div.title { + position: relative; + display: flex; + border-radius: 10px; + padding: 0.3rem 0.5rem; + transition: background ease-in-out 300ms; + &:hover{ + background: #66666622; + } + + & > div.text { + position: relative; + flex: 1; + @include autoHide; + @include font-serif; + font-weight: 600; + } + + & > div.cmd { + position: relative; + //width: 50px; + flex-shrink: 0; + display: flex; + align-items: center; + & > img{ + width: 25px; + + } + & > img:nth-child(2){ + width: 22px; + margin-left: 10px; + } + } + } + & > div.titleChoose{ + background: #ffc93c99 !important; + } } \ No newline at end of file diff --git a/src/components/Editor/index.jsx b/src/components/Editor/index.jsx index 39f3dda..7700ba5 100644 --- a/src/components/Editor/index.jsx +++ b/src/components/Editor/index.jsx @@ -14,7 +14,7 @@ export default function Editor(props) { const [inputValue, setInputValue] = useState('') const [img, setImg] = useState(svgImg) const [defaultImg, setDefaultImg] = useState('') - + if(!props.element) return null useEffect(() => { // console.log('ELement', props.element) setElement(props.element) @@ -111,7 +111,7 @@ export default function Editor(props) { defaultStore.setInputValue(url) } - if(!props.element) return null + switch (element.identify) { // 单元素结构 diff --git a/src/request/api.js b/src/request/api.js index 053cc06..c3e2d91 100644 --- a/src/request/api.js +++ b/src/request/api.js @@ -29,5 +29,25 @@ export default { formData.append(item, data[item]) }) return instance.post('/fileStorage/putfile/',formData) + }, + getMenuList(){ + return instance.get('/menu/getMenu/') + }, + createMenuItem(data){ + const formData = new FormData() + Object.keys(data).map(item => { + formData.append(item, data[item]) + }) + return instance.post('/menu/createMneuItem/',formData) + }, + deleteMenuItem(data){ + return instance.delete('/menu/deleteMenu/',{params:data}) + }, + updateMenuItem(data){ + const formData = new FormData() + Object.keys(data).map(item => { + formData.append(item, data[item]) + }) + return instance.put('/menu/updateMenu/',formData) } } \ No newline at end of file diff --git a/src/store/defaultStore.js b/src/store/defaultStore.js index b686b3d..8271d34 100644 --- a/src/store/defaultStore.js +++ b/src/store/defaultStore.js @@ -38,8 +38,14 @@ class DefaultStore { // 容器列表 thumbnailList = []; + // 菜单列表 + menuList = []; // 当前MenuId menuId = 10; + // 创建子菜单的ID + newMenuChidlrenId = null; + // 设置菜单 + settingMenuId = null; // 修改样式参数 styleRealRand = null; styleReal = null; @@ -64,6 +70,7 @@ class DefaultStore { deleteChooseNodeId: observable, newElementIdentify: observable, thumbnailList: observable, + menuList: observable, menuId: observable, styleRealRand: observable, styleReal: observable, @@ -72,6 +79,8 @@ class DefaultStore { templateList:observable, templateAddModalState: observable, templateContainer: observable, + newMenuChidlrenId: observable, + settingMenuId: observable, containerList: computed, @@ -89,9 +98,15 @@ class DefaultStore { setTemplateAddModalState: action, setTemplateContainer:action, createTemplateConatiner: action, + getMenuList: action, + createMneuItem: action, + setNewMenuChildren: action, + setSettingMenuId: action, + setChooseMenuId: action }); } + // 获取页面容器列表 get containerList() { const containerList = {} this.thumbnailList.map(item => { @@ -134,6 +149,18 @@ class DefaultStore { setTemplateContainer(container){ this.templateContainer = container } + // 设置增加子菜单 + setNewMenuChildren(id){ + this.newMenuChidlrenId = id + } + // 设置菜单 + setSettingMenuId(id){ + this.settingMenuId = id + } + // 选择菜单 + setChooseMenuId(id){ + this.menuId = id + } // 获取内容列表 async getContainerList(menuId) { @@ -181,6 +208,29 @@ class DefaultStore { const response = await api.deleteContainer(data) this.getContainerList(this.menuId) } + // 获取菜单 + async getMenuList(){ + const response = await api.getMenuList() + runInAction(() => { + this.menuList = response.data.data + console.log(this.menuList) + }) + } + // 添加菜单 + async createMneuItem(data){ + await api.createMenuItem(data) + this.getMenuList() + } + // 删除菜单 + async deleteMenuItem(data){ + await api.deleteMenuItem(data) + this.getMenuList() + } + // 更新菜单 + async updateMenuItem(data){ + await api.updateMenuItem(data) + this.getMenuList() + } } export default DefaultStore \ No newline at end of file diff --git a/src/tools/index.js b/src/tools/index.js index 5d6b728..5bf06b7 100644 --- a/src/tools/index.js +++ b/src/tools/index.js @@ -34,7 +34,7 @@ export function getTargetNode(id, node) { if (node.id == id) { return node } else { - if (node.childElement.length > 0) { + if (node.childElement && node.childElement.length > 0) { const s = getTargetNode(id, node.childElement) if (s) targetNode = s } diff --git a/src/view/EditPageNew/index.jsx b/src/view/EditPageNew/index.jsx index 7070c9b..8b65491 100644 --- a/src/view/EditPageNew/index.jsx +++ b/src/view/EditPageNew/index.jsx @@ -34,6 +34,7 @@ export default function EditPageNew() { const [nowElement, setNowElement] = useState(null); // 当前目录 const [nowMenuId, setNowMenuId] = useState(10); + // 当前页面容器 const [nowContainerId, setNowContainerId] = useState(0) // 属性页开关 @@ -41,6 +42,15 @@ export default function EditPageNew() { // 属性页标签位置 const [attrLabelPosition, setAttrLabelPosition] = useState(0); + // 添加菜单状态 + const [createMenuItemState, setCreateMenuItemState] = useState(false) + // 菜单信息 + const [menuData, setMenuData] = useState({name:'', route:'', rank:0, father:0, icon: '', remarks:''}) + // 菜单列表 + const [menuList, setMenuList] = useState([]) + // 删除菜单状态 + const [deleteMenuState, setDeleteMenuState] = useState(false) + // 模板添加 const [templateAddModalState, setTemplateAddModalState] = useState(false) @@ -51,9 +61,70 @@ export default function EditPageNew() { useEffect(() => { console.log('生命周期开始,发送请求!') - defaultStore.getContainerList(10) + // defaultStore.getContainerList(10) defaultStore.getTemplateList() + defaultStore.getMenuList() }, [0]) + // 获取菜单列表 + useEffect(() => { + const a = autorun(() => { + if(defaultStore.menuList.length ==0)return + setMenuList(defaultStore.menuList) + }) + return () => { + a() + } + }) + // 添加子菜单 + useEffect(() => { + const a = autorun(() => { + if(defaultStore.newMenuChidlrenId == null)return; + const menu = {name:'', route:'', rank:0, father:0, icon: '', remarks:''} + const menuItem = menuList.find(item => { + if(item.id == defaultStore.newMenuChidlrenId) return true + }) + menu.father = menuItem.id + setCreateMenuItemState(true) + setMenuData({...menu}) + // 发请求修改 + defaultStore.setNewMenuChildren(null) + }) + return () => { + a() + } + }) + // 编辑菜单 + useEffect(() => { + const a = autorun(() => { + if(defaultStore.settingMenuId == null)return; + const menuItem = menuList.find(item => { + if(item.id == defaultStore.settingMenuId) return true + }) + setCreateMenuItemState(true) + setMenuData({...menuItem}) + setDeleteMenuState(true) + // 发请求修改 + defaultStore.setSettingMenuId(null) + }) + return () => { + a() + } + }) + // 选择菜单 + useEffect(() => { + const a = autorun(() => { + if(defaultStore.menuId == nowMenuId) return + setNowMenuId(defaultStore.menuId) + defaultStore.getContainerList(defaultStore.menuId) + setNowContent({}) + setNowElement(null) + defaultStore.setChooseNodeId(null) + setNowContainerId(0) + }) + return () => { + a() + } + },[nowMenuId]) // 获取容器列表 useEffect(() => { const q = autorun(() => { @@ -147,12 +218,13 @@ export default function EditPageNew() { const a = autorun(() => { if(!(defaultStore.inputValue && nowElement))return const node = getTargetNode(defaultStore.chooseNodeId, nowContent) + console.log(node) if (!node) { alert('未找到节点元素。') } else { - setNowElement(node) + // setNowElement(node) } - nowElement.inputValue = defaultStore.inputValue + node.inputValue = defaultStore.inputValue setNowElement(JSON.parse(JSON.stringify(nowElement))) setNowContent(JSON.parse(JSON.stringify(nowContent))) for (let i in nowContentList) { @@ -184,7 +256,6 @@ export default function EditPageNew() { if(defaultStore.templateList){ if(defaultStore.templateList != templateList){ setTemplateList(defaultStore.templateList) - console.log('SETT', defaultStore.templateList) } } }) @@ -318,6 +389,52 @@ export default function EditPageNew() { setAttrLabelPosition(index) } + // 关闭添加菜单 + function closeCreateMenuModal(){ + setCreateMenuItemState(false) + setDeleteMenuState(false) + } + // 取消添加 + function handleCancelCreateMenuItem(){ + closeCreateMenuModal() + } + // 确认添加 + function handleCreateMenuItem(){ + closeCreateMenuModal() + if(deleteMenuState){ + defaultStore.updateMenuItem(menuData) + }else{ + defaultStore.createMneuItem(menuData) + } + setDeleteMenuState(false) + } + // 确认删除 + function handleDeleteMenuItem(){ + closeCreateMenuModal() + defaultStore.deleteMenuItem({ + id:menuData.id + }) + } + // 更改菜单值 + function handleMenuDataChange(e, name){ + const value = e.target.value + switch (name){ + case 'name': + menuData.name = value + break; + case 'route': + menuData.route = value + break; + case 'rank': + menuData.rank = value + break; + case 'remarks': + menuData.remarks = value + break + } + setMenuData({...menuData}) + } + return
@@ -332,8 +449,37 @@ export default function EditPageNew() {
+ +
+
编辑菜单信息
+
+
+
菜单名称
+
handleMenuDataChange(e, 'name')}/>
+
+
+
路由标志
+
handleMenuDataChange(e, 'route')}/>
+
+
+
菜单说明
+
handleMenuDataChange(e, 'remarks')}/>
+
+
+
菜单位置
+
handleMenuDataChange(e, 'rank')}/>
+
+
+
+ + {deleteMenuState && } + +
+
+
+
+ tree={menuList}>