123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298 |
- import { Button, Checkbox, Col, Drawer, Form, Input, InputNumber, message, Modal, Radio, RadioChangeEvent, 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, LinkButton, Shelfnew, WxAutoButton, Floatbutton } from '../../req'
- import { imgContent, txtContent, ghContent, topvideoNewContent, linkContent, topsliderContent, topimgContent, topvideoContent, shelfnewContent, shelfnewContent2, btModelJumpGh, btModelJumpLink, btModelJumpLink103, btModelJumpGh103, jumpLink104, jumpGh104, jumpLink103, jumpGh103, wxAutoContent, jumpWxAuto104, jumpWxAuto103, btModelJumpWxAuto, btModelJumpWxAuto103, floatbuttonContent, floatbuttonBtTypeWxAuto, floatbuttonBtTypeGh } 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, 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 [imgSize, setImgSize] = useState<{
- aspectRatio?: string, //宽高比
- minWidth?: string, //最小宽度
- maxWidth?: string, //最大宽度
- minHeight?: string, //最小高度
- maxHeight?: string, //最大高度
- minMediaSize?: number, // 最小媒体大小
- maxMediaSize?: number, // 最大媒体大小
- minVideoLength?: number, // 最小视频时长
- maxVideoLength?: number, // 最大视频时长
- minVideoBitRate?: number, // 最小视频比特率
- maxVideoBitRate?: number, // 最大视频比特率
- mediaType?: 'IMG' | 'VIDEO' | 'PAGE', // 内容类型 1 图片 2 视频
- }>({}) // 要选择的素材信息
- const [isFootlock, setIsFootlock] = useState<boolean>(false) // 是否横板视频
- 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] || {}
- 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])
- console.log('componentItem------>', componentItem);
- 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") {
- setIsFootlock(() => false)
- 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') { // 内容图片
- setIsFootlock(() => false)
- 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 })
- setIsFootlock(() => false)
- } 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 })
- setIsFootlock(() => false)
- }
- } else if (selectData?.elementType === 'shelfnew') { // 图文复合组件 1个
- if (selectData?.type === '104') {
- setIsFootlock(() => false)
- setImgSize(() => ({ minWidth: '360', maxWidth: '360', minHeight: '360', maxHeight: '360', minMediaSize: 0, maxMediaSize: 307200, mediaType: 'IMG' }))
- } else if (selectData?.type === '103') {
- setIsFootlock(() => false)
- setImgSize(() => ({ minWidth: '480', maxWidth: '480', minHeight: '480', maxHeight: '480', minMediaSize: 0, maxMediaSize: 307200, mediaType: 'IMG' }))
- }
- } else if (selectData?.elementType === 'FLOAT_BUTTON') {
- setIsFootlock(() => false)
- 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 === 'shelfnew') {
- // newCon.push({ ...shelfnewContent, 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 'shelfnew': // 图文复合组件
- // newContent.splice(index, 0, { ...shelfnewContent });
- // 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 === 'shelfnew') {
- // 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, isTopImg?: 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[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, count: number, 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]
- if (selectCon?.type === '103') {
- let componentItem = selectCon?.layoutItems.componentItem[goodsCount]
- let shelfnewItem = componentItem?.layoutItems?.componentItem[0]?.layoutItems?.componentItem
- shelfnewItem[count + 1][parameter] = value
- if (count + 1 === 2 && parameter === 'content') {
- if (shelfnewItem[count + 1]?.name === '价格') {
- shelfnewItem[count + 1][parameter] = '¥' + value
- } else {
- shelfnewItem[count + 1][parameter] = value
- }
- }
- } else if (selectCon?.type === '104') {
- let componentItem = selectCon?.layoutItems?.componentItem[0]?.layoutItems?.componentItem
- let textData = componentItem[1]?.layoutItems?.componentItem
- textData[count][parameter] = value
- if (count === 1 && parameter === 'content') {
- let name = textData[count]?.name
- if (name === '价格') {
- textData[count][parameter] = '¥' + value
- } else {
- textData[count][parameter] = value
- }
- }
- }
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }, [content, goodsCount])
- /** 设置描述类型 */
- const onSetShelfnewDescType = useCallback((e: RadioChangeEvent) => {
- 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]
- if (selectCon?.type === '103') {
- let componentItem = selectCon?.layoutItems.componentItem[goodsCount]
- let shelfnewItem = componentItem?.layoutItems?.componentItem[0]
- shelfnewItem.descType = e.target.value
- let textData = shelfnewItem?.layoutItems?.componentItem
- if (e.target.value === 'price') {
- textData[2] = {
- ...textData[2],
- name: '价格',
- content: '',
- fontColor: '#353535',
- fontSize: '32',
- showType: "1",
- }
- } else {
- let { showType, ...desc } = textData[2]
- textData[2] = {
- ...desc,
- name: '描述',
- content: '',
- fontColor: '#4D4D4D',
- fontSize: '24'
- }
- }
- } else if (selectCon?.type === '104') {
- let componentItem = selectCon?.layoutItems?.componentItem[0]?.layoutItems?.componentItem
- componentItem[1].descType = e.target.value
- let textData = componentItem[1]?.layoutItems?.componentItem
- if (e.target.value === 'price') {
- textData[1] = {
- ...textData[1],
- name: '价格',
- content: '',
- fontColor: '#353535',
- fontSize: '32',
- showType: "1",
- }
- } else {
- let { showType, ...desc } = textData[1]
- textData[1] = {
- ...desc,
- name: '描述',
- content: '',
- fontColor: '#4D4D4D',
- fontSize: '24'
- }
- }
- }
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }, [content, goodsCount])
- /** 设置跳转方式 */
- const onSetShelfnewJumpMode = useCallback((e: RadioChangeEvent) => {
- 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]
- if (selectCon?.type === '103') {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].jumpMode = e.target.value
- let jumpData = selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3]
- let widgetTypeV2 = jumpData?.widgetTypeV2
- let componentItem = selectCon?.layoutItems?.componentItem[goodsCount]?.layoutItems?.componentItem
- if (e.target.value === 'btn_jump') {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem = [{ ...componentItem[0] }]
- } else {
- switch (widgetTypeV2) {
- case 'link':
- componentItem[1] = { ...btModelJumpLink103, origBtnJumpUrl: jumpData?.origBtnJumpUrl }
- break
- case 'gh':
- componentItem[1] = { ...btModelJumpGh103, subType: jumpData?.subType, btnFontType: jumpData?.btnFontType }
- break
- case 'enterprise_wx_auto':
- componentItem[1] = { ...btModelJumpWxAuto103, subType: jumpData?.subType, btnFontType: jumpData?.btnFontType }
- break
- }
- }
- } else if (selectCon?.type === '104') {
- selectCon.layoutItems.componentItem[0].jumpMode = e.target.value
- let textData = selectCon?.layoutItems?.componentItem[0]?.layoutItems?.componentItem[1]?.layoutItems?.componentItem
- let widgetTypeV2 = textData[2].widgetTypeV2
- let componentItem = selectCon?.layoutItems?.componentItem
- if (e.target.value === 'btn_jump') {
- selectCon.layoutItems.componentItem = [{ ...componentItem[0] }]
- } else {
- switch (widgetTypeV2) {
- case 'link':
- componentItem[1] = { ...btModelJumpLink, origBtnJumpUrl: textData[2]?.origBtnJumpUrl }
- break
- case 'gh':
- componentItem[1] = { ...btModelJumpGh, subType: textData[2]?.subType, btnFontType: textData[2]?.btnFontType }
- break
- case 'enterprise_wx_auto':
- componentItem[1] = { ...btModelJumpWxAuto, subType: textData[2]?.subType, btnFontType: textData[2]?.btnFontType }
- break
- }
- }
- }
- 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]
- // "btn_jump" "total_jump"
- if (selectCon?.type === '103') {
- let jumpMode = selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].jumpMode
- let btnContent = selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3]
- if (value === 'link') {
- if (jumpMode === "total_jump") {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[1] = { ...btModelJumpLink103 }
- }
- if (btnContent?.horizontalAlignment) {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3] = { ...jumpLink103, horizontalAlignment: '1' }
- } else {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3] = { ...jumpLink103 }
- }
- } else if (value === 'gh') {
- if (jumpMode === "total_jump") {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[1] = { ...btModelJumpGh103 }
- }
- if (btnContent?.horizontalAlignment) {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3] = { ...jumpGh103, horizontalAlignment: '1' }
- } else {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3] = { ...jumpGh103 }
- }
- } else if (value === 'enterprise_wx_auto') {
- if (jumpMode === "total_jump") {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[1] = { ...btModelJumpWxAuto103 }
- }
- if (btnContent?.horizontalAlignment) {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3] = { ...jumpWxAuto103, horizontalAlignment: '1' }
- } else {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3] = { ...jumpWxAuto103 }
- }
- }
- } else if (selectCon?.type === '104') {
- let jumpMode = selectCon.layoutItems.componentItem[0].jumpMode
- if (value === 'link') {
- if (jumpMode === "total_jump") {
- selectCon.layoutItems.componentItem[1] = { ...btModelJumpLink }
- }
- selectCon.layoutItems.componentItem[0].layoutItems.componentItem[1].layoutItems.componentItem[2] = { ...jumpLink104 }
- } else if (value === 'gh') {
- if (jumpMode === "total_jump") {
- selectCon.layoutItems.componentItem[1] = { ...btModelJumpGh }
- }
- selectCon.layoutItems.componentItem[0].layoutItems.componentItem[1].layoutItems.componentItem[2] = { ...jumpGh104 }
- } else if (value === 'enterprise_wx_auto') {
- if (jumpMode === "total_jump") {
- selectCon.layoutItems.componentItem[1] = { ...btModelJumpWxAuto }
- }
- selectCon.layoutItems.componentItem[0].layoutItems.componentItem[1].layoutItems.componentItem[2] = { ...jumpWxAuto104 }
- }
- }
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- }
- }, [content, goodsCount])
- // 配置图文跳转链接按钮字段
- const onSetShelfnewButtonField = useCallback((field: string, 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]
- if (selectCon?.type === '103') {
- let jumpMode = selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].jumpMode
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3][field] = value
- if (field === 'btnBorderColorTheme') {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[0].layoutItems.componentItem[3]['borderSize'] = "2"
- }
- if (jumpMode === 'total_jump' && (field === 'subType' || field === 'btnFontType')) {
- selectCon.layoutItems.componentItem[goodsCount].layoutItems.componentItem[1][field] = value
- }
- } else if (selectCon?.type === '104') {
- let jumpMode = selectCon.layoutItems.componentItem[0].jumpMode
- selectCon.layoutItems.componentItem[0].layoutItems.componentItem[1].layoutItems.componentItem[2][field] = value
- if (field === 'btnBorderColorTheme') {
- selectCon.layoutItems.componentItem[0].layoutItems.componentItem[1].layoutItems.componentItem[2]['borderSize'] = "2"
- }
- if (jumpMode === 'total_jump' && (field === 'subType' || field === 'btnFontType')) {
- selectCon.layoutItems.componentItem[1][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 === '103') {
- newContent[selectIndex] = { ...shelfnewContent2, comptActive: true }
- } else if (value === '104') {
- newContent[selectIndex] = { ...shelfnewContent, comptActive: true }
- }
- dispatch({ type: 'setCon', params: { content: [...newContent] } })
- }
- }, [content])
- // 设置对齐方式
- const setAilgin103 = useCallback((align: number) => {
- let newContent = JSON.parse(JSON.stringify(content))
- let selectIndex = newContent?.findIndex((item: Content) => item.comptActive)
- if (selectIndex !== -1) {
- let selectCon = newContent[selectIndex]
- selectCon.wxad_align = align
- let componentItem = selectCon?.layoutItems?.componentItem?.map((item: any) => {
- let shelfnewItem = item?.layoutItems?.componentItem[0]?.layoutItems?.componentItem
- if (align === 0) {
- shelfnewItem = shelfnewItem?.map((oldItem: any, index: number) => {
- if (index === 0) {
- return oldItem
- } else if (index === 1 || index === 2) {
- let { textAlignment, ...newItem } = oldItem
- return newItem
- } else {
- let { horizontalAlignment, ...newItem } = oldItem
- return newItem
- }
- })
- } else {
- shelfnewItem = shelfnewItem?.map((newItem: any, index: number) => {
- if (index === 0) {
- return newItem
- } else if (index === 1 || index === 2) {
- return { ...newItem, textAlignment: "1" }
- } else {
- return { ...newItem, horizontalAlignment: "1" }
- }
- })
- }
- item.layoutItems.componentItem[0].layoutItems.componentItem = shelfnewItem
- return item
- })
- selectCon.layoutItems.componentItem = componentItem
- newContent[selectIndex] = { ...selectCon }
- 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, type, initHeight, outerUseTopMaterial, componentCount, activeIndex, componentGroupList, origBtnJumpUrl,
- layoutItems, borderColor, bgColor, title, desc, titleColor, descColor, componentItem, appearType, disappearType } = selectCon
- let descType = "text"
- let jumpMode = "btn_jump"
- let shelfnewImgData: { pureImageUrl: string } = { pureImageUrl: '' } // 图片信息
- let shelfnewTitleData: { content: string, fontColor: string } = { content: "", fontColor: "#353535" } // 标题信息
- let shelfnewDescData: { name: string, content: string, fontColor: string } = { name: '', content: "", fontColor: "#B2B2B2" } // 描述信息
- let shelfnewBtData: {
- widgetTypeV2: string, btnTitle: string, btnBgColorTheme: string,
- subType: '17' | '1', btnFontType: '0' | '1',
- btnBorderColorTheme: string, fontColor: string, origBtnJumpUrl: string,
- custorData: any[]
- } = { widgetTypeV2: '', btnFontType: '0', subType: '17', btnTitle: "", btnBgColorTheme: "#07C160", btnBorderColorTheme: "#FFFFFF", fontColor: "#FFFFFF", origBtnJumpUrl: "", custorData: [] }
- let custorGroup = []
- if (elementType === 'enterprise_wx_auto') {
- custorGroup = selectCon?.custorData || []
- } else if (elementType === 'shelfnew') {
- if (type === '104') { // 图文复合组件 单个
- let shelfnewData = layoutItems?.componentItem[0]?.layoutItems?.componentItem
- jumpMode = layoutItems?.componentItem[0]?.jumpMode
- descType = shelfnewData[1]?.descType
- shelfnewImgData = shelfnewData[0]
- shelfnewTitleData = shelfnewData[1]?.layoutItems?.componentItem[0]
- shelfnewDescData = shelfnewData[1]?.layoutItems?.componentItem[1]
- shelfnewBtData = shelfnewData[1]?.layoutItems?.componentItem[2]
- } else if (type === '103') {
- // goodsCount
- let componentItems = layoutItems.componentItem
- let componentItem = componentItems[goodsCount]
- borderColor = componentItem?.borderColor || "#e5e5e5"
- bgColor = componentItem?.bgColor || "#ffffff"
- jumpMode = componentItem?.layoutItems?.componentItem[0]?.jumpMode
- let shelfnewItem = componentItem?.layoutItems?.componentItem[0]?.layoutItems?.componentItem
- descType = componentItem?.layoutItems?.componentItem[0]?.descType
- shelfnewImgData = shelfnewItem[0]
- shelfnewTitleData = shelfnewItem[1]
- shelfnewDescData = shelfnewItem[2]
- shelfnewBtData = shelfnewItem[3]
- }
- }
- 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, true) }} 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, true) }}>
- <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="请输入"
- autoSize={{ minRows: 4, maxRows: 6 }}
- value={text}
- onChange={(e) => { setCon('text', 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 === 'shelfnew' ? <div className="widget">
- {/* {imgTextButtonShow ? <>
- <div className="caption section goBack" onClick={() => { setImgTextButtonShow(false) }}>
- <SwapLeftOutlined />
- <span>返回</span>
- </div>
- {shelfnewBtData.widgetTypeV2 === 'gh' || shelfnewBtData.widgetTypeV2 === 'link' || shelfnewBtData.widgetTypeV2 === 'enterprise_wx_auto' ? <>
- {shelfnewBtData.widgetTypeV2 === 'link' ? <div className="form section">
- <div className="form-caption">链接设置</div>
- <Input placeholder="以 http:// 或 https:// 开头" value={shelfnewBtData?.origBtnJumpUrl} onChange={(e) => { onSetShelfnewButtonField('origBtnJumpUrl', e.target.value) }} />
- </div> : shelfnewBtData.widgetTypeV2 === 'gh' ? <div className="form section">
- <Space>
- <Switch size="small" checked={shelfnewBtData?.subType === '17' ? true : false} onChange={(e) => { onSetShelfnewButtonField('subType', e ? '17' : '1') }} />
- 一键关注
- <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">
- <Button size="small" onClick={clickCustorGroup}>{shelfnewBtData?.custorData?.length > 0 ? '修改客服组' : '选择客服组'}</Button>
- </div>
- </div>
- </div>
- {shelfnewBtData?.custorData?.length > 0 && <div className='adui-form-item custorGroup'>
- {shelfnewBtData?.custorData?.map((item: { label: string, custorData: any[], id: number }) => <div key={item.id}>
- <strong>{item.label}:</strong><span>{item.custorData[0]?.name}</span>
- </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">
- <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={shelfnewBtData?.btnTitle} onChange={(e) => { onSetShelfnewButtonField('btnTitle', e.target.value) }} /> <span>{shelfnewBtData?.btnTitle?.length}/5</span>
- </div>
- </div>
- <Radio.Group onChange={(e) => { onSetShelfnewButtonField('btnFontType', e.target.value) }} value={shelfnewBtData?.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={shelfnewBtData?.fontColor}></ColorPicker><div className="colorShow">{shelfnewBtData?.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={shelfnewBtData?.btnBorderColorTheme}></ColorPicker><div className="colorShow">{shelfnewBtData?.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={shelfnewBtData?.btnBgColorTheme}></ColorPicker><div className="colorShow">{shelfnewBtData?.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={type}>
- <Radio value='104'>一行1个</Radio>
- <Radio value='103'>一行2个</Radio>
- </Radio.Group>
- {type === '103' && <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); setNum(1) }}>上传图片</Button>
- <div style={{ marginTop: 4, fontSize: 12, color: '#636363' }}>{type === '103' ? '尺寸: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, ""), 0, 'content') }} value={shelfnewTitleData?.content} showCount maxLength={type === '104' ? 12 : 8} autoSize />
- </div>
- </div>
- <div className="adui-form-item">
- <div className="adui-form-label">描述</div>
- <div className="adui-form-control">
- <Space direction="vertical" style={{ width: '100%' }}>
- <Radio.Group onChange={onSetShelfnewDescType} value={descType}>
- <Radio value="text">文字</Radio>
- <Radio value="price">价格</Radio>
- </Radio.Group>
- {descType === 'text' ?
- <Input.TextArea placeholder="请输入描述" onChange={(e) => { onShelfnewTxtCon(e.target.value?.replace(/\r|\n/ig, ""), 1, 'content') }} value={shelfnewDescData?.content} showCount maxLength={type === '104' ? 15 : 10} autoSize={{ minRows: 2, maxRows: 2 }} /> :
- <div>
- <Input placeholder="请输入" suffix="元" onChange={(e) => { onShelfnewTxtCon(e.target.value, 1, 'content') }} style={{ width: 150 }} value={shelfnewDescData?.content?.split('¥')[1]} />
- <div style={{ fontSize: 12, color: '#636363', marginTop: 5 }}>价格范围0.01~999,999,999.99元</div>
- </div>
- }
- </Space>
- </div>
- </div>
- {type === '103' && <div className="adui-form-item">
- <div className="adui-form-label">对齐</div>
- <div className="adui-form-control">
- <Radio.Group onChange={(e) => { setAilgin103(e.target.value) }} value={wxad_align}>
- <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, 0, 'fontColor') }} color={shelfnewTitleData?.fontColor}></ColorPicker> <div className="colorShow">{shelfnewTitleData?.fontColor}</div></Space>
- <div className="colorName">标题</div>
- </div>
- <div>
- <Space><ColorPicker onColor={(color: string) => { onShelfnewTxtCon(color, 1, 'fontColor') }} color={shelfnewDescData?.fontColor}></ColorPicker> <div className="colorShow">{shelfnewDescData?.fontColor}</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) => { setCon('borderColor', color) }} color={borderColor}></ColorPicker> <div className="colorShow">{borderColor}</div></Space>
- <div className="colorName">边框</div>
- </div>
- <div>
- <Space><ColorPicker onColor={(color: string) => { setCon('bgColor', color) }} color={bgColor}></ColorPicker> <div className="colorShow">{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={onSetShelfnewJumpMode} value={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={shelfnewBtData.widgetTypeV2} onChange={(e) => { onSetShelfnewButton(e) }}>
- <Option value="link">跳转链接</Option>
- <Option value="gh">关注公众号</Option>
- <Option value="enterprise_wx_auto">添加商家微信</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)
- }, [imgSize, scType, content, sliderImgContent])
- /** 选择视频 */
- const clickUpdateVideo = useCallback(() => {
- setCcType(2)
- setSelectImgVisible(true)
- }, [imgSize, 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]
- if (selectCon?.type === '104') {
- let componentItem = selectCon?.layoutItems?.componentItem[0]?.layoutItems?.componentItem
- componentItem[0] = {
- ...componentItem[0],
- pureImageUrl: value[0]?.content
- }
- oldContent[selectIndex] = { ...selectCon }
- dispatch({ type: 'setCon', params: { content: [...oldContent] } })
- } else if (selectCon?.type === '103') {
- let componentItem = selectCon?.layoutItems.componentItem[goodsCount]
- let shelfnewItem = componentItem?.layoutItems?.componentItem[0]?.layoutItems?.componentItem
- shelfnewItem[0].pureImageUrl = value[0]?.content
- 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 === "shelfnew") {
- return true
- } 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 }
- 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(`shelfnew`)}> <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)
|