import React, { useState, useEffect, useMemo, useCallback, useRef, useContext } from 'react'; import { Result, Tabs, Modal, Menu } from 'antd'; import { PieChartOutlined, PlayCircleOutlined, HighlightOutlined, DoubleRightOutlined, DoubleLeftOutlined, } from '@ant-design/icons'; import { connect } from 'dva'; import HeaderComponent from './components/Header'; import CanvasControl from './components/CanvasControl'; import SourceBox from './SourceBox'; import TargetBox from './TargetBox'; import Calibration from '../../components/Calibration'; import DynamicEngine, { componentsType } from 'editorCore/DynamicEngine'; import FormRender from 'editorCore/FormRender'; import template from '../../components/BasicShop/BasicComponents/template'; import basictemplate from '../../components/BasicPcShop/BasicComponents/template'; import mediaTpl from '../../components/BasicShop/MediaComponents/template'; import basicmediaTpl from '../../components/BasicPcShop/MediaComponents/template'; import graphTpl from '../../components/BasicShop/VisualComponents/template'; import schemaH5 from '../../components/BasicShop/schema'; import schema from '../../components/BasicPcShop/schema'; import { ActionCreators, StateWithHistory } from 'redux-undo'; import { throttle } from 'editorUtils/tool'; import styles from './index.less'; import { createHtml, nodeToString } from '../../utils/tool'; import { dooringContext } from '../../layouts'; import SourcePcBox from './SourcePcBox'; import _ from 'lodash'; import SubMenu from 'antd/lib/menu/SubMenu'; import styled from 'styled-components'; const { TabPane } = Tabs; const MARKETING_COMPONENTS_WX = [ 'MarketingMix', 'Crowdfunding', 'PreSale', 'GroupBuying', 'GoldCoinPurchase', 'ProductFlashSale', 'ComboFlashSale', ]; const Container = (props: { history?: any; location?: any; pstate?: any; cstate?: any; dispatch?: any; }) => { const [scaleNum, setScale] = useState(1); const [collapsed, setCollapsed] = useState(false); const [rightColla, setRightColla] = useState(true); const { pstate, cstate, dispatch } = props; const pointData = pstate?.pointData ? pstate?.pointData : []; const cpointData = cstate?.pointData ? cstate?.pointData : []; const changeCollapse = useMemo(() => { return (c: boolean) => { setCollapsed(c); }; }, []); const changeRightColla = useMemo(() => { return (c: boolean) => { setRightColla(c); }; }, []); const curPoint = pstate?.curPoint ? pstate?.curPoint : {}; // 指定画布的id let canvasId = 'js_canvas'; const backSize = () => { setScale(1); setDragState({ x: 0, y: 0 }); }; const CpIcon = { base: , media: , visible: , }; const generateHeader = useMemo(() => { return (type: componentsType, text: string) => { return (
{CpIcon[type]} {text}
); }; }, [CpIcon]); const handleSlider = useMemo(() => { return (type: any) => { if (type) { setScale((prev: number) => +(prev + 0.1).toFixed(1)); } else { setScale((prev: number) => +(prev - 0.1).toFixed(1)); } }; }, []); const handleFormSave = useMemo(() => { return (data: any) => { console.log(data, '!!!!'); dispatch({ type: 'editorModal/modPointData', payload: { ...curPoint, item: { ...curPoint.item, config: data } }, }); }; }, [curPoint, dispatch]); const clearData = useCallback(() => { dispatch({ type: 'editorModal/clearAll' }); }, [dispatch]); const handleDel = useMemo(() => { return (id: any) => { dispatch({ type: 'editorModal/delPointData', payload: { id }, }); }; }, [dispatch]); const redohandler = useMemo(() => { return () => { dispatch(ActionCreators.redo()); }; }, [dispatch]); const undohandler = useMemo(() => { return () => { if (curPoint) { dispatch(ActionCreators.undo()); } }; }, [dispatch, pointData, curPoint]); const importTpl = (data: any) => { dispatch({ type: 'editorModal/importTplData', payload: data, }); }; useEffect(() => { if (pstate?.curPoint && pstate?.curPoint.status === 'inToCanvas') { setRightColla(false); } }, [pstate?.curPoint]); const allType = useMemo(() => { let arr: string[] = []; template.forEach((v) => { arr.push(v.type); }); basictemplate.forEach((v) => { arr.push(v.type); }); mediaTpl.forEach((v) => { arr.push(v.type); }); basicmediaTpl.forEach((v) => { arr.push(v.type); }); graphTpl.forEach((v) => { arr.push(v.type); }); return arr; }, [graphTpl, mediaTpl, template, basictemplate, basicmediaTpl]); const [dragstate, setDragState] = useState({ x: 0, y: 0 }); const ref = useRef(null); const renderRight = useMemo(() => { const displayName = template.find((item) => item.type === curPoint?.item?.type)?.displayName || ''; return (
{pointData.length && curPoint?.id ? ( <>
{displayName}
) : (
)}
); }, [cpointData.length, curPoint, handleDel, handleFormSave, pointData.length, rightColla]); const containerRef = useRef(null); const [diffmove, setDiffMove] = useState({ start: { x: 0, y: 0 }, move: false, }); const mousedownfn = useMemo(() => { return (e: React.MouseEvent) => { if (e.target === containerRef.current) { setDiffMove({ start: { x: e.clientX, y: e.clientY, }, move: true, }); } }; }, []); const mousemovefn = useMemo(() => { return (e: React.MouseEvent) => { if (diffmove.move) { let diffx: number; let diffy: number; const newX = e.clientX; const newY = e.clientY; diffx = newX - diffmove.start.x; diffy = newY - diffmove.start.y; setDiffMove({ start: { x: newX, y: newY, }, move: true, }); setDragState((prev) => { return { x: prev.x + diffx, y: prev.y + diffy, }; }); } }; }, [diffmove.move, diffmove.start.x, diffmove.start.y]); const mouseupfn = useMemo(() => { return () => { setDiffMove({ start: { x: 0, y: 0 }, move: false, }); }; }, []); const onwheelFn = useMemo(() => { return (e: React.WheelEvent) => { if (e.deltaY < 0) { setDragState((prev) => ({ x: prev.x, y: prev.y + 40 > 0 ? 0 : prev.y + 40, })); } else { setDragState((prev) => ({ x: prev.x, y: prev.y - 40, })); } }; }, []); useEffect(() => { if (diffmove.move && containerRef.current) { containerRef.current.style.cursor = 'move'; } else { containerRef.current!.style.cursor = 'default'; } }, [diffmove.move]); const { setTheme, theme } = useContext(dooringContext); const savePage = () => { // if (pstate?.isNewPage) { const node = document.getElementById(canvasId); const bodyHtml = nodeToString(node, theme === 'h5' ? 'wapContainer' : 'pcContainer'); const pageConfigInfo = pstate?.pageConfig; const html = createHtml(bodyHtml, pageConfigInfo, theme === 'h5' ? 'wap' : 'pc'); const _pointData = _.cloneDeep(pointData); _pointData.forEach((element) => { const translates = document.defaultView.getComputedStyle( document.getElementById(element?.id), null, ).transform; const translateData: any[] = translates.substring(7, translates.length - 1).split(','); element.translateSortX = translateData[4] / 1; element.translateSortY = translateData[5] / 1; }); _pointData.sort( (a, b) => a.translateSortY - b.translateSortY || a.translateSortX - b.translateSortX, ); _pointData.forEach((element) => { element.point = { ...element.point, y: element.translateSortY / 2, }; console.log(element.point.y, element, '当前数据'); }); dispatch({ type: 'editorModal/savePage', payload: { client: mode ==='miniApp' ? 'wx_lite' : (theme === 'h5' ? 'wap' : 'pc'), content: html, html_param: JSON.stringify({ pointData: _pointData, pageConfig: pstate?.pageConfig, }), id: pstate?.pageId, param: { online_consult: pageConfigInfo?.online_consult, sub_status: pageConfigInfo?.sub_status, }, sub_status: pageConfigInfo?.sub_status, type: 2, }, }); // } else { // const pageConfigInfo = pstate?.pageConfig; // dispatch({ // type: 'editorModal/savePage', // payload: { // client: theme === 'h5' ? 'wap' : 'pc', // id: pstate?.pageId, // param: { // online_consult: pageConfigInfo?.online_consult, // sub_status: pageConfigInfo?.sub_status // }, // sub_status: pageConfigInfo?.sub_status, // type: 2 // } // }); // } }; const delPage = () => { Modal.confirm({ width: 600, title: '删除', content: '是否要删除?', cancelText: '取消', okText: '确认', onOk: () => { dispatch({ type: 'editorModal/delPage', payload: { type: mode ==='miniApp' ? 'wx_lite' : (theme === 'h5' ? 'wap' : 'pc'), id: pstate?.pageId, }, }); }, onCancel() { console.log('Cancel'); }, }); }; const { mode = 'wap' } = props.history.location.query || {}; console.log('template', template); const eleComponentsListBasicTemplate = ( {basictemplate.map((value, i) => { return ( ); })} ); const eleComponentsList = ( {template .filter((item) => item.mode === mode) .filter((item) => !MARKETING_COMPONENTS_WX.includes(item.type)) .map((value, i) => { return ( ); })} ); const eleComponentsListMarketing = ( {template .filter((item) => item.mode === mode) .filter((item) => MARKETING_COMPONENTS_WX.includes(item.type)) .map((value, i) => { return ( ); })} ); const menuEle = ( {theme === 'h5' && eleComponentsList} {theme !== 'h5' && eleComponentsListBasicTemplate} {mode === 'miniApp' && ( {theme === 'h5' && eleComponentsListMarketing} )} ); return (
changeCollapse(false)} defaultActiveKey="1" tabPosition={'left'} > {menuEle}
changeCollapse(!collapsed)} > {collapsed ? : }
{theme === 'h5' ? ( ) : ( )}
{renderRight}
changeRightColla(!rightColla)} > {!rightColla ? : }
); }; export default connect((state: StateWithHistory) => { return { pstate: state.editorModal, cstate: state.editorPcModal }; })(Container); const ComponentListBox = styled.div` overflow: auto; display: flex; flex-direction: row; flex-wrap: wrap; `;