parent
e73d3deb7f
commit
19ea528307
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{ |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue