基本完成编辑,需要优化显示,完善模板,选择联动。链接目录

main
expressgy 2 years ago
parent e73d3deb7f
commit 19ea528307
  1. 7
      src/assets/img.svg
  2. 174
      src/components/Editor/index.jsx
  3. 80
      src/components/Editor/index.module.scss
  4. 5
      src/components/Modal/index.jsx
  5. 77
      src/components/StyleControl/index.jsx
  6. 8
      src/store/defaultStore.js
  7. 95
      src/tools/index.js
  8. 53
      src/view/EditPageNew/index.jsx
  9. 3
      src/view/EditPageNew/index.module.scss
  10. 4
      vite.config.js

@ -0,0 +1,7 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1676450585232" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2796"
xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
<path d="M852.314 202.247H171.686c-48.893 0-88.531 39.638-88.531 88.548v442.408c0 48.912 39.638 88.551 88.531 88.551h680.628c48.893 0 88.53-39.639 88.53-88.551V290.795c0.001-48.911-39.637-88.548-88.53-88.548zM257.206 424.628c-41.489 0-75.106-33.654-75.106-75.124 0-41.507 33.617-75.125 75.106-75.125s75.106 33.618 75.106 75.125c0.001 41.47-33.617 75.124-75.106 75.124z m209.501 300.649H319.224l128.748-222.982 74.957 129.832 53.791 93.15H466.707z m132.468-1.123l-53.772-93.186 115.604-191.42 171.825 284.606H599.175z"
p-id="2797"></path>
</svg>

After

Width:  |  Height:  |  Size: 897 B

@ -0,0 +1,174 @@
import css from './index.module.scss'
import {useEffect, useState} from "react";
import svgImg from '@/assets/img.svg'
import {getMD5} from "@/tools/index.js";
import api from "@/request/api.js";
import {defaultStore} from "@/store/index.js";
export default function Editor(props) {
const [element, setElement] = useState({})
const [style, setStyle] = useState({})
const [href, setHref] = useState({url: '', state: 0,})
const [editState, setEditState] = useState(false)
const [inputValue, setInputValue] = useState('')
const [img, setImg] = useState(svgImg)
const [defaultImg, setDefaultImg] = useState('')
useEffect(() => {
// console.log('ELement', props.element)
setElement(props.element)
if (props.element.config && props.element.config.styleReal) {
const styleReal = props.element.config.styleReal
const styleTem = {
backgroundImage: styleReal.background
?`url('/ossStatic/${styleReal.background
}')`:null,
backgroundColor: '#'+styleReal['background-color'],
position: styleReal.position,
width: styleReal.width + styleReal['width-mx'],
height: styleReal.height + styleReal['height-mx'],
backdropFilter: styleReal['backdrop-filter'],
top: styleReal.top + styleReal['top-mx'],
right: styleReal.right + styleReal['right-mx'],
bottom: styleReal.bottom + styleReal['bottom-mx'],
left: styleReal.left + styleReal['left-mx'],
margin: styleReal.margin,
padding: styleReal.padding,
borderRadius: styleReal['border-radius'] + styleReal['border-radius-mx'],
border: styleReal.border,
overflow: styleReal.overflow,
color: '#'+styleReal.color,
fontSize: styleReal['font-size'] + styleReal['font-size-mx'],
fontWeight: styleReal['font-weight'],
lineHeight: styleReal['line-height'] + styleReal['line-height-mx'],
textIndent: styleReal['text-indent'] + styleReal['text-indent-mx'],
textAlign: styleReal['text-align'],
whiteSpace: styleReal['white-space'],
}
if(styleReal['all-center']){
styleTem.display = 'flex';
styleTem['alignItems'] = 'center';
styleTem['justifyContent'] = 'center';
}
setStyle(styleTem)
setHref({
href: styleReal.href,
state: styleReal['href-mx']
})
if (props.element.inputValue) {
setInputValue(props.element.inputValue)
}
}
if(props.element.identify == 'image' && props.element.inputValue){
setImg('/ossStatic/' + props.element.inputValue)
}
}, [props.element])
useEffect(() => {
// console.log(style)
}, [style])
function hrefClick(e) {
e.stopPropagation();
if (!href.url) return;
if (href.url.length < 3) return
if (href.state == '0') {
window.location.href = href.url
} else {
window.open(href.url)
}
}
//
function handleEditInputValueOk() {
setEditState(false)
// console.log(inputValue.split('\n').join('<br/>'))
setInputValue(inputValue.split('\n').join('<br/>'))
defaultStore.setChooseNodeId(element.id)
defaultStore.setInputValue(inputValue.split('\n').join('<br/>'))
}
//
async function handleImgChange(e){
const file = e.target.files[0];
const md5 = await getMD5(file)
const data = {
md5,
file
}
const response = await api.putFile(data)
if(!response.data.state){
alert(response.data.data.message)
return
}
const url = response.data.data.filename
console.log(url)
setImg('/ossStatic/' + url)
defaultStore.setChooseNodeId(element.id)
defaultStore.setInputValue(url)
}
if(!props.element) return null
switch (element.identify) {
//
case 'singleFrame':
return <div className={css.singleFrame} style={style} onClick={hrefClick}>
{
Array.isArray(props.element.childElement) ? props.element.childElement.map(item => {
{return <Editor element={item} key={item.id}></Editor>}
}) : <Editor element={props.element.childElement}></Editor>
}
</div>
break;
//
case 'transverseFrame':
return <div className={css.transverseFrame} style={style} onClick={hrefClick}>
{
Array.isArray(props.element.childElement) ? props.element.childElement.map(item => {
{return <Editor element={item} key={item.id}></Editor>}
}) : <Editor element={props.element.childElement}></Editor>
}
</div>
break;
//
case 'longitudinalFrame':
return <div className={css.longitudinalFrame} style={style} onClick={hrefClick}>
{
Array.isArray(props.element.childElement) ? props.element.childElement.map(item => {
{return <Editor element={item} key={item.id}></Editor>}
}) : <Editor element={props.element.childElement}></Editor>
}
</div>
break;
//
case 'span':
return <div className={css.span} style={style} onClick={() => setEditState(true)}>{!editState ? inputValue : <div
className={css.spanDiv}><input type="text" onChange={e => setInputValue(e.target.value)}
value={inputValue} onBlur={handleEditInputValueOk}/></div>}</div>
break;
//
case 'blockText':
return <div className={css.span} style={style} onClick={() => setEditState(true)}>{!editState ? <div dangerouslySetInnerHTML={
{ __html: inputValue}}></div> : <div
className={css.spanDiv}><textarea onChange={e => setInputValue(e.target.value)}
value={inputValue} onBlur={handleEditInputValueOk}/></div>}</div>
break;
//
case 'image':
return <div className={css.image} style={style}>
<img src={img} alt="" style={style}/>
<input onChange={handleImgChange} value={defaultImg} type="file"/>
</div>
break;
//
case 'video':
break;
default:
return null
break
}
}

@ -0,0 +1,80 @@
// 框架
@mixin frame{
position: relative;
min-height: 3rem;
border: solid 1px #333;
box-sizing: border-box;
}
// 单元素结构
.singleFrame {
@include frame;
}
// 横向多元素结构
.transverseFrame{
display: flex;
flex-wrap: wrap;
@include frame;
}
// 纵向多元素结构
.longitudinalFrame {
display: flex;
flex-direction: column;
@include frame;
}
// 行内文本
.span{
@include frame;
padding: 10px;
width: auto;
height: auto;
}
.spanDiv{
position: relative;
display: flex;
padding: 5px;
box-sizing: border-box;
& > input{
position: relative;
display: block;
flex: 1;
line-height: 1.5em;
background: #ffffff99;
border: 1px solid #333;
font-size: inherit;
color: inherit;
}
}
.editInput{
position: relative;
min-height: 2em;
}
// 块文本
.blockText{
}
// 图像
.image{
position: relative;
@include frame;
padding: 0;
width: 100px;
& > input{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
min-width: 30px;
min-height: 20px;
opacity: 0;
display: block;
}
& > img{
position: relative;
}
}
// 视频
.video{
}

@ -24,7 +24,9 @@ export default function Dialog(props){
const [temCloseAnimation, settemCloseAnimation] = useState(BPEMR.temModalShow) const [temCloseAnimation, settemCloseAnimation] = useState(BPEMR.temModalShow)
useEffect(() => { useEffect(() => {
if(!modalRoot)return
setState(props.state) setState(props.state)
// console.log(state, props.state)
setWidth(props.width) setWidth(props.width)
if(state){ if(state){
modalRoot.style.animation = '' modalRoot.style.animation = ''
@ -33,9 +35,10 @@ export default function Dialog(props){
modalRoot.style.display = 'none' modalRoot.style.display = 'none'
settemCloseAnimation(BPEMR.temModalShow) settemCloseAnimation(BPEMR.temModalShow)
} }
}, [state, width]) }, [state, width, props.state, props.width])
useEffect(() => { useEffect(() => {
if(!modalRoot)return
modalRoot.style.animation = 'modalRootHide ease-in-out 500ms forwards' modalRoot.style.animation = 'modalRootHide ease-in-out 500ms forwards'
},[temCloseAnimation]) },[temCloseAnimation])

@ -1,13 +1,22 @@
import css from './index.module.scss' import css from './index.module.scss'
import {useState} from "react"; import {useEffect, useState} from "react";
import {defaultStore} from "@/store/index.js"; import {defaultStore} from "@/store/index.js";
import {getMD5} from "@/tools/index.js"; import {getMD5} from "@/tools/index.js";
import api from '@/request/api' import api from '@/request/api'
export default function StyleControl(props) { export default function StyleControl(props) {
if (!props.node) return null; const [styleReal, setStyleReal] = useState({})
const styleArr = props.node.config.style; const [styleArr, setStyleArr] = useState([])
let styleRealTem = { useEffect(() => {
if(!props.node){
}else{
setStyleArr(props.node.config.style)
if(props.node.config.styleReal){
const styleRealTem = JSON.parse(JSON.stringify(props.node.config.styleReal))
setStyleReal(styleRealTem)
}else{
const styleRealTem = {
'background-img': '', 'background-img': '',
'background-color': '', 'background-color': '',
'background-other': '', 'background-other': '',
@ -31,10 +40,11 @@ export default function StyleControl(props) {
'border-radius-mx': 'px', 'border-radius-mx': 'px',
'border': '', 'border': '',
'href': '', 'href': '',
'href-mx':'0',
'overflow': 'auto', 'overflow': 'auto',
'color': '', 'color': '',
'font-size': '', 'font-size': '',
'font-size-mx': 'em', 'font-size-mx': 'px',
'font-weight': '', 'font-weight': '',
'line-height': '', 'line-height': '',
'line-height-mx': 'px', 'line-height-mx': 'px',
@ -42,12 +52,12 @@ export default function StyleControl(props) {
'white-space': '', 'white-space': '',
'text-indent': '', 'text-indent': '',
'text-indent-mx': 'px', 'text-indent-mx': 'px',
'all-center':false
} }
if(props.node.config.styleReal){ setStyleReal(styleRealTem)
styleRealTem = JSON.parse(JSON.stringify(props.node.config.styleReal))
} }
}
const [styleReal, setStyleReal] = useState(styleRealTem) },[props.node])
async function handleStyleCHange(e, caseText) { async function handleStyleCHange(e, caseText) {
if(caseText == "background-img"){ if(caseText == "background-img"){
@ -62,11 +72,12 @@ export default function StyleControl(props) {
alert(response.data.data.message) alert(response.data.data.message)
return return
} }
styleReal.img = response.data.data.filename styleReal.background = response.data.data.filename
}else{ }else{
styleReal[caseText] = e.target.value; styleReal[caseText] = e.target.value;
} }
setStyleReal({...styleReal}) setStyleReal({...styleReal})
// console.log(styleReal)
if(defaultStore.styleTimeout){ if(defaultStore.styleTimeout){
clearTimeout(defaultStore.styleTimeout) clearTimeout(defaultStore.styleTimeout)
defaultStore.setStyleTimeout(setTimeout(() => { defaultStore.setStyleTimeout(setTimeout(() => {
@ -80,8 +91,9 @@ export default function StyleControl(props) {
},1000)) },1000))
} }
} }
if(!props.node){
return null
}
return Object.keys(styleArr).map((item, index) => { return Object.keys(styleArr).map((item, index) => {
return <div className={css.styleBox} key={item}> return <div className={css.styleBox} key={item}>
<div className={css.title}> <div className={css.title}>
@ -178,6 +190,26 @@ export default function StyleControl(props) {
</div> </div>
</div> </div>
} }
{
name == 'all-center' && <div>
<div className={css.one}>
<div className={css.title}>全剧中</div>
<div className={css.two}>
<div className={css.inputTextSmall}>
<div></div>
<div></div>
<div>
<label><input type="radio" name='height' defaultChecked={styleReal['all-center'] != false}
value={true}
onChange={e => handleStyleCHange(e, 'all-center')}/>true</label>
<label><input type="radio" name='height' value={false} defaultChecked={styleReal['all-center'] == false}
onChange={e => handleStyleCHange(e, 'all-center')}/>false</label>
</div>
</div>
</div>
</div>
</div>
}
{ {
name == 'background' && <div> name == 'background' && <div>
<div className={css.one}> <div className={css.one}>
@ -392,6 +424,11 @@ export default function StyleControl(props) {
value={styleReal['href']} value={styleReal['href']}
onChange={e => handleStyleCHange(e, 'href')}/></div> onChange={e => handleStyleCHange(e, 'href')}/></div>
<div> <div>
<label><input type="radio" name='href' defaultChecked={styleReal['href-mx'] != '1'}
value='0'
onChange={e => handleStyleCHange(e, 'href-mx')}/></label>
<label><input type="radio" name='href' value='1' defaultChecked={styleReal['href-mx'] == '1'}
onChange={e => handleStyleCHange(e, 'href-mx')}/></label>
</div> </div>
</div> </div>
</div> </div>
@ -538,20 +575,18 @@ export default function StyleControl(props) {
<div className={css.two}> <div className={css.two}>
<div className={css.inputTextSmall}> <div className={css.inputTextSmall}>
<div></div> <div></div>
<div><input type="number" style={{width: '40px'}} <div>
value={styleReal['text-indent']}
onChange={e => handleStyleCHange(e, 'text-align')}/>
</div> </div>
<div> <div>
<label><input type="radio" name='text-indent' defaultChecked={styleReal['text-align-mx'] != 'center' || styleReal['text-align-mx'] != 'right'} <label><input type="radio" name='text-align' defaultChecked={styleReal['text-align'] != 'center' || styleReal['text-align'] != 'right'}
value='left' value='left'
onChange={e => handleStyleCHange(e, 'text-indent-mx')}/>px</label> onChange={e => handleStyleCHange(e, 'text-align')}/>left</label>
<label><input type="radio" name='text-indent' defaultChecked={styleReal['text-align-mx'] == 'center'} <label><input type="radio" name='text-align' defaultChecked={styleReal['text-align'] == 'center'}
value='center' value='center'
onChange={e => handleStyleCHange(e, 'text-indent-mx')}/>em</label> onChange={e => handleStyleCHange(e, 'text-align')}/>center</label>
<label><input type="radio" name='text-indent' defaultChecked={styleReal['text-align-mx'] == 'right'} <label><input type="radio" name='text-align' defaultChecked={styleReal['text-align'] == 'right'}
value='right' value='right'
onChange={e => handleStyleCHange(e, 'text-indent-mx')}/>rem</label> onChange={e => handleStyleCHange(e, 'text-align')}/>right</label>
</div> </div>
</div> </div>
</div> </div>

@ -44,6 +44,9 @@ class DefaultStore {
styleRealRand = null; styleRealRand = null;
styleReal = null; styleReal = null;
styleTimeout = null; styleTimeout = null;
// 输入内容
inputValue = null;
constructor() { constructor() {
// mobx6 和以前版本这是最大的区别 // mobx6 和以前版本这是最大的区别
@ -59,6 +62,7 @@ class DefaultStore {
styleRealRand: observable, styleRealRand: observable,
styleReal: observable, styleReal: observable,
styleTimeout: observable, styleTimeout: observable,
inputValue:observable,
containerList: computed, containerList: computed,
@ -105,6 +109,10 @@ class DefaultStore {
setStyleTimeout(a){ setStyleTimeout(a){
this.styleTimeout = a this.styleTimeout = a
} }
// 设置新内容
setInputValue(value) {
this.inputValue = value
}
// 获取内容列表 // 获取内容列表
async getContainerList(menuId) { async getContainerList(menuId) {

@ -1,80 +1,80 @@
import SparkMD5 from 'spark-md5' import SparkMD5 from 'spark-md5'
// 从元素模板中获取指定元素 // 从元素模板中获取指定元素
export function getTargetElement(identify, AtomTemplate){ export function getTargetElement(identify, AtomTemplate) {
let element = null; let element = null;
for(let i in AtomTemplate){ for (let i in AtomTemplate) {
if(AtomTemplate[i].identify == identify){ if (AtomTemplate[i].identify == identify) {
element = AtomTemplate[i]; element = AtomTemplate[i];
break break
}else if(Array.isArray(AtomTemplate[i].children)){ } else if (Array.isArray(AtomTemplate[i].children)) {
const s = getTargetElement(identify, AtomTemplate[i].children); const s = getTargetElement(identify, AtomTemplate[i].children);
if(s) element = s if (s) element = s
} }
} }
return element return element
} }
// 选择元素节点数的节点 // 选择元素节点数的节点
export function getTargetNode(id, node){ export function getTargetNode(id, node) {
let targetNode = null let targetNode = null
if(Array.isArray(node)){ if (Array.isArray(node)) {
node.map((item, index) => { node.map((item, index) => {
if(item.id == id){ if (item.id == id) {
targetNode = item targetNode = item
return item return item
}else{ } else {
if(item.childElement && item.childElement.length > 0){ if (item.childElement && item.childElement.length > 0) {
const s = getTargetNode(id, item.childElement) const s = getTargetNode(id, item.childElement)
if(s) targetNode = s if (s) targetNode = s
} }
} }
}) })
}else{ } else {
if(node.id == id){ if (node.id == id) {
return node return node
}else{ } else {
if(node.childElement.length > 0){ if (node.childElement.length > 0) {
const s = getTargetNode(id, node.childElement) const s = getTargetNode(id, node.childElement)
if(s) targetNode = s if (s) targetNode = s
} }
} }
} }
return targetNode return targetNode
} }
// 删除元素节点数的节点 // 删除元素节点数的节点
export function deleteTargetNode(id, node){ export function deleteTargetNode(id, node){
if(Array.isArray(node)){ if(Array.isArray(node)){
const newList = node.filter((item, index) => { // 子元素
if(item.id!=id)return true let deleteIndex = null;
if(item.childElement && item.childElement.length > 0){ for(let i in node){
const nodeSS = deleteTargetNode(id, item.childElement) if(node[i].id == id){
if(nodeSS != null){ deleteIndex = i;
item.childElement = nodeSS break;
} }
} }
}) if(deleteIndex != null){
if(newList.length != node){ node = node.splice(deleteIndex, 1)
return newList
}else{ }else{
return null for(let i in node){
if(node[i].childElement && node[i].childElement.length > 0){
deleteTargetNode(id, node[i].childElement)
}
}
} }
}else{ }else{
if(node.id == id){ // 根节点
if(id == node.id){
alert('根节点无法删除') alert('根节点无法删除')
return node return node
}else{ }else{
if(node.childElement.length > 0){ const a = deleteTargetNode(id, node.childElement)
const nodeSS = deleteTargetNode(id, node.childElement)
if(nodeSS != null){
node.childElement = nodeSS
}
}
} }
} }
return node
} }
export function getMD5(file){ export function getMD5(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let fileReader = new FileReader() let fileReader = new FileReader()
@ -105,12 +105,13 @@ const style1 = [
'border-radius', 'border-radius',
'href',// 跳转 'href',// 跳转
'overflow', 'overflow',
'box-shadow' 'box-shadow',
'all-center'
// '全剧中', // '全剧中',
] ]
// 文字属性 // 文字属性
const style2 = [ const style2 = [
'color', 'font-size', 'font-weight', 'white-space', 'text-indent', 'line-height', 'text-align' 'color', 'font-size', 'font-weight', 'white-space', 'text-indent', 'line-height', 'text-align', 'href'
] ]
const containerStyle = style1; const containerStyle = style1;
@ -193,7 +194,7 @@ export class NE {
config: { config: {
childrenType: 'text', childrenType: 'text',
middle: '中间件', middle: '中间件',
style: {containerStyle, textStyle}, style: {textStyle},
styleLimit: {}, styleLimit: {},
event: {} event: {}
}, },
@ -206,7 +207,7 @@ export class NE {
config: { config: {
childrenType: 'text', childrenType: 'text',
middle: '中间件', middle: '中间件',
style: {containerStyle, textStyle}, style: {textStyle},
styleLimit: {}, styleLimit: {},
event: {} event: {}
}, },
@ -219,7 +220,9 @@ export class NE {
config: { config: {
childrenType: 'images', childrenType: 'images',
middle: '中间件', middle: '中间件',
style: {containerStyle, textStyle}, style: {
textStyle: [...textStyle, 'width','height']
},
styleLimit: {}, styleLimit: {},
event: {} event: {}
}, },
@ -232,7 +235,9 @@ export class NE {
config: { config: {
childrenType: 'video', childrenType: 'video',
middle: '中间件', middle: '中间件',
style: {containerStyle, textStyle}, style: {
textStyle: [...textStyle, 'width','height']
},
styleLimit: {}, styleLimit: {},
event: {} event: {}
}, },
@ -256,7 +261,7 @@ export class NE {
config: { config: {
childrenType: 'text', childrenType: 'text',
middle: '中间件', middle: '中间件',
style: {containerStyle, textStyle}, style: {textStyle},
styleLimit: {}, styleLimit: {},
event: {} event: {}
}, },
@ -269,7 +274,7 @@ export class NE {
config: { config: {
childrenType: 'text', childrenType: 'text',
middle: '中间件', middle: '中间件',
style: {containerStyle, textStyle}, style: {textStyle},
styleLimit: {}, styleLimit: {},
event: {} event: {}
}, },
@ -282,7 +287,7 @@ export class NE {
config: { config: {
childrenType: 'text', childrenType: 'text',
middle: '中间件', middle: '中间件',
style: {containerStyle, textStyle}, style: {textStyle},
styleLimit: {}, styleLimit: {},
event: {} event: {}
}, },
@ -295,7 +300,7 @@ export class NE {
config: { config: {
childrenType: 'text', childrenType: 'text',
middle: '中间件', middle: '中间件',
style: {containerStyle, textStyle}, style: {textStyle},
styleLimit: {}, styleLimit: {},
event: {} event: {}
}, },

@ -7,6 +7,7 @@ import Button from "@/components/Button/index.jsx";
import Atom from "@/components/Atom/index.jsx"; import Atom from "@/components/Atom/index.jsx";
import ElementStructureTree from "@/components/ElementStructureTree/index.jsx"; import ElementStructureTree from "@/components/ElementStructureTree/index.jsx";
import StyleControl from "@/components/StyleControl/index.jsx"; import StyleControl from "@/components/StyleControl/index.jsx";
import Editor from "@/components/Editor/index.jsx";
import css from './index.module.scss' import css from './index.module.scss'
import svgLolipop from '@/assets/lolipop.svg' import svgLolipop from '@/assets/lolipop.svg'
@ -30,13 +31,15 @@ export default function EditPageNew() {
const [nowContent, setNowContent] = useState({}); const [nowContent, setNowContent] = useState({});
// //
const [nowElement, setNowElement] = useState(null); const [nowElement, setNowElement] = useState(null);
//
const [nowMenuId, setNowMenuId] = useState(10);
const [nowContainerId, setNowContainerId] = useState(0)
// //
const [attributeSwitch, setAttributeSwitch] = useState(false); const [attributeSwitch, setAttributeSwitch] = useState(false);
// //
const [attrLabelPosition, setAttrLabelPosition] = useState(0); const [attrLabelPosition, setAttrLabelPosition] = useState(0);
useEffect(() => { useEffect(() => {
console.log('生命周期开始,发送请求!') console.log('生命周期开始,发送请求!')
defaultStore.getContainerList(10) defaultStore.getContainerList(10)
@ -47,10 +50,19 @@ export default function EditPageNew() {
if(defaultStore.thumbnailList != thumbnailList){ if(defaultStore.thumbnailList != thumbnailList){
setThumbnailList(defaultStore.thumbnailList) setThumbnailList(defaultStore.thumbnailList)
} }
if(defaultStore.containerList != nowContentList){ if(defaultStore.containerList != nowContentList){
setNowContentList(defaultStore.containerList) setNowContentList(defaultStore.containerList)
} }
}) })
if(defaultStore.thumbnailList == thumbnailList){
thumbnailList.forEach((item, index) => {
if(item.id == nowContainerId){
chooseThumbnail(index)
return
}
})
}
return () => { return () => {
q() q()
} }
@ -134,10 +146,9 @@ export default function EditPageNew() {
useEffect(() => { useEffect(() => {
const a = autorun(() => { const a = autorun(() => {
if(!defaultStore.styleRealRand)return if(!defaultStore.styleRealRand)return
// console.log(nowElement)
nowElement.config.styleReal = defaultStore.styleReal nowElement.config.styleReal = defaultStore.styleReal
setNowElement({...nowElement}) setNowElement(JSON.parse(JSON.stringify(nowElement)))
setNowContent({...nowContent}) setNowContent(JSON.parse(JSON.stringify(nowContent)))
for (let i in nowContentList) { for (let i in nowContentList) {
if (nowContentList[i].id == nowContent.id) { if (nowContentList[i].id == nowContent.id) {
nowContentList[i] = nowContent; nowContentList[i] = nowContent;
@ -150,6 +161,31 @@ export default function EditPageNew() {
a() a()
} }
}, [nowContent, nowContentList, nowElement]) }, [nowContent, nowContentList, nowElement])
//
useEffect(() => {
const a = autorun(() => {
if(!(defaultStore.inputValue && nowElement))return
const node = getTargetNode(defaultStore.chooseNodeId, nowContent)
if (!node) {
alert('未找到节点元素。')
} else {
setNowElement(node)
}
nowElement.inputValue = defaultStore.inputValue
setNowElement(JSON.parse(JSON.stringify(nowElement)))
setNowContent(JSON.parse(JSON.stringify(nowContent)))
for (let i in nowContentList) {
if (nowContentList[i].id == nowContent.id) {
nowContentList[i] = nowContent;
break
}
}
defaultStore.setInputValue(null)
})
return () => {
a()
}
}, [nowContent, nowContentList, nowElement])
// //
function closeThumbnailModal() { function closeThumbnailModal() {
@ -190,13 +226,14 @@ export default function EditPageNew() {
// //
function chooseThumbnail(index) { function chooseThumbnail(index) {
if(nowContentList[thumbnailList[index].id].id == nowContent.id)return
thumbnailList.forEach(item => { thumbnailList.forEach(item => {
item.choose = false; item.choose = false;
}) })
thumbnailList[index].choose = true; thumbnailList[index].choose = true;
setThumbnailList([...thumbnailList]) setThumbnailList([...thumbnailList])
setNowContent(nowContentList[thumbnailList[index].id]); setNowContent(nowContentList[thumbnailList[index].id]);
console.log(nowContentList[thumbnailList[index].id]) setNowContainerId(thumbnailList[index].id)
defaultStore.setChooseNodeId(null) defaultStore.setChooseNodeId(null)
setNowElement(null) setNowElement(null)
} }
@ -252,7 +289,7 @@ export default function EditPageNew() {
{ {
thumbnailList.map((item, index) => { thumbnailList.map((item, index) => {
return <div return <div
className={item.choose ? moleculeBoxChoose : css.moleculeBox} className={item.choose || item.id == nowContainerId? moleculeBoxChoose : css.moleculeBox}
key={index} onClick={() => chooseThumbnail(index)}> key={index} onClick={() => chooseThumbnail(index)}>
<div> <div>
<div className={css.molecule}> <div className={css.molecule}>
@ -275,7 +312,7 @@ export default function EditPageNew() {
} }
</div> </div>
<div className={css.moleculeAdd} onClick={() => { <div className={css.moleculeAdd} onClick={() => {
setAddThumbnailState(true) setAddThumbnailState(true);
}}> }}>
<div>+</div> <div>+</div>
</div> </div>
@ -297,7 +334,7 @@ export default function EditPageNew() {
</div> </div>
</div> </div>
<div className={css.middle}> <div className={css.middle}>
<Editor element={nowContent}></Editor>
</div> </div>
<div className={css.right} style={{ <div className={css.right} style={{
width: attributeSwitch ? '0' : '300px', width: attributeSwitch ? '0' : '300px',

@ -337,6 +337,9 @@
margin-left: 1rem; margin-left: 1rem;
box-shadow: 0px 0px 10px 1px #66666611 inset; box-shadow: 0px 0px 10px 1px #66666611 inset;
background: #66666611; background: #66666611;
padding: 1rem;
box-sizing: border-box;
overflow: auto;
} }
// 右部属性区 // 右部属性区

@ -22,6 +22,10 @@ export default defineConfig({
// ws: true, // 是否代理websockets // ws: true, // 是否代理websockets
// rewrite target目标地址 + '/abc',如果接口是这样的,那么不用重写 // rewrite target目标地址 + '/abc',如果接口是这样的,那么不用重写
rewrite: (path) => path.replace(/^\/api/, '') // 路径重写,本项目不需要重写 rewrite: (path) => path.replace(/^\/api/, '') // 路径重写,本项目不需要重写
},
'/ossStatic':{
target: 'http://localhost:3000', // 代理的目标地址
changeOrigin: true, // 开发模式,默认的origin是真实的 origin:localhost:3000 代理服务会把origin修改为目标地址
} }
} }
}, },

Loading…
Cancel
Save