1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080 |
- import { Button, Col, Drawer, Form, Input, InputNumber, message, Modal, Radio, Row, Select, Slider, Space, Spin, Switch, Tooltip } from 'antd'
- import React, { useCallback, useEffect, useMemo, useState } from "react"
- import modal from "antd/lib/modal"
- import style from './index.less'
- import './index1.less'
- import { ReactComponent as Topimg } from '@/assets/topimg.svg'
- import { ReactComponent as Topslider } from '@/assets/topslider.svg'
- import { ReactComponent as Topvideo } from '@/assets/topvideo.svg'
- import { ReactComponent as Img } from '@/assets/img.svg'
- import { ReactComponent as MyText } from '@/assets/text.svg'
- import { ReactComponent as TopNullBack } from '@/assets/topNullBack.svg'
- import { ReactComponent as FollowAcc } from '@/assets/followAcc.svg'
- import { ReactComponent as EditSvg } from '@/assets/edit.svg'
- import { ReactComponent as SliderImgSvg } from '@/assets/sliderImgSvg.svg'
- import { ReactComponent as JumpLink } from '@/assets/jumpLink.svg'
- import { ReactComponent as ImgText } from '@/assets/imgText.svg'
- import { ReactComponent as FloatbuttonSvg } from '@/assets/floatbuttonSvg.svg'
- import { ReactComponent as WxAutoSvg } from '@/assets/wxAutoSvg.svg'
- import { AlignCenterOutlined, AlignLeftOutlined, AlignRightOutlined, DeleteOutlined, PlusOutlined, QuestionCircleOutlined, RetweetOutlined, SwapLeftOutlined, SwapRightOutlined } from '@ant-design/icons'
- import { useDrop, useDrag } from 'ahooks'
- import arrayMove from "array-move";
- import ColorPicker from '@/components/ColorPicker1'
- import TextArea from 'antd/lib/input/TextArea'
- import moment from 'moment'
- import { TopImg, TopVideo, Text, Img as ImgProps, GhButton, TopSlider, Floatbutton, ImageTextItem, ITItemGhSpec } from '../../req'
- import { imgContent, txtContent, ghContent, topvideoNewContent, topsliderContent, topimgContent, wxAutoContent, floatbuttonContent, floatbuttonBtTypeWxAuto, floatbuttonBtTypeGh, imageTextGh, ghITItemContent, wxAutoITItemContent, imageTextItem } from './content'
- import { landingPageReducer, Content, Props } from './landingPageReducer'
- import {
- SortableList,
- SortableItemText,
- SortableItemImg,
- SortableItemFollowAcc,
- SortableItemImgText,
- SortableUlList,
- SortableItemNoLi,
- SortableItemLi,
- SortableItemJumpLink,
- SortableItemWxAuto,
- SortableItemFloatbutton
- } from './sortable'
- import { useModel } from 'umi'
- import SelectCloud from '../selectCloud'
- import { getTypeKey, replaceSpecialTxt, txtLength } from '@/utils/utils'
- const { Option } = Select;
- function AddLandingPage(props: Props) {
- let { visible, hideModal, ajax, id } = props
- const { state, stateGlobal, dispatch, dispatchGlobal } = landingPageReducer()
- const { content, pageBackColor } = state
- const { componentItem } = stateGlobal
- const { currentUser }: any = useModel('@@initialState', model => ({ currentUser: model.initialState?.currentUser }))
- const { init, add, get } = useModel('useLaunchAdq.useBdMediaPup')
- const { state: { parentId, belongUser } } = useModel('useLaunchAdq.useBdMedia')
- /** 变量开始 */
- const [selectImgVisible, setSelectImgVisible] = useState<boolean>(false) // 选择图片弹窗
- const [lastVisible, setLastVisible] = useState<boolean>(false) // 最后保存设置
- const [shareTittle, setShareTittle] = useState<string>('') // 分享标题
- const [shareDesc, setShareDesc] = useState<string>('') // 分享描述
- const [pageName, setPageName] = useState<string>('') // 落地页名称
- const [sort, setSort] = useState<number>(0) // 排序
- const [scType, setCcType] = useState<1 | 2 | 3 | 4 | 5>(1) // 视频 单图片 多图片处理
- const [sliderImgContent, setSliderImgContent] = useState<{ url: string, width?: number, height?: number }[]>([]) // 保存回填数据
- const [imgTextButtonShow, setImgTextButtonShow] = useState<boolean>(false)
- const [goodsCount, setGoodsCount] = useState<number>(0)
- /** 变量结束 */
- console.log('content---->', content)
- // 回填
- useEffect(() => {
- if (id) {
- get.run({ sysMediaId: id, mediaType: 'PAGE' }).then(res => {
- if (res) {
- const { pageSpecsList, shareContentSpec, globalSpec } = res
- dispatch({ type: 'setPageBackColor', params: { pageBackColor: pageSpecsList[0]?.bgColor } })
- let pageElementsSpecList = pageSpecsList[0]?.pageElementsSpecList
- dispatch({
- type: 'setCon', params: {
- content: pageElementsSpecList?.map((item: any) => {
- let typeKey = getTypeKey(item?.elementType)
- if (typeKey) {
- let data = item[typeKey] || {}
- if (item?.elementType === "IMAGE_TEXT" && data?.imageTextItem) {
- data.imageTextItem = data.imageTextItem?.map((item: any) => {
- if (item?.subElemType === 'GH') {
- let { ghSpec, ...GHData } = item
- return { ...GHData, content: { ...ghSpec } }
- } else {
- let { enterpriseWxSpec, ...EnterpriseWxData } = item
- return { ...EnterpriseWxData, content: { ...enterpriseWxSpec } }
- }
- })
- }
- return {
- elementType: item?.elementType,
- ...data
- }
- }
- return item
- })
- }
- })
- setShareDesc(() => shareContentSpec?.shareTitle || '')
- setShareTittle(() => shareContentSpec?.shareDescription || '')
- if (globalSpec && Object.keys(globalSpec).length > 0) {
- let globalElementsSpecList = globalSpec.globalElementsSpecList
- let newComponentItem = globalElementsSpecList?.map((item: { elementType: string }) => {
- let typeKey = getTypeKey(item.elementType)
- let { elementType, ...data } = item[typeKey]
- let typeKey1 = getTypeKey(elementType)
- let componentItem: any = data[typeKey1]
- if (componentItem) {
- componentItem['elementType'] = elementType
- }
- data.componentItem = componentItem
- data.elementType = item.elementType
- delete data[typeKey1]
- return data
- })
- dispatchGlobal({ type: "setConItem", params: { componentItem: newComponentItem || [] } })
- }
- }
- })
- } else {
- // dispatch({ type: 'init', params: { elementType: 'empty' } })
- }
- }, [id])
- const config = {
- title: '警告!',
- cancelText: '取消',
- okText: '确定',
- onOk: () => { hideModal() },
- content: (
- <>
- <div>不会保存您所做的更改,确定关闭?</div>
- </>
- ),
- };
- /** 获取选中内容对应图片视频尺寸大小 */
- useEffect(() => {
- let selectData = content?.find((item: Content) => item.comptActive)
- if (!selectData) {
- selectData = componentItem?.find((item: { comptActive: boolean }) => item.comptActive)
- }
- if (selectData?.elementType === "TOP_IMAGE") {
- if (selectData?.adLocation === 'sns') { // 朋友圈信息流
- if (selectData?.outerStyle === 0) { // 常规广告
- init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 800, height: 800 }]], maxSize: 300 * 1024 })
- } else { // 卡片广告
- init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 800, height: 450 }]], maxSize: 300 * 1024 })
- }
- } else { // 公众号及其他
- init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 800, height: 800 }], [{ relation: '=', width: 800, height: 450 }], [{ relation: '=', width: 800, height: 640 }], [{ relation: '=', width: 640, height: 800 }]], maxSize: 300 * 1024 })
- }
- } else if (selectData?.elementType === 'IMAGE') { // 内容图片
- init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 750, height: null }, { relation: '<=', width: null, height: 1536 }]], maxSize: 300 * 1024 })
- } else if (selectData?.elementType === 'TOP_SLIDER') { // 轮播图
- init({ mediaType: 'IMG', num: selectData?.imageUrlList?.length || 3, cloudSize: [[{ relation: '=', width: 800, height: 800 }]], maxSize: 300 * 1024 })
- } else if (selectData?.elementType === 'TOP_VIDEO') { // 视频
- if (selectData?.adLocation === 'sns') { // 朋友圈信息流
- if (selectData?.outerStyle === 0) { // 常规广告
- init({ mediaType: 'VIDEO', cloudSize: [[{ relation: '=', width: 640, height: 480 }], [{ relation: '=', width: 640, height: 360 }], [{ relation: '=', width: 750, height: 1334 }], [{ relation: '=', width: 720, height: 1280 }]], maxSize: 20 * 1024 * 1024 })
- } else { // 卡片广告
- init({ mediaType: 'VIDEO', cloudSize: [[{ relation: '=', width: 750, height: null }, { relation: '<=', width: null, height: 1536 }]], maxSize: 20 * 1024 * 1024 })
- }
- } else { // 公众号及其它
- init({ mediaType: 'VIDEO', cloudSize: [[{ relation: '=', width: 750, height: null }, { relation: '<=', width: null, height: 1536 }]], maxSize: 20 * 1024 * 1024 })
- }
- } else if (selectData?.elementType === 'IMAGE_TEXT') { // 图文复合组件 1个
- if (selectData?.imageTextItem?.length === 1) {
- init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 360, height: 360 }]], maxSize: 300 * 1024 })
- } else if (selectData?.imageTextItem?.length === 2) {
- init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 480, height: 480 }]], maxSize: 300 * 1024 })
- }
- } else if (selectData?.elementType === 'FLOAT_BUTTON') {
- init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 96, height: 96 }]], maxSize: 300 * 1024 })
- }
- }, [content])
- const [dragging, setDragging] = useState<string | null>(null);
- const getDragProps = useDrag({
- onDragStart: (data) => {
- setDragging(data);
- },
- onDragEnd: () => {
- setDragging(null);
- },
- });
- // 头部内容拖到接收区
- const [dropProps] = useDrop({
- onDom: (con: string, e) => { // 头部
- let newCon = content?.map((item: TopImg | TopVideo | TopSlider) => {
- return { ...item, comptActive: false }
- })
- let topCon = newCon[0]
- topCon.type = con
- topCon.comptActive = true
- let conContent: TopImg | TopVideo | TopSlider
- if (con === 'TOP_SLIDER') {
- conContent = { ...topsliderContent, comptActive: true } as TopSlider
- } else if (con === 'TOP_IMAGE') {
- conContent = { ...topimgContent, comptActive: true } as TopImg
- } else if (con === 'TOP_VIDEO') {
- conContent = { ...topvideoNewContent, comptActive: true } as TopVideo
- } else {
- return
- }
- topCon = { ...conContent }
- newCon[0] = topCon
- dispatch({ type: 'setCon', params: { content: newCon } })
- },
- });
- const [draggingCon, setDraggingCon] = useState<string | null>(null);
- const getDragPropsCon = useDrag({
- onDragStart: (data) => {
- setDraggingCon(data);
- },
- onDragEnd: () => {
- setDraggingCon(null);
- },
- });
- // 内容拖到接收区
- const [dropConProps, { isHovering: isHoveringCon }] = useDrop({
- onDom: (con: string, e) => { // 内容
- let newCon: Content[] = content?.map((item: Text | ImgProps | GhButton) => { // | LinkButton | WxAutoButton
- return { ...item, comptActive: false }
- })
- let newConItem = componentItem?.map((item: Floatbutton) => {
- return { ...item, comptActive: false }
- })
- if (con === 'TEXT') {
- newCon.push({ ...txtContent, comptActive: true } as any)
- } else if (con === 'IMAGE') {
- newCon.push({ ...imgContent, comptActive: true } as any)
- } else if (con === 'GH') {
- newCon.push({ ...ghContent, comptActive: true } as any)
- // } else if (con === 'JumpLink') {
- // newCon.push({ ...linkContent, comptActive: true } as any)
- } else if (con === 'IMAGE_TEXT') {
- newCon.push({ ...imageTextGh, comptActive: true } as any)
- } else if (con === 'ENTERPRISE_WX') {
- newCon.push({ ...wxAutoContent, comptActive: true } as any)
- } else if (con === 'FLOAT_BUTTON') {
- newConItem.push({ ...floatbuttonContent, comptActive: true })
- setDraggingCon(null);
- } else {
- return
- }
- dispatch({ type: 'setCon', params: { content: newCon } })
- dispatchGlobal({ type: "setConItem", params: { componentItem: newConItem } })
- },
- });
- /** 选中设置 */
- const installActive = useCallback((e, index: number) => {
- e.stopPropagation(); e.preventDefault();
- let newCon = content?.map((item: any) => {
- return { ...item, comptActive: false }
- })
- let newConItem = componentItem?.map((item: { elementType: string }) => {
- return { ...item, comptActive: false }
- })
- setImgTextButtonShow(false)
- if (index === 99999) {
- newConItem = newConItem?.map((item: { elementType: string }) => {
- if (item.elementType === 'FLOAT_BUTTON') {
- return { ...item, comptActive: true }
- }
- return item
- })
- } else {
- newCon[index].comptActive = true
- }
- dispatch({ type: 'setCon', params: { content: newCon } })
- dispatchGlobal({ type: "setConItem", params: { componentItem: newConItem } })
- }, [content, imgTextButtonShow, componentItem])
- /** 清除选中 */
- const installActiveNull = useCallback((e) => {
- e.stopPropagation(); e.preventDefault();
- let newCon = content?.map((item: any) => {
- return { ...item, comptActive: false }
- })
- setImgTextButtonShow(false)
- dispatch({ type: 'setCon', params: { content: newCon } })
- let newConItem = componentItem?.map((item: { widgetTypeV2: string }) => {
- return { ...item, comptActive: false }
- })
- dispatchGlobal({ type: "setConItem", params: { componentItem: newConItem } })
- }, [content])
- /** 内容功能按钮区 */
- const handleBtn = useCallback((type: string, index: number) => {
- let newContent = JSON.parse(JSON.stringify(content))
- switch (type) {
- case 'lower': // 下移动
- dispatch({ type: 'setCon', params: { content: arrayMove(content, index, index + 1) } })
- break;
- case 'upper': // 上移动
- dispatch({ type: 'setCon', params: { content: arrayMove(content, index, index - 1) } })
- break;
- case 'IMAGE': // 图片
- newContent.splice(index, 0, { ...imgContent });
- dispatch({ type: 'setCon', params: { content: newContent } })
- break;
- case 'TEXT': // 文本
- newContent.splice(index, 0, { ...txtContent });
- dispatch({ type: 'setCon', params: { content: newContent } })
- break;
- case 'GH': // 关注公众号按钮
- newContent.splice(index, 0, { ...ghContent });
- dispatch({ type: 'setCon', params: { content: newContent } })
- break;
- // case 'link': // 跳转链接按钮
- // newContent.splice(index, 0, { ...linkContent });
- // dispatch({ type: 'setCon', params: { content: newContent } })
- // break;
- case 'IMAGE_TEXT': // 图文复合组件
- newContent.splice(index, 0, JSON.parse(JSON.stringify(imageTextGh)));
- dispatch({ type: 'setCon', params: { content: newContent } })
- break;
- case 'ENTERPRISE_WX': // 图文复合组件
- newContent.splice(index, 0, { ...wxAutoContent });
- dispatch({ type: 'setCon', params: { content: newContent } })
- break;
- }
- }, [content])
- /** 头部删除 */
- const topDelType = useCallback(() => {
- setDragging(null);
- content[0] = {
- elementType: 'empty',
- comptActive: false
- }
- dispatch({ type: 'setCon', params: { content } })
- }, [content, dragging])
- /** 内容删除 */
- const delType = useCallback((e, index: number) => {
- e.stopPropagation(); e.preventDefault();
- setImgTextButtonShow(false)
- if (index === 99999) { // 删除悬浮组件
- let newContentItem = JSON.parse(JSON.stringify(componentItem))
- newContentItem = newContentItem?.filter((item: { elementType: string }) => item.elementType !== 'FLOAT_BUTTON')
- dispatchGlobal({ type: 'setConItem', params: { componentItem: JSON.parse(JSON.stringify(newContentItem)) } })
- } else {
- let newContent = JSON.parse(JSON.stringify(content))
- newContent?.splice(index, 1)
- dispatch({ type: 'setCon', params: { content: JSON.parse(JSON.stringify(newContent)) } })
- }
- }, [content, componentItem, imgTextButtonShow])
- const onSortEnd = ({ oldIndex, newIndex }: { oldIndex: number, newIndex: number }) => {
- dispatch({ type: 'setCon', params: { content: arrayMove(content, oldIndex, newIndex) } })
- }
- // 基础内容
- const comptCon = () => {
- if (content?.length === 0) {
- return null
- } else {
- return <SortableList axis='y' onSortEnd={onSortEnd} useDragHandle isFloatButton={componentItem?.some((item: { elementType: string }) => item.elementType === 'FLOAT_BUTTON')}>
- {content.map((value: Text | ImgProps | GhButton, index: number) => {
- if (value?.elementType === 'IMAGE') {
- return <SortableItemImg key={`item-${value.elementType}-${index}`} index={index} data={{ length: content?.length, index }} item={value} click={(e: any) => { installActive(e, index) }} del={(e: any) => { delType(e, index) }} upload={(num: number) => { clickUpdateImg(num) }} handleBtn={handleBtn} />
- } else if (value?.elementType === 'TEXT') {
- return <SortableItemText key={`item-${value.elementType}-${index}`} index={index} data={{ length: content?.length, index }} item={value} click={(e: any) => { installActive(e, index) }} del={(e: any) => { delType(e, index) }} pageBackColor={pageBackColor} handleBtn={handleBtn} />
- } else if (value?.elementType === 'GH') {
- return <SortableItemFollowAcc key={`item-${value.elementType}-${index}`} index={index} data={{ length: content?.length, index }} item={value} click={(e: any) => { installActive(e, index) }} del={(e: any) => { delType(e, index) }} handleBtn={handleBtn} />
- } else if (value?.elementType === 'ENTERPRISE_WX') {
- return <SortableItemWxAuto key={`item-${value.elementType}-${index}`} index={index} data={{ length: content?.length, index }} item={value} click={(e: any) => { installActive(e, index) }} del={(e: any) => { delType(e, index) }} handleBtn={handleBtn} />
- // } else if (value?.elementType === 'link') {
- // return <SortableItemJumpLink key={`item-${value.elementType}-${index}`} index={index} data={{ length: content?.length, index }} item={value} click={(e: any) => { installActive(e, index) }} del={(e: any) => { delType(e, index) }} handleBtn={handleBtn} />
- } else if (value?.elementType === 'IMAGE_TEXT') {
- return <SortableItemImgText key={`item-${value.elementType}-${index}`} index={index} data={{ length: content?.length, index }} item={value} click={(e: any) => { installActive(e, index) }} del={(e: any) => { delType(e, index) }} handleBtn={handleBtn} />
- } else {
- return null
- }
- })}
- <div className={`comptCon ${isHoveringCon && 'hovering'} ${draggingCon && 'draggingCon'}`} {...dropConProps}>{(isHoveringCon || draggingCon) && '请拖至此处'}</div>
- {componentItem?.some((item: { elementType: string }) => item.elementType === 'FLOAT_BUTTON') && <SortableItemFloatbutton index={99999} item={componentItem.find((item: { elementType: string }) => item.elementType === 'FLOAT_BUTTON')} click={(e: any) => { installActive(e, 99999) }} del={(e: any) => { delType(e, 99999) }} />}
- </SortableList>
- }
- }
- /** 设置start */
- const setCon = useCallback((key: string, value: any) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- selectCon[key] = value
- if (selectCon?.elementType === 'TOP_VIDEO' && (key === 'adLocation' || key === 'outerStyle')) {
- selectCon['videoUrl'] = ''
- }
- let newSelectCon = { ...selectCon }
- oldContent[selectIndex] = newSelectCon
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }, [content, goodsCount])
- /** 设置end */
- // 顶部组件
- const topCon = useMemo(() => {
- let { imageUrl, elementType, activeIndex, imageUrlList, videoUrl } = content[0]
- return <>
- {
- elementType === 'TOP_IMAGE' ? <>
- <div className={`compt componentType41 ${content[0]?.comptActive && 'comptActive'}`} onClick={(e) => { installActive(e, 0) }}>
- <div className={'componentWrap'}>
- <div className={'componentContent'}>
- {imageUrl ? <img src={imageUrl} style={{ display: 'block', width: '100%', margin: 0 }} /> : <div className={'default'} style={{ width: 375, height: 300, margin: 0 }}>
- <div className={'defaultIcon'} style={{ marginTop: 80 }}>
- <Topimg />
- </div>
- </div>}
- </div>
- </div>
- {!imageUrl && <div className={'comptUpload'} style={{ margin: 0 }}>
- <button style={{ marginTop: 150 }} className={'comptEditButton'} onClick={() => { clickUpdateImg(1) }}>上传图片</button>
- </div>}
- <section className={'comptEditBtns'}>
- <div className={'comptEditBtnsInner'}>
- {imageUrl && <button onClick={() => { editSelectImg(imageUrl) }}><EditSvg /></button>}
- <button onClick={topDelType}><DeleteOutlined /></button>
- </div>
- </section>
- </div>
- </> :
- elementType === 'TOP_SLIDER' ? <>
- <div className={`compt componentType101 ${content[0]?.comptActive && 'comptActive'}`} onClick={(e) => { installActive(e, 0) }}>
- <div className={'componentWrap'}>
- <div className={'componentContent'}>
- {imageUrlList?.length > 0 ? <div style={{ position: 'relative', width: 375, height: 375 }}>
- {imageUrlList?.map((imgUrl: any, index: number) => {
- if (imgUrl) {
- return <img src={imgUrl} key={index} style={{ maxWidth: '100%', position: 'absolute', display: 'block', zIndex: activeIndex === index ? 1 : 0 }} />
- } else {
- return <div className="default" key={index} style={{ width: 375, zIndex: activeIndex === index ? 1 : 0, height: '100%', position: 'absolute', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
- <div className="defaultIcon">
- <SliderImgSvg />
- </div>
- </div>
- }
- })}
- <div className={'sliderD'}>
- {imageUrlList.map((item: any, index: number) => <i key={index} style={activeIndex === index ? { backgroundColor: 'rgba(0, 0, 0, .4)' } : {}}></i>)}
- </div>
- </div> : <div style={{ position: 'relative', height: 222, width: 375 }} className={'sliderCon'}>
- <div className={'default'}>
- <div className={'defaultIcon'}>
- <Topslider />
- </div>
- </div>
- <div className={'sliderD'}>
- {imageUrlList.fill('').map((item: any, index: number) => <i key={index} style={activeIndex === index ? { backgroundColor: 'rgba(0, 0, 0, .4)' } : {}}></i>)}
- </div>
- </div>}
- </div>
- </div>
- <section className={'comptEditBtns'}>
- <div className={'comptEditBtnsInner'}>
- <button onClick={topDelType}><DeleteOutlined /></button>
- </div>
- </section>
- </div>
- </> :
- elementType === 'TOP_VIDEO' ? <>
- <div className={`compt componentType61 ${content[0]?.comptActive && 'comptActive'}`} onClick={(e) => { installActive(e, 0) }}>
- <div className={'componentWrap'}>
- <div className={'componentContent'}>
- {
- videoUrl ? <div className="videoPlay">
- <video src={videoUrl} style={{ display: 'block', width: '100%', margin: 0 }} />
- <span></span>
- </div>
- : <div className={'default'} style={{ width: 375, height: 300, margin: 0 }}>
- <div className={'defaultIcon'} style={{ marginTop: 80 }}>
- <Topvideo />
- </div>
- </div>
- }
- </div>
- </div>
- {!videoUrl && <div className={'comptUpload'} style={{ margin: 0 }}>
- <button style={{ marginTop: 150 }} className={'comptEditButton'} onClick={() => { clickUpdateVideo() }}>上传视频</button>
- </div>}
- <section className={'comptEditBtns'}>
- <div className={'comptEditBtnsInner'}>
- {videoUrl && <button onClick={() => { clickUpdateVideo() }}><EditSvg /></button>}
- <button onClick={topDelType}><DeleteOutlined /></button>
- </div>
- </section>
- </div>
- </> :
- <div className={`compt topComptArea ${dragging ? 'dragging' : ''}`} {...dropProps}>
- <TopNullBack />
- {dragging ? <div className="topAreaTitle" style={{ marginTop: 30 }}>
- 拖至此处
- </div> : <>
- <p className={'topAreaTitle'}>顶部组件区</p>
- <div className={'desc'}>在左上方,选择顶部组件添加到此处</div>
- </>}
- </div>
- }
- </>
- }, [content, state, dragging])
- /** 图标开启与关闭 */
- const iconHandle = (e: boolean) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- selectCon['useIcon'] = e ? 1 : 0
- oldContent[selectIndex] = selectCon
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }
- /** 视频切换广告位 */
- const changeAdLocation = (value: 'sns' | 'gh') => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- selectCon['adLocation'] = value
- if (value === 'gh') {
- selectCon['styleType'] = 1
- } else {
- selectCon['styleType'] = 0
- }
- selectCon['videoUrl'] = ''
- oldContent[selectIndex] = selectCon
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }
- /** 视频切换外层样式 */
- const changeOuterLayout = (value: string) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- selectCon['viewType'] = value
- let newSelectCon: any
- if (value === '0') {
- let { outerUseTopMaterial, streamDisplayWidth, streamDisplayHeight, streamVideoThumb, streamVideoUrl, streamDisplayType, streamThumbMd5, streamVideoMd5, displayType, ...clearSelectCon } = selectCon
- newSelectCon = {
- ...clearSelectCon
- }
- } else {
- newSelectCon = {
- ...selectCon,
- outerUseTopMaterial: '0',
- styleType: '0'
- }
- }
- oldContent[selectIndex] = newSelectCon
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }
- /** 轮播图选择点击切换图片 多张图片 */
- const sliderSelect = (index: number, count: number) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- if (selectIndex !== -1) {
- let selectCon = newContent[selectIndex]
- let imgList: any[] = []
- selectCon?.imageUrlList?.forEach((item: string) => {
- if (item) {
- imgList.push({ url: item })
- }
- })
- setSliderImgContent(imgList)
- }
- setCon('activeIndex', index)
- setCcType(3)
- setSelectImgVisible(true)
- }
- /** 轮播图图片数量设置 */
- const sliderImgNum = useCallback((num: string) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- let { imageUrlList } = selectCon
- if (imageUrlList?.length > Number(num)) { // 减少
- selectCon['imageUrlList'] = [...imageUrlList?.splice(0, Number(num))]
- } else { // 增加
- let newGroup = Array(Number(num) - imageUrlList?.length).fill('').map(() => "")
- imageUrlList = [...imageUrlList, ...newGroup]
- selectCon['imageUrlList'] = imageUrlList
- }
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }, [content])
- /** 轮播图位置拖动切换顺序 */
- const onSortEndSlider = useCallback(({ oldIndex, newIndex }: { oldIndex: number, newIndex: number }) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- let { imageUrlList } = selectCon
- imageUrlList = arrayMove(imageUrlList, oldIndex, newIndex)
- selectCon['imageUrlList'] = imageUrlList
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }, [content])
- /** 图文单个设置 */
- const onShelfnewTxtCon = useCallback((value: string, parameter: string) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- let length = selectCon?.imageTextItem?.length || 0;
- if (length === 2) {
- let imageTextItem = selectCon?.imageTextItem[goodsCount]
- imageTextItem[parameter] = value
- } else if (length === 1) {
- let imageTextItem = selectCon?.imageTextItem[0]
- imageTextItem[parameter] = value
- }
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }, [content, goodsCount])
- // 设置图文跳转链接按钮
- const onSetShelfnewButton = useCallback((value: string) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- let length = selectCon?.imageTextItem?.length || 0;
- if (length === 2) {
- let imageTextItem = selectCon?.imageTextItem[goodsCount]
- imageTextItem.subElemType = value
- switch(value) {
- case 'GH':
- imageTextItem.content = JSON.parse(JSON.stringify(ghITItemContent))
- break;
- case 'ENTERPRISE_WX':
- imageTextItem.content = JSON.parse(JSON.stringify(wxAutoITItemContent))
- break
- }
- } else if (length === 1) {
- let imageTextItem = selectCon?.imageTextItem[0]
- imageTextItem.subElemType = value
- switch(value) {
- case 'GH':
- imageTextItem.content = JSON.parse(JSON.stringify(ghITItemContent))
- break;
- case 'ENTERPRISE_WX':
- imageTextItem.content = JSON.parse(JSON.stringify(wxAutoITItemContent))
- break
- }
- }
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }, [content, goodsCount])
- // 配置图文跳转链接按钮字段
- const onSetShelfnewButtonField = useCallback((field: string, value: string | number) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- let length = selectCon.imageTextItem.length
- if (length === 2) {
- let content = selectCon.imageTextItem[goodsCount].content
- content[field] = value
- } else if (length === 1) {
- let content = selectCon.imageTextItem[0].content
- content[field] = value
- }
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }, [content, goodsCount])
- // 设置图文复合组件类型
- const setShelfnewType = useCallback((value: string) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- if (selectIndex !== -1) {
- if (value === '2') {
- newContent[selectIndex].imageTextItem = [
- JSON.parse(JSON.stringify({
- ...imageTextItem,
- content: {
- ...ghITItemContent
- }
- })),
- JSON.parse(JSON.stringify({
- ...imageTextItem,
- content: {
- ...ghITItemContent
- }
- }))
- ]
- } else if (value === '1') {
- newContent[selectIndex].alignMode = 0
- let imageTextItem = newContent[selectIndex].imageTextItem
- let newImageTextItem = imageTextItem.splice(0, 1)
- newContent[selectIndex].imageTextItem = newImageTextItem
- }
- dispatch({ type: 'setCon', params: { content: [...newContent] } })
- }
- }, [content])
- // 设置悬浮弹窗
- const setGlobalComponentItem = (key: string, value: any, isDel = false) => {
- let newConItem = JSON.parse(JSON.stringify(componentItem))
- let selectIndex = newConItem?.findIndex((item: Content) => item.comptActive)
- let oldContent = newConItem
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- // 设置悬浮窗 转化按钮
- if (key === 'componentItem' && (value === 'GH' || value === 'ENTERPRISE_WX')) {
- if (value === 'GH') {
- selectCon[key] = floatbuttonBtTypeGh
- } else if (value === 'ENTERPRISE_WX') {
- selectCon[key] = floatbuttonBtTypeWxAuto
- }
- } else {
- if (!isDel) {
- selectCon[key] = value
- if (key === 'styleType') {
- if (value === 0) {
- selectCon['imageUrl'] = ""
- selectCon['desc'] = selectCon?.desc || ""
- } else if (value === 1) {
- delete selectCon['imageUrl']
- selectCon['desc'] = selectCon?.desc || ""
- } else if (value === 2) {
- delete selectCon['imageUrl']
- delete selectCon['desc']
- }
- selectCon[key] = value
- }
- } else {
- delete selectCon[key]
- }
- }
- dispatchGlobal({ type: 'setConItem', params: { componentItem: JSON.parse(JSON.stringify(oldContent)) } })
- }
- }
- // 选中设置
- const rightCon = () => {
- let selectCon = content?.find((item: Content) => item.comptActive)
- if (!selectCon) {
- selectCon = componentItem?.find((item: { comptActive: boolean }) => item.comptActive)
- }
- if (selectCon) {
- let { elementType, adLocation, outerStyle, imageUrlList, imageUrl, text, fontColor, fontSize, fontStyle, textAlignment,
- paddingTop, paddingBottom, fastFollow, btnTitle, btnFontType, btnBorderColorTheme, btnBgColorTheme, useIcon,
- styleType, imageTextItem, initHeight, alignMode, activeIndex, title, desc, titleColor, descColor, componentItem, appearType, disappearType } = selectCon
- let imgTextData: ImageTextItem = {
- borderColor: '#e5e5e5',
- titleColor: '#353535',
- descColor: '#b2b2b2',
- bgColor: '#ffffff',
- jumpMode: 'btn_jump',
- imageUrl: '',
- title: '',
- desc: '',
- subElemType: 'GH',
- content: {
- btnTitle: '关注公众号',
- fontColor: '#FFFFFF',
- btnBgColorTheme: '#07C160',
- btnBorderColorTheme: '#FFFFFF',
- btnFontType: 0,
- useIcon: 0,
- fastFollow: 1,
- paddingTop: 28,
- paddingBottom: 28,
- }
- }
- let imageTextItemIndex = 1;
- let custorGroup = []
- if (elementType === 'enterprise_wx_auto') {
- custorGroup = selectCon?.custorData || []
- } else if (elementType === 'IMAGE_TEXT') {
- imageTextItemIndex = imageTextItem?.length || 1
- if (imageTextItemIndex === 1) { // 图文复合组件 单个
- imgTextData = imageTextItem[0]
- } else if (imageTextItemIndex === 2) {
- imgTextData = imageTextItem[goodsCount]
- }
- }
- return <>
- {
- elementType === 'TOP_IMAGE' ? <div className="widget">
- <div className="caption section">
- <div className="caption-title">顶部组件:图片</div>
- </div>
- <div className="form section">
- <div className="form-caption">广告位与样式</div>
- <div className="adui-form-item">
- <div className="adui-form-label">广告位</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { setCon('adLocation', e.target.value) }} value={adLocation} size='small'>
- <Radio value='sns'>朋友圈信息流</Radio>
- <Radio value='gzh'>公众号及其他</Radio>
- </Radio.Group>
- </div>
- </div>
- {adLocation === 'sns' && <div className="adui-form-item">
- <div className="adui-form-label">外层样式</div>
- <div className="adui-form-control">
- <Select value={outerStyle} style={{ width: 100 }} onChange={(e) => { setCon('outerStyle', e) }}>
- <Option value={0}>常规广告</Option>
- <Option value={1}>卡片广告</Option>
- </Select>
- </div>
- </div>}
- </div>
- <div className="form section">
- <div className="form-caption">素材设置</div>
- <div className="adui-form-item" style={{ alignItems: 'flex-start' }}>
- <div className="adui-form-label">图片素材</div>
- <div className="adui-form-control">
- <div className={`upload-img-item ${imageUrl ? 'upload-img-item_uploaded' : ''}`}>
- {imageUrl ? <div className="upload-img-item-inner" style={{ backgroundImage: `url(${imageUrl})` }}>
- <div className='upload-img-item-action' onClick={() => { clickUpdateImg(1) }}>
- <RetweetOutlined />
- </div>
- </div> : <div className="upload-img-item-inner" onClick={() => { clickUpdateImg(1) }}>
- <PlusOutlined />
- </div>}
- </div>
- </div>
- </div>
- </div>
- </div>
- :
- elementType === 'TOP_SLIDER' ? <div className="widget">
- <div className="caption section">
- <div className="caption-title">顶部组件:轮播图</div>
- </div>
- <div className="form section">
- <div className="form-caption">素材设置</div>
- <div className="adui-form-item">
- <div className="adui-form-label">图片数量</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { sliderImgNum(e.target.value) }} value={imageUrlList?.length || 3} size='small'>
- <Radio.Button value={3}>3张</Radio.Button>
- <Radio.Button value={4}>4张</Radio.Button>
- <Radio.Button value={6}>6张</Radio.Button>
- </Radio.Group>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="form-caption">上传素材</div>
- <SortableUlList axis='xy' onSortEnd={onSortEndSlider} useDragHandle>
- {imageUrlList?.map((item: any, index: number) => {
- if (item) {
- return <SortableItemLi key={`slider-${index}`} index={index} isActive={activeIndex === index} pureImageUrl={item} click={() => { sliderSelect(index, imageUrlList.length) }} setActiveIndex={() => { setCon('activeIndex', index) }}></SortableItemLi>
- } else {
- return <SortableItemNoLi key={`slider-${index}`} index={index} isActive={activeIndex === index} click={() => { sliderSelect(index, imageUrlList.length) }}></SortableItemNoLi>
- }
- })}
- </SortableUlList>
- </div>
- </div>
- :
- elementType === 'TOP_VIDEO' ? <div className="widget">
- <div className="caption section">
- <div className="caption-title">顶部组件:视频</div>
- </div>
- <div className="form section">
- <div className="form-caption">广告位与样式</div>
- <div className="adui-form-item">
- <div className="adui-form-label">广告位</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { changeAdLocation(e.target.value) }} value={adLocation} size='small'>
- <Radio value='sns'>朋友圈信息流</Radio>
- <Radio value='gzh'>公众号及其他</Radio>
- </Radio.Group>
- </div>
- </div>
- {adLocation === 'sns' && <div className="adui-form-item">
- <div className="adui-form-label">外层样式</div>
- <div className="adui-form-control">
- <Select size="small" value={outerStyle} style={{ width: 100 }} onChange={(e) => { changeOuterLayout(e) }}>
- <Option value={0}>常规广告</Option>
- <Option value={1} disabled>卡片广告</Option>
- </Select>
- </div>
- </div>}
- {/* {
- adLocation === 'sns' && outerStyle === 0 && <div className="adui-form-item">
- <div className="adui-form-label">视频类型</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { viewTypeChange(e.target.value, 1) }} value={styleType} size='small'>
- <Radio value='0'>横板视频</Radio>
- <Radio value='1'>竖版视频</Radio>
- </Radio.Group>
- </div>
- </div>
- }
- {
- adLocation === 'sns' && outerStyle === 1 && <div className="adui-form-item">
- <div className="adui-form-label">外层素材</div>
- <div className="adui-form-control">
- <Checkbox onChange={(e: CheckboxChangeEvent) => { outerUseTopMaterialHandle(e.target.checked) }} checked={outerUseTopMaterial === '0' ? false : true}>顶部素材不用于广告外层</Checkbox>
- </div>
- </div>
- } */}
- {/* {
- outerUseTopMaterial === '1' && <div className="adui-form-item">
- <div className="adui-form-label">视频类型</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { viewTypeChange(e.target.value, 2) }} value={type} size='small'>
- <Radio value='61'>短视频</Radio>
- <Radio value='62'>长视频</Radio>
- </Radio.Group>
- </div>
- </div>
- } */}
- {/* {
- adLocation === 'gh' && <div className="adui-form-item">
- <div className="adui-form-label">视频类型</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { viewTypeChange(e.target.value, 2) }} value={type} size='small'>
- <Radio value='61'>短视频</Radio>
- <Radio value='62'>长视频</Radio>
- </Radio.Group>
- </div>
- </div>
- } */}
- {adLocation === 'sns' && styleType === '1' && <div className="adui-form-item" style={{ alignItems: 'flex-start' }}>
- <div className="adui-form-label" style={{ marginTop: 2 }}>视频尺寸</div>
- <div className="adui-form-control">
- <Radio.Group value={initHeight} onChange={(e) => { setCon('initHeight', e.target.value) }}>
- <Radio value={1536}>750像素 x 1536像素</Radio>
- <Radio value={1334}>750像素 x 1334像素</Radio>
- <Radio value={1280}>720像素 x 1280像素</Radio>
- </Radio.Group>
- </div>
- </div>}
- </div>
- </div>
- :
- elementType === 'TEXT' ? <div className="widget">
- <div className="caption section">
- <div className="caption-title">文本</div>
- </div>
- <div className="form section">
- <div className="form-caption">推广文案</div>
- <TextArea
- placeholder={`请输入(不包含<>&'"/\以及TAB、换行、回车键)`}
- autoSize={{ minRows: 4, maxRows: 6 }}
- value={text}
- onChange={(e) => { setCon('text', replaceSpecialTxt(e.target.value)) }}
- />
- </div>
- <div className="form section">
- <div className="form-caption">字符与段落</div>
- <div className="adui-form-item">
- <div className="adui-form-label">字符样式</div>
- <div className="adui-form-control">
- <div className="fl-sb">
- <div style={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center' }}>
- <Space>
- <Select value={fontSize} style={{ width: 60 }} onChange={(e) => { setCon('fontSize', e) }}>
- {[14, 15, 16, 18, 20, 24, 36].map((item: number) => (<Option value={item} key={item}>{item}</Option>))}
- </Select>
- <ColorPicker onColor={(color: string) => { setCon('fontColor', color) }} color={fontColor}></ColorPicker>
- </Space>
- </div>
- <Radio.Group onChange={(e) => { setCon('fontStyle', e.target.value) }} value={fontStyle}>
- <Radio.Button value={0}>常规</Radio.Button>
- <Radio.Button value={1}>加粗</Radio.Button>
- </Radio.Group>
- </div>
- </div>
- </div>
- <div className="adui-form-item">
- <div className="adui-form-label">对齐方式</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { setCon('textAlignment', e.target.value) }} value={textAlignment}>
- <Radio.Button value={0}><AlignLeftOutlined /></Radio.Button>
- <Radio.Button value={1}><AlignCenterOutlined /></Radio.Button>
- <Radio.Button value={2}><AlignRightOutlined /></Radio.Button>
- </Radio.Group>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="form-caption">边距</div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">上边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">下边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- </div>
- </div>
- :
- elementType === 'IMAGE' ? <div className="widget">
- <div className="caption section">
- <div className="caption-title">图片</div>
- </div>
- <div className="form section">
- <div className="form-caption">素材设置</div>
- <div className="adui-form-item" style={{ alignItems: 'flex-start' }}>
- <div className="adui-form-label">图片素材</div>
- <div className="adui-form-control">
- <div className={`upload-img-item ${imageUrl ? 'upload-img-item_uploaded' : ''}`}>
- {
- imageUrl ? <div className="upload-img-item-inner" style={{ backgroundImage: `url(${imageUrl ? imageUrl : ""})` }}>
- <div className='upload-img-item-action' onClick={() => { clickUpdateImg(1) }}>
- <RetweetOutlined />
- </div>
- </div>
- :
- <div className="upload-img-item-inner" onClick={() => { clickUpdateImg(1) }}>
- <PlusOutlined />
- </div>
- }
- </div>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="form-caption">边距</div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">上边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">下边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- </div>
- </div>
- :
- elementType === 'GH' ? <div className="widget">
- <div className="caption section">
- <div className="caption-title">关注公众号</div>
- </div>
- <div className="form section">
- <Space>
- <Switch size="small" checked={fastFollow === 1 ? true : false} onChange={(e) => { setCon('fastFollow', e ? 1 : 0) }} />
- 一键关注
- <Tooltip placement="top" title={'唤起公众号简介的半屏面板,点击其中按钮直接关注公众号'}>
- <QuestionCircleOutlined />
- </Tooltip>
- </Space>
- </div>
- <div className="form section">
- <div className="form-caption">按钮外观</div>
- <div className="adui-form-item">
- <div className="adui-form-label">按钮文案</div>
- <div className="adui-form-control">
- <div className="fl-sb">
- <div style={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center' }}>
- <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', border: '1px solid #d9d9d9', borderRadius: 2, paddingRight: 8 }}>
- <Input maxLength={useIcon === 1 ? 8 : 10} style={{ width: 90 }} bordered={false} value={btnTitle} onChange={(e) => { setCon('btnTitle', e.target.value) }} /> <span>{btnTitle?.length}/{useIcon === 1 ? 8 : 10}</span>
- </div>
- </div>
- <Radio.Group onChange={(e) => { setCon('btnFontType', e.target.value) }} value={btnFontType}>
- <Radio.Button value={0}>常规</Radio.Button>
- <Radio.Button value={1}>加粗</Radio.Button>
- </Radio.Group>
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">字体色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setCon('fontColor', color) }} color={fontColor}></ColorPicker><div className="colorShow">{fontColor}</div></Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">图标</div>
- <div className="adui-form-control">
- <Switch size="small" checked={useIcon === 1 ? true : false} onChange={(e) => { iconHandle(e) }} /> <span>{useIcon === 1 ? '已启用' : '未启用'}</span>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">边框色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setCon('btnBorderColorTheme', color) }} color={btnBorderColorTheme}></ColorPicker><div className="colorShow">{btnBorderColorTheme}</div></Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">背景色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setCon('btnBgColorTheme', color) }} color={btnBgColorTheme}></ColorPicker><div className="colorShow">{btnBgColorTheme}</div></Space>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="form-caption">边距</div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">上边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">下边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- </div>
- </div> :
- elementType === 'ENTERPRISE_WX' ? <div className="widget">
- <div className="caption section">
- <div className="caption-title">添加商家微信</div>
- </div>
- <div className="form section">
- <div className="form-caption">按钮外观</div>
- <div className="adui-form-item">
- <div className="adui-form-label">按钮文案</div>
- <div className="adui-form-control">
- <div className="fl-sb">
- <div style={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center' }}>
- <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', border: '1px solid #d9d9d9', borderRadius: 2, paddingRight: 8 }}>
- <Input maxLength={useIcon === 1 ? 8 : 10} style={{ width: 90 }} bordered={false} value={btnTitle} onChange={(e) => { setCon('btnTitle', e.target.value) }} /> <span>{btnTitle?.length}/{useIcon === 1 ? 8 : 10}</span>
- </div>
- </div>
- <Radio.Group onChange={(e) => { setCon('btnFontType', e.target.value) }} value={btnFontType}>
- <Radio.Button value={0}>常规</Radio.Button>
- <Radio.Button value={1}>加粗</Radio.Button>
- </Radio.Group>
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">字体色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setCon('fontColor', color) }} color={fontColor}></ColorPicker> <div className="colorShow">{fontColor}</div></Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">图标</div>
- <div className="adui-form-control">
- <Switch size="small" checked={useIcon === 1 ? true : false} onChange={(e) => { iconHandle(e) }} /> <span>{useIcon === 1 ? '已启用' : '未启用'}</span>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">边框色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setCon('btnBorderColorTheme', color) }} color={btnBorderColorTheme}></ColorPicker> <div className="colorShow">{btnBorderColorTheme}</div></Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">背景色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setCon('btnBgColorTheme', color) }} color={btnBgColorTheme}></ColorPicker> <div className="colorShow">{btnBgColorTheme}</div></Space>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="form-caption">边距</div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">上边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">下边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- </div>
- </div>
- :
- elementType === 'link' ? <div className="widget">
- {/* <div className="caption section">
- <div className="caption-title">跳转链接</div>
- </div>
- <div className="form section">
- <div className="form-caption">链接设置</div>
- <Input placeholder="以 http:// 或 https:// 开头" value={origBtnJumpUrl} onChange={(e) => { setCon('origBtnJumpUrl', e.target.value) }} />
- </div>
- <div className="form section">
- <div className="form-caption">按钮外观</div>
- <div className="adui-form-item">
- <div className="adui-form-label">按钮文案</div>
- <div className="adui-form-control">
- <div className="fl-sb">
- <div style={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center' }}>
- <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', border: '1px solid #d9d9d9', borderRadius: 2, paddingRight: 8 }}>
- <Input maxLength={10} style={{ width: 90 }} bordered={false} value={btnTitle} onChange={(e) => { setCon('btnTitle', e.target.value) }} /> <span>{btnTitle?.length}/10</span>
- </div>
- </div>
- <Radio.Group onChange={(e) => { setCon('btnFontType', e.target.value) }} value={btnFontType}>
- <Radio.Button value="0">常规</Radio.Button>
- <Radio.Button value="1">加粗</Radio.Button>
- </Radio.Group>
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">字体色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setCon('fontColor', color) }} color={fontColor}></ColorPicker><div className="colorShow">{fontColor}</div></Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">图标</div>
- <div className="adui-form-control">
- <Switch size="small" checked={useIcon === '1' ? true : false} onChange={(e) => { iconHandle(e) }} /> <span>{useIcon === '1' ? '已启用' : '未启用'}</span>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">边框色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setCon('btnBorderColorTheme', color) }} color={btnBorderColorTheme}></ColorPicker><div className="colorShow">{btnBorderColorTheme}</div></Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">背景色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setCon('btnBgColorTheme', color) }} color={btnBgColorTheme}></ColorPicker><div className="colorShow">{btnBgColorTheme}</div></Space>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="form-caption">边距</div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">上边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">下边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- </div> */}
- </div>
- :
- elementType === 'IMAGE_TEXT' ? <div className="widget">
- {imgTextButtonShow ? <>
- <div className="caption section goBack" onClick={() => { setImgTextButtonShow(false) }}>
- <SwapLeftOutlined />
- <span>返回</span>
- </div>
- {imgTextData.subElemType === 'GH' || imgTextData.subElemType === 'ENTERPRISE_WX' ? <>
- {imgTextData.subElemType === 'GH' && <div className="form section">
- <Space>
- <Switch size="small" checked={(imgTextData?.content as ITItemGhSpec)?.fastFollow === 1 ? true : false} onChange={(e) => { onSetShelfnewButtonField('fastFollow', e ? 1 : 0) }} />
- 一键关注
- <Tooltip placement="top" title={'唤起公众号简介的半屏面板,点击其中按钮直接关注公众号'}>
- <QuestionCircleOutlined />
- </Tooltip>
- </Space>
- </div>}
- <div className="form section">
- <div className="form-caption">按钮外观</div>
- <div className="adui-form-item">
- <div className="adui-form-label">按钮文案</div>
- <div className="adui-form-control">
- <div className="fl-sb">
- <div style={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center' }}>
- <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', border: '1px solid #d9d9d9', borderRadius: 2, paddingRight: 8 }}>
- <Input maxLength={5} style={{ width: 90 }} bordered={false} value={imgTextData?.content?.btnTitle} onChange={(e) => { onSetShelfnewButtonField('btnTitle', e.target.value) }} /> <span>{imgTextData?.content?.btnTitle?.length}/5</span>
- </div>
- </div>
- <Radio.Group onChange={(e) => { onSetShelfnewButtonField('btnFontType', e.target.value) }} value={imgTextData?.content?.btnFontType}>
- <Radio.Button value={0}>常规</Radio.Button>
- <Radio.Button value={1}>加粗</Radio.Button>
- </Radio.Group>
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">字体色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { onSetShelfnewButtonField('fontColor', color) }} color={imgTextData?.content?.fontColor}></ColorPicker><div className="colorShow">{imgTextData?.content?.fontColor}</div></Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">边框色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { onSetShelfnewButtonField('btnBorderColorTheme', color) }} color={imgTextData?.content?.btnBorderColorTheme}></ColorPicker><div className="colorShow">{imgTextData?.content?.btnBorderColorTheme}</div></Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">背景色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { onSetShelfnewButtonField('btnBgColorTheme', color) }} color={imgTextData?.content?.btnBgColorTheme}></ColorPicker><div className="colorShow">{imgTextData?.content?.btnBgColorTheme}</div></Space>
- </div>
- </div>
- </div>
- </> : <></>}
- </> : <>
- <div className="caption section">
- <div className="caption-title">图文复合组件</div>
- </div>
- <div className="form section">
- <div className="adui-form-item">
- <div className="adui-form-label">类型</div>
- <div className="adui-form-control">
- <>
- <Radio.Group onChange={(e) => { setShelfnewType(e.target.value) }} value={imageTextItemIndex.toString()}>
- <Radio value='1'>一行1个</Radio>
- <Radio value='2'>一行2个</Radio>
- </Radio.Group>
- {imageTextItemIndex === 2 && <Radio.Group onChange={(e) => { setGoodsCount(e.target.value) }} value={goodsCount} size='small' style={{ marginTop: 10 }}>
- <Radio.Button value={0}>商品1</Radio.Button>
- <Radio.Button value={1}>商品2</Radio.Button>
- </Radio.Group>}
- </>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="adui-form-item">
- <div className="adui-form-label">配图</div>
- <div className="adui-form-control">
- <div>
- <Button onClick={() => { setCcType(4); setSelectImgVisible(true); }}>上传图片</Button>
- <div style={{ marginTop: 4, fontSize: 12, color: '#636363' }}>{imageTextItemIndex === 2 ? '尺寸:480像素*480像素' : '尺寸:360像素*360像素'}</div>
- <div style={{ marginTop: 4, fontSize: 12, color: '#636363' }}>格式:不超过300k</div>
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'flex-start' }}>
- <div className="adui-form-label" style={{ marginTop: 6 }}>标题</div>
- <div className="adui-form-control">
- <Input.TextArea placeholder="请输入标题" onChange={(e) => { onShelfnewTxtCon(e.target.value?.replace(/\r|\n/ig, ""), 'title') }} value={imgTextData?.title} showCount maxLength={imageTextItemIndex === 1 ? 8 : 12} autoSize />
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'flex-start' }}>
- <div className="adui-form-label">描述</div>
- <div className="adui-form-control">
- <Space direction="vertical" style={{ width: '100%' }}>
- <Radio.Group defaultValue='text'>
- <Radio value="text">文字</Radio>
- <Radio value="price" disabled>价格</Radio>
- </Radio.Group>
- <Input.TextArea placeholder="请输入描述" onChange={(e) => { onShelfnewTxtCon(e.target.value?.replace(/\r|\n/ig, ""), 'desc') }} value={imgTextData?.desc} showCount maxLength={imageTextItemIndex === 1 ? 10 : 15} autoSize={{ minRows: 2, maxRows: 2 }} />
- </Space>
- </div>
- </div>
- {imageTextItemIndex === 2 && <div className="adui-form-item">
- <div className="adui-form-label">对齐</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { setCon('alignMode', e.target.value) }} value={alignMode}>
- <Radio value={0}>左对齐</Radio>
- <Radio value={1}>居中对齐</Radio>
- </Radio.Group>
- </div>
- </div>}
- <div className="adui-form-item" style={{ alignItems: 'flex-start' }}>
- <div className="adui-form-label" style={{ marginTop: 14 }}>字体颜色</div>
- <div className="adui-form-control">
- <Space style={{ width: '100%' }} size="large" className="shelfnewColor">
- <div>
- <Space><ColorPicker onColor={(color: string) => { onShelfnewTxtCon(color, 'titleColor') }} color={imgTextData.titleColor}></ColorPicker> <div className="colorShow">{imgTextData.titleColor}</div></Space>
- <div className="colorName">标题</div>
- </div>
- <div>
- <Space><ColorPicker onColor={(color: string) => { onShelfnewTxtCon(color, 'descColor') }} color={imgTextData.descColor}></ColorPicker> <div className="colorShow">{imgTextData.descColor}</div></Space>
- <div className="colorName">{/*shelfnewDescData?.name*/'描述'}</div>
- </div>
- </Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'flex-start' }}>
- <div className="adui-form-label" style={{ marginTop: 14 }}>其它颜色</div>
- <div className="adui-form-control">
- <Space style={{ width: '100%' }} size="large" className="shelfnewColor">
- <div>
- <Space><ColorPicker onColor={(color: string) => { onShelfnewTxtCon(color, 'borderColor') }} color={imgTextData.borderColor}></ColorPicker> <div className="colorShow">{imgTextData.borderColor}</div></Space>
- <div className="colorName">边框</div>
- </div>
- <div>
- <Space><ColorPicker onColor={(color: string) => { onShelfnewTxtCon(color, 'bgColor') }} color={imgTextData.bgColor}></ColorPicker> <div className="colorShow">{imgTextData.bgColor}</div></Space>
- <div className="colorName">背景</div>
- </div>
- </Space>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="form-caption">边距</div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">上边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingTop} onChange={(value: number) => { setCon('paddingTop', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">下边距</div>
- <div className="adui-form-control">
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div style={{ flexGrow: 1 }}><Slider value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} /></div>
- <InputNumber min={0} max={100} step={1} value={paddingBottom} onChange={(value: number) => { setCon('paddingBottom', value) }} style={{ width: 80, marginLeft: 20 }} />
- </div>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="form-caption">按钮</div>
- <div className="adui-form-item">
- <div className="adui-form-label">跳转方式</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => onShelfnewTxtCon(e.target.value, 'jumpMode')} value={imgTextData.jumpMode}>
- <Radio value="btn_jump">按钮跳转</Radio>
- <Radio value="total_jump">全局跳转</Radio>
- </Radio.Group>
- </div>
- </div>
- <div className="adui-form-item">
- <div className="adui-form-label">按钮类型</div>
- <div className="adui-form-control">
- <Space>
- <Select style={{ width: 120 }} value={imgTextData.subElemType} onChange={(e) => { onSetShelfnewButton(e) }}>
- {/* <Option value="link">跳转链接</Option> */}
- <Option value="GH">关注公众号</Option>
- <Option value="ENTERPRISE_WX" disabled>添加商家微信</Option>
- </Select>
- <Button type="link" size="small" onClick={() => { setImgTextButtonShow(true) }}>配置</Button>
- </Space>
- </div>
- </div>
- </div>
- </>}
- </div>
- :
- elementType === 'FLOAT_BUTTON' ? <div style={{ height: '100%' }}>
- <div className={`widget ${imgTextButtonShow ? 'widget_back' : ''}`}>
- <div className="caption section">
- <div className="caption-title">悬浮按钮</div>
- </div>
- <div className="form section">
- <div className="form-caption">卡片设置</div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <div className="adui-form-label">转化按钮</div>
- <div className="adui-form-control">
- <div className='form-result-text'><span>{componentItem?.name}</span> <Button type="link" size='small' style={{ color: '#6b6b6b', fontSize: 12 }} onClick={() => { setImgTextButtonShow(true) }}>设置</Button> </div>
- </div>
- </div>
- <div className="adui-form-item">
- <div className="adui-form-label">卡片样式</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { setGlobalComponentItem('styleType', e.target.value) }} className="floatType" value={styleType}>
- <Radio.Button value={0}>
- <div className='floatTypeInner'>
- <i className="floatTypeAvatar"></i>
- <i className="floatTypeText_two"></i>
- <i className="floatTypeButton"></i>
- </div>
- </Radio.Button>
- <Radio.Button value={1}>
- <div className='floatTypeInner'>
- <i style={{ display: 'inline-block', height: 12 }}></i>
- <i className="floatTypeText_two"></i>
- <i className="floatTypeButton"></i>
- </div>
- </Radio.Button>
- <Radio.Button value={2}>
- <div className='floatTypeInner'>
- <i style={{ display: 'inline-block', height: 12 }}></i>
- <i className="floatTypeText_one"></i>
- <i className="floatTypeButton"></i>
- </div>
- </Radio.Button>
- </Radio.Group>
- </div>
- </div>
- </div>
- <div className="form section">
- <div className="form-caption">内容设置</div>
- {styleType === 0 && <div className="adui-form-item" style={{ alignItems: 'flex-start' }}>
- <div className="adui-form-label">图片</div>
- <div className="adui-form-control">
- <div className={`upload-img-item ${imageUrl ? 'upload-img-item_uploaded' : ''}`}>
- {
- imageUrl ? <div className="upload-img-item-inner" style={{ backgroundImage: `url(${imageUrl ? imageUrl : ""})` }}>
- <div className='upload-img-item-action' onClick={() => { setCcType(5); setSelectImgVisible(true); }}>
- <RetweetOutlined />
- </div>
- </div>
- :
- <div className="upload-img-item-inner" onClick={() => { setCcType(5); setSelectImgVisible(true); }}>
- <PlusOutlined />
- </div>
- }
- </div>
- <div style={{ marginTop: 4, fontSize: 12, color: '#A3A3A3' }}>尺寸:96像素*96像素</div>
- <div style={{ marginTop: 4, fontSize: 12, color: '#A3A3A3' }}>格式:不超过300k</div>
- </div>
- </div>}
- <div className="adui-form-item" style={{ alignItems: 'flex-start', marginBottom: 10 }}>
- <div className="adui-form-label" style={{ marginTop: 6 }}>标题</div>
- <div className="adui-form-control">
- <Input.TextArea placeholder="请输入标题" onChange={(e) => { setGlobalComponentItem('title', e.target.value?.replace(/\r|\n/ig, "")) }} value={title} showCount maxLength={10} autoSize />
- </div>
- </div>
- {(styleType === 1 || styleType === 0) && <div className="adui-form-item" style={{ alignItems: 'flex-start', marginBottom: 10 }}>
- <div className="adui-form-label" style={{ marginTop: 6 }}>描述</div>
- <div className="adui-form-control">
- <Input.TextArea placeholder="请输入描述" onChange={(e) => { setGlobalComponentItem('desc', e.target.value?.replace(/\r|\n/ig, "")) }} value={desc} showCount maxLength={14} autoSize />
- </div>
- </div>}
- <div className="adui-form-item" style={{ alignItems: 'center', marginBottom: 10 }}>
- <div className="adui-form-label" style={{ marginTop: 6 }}>标题字色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setGlobalComponentItem('titleColor', color) }} color={titleColor}></ColorPicker> <div className="colorShow">{titleColor}</div></Space>
- </div>
- </div>
- {(styleType === 1 || styleType === 0) && <div className="adui-form-item" style={{ alignItems: 'center', marginBottom: 10 }}>
- <div className="adui-form-label" style={{ marginTop: 6 }}>描述字色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setGlobalComponentItem('descColor', color) }} color={descColor}></ColorPicker> <div className="colorShow">{descColor}</div></Space>
- </div>
- </div>}
- </div>
- <div className="form section">
- <div className="form-caption">更多设置</div>
- <div className='adui-form-tip adui-form-tip_normal'>如果落地页只有一页,悬浮组件的更多设置必须为“进入页面时出现”、且“不消失”</div>
- <div className="adui-form-item">
- <div className="adui-form-label">出现方式</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { setGlobalComponentItem('appearType', e.target.value) }} value={appearType}>
- <Radio value={0}>进入页面时出现</Radio>
- <Radio value={1}>滑动页面时出现</Radio>
- </Radio.Group>
- </div>
- </div>
- <div className="adui-form-item">
- <div className="adui-form-label">消失方式</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { setGlobalComponentItem('disappearType', e.target.value) }} value={disappearType}>
- <Radio value={0}>不消失</Radio>
- <Radio value={1}>滑至页面底部时消失</Radio>
- </Radio.Group>
- </div>
- </div>
- </div>
- </div>
- {/* 设置转化按钮 imgTextButtonShow */}
- <div className='aside' style={{ transform: imgTextButtonShow ? 'translate3d(0px, 0px, 0px)' : 'translate3d(100%, 0px, 0px)', transition: 'all 0.3s cubic-bezier(0, 0, 0.2, 1) 0s' }}>
- <div className='aside-nav'>
- <Button type='link' icon={<SwapLeftOutlined />} onClick={() => { setImgTextButtonShow(false) }}>返回</Button>
- </div>
- <div className="form section">
- <div className="form-caption">按钮类型</div>
- <div className="adui-form-item" style={{ alignItems: 'center' }}>
- <Select style={{ width: 180 }} className="aside-select" dropdownClassName="aside-select" onChange={(e) => { setGlobalComponentItem('componentItem', e) }} value={componentItem?.elementType} size="small">
- <Option value="GH"><FollowAcc />关注公众号</Option>
- <Option value="ENTERPRISE_WX"><WxAutoSvg />添加商家微信</Option>
- </Select>
- </div>
- </div>
- {componentItem?.elementType === 'GH' ? <>
- <div className="form section">
- <Space>
- <Switch size="small" checked={componentItem?.fastFollow} onChange={(e) => { setGlobalComponentItem('componentItem', { ...componentItem, fastFollow: e ? 1 : 0 }) }} />
- 一键关注
- <Tooltip placement="top" title={'唤起公众号简介的半屏面板,点击其中按钮直接关注公众号'}>
- <QuestionCircleOutlined />
- </Tooltip>
- </Space>
- </div>
- </> : null}
- <div className="form section">
- <div className="form-caption">按钮外观</div>
- <div className="adui-form-item" style={{ marginBottom: 10 }}>
- <div className="adui-form-label">按钮文案</div>
- <div className="adui-form-control">
- <div className="fl-sb">
- <div style={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center' }}>
- <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', border: '1px solid #d9d9d9', borderRadius: 2, paddingRight: 8 }}>
- <Input maxLength={5} style={{ width: 90 }} bordered={false} value={componentItem?.btnTitle} onChange={(e) => { setGlobalComponentItem('componentItem', { ...componentItem, btnTitle: e.target.value }) }} /> <span>{componentItem?.btnTitle?.length}/5</span>
- </div>
- </div>
- <Radio.Group onChange={(e) => { setGlobalComponentItem('componentItem', { ...componentItem, btnFontType: e.target.value }) }} value={componentItem?.btnFontType}>
- <Radio.Button value={0}>常规</Radio.Button>
- <Radio.Button value={1}>加粗</Radio.Button>
- </Radio.Group>
- </div>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center', marginBottom: 10 }}>
- <div className="adui-form-label">字体色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setGlobalComponentItem('componentItem', { ...componentItem, fontColor: color }) }} color={componentItem?.fontColor}></ColorPicker><div className="colorShow">{componentItem?.fontColor}</div></Space>
- </div>
- </div>
- <div className="adui-form-item" style={{ alignItems: 'center', marginBottom: 10 }}>
- <div className="adui-form-label">填充色</div>
- <div className="adui-form-control">
- <Space><ColorPicker onColor={(color: string) => { setGlobalComponentItem('componentItem', { ...componentItem, btnBgColorTheme: color }) }} color={componentItem?.btnBgColorTheme}></ColorPicker><div className="colorShow">{componentItem?.btnBgColorTheme}</div></Space>
- </div>
- </div>
- </div>
- </div>
- </div> :
- null
- }
- </>
- } else {
- return null
- }
- }
- /** 选择单张图片 */
- const clickUpdateImg = useCallback((num: number) => {
- setSliderImgContent([])
- setCcType(1)
- setSelectImgVisible(true)
- }, [scType, content, sliderImgContent])
- /** 选择视频 */
- const clickUpdateVideo = useCallback(() => {
- setCcType(2)
- setSelectImgVisible(true)
- }, [scType])
- /** 弹窗返回设置图片 */
- const setImg = useCallback((value: any[]) => {
- setSelectImgVisible(false)
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- let oldContent = newContent
- if (scType === 1) { // 图片
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- selectCon['imageUrl'] = value[0]?.url
- selectCon['width'] = Number(value[0]?.width)
- selectCon['height'] = Number(value[0]?.height)
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- } else if (scType === 2) { // 视频要判断是否是长视频 还是短视频
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- selectCon['width'] = value[0]?.width
- selectCon['height'] = value[0]?.height
- selectCon['videoUrl'] = value[0]?.url
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- } else if (scType === 3) { // 轮播
- if (selectIndex !== -1) {
- let urlList = value?.map(item => item?.url)
- let selectCon = oldContent[selectIndex]
- selectCon.imageUrlList = selectCon.imageUrlList?.reduce((prev: any[], cur: any, index: number) => {
- prev.push(urlList[index] || "")
- return prev
- }, [])
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- } else if (scType === 4) { // 设置图文复合组件图片
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- let length = selectCon?.imageTextItem?.length || 0
- if (length === 1) {
- let imageTextItem = selectCon?.imageTextItem[0]
- imageTextItem.imageUrl = value[0]?.url
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- } else if (length === 2) {
- let imageTextItem = selectCon?.imageTextItem[goodsCount]
- imageTextItem.imageUrl = value[0]?.url
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }
- } else if (scType === 5) { // 设置悬浮组件
- let newConItem = JSON.parse(JSON.stringify(componentItem))
- let selectIndex = newConItem?.findIndex((item: Content) => item.comptActive)
- let oldContent = newConItem
- if (selectIndex !== -1) {
- let selectCon = oldContent[selectIndex]
- selectCon['imageUrl'] = value[0]?.url
- dispatchGlobal({ type: 'setConItem', params: { componentItem: JSON.parse(JSON.stringify(oldContent)) } })
- }
- }
- }, [content, scType, goodsCount])
- /** 回填数据 */
- const editSelectImg = useCallback((url: any[]) => {
- setSelectImgVisible(true)
- }, [selectImgVisible])
- /** 下一步 */
- const nextHandle = useCallback(() => {
- if (content.length === 1) {
- message.error('请完善内容')
- return
- }
- if (((content[0]?.elementType === "TOP_IMAGE") && !content[0].imageUrl) || content[0]?.elementType === "empty") {
- message.error('请完善顶部组件内容')
- return
- }
- if (content[0]?.elementType === "TOP_SLIDER" && !content[0].imageUrlList?.every((item: string) => item)) {
- message.error('请完善轮播图组件内容~~')
- return
- }
- if (content[0]?.elementType === "TOP_VIDEO" && !content[0].videoUrl) {
- message.error('请完善顶部视频组件内容~~')
- return
- }
- let reg = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/;
- let a = content?.every((item: any) => {
- if (item?.elementType === "GH") {
- if (item?.btnTitle) {
- return true
- } else {
- message.error('关注公众号按钮按钮文案未填写')
- return false
- }
- } else if (item?.elementType === "link") {
- if (!reg.test(item?.origBtnJumpUrl)) {
- message.error('跳转链接按钮请输入正确链接')
- return false
- }
- if (item?.btnTitle) {
- return true
- } else {
- message.error('关注公众号按钮按钮文案未填写')
- return false
- }
- } else if (item?.elementType === "IMAGE") {
- if (item.imageUrl) {
- return true
- } else {
- message.error('请选择图片')
- return false
- }
- } else if (item?.elementType === "TEXT") {
- if (item.text) {
- return true
- } else {
- message.error('请完善文本内容')
- return false
- }
- } else if (item?.elementType === "ENTERPRISE_WX") {
- if (item?.btnTitle) {
- return true
- } else {
- message.error('客服组按钮按钮文案未填写')
- return false
- }
- } else if (item?.elementType === "IMAGE_TEXT") {
- return item?.imageTextItem?.every((imageTextItem: ImageTextItem) => {
- if (imageTextItem?.imageUrl && imageTextItem?.title && imageTextItem?.desc) {
- return true
- }
- message.error('请完善图文复合组件内容')
- return false
- })
- } else {
- return true
- }
- })
- if (componentItem?.length > 0) {
- let b = componentItem?.every((item: any) => {
- if (item?.elementType === "FLOAT_BUTTON") {
- if (item?.styleType === 0) {
- if (!item?.imageUrl) {
- message.error('悬浮组件请上传图片')
- return false
- }
- if (!item?.title) {
- message.error('悬浮组件请输入标题')
- return false
- }
- if (!item?.desc) {
- message.error('悬浮组件请输入描述')
- return false
- }
- } else if (item?.wxad_styleType === 1) {
- if (!item?.title) {
- message.error('悬浮组件请输入标题')
- return false
- }
- if (!item?.desc) {
- message.error('悬浮组件请输入描述')
- return false
- }
- } else if (item?.wxad_styleType === 2) {
- if (!item?.title) {
- message.error('悬浮组件请输入标题')
- return false
- }
- }
- }
- return true
- })
- if (b) {
- } else {
- return
- }
- }
- if (a) {
- setLastVisible(true)
- }
- }, [lastVisible, state, componentItem])
- /** 保存 */
- const saveHandle = useCallback(() => {
- let { content, pageBackColor } = state
- if (!shareTittle || !shareDesc) {
- message.error('请填写分享标题或者描述')
- return
- }
- let layoutName: string = pageName
- if (!pageName) {
- layoutName = `${id ? '复制' : ''}原生推广页` + moment().format("YYYYMMDDHHmmss") + '_' + currentUser?.userId
- }
- let pageContextList: Array<ImgProps | TopImg | TopVideo | TopSlider | Text | GhButton> = content?.map((item: { elementType: string, comptActive: boolean, activeIndex: boolean }) => {
- let { elementType, comptActive, activeIndex, ...data } = item
- let typeKey = getTypeKey(elementType)
- let newItem = { elementType }
- if (elementType === 'IMAGE_TEXT') {
- let { imageTextItem, ...spec } = data as any
- let newImageTextItem = imageTextItem?.map((item: any) => {
- let { content, ...newItem } = item
- let key = getTypeKey(newItem.subElemType)
- newItem[key] = content
- return newItem
- })
- newItem[typeKey] = {
- ...spec,
- imageTextItem: newImageTextItem
- }
- } else {
- newItem[typeKey] = data
- }
- return newItem
- })
- let globalSpec: any = {}
- if (componentItem?.length > 0) {
- let globalElementsSpecList = componentItem?.map((item: { elementType: string, comptActive: boolean, componentItem: { elementType: string } }) => {
- let { elementType, comptActive, componentItem, ...data } = item
- let typeKey = getTypeKey(elementType);
- let newItem = { elementType };
- (data as any).elementType = componentItem.elementType
- if (componentItem?.elementType) {
- let { elementType, ...data1 } = componentItem
- let type1Key = getTypeKey(elementType);
- data[type1Key] = data1
- }
- newItem[typeKey] = data
- return newItem
- })
- globalSpec.globalElementsSpecList = globalElementsSpecList
- } else {
- globalSpec = null
- }
- let pageSpecs = {
- bgColor: pageBackColor,
- pageElementsSpecList: pageContextList
- }
- let params = {
- mediaType: 'PAGE',
- folder: false,
- parentId,
- title: layoutName,
- pageName: layoutName,
- belongUser: belongUser === '0' ? false : true,
- sort,
- pageSpecsList: [pageSpecs],
- globalSpec,
- shareContentSpec: {
- shareTitle: shareTittle,
- shareDescription: shareDesc
- }
- }
- add.run(params).then(res => {
- if (res) {
- ajax.refresh()
- hideModal && hideModal()
- }
- })
- }, [state, shareTittle, pageName, parentId, sort, shareDesc, belongUser, currentUser, ajax, id, componentItem])
- return <Drawer
- title={
- <div className={style.drawerTitle}>
- <div>
- <Space>
- <span>{id ? '复制' : '创建'}推广页</span>
- </Space>
- </div>
- <Button type='primary' size='small' className={style.next} onClick={() => { nextHandle() }}>下一步 <SwapRightOutlined /></Button>
- </div>
- }
- placement="right"
- onClose={() => {
- modal.confirm(config);
- }}
- visible={visible}
- width='90%'
- className={`addDraw ${style.drawer}`}
- >
- {/* 选择素材 */}
- {selectImgVisible && <SelectCloud visible={selectImgVisible} sliderImgContent={sliderImgContent} onClose={() => setSelectImgVisible(false)} onChange={setImg} />}
- <Modal
- title={<>
- <div style={{ marginBottom: 2, color: '#1f1f1f' }}>分享设置</div>
- <div style={{ color: '#a3a3a3', fontSize: 12 }}>设置推广页的分享样式</div>
- </>}
- visible={lastVisible}
- confirmLoading={add.loading}
- onOk={saveHandle}
- onCancel={() => { setLastVisible(false) }}
- >
- <Form labelCol={{ span: 4 }}>
- <Form.Item label="落地页名称">
- <Space><Input placeholder='落地页名称(不填写,创建时间+创建者ID)' value={pageName} onChange={(e) => { setPageName(e.target.value) }} style={txtLength(pageName) > 60 ? { width: 300, borderColor: 'red' } : { width: 300 }} /><span style={txtLength(pageName) > 60 ? { color: 'red' } : {}}>{txtLength(pageName)}/60</span></Space>
- </Form.Item>
- <Form.Item label="分享标题">
- <Space><Input placeholder='建议与详情页面主题相符' value={shareTittle} onChange={(e) => { setShareTittle(e.target.value) }} style={txtLength(shareTittle) > 20 ? { width: 300, borderColor: 'red' } : { width: 300 }} /><span style={txtLength(shareTittle) > 20 ? { color: 'red' } : {}}>{txtLength(shareTittle)}/20</span></Space>
- </Form.Item>
- <Form.Item label="分享描述">
- <Space><Input placeholder='对标题的简要解读' style={txtLength(shareDesc) > 30 ? { width: 300, borderColor: 'red' } : { width: 300 }} value={shareDesc} onChange={(e) => { setShareDesc(e.target.value) }} /><span style={txtLength(shareTittle) > 30 ? { color: 'red' } : {}}>{txtLength(shareDesc)}/30</span></Space>
- </Form.Item>
- <Form.Item label="排序" tooltip="值越大越靠前">
- <InputNumber placeholder='输入排序' min={0} value={sort} onChange={(e) => { setSort(e) }} />
- </Form.Item>
- </Form>
- </Modal>
- <Spin spinning={get.loading}>
- <div className={style.boxCont}>
- <Row className={style.row}>
- <Col flex="320px" className={style.right}>
- <div className={style.title}>顶部组件</div>
- <div className={style.assembly}>
- {
- content[0].elementType === 'empty' ? <>
- <div {...getDragProps(`TOP_IMAGE`)}> <Topimg /> <span>图片</span> </div>
- <div {...getDragProps(`TOP_SLIDER`)}> <Topslider /> <span>轮播图</span> </div>
- <div {...getDragProps(`TOP_VIDEO`)}> <Topvideo /> <span>视频</span></div>
- </>
- :
- <>
- <div className={style.disabled}> <Topimg /> <span>图片</span> </div>
- <div className={style.disabled}> <Topslider /> <span>轮播图</span> </div>
- <div className={style.disabled}> <Topvideo /> <span>视频</span></div>
- </>
- }
- </div>
- <div className={style.title}>基础组件</div>
- <div className={style.assembly}>
- <div {...getDragPropsCon(`IMAGE`)}> <Img /> <span className="my">图片</span> </div>
- <div {...getDragPropsCon(`TEXT`)}> <MyText /> <span>文字</span> </div>
- </div>
- <div className={style.title}>转化按钮</div>
- <div className={style.assembly}>
- <div {...getDragPropsCon(`GH`)}> <FollowAcc /> <span className="my">关注公众号</span> </div>
- {/* <div {...getDragPropsCon(`JumpLink`)}> <JumpLink /> <span className="my">跳转链接</span> </div> */}
- <div {...getDragPropsCon(`ENTERPRISE_WX`)}> <WxAutoSvg /> <span className="my">添加商家微信</span> </div>
- </div>
- <div className={style.title}>营销组件</div>
- <div className={style.assembly}>
- <div {...getDragPropsCon(`IMAGE_TEXT`)}> <ImgText /> <span className="my">图文复合组件</span> </div>
- {componentItem?.some((item: { elementType: string }) => item.elementType === 'FLOAT_BUTTON') ?
- <div className={style.disabled}> <FloatbuttonSvg /> <span>悬浮组件</span></div> : <div {...getDragPropsCon(`FLOAT_BUTTON`)}> <FloatbuttonSvg /> <span className="my">悬浮组件</span></div>
- }
- </div>
- </Col>
- <Col flex="auto" className={style.center} onClick={installActiveNull}>
- <div className={style.page} style={{ backgroundColor: pageBackColor || '#FFFFFF' }}>
- {/* 头部 */}
- <div>{topCon}</div>
- {/* 内容*/}
- <div className={`comptPlaceholder lastChild`} id="comptCon">
- {comptCon()}
- </div>
- <div className={style.sidebar}>
- <div>
- <ColorPicker onColor={(color: string) => { dispatch({ type: 'setPageBackColor', params: { pageBackColor: color } }) }} color={pageBackColor}></ColorPicker>
- <div style={{ marginTop: 4 }}>背景</div>
- </div>
- </div>
- </div>
- </Col>
- <Col flex="380px" className={style.left}>{rightCon()}</Col>
- </Row>
- </div>
- </Spin>
- </Drawer>
- }
- export default React.memo(AddLandingPage)
|