index.tsx 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. import { Button, Checkbox, InputNumber, message, Modal, Popconfirm, Radio, Select, Space, Spin } from "antd";
  2. import React, { useCallback, useEffect, useState } from "react";
  3. import style1 from './index.less'
  4. import { TopImg, TopVideo, TopSlider } from '../../req'
  5. import { DeleteOutlined, PlusOutlined, RetweetOutlined } from "@ant-design/icons";
  6. import { SortableUlList, SortableItemNoLi, SortableItemLi } from '../../components/addLandingPage/sortable'
  7. import arrayMove from "array-move"
  8. import SelectCloud from '../selectCloud'
  9. import { topsliderContent, topimgContent, topvideoNewContent } from '../../components/addLandingPage/content'
  10. import { BcForm } from "@/pages/launchSystem/launchManage/weChat/components/createPlan/components/AdBasicConfig";
  11. import { useModel } from "umi";
  12. import { getTypeKey } from "@/utils/utils";
  13. import moment from "moment";
  14. import { bdSysMediaAdd } from '@/services/launchAdq/material';
  15. interface Props {
  16. visible: boolean,
  17. id: number,
  18. onChange?: () => void,
  19. onClose?: () => void,
  20. ajaxHome?: any
  21. }
  22. /**
  23. * 批量复制落地页
  24. * @param props
  25. * @returns
  26. */
  27. function BathLauCopy(props: Props) {
  28. const { visible, id, onChange, onClose, ajaxHome } = props
  29. /** ==============数据参数开始=============== */
  30. const [elementType, setElementType] = useState<string | undefined>(undefined) // 顶部素材类型
  31. const [adLocation, setAdLocation] = useState<string>('sns') // 广告位
  32. const [outerStyle, setOuterStyle] = useState<number>(0) // 外层样式
  33. const [componentCount, setComponentCount] = useState<number>(3) // 图片数量
  34. const [selectImgVisible, setSelectImgVisible] = useState<boolean>(false) // 选择图片弹窗
  35. const [isFootlock, setIsFootlock] = useState<boolean>(false) // 是否横板视频
  36. const [sliderImgContent, setSliderImgContent] = useState<{ url: string, width?: number, height?: number }[]>([]) // 保存回填数据
  37. const [groupIndex, setGroupIndex] = useState<number>(-1) // 保存正在操作的组 下标
  38. const [loading, setLoading] = useState<boolean>(false) // 确定按钮loading
  39. const { init, get } = useModel('useLaunchAdq.useBdMediaPup')
  40. const { state: { parentId, belongUser } } = useModel('useLaunchAdq.useBdMedia')
  41. const [data, setData] = useState<any>({})
  42. const [topData, setTopData] = useState<Array<TopImg | TopVideo | TopSlider>>([]) // 顶部素材数据
  43. const [sort, setSort] = useState<number>(0) // 排序
  44. /** ===============数据参数结束=============== */
  45. // 回填
  46. useEffect(() => {
  47. if (id) {
  48. get.run({ sysMediaId: id, mediaType: 'PAGE' }).then(res => {
  49. if (res) {
  50. setData(res)
  51. const { pageSpecsList } = res
  52. let pageElementsSpec = pageSpecsList[0]?.pageElementsSpecList[0]
  53. setElementType(pageElementsSpec?.elementType)
  54. let typeKey = getTypeKey(pageElementsSpec?.elementType)
  55. setTopData([{
  56. elementType: pageElementsSpec?.elementType as any,
  57. ...pageElementsSpec[typeKey]
  58. }])
  59. if (pageElementsSpec?.elementType === 'TOP_IMAGE' || pageElementsSpec?.elementType === 'TOP_VIDEO') {
  60. setAdLocation(() => pageElementsSpec[typeKey]?.adLocation)
  61. setOuterStyle(() => pageElementsSpec[typeKey]?.outerStyle)
  62. setComponentCount(1)
  63. } else if (pageElementsSpec?.elementType === 'TOP_SLIDER') {
  64. setComponentCount(pageElementsSpec[typeKey]?.imageUrlList?.length || 3)
  65. }
  66. setSort(res?.sort || 0)
  67. }
  68. })
  69. }
  70. }, [id])
  71. // 设置选择的图片参数
  72. /** 获取选中内容 */
  73. useEffect(() => {
  74. if (elementType === 'TOP_IMAGE') {
  75. setIsFootlock(() => false)
  76. if (adLocation === 'sns') { // 朋友圈信息流
  77. if (outerStyle === 0) { // 常规广告
  78. init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 800, height: 800 }]] })
  79. } else { // 卡片广告
  80. init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 800, height: 450 }]] })
  81. }
  82. } else { // 公众号及其他
  83. init({ mediaType: 'IMG', cloudSize: [[{ relation: '=', width: 800, height: 800 }], [{ relation: '=', width: 800, height: 450 }], [{ relation: '=', width: 800, height: 640 }], [{ relation: '=', width: 640, height: 800 }]] })
  84. }
  85. } else if (elementType === 'TOP_SLIDER') { // 轮播图
  86. setIsFootlock(() => false)
  87. init({ mediaType: 'IMG', num: componentCount, cloudSize: [[{ relation: '=', width: 800, height: 800 }]] })
  88. } else if (elementType === 'TOP_VIDEO') { // 视频
  89. if (adLocation === 'sns') { // 朋友圈信息流
  90. if (outerStyle === 0) { // 常规广告
  91. init({ mediaType: 'VIDEO', cloudSize: [[{ relation: '=', width: 640, height: 480 }], [{ relation: '=', width: 640, height: 360 }], [{ relation: '=', width: 750, height: 1334 }], [{ relation: '=', width: 720, height: 1280 }]] })
  92. } else { // 卡片广告
  93. init({ mediaType: 'VIDEO', cloudSize: [[{ relation: '=', width: 750, height: null }, { relation: '<=', width: null, height: 1536 }]] })
  94. }
  95. } else { // 公众号及其它
  96. init({ mediaType: 'VIDEO', cloudSize: [[{ relation: '=', width: 750, height: null }, { relation: '<=', width: null, height: 1536 }]] })
  97. setIsFootlock(() => false)
  98. }
  99. }
  100. }, [elementType, adLocation, outerStyle, componentCount])
  101. // 关闭弹窗
  102. const hideHandle = () => {
  103. onClose && onClose()
  104. }
  105. const handleOk = useCallback(() => {
  106. if (elementType === 'TOP_SLIDER' && !topData?.every((item1: any) => {
  107. if (!item1.imageUrlList?.every((item: string) => item)) {
  108. return false
  109. } else {
  110. return true
  111. }
  112. })) {
  113. message.error('顶部轮播图组缺少图片')
  114. return
  115. } else if (elementType === 'TOP_IMAGE' && !topData?.every((item: any) => item.imageUrl)) {
  116. message.error('顶部图片组缺少图片')
  117. return
  118. } else if (elementType === 'TOP_VIDEO' && !topData?.every((item: any) => item.videoUrl)) {
  119. message.error('顶部视频组缺少视频')
  120. return
  121. }
  122. setLoading(true)
  123. let ajax = topData?.map((item: any, index: number) => {
  124. const { elementType, ...newItem } = item
  125. let newTopPage = { elementType }
  126. let typeKey = getTypeKey(elementType)
  127. newTopPage[typeKey] = { ...newItem }
  128. let pageSpecsList: any[] = JSON.parse(JSON.stringify(data?.pageSpecsList))
  129. pageSpecsList[0].pageElementsSpecList[0] = { ...newTopPage }
  130. let params = {
  131. mediaType: 'PAGE',
  132. folder: false,
  133. parentId,
  134. title: `批量复制` + moment().format("YYYYMMDDHHmmss"),
  135. pageName: `批量复制` + moment().format("YYYYMMDDHHmmss"),
  136. belongUser: belongUser === '0' ? false : true,
  137. sort,
  138. pageSpecsList,
  139. globalSpec: data?.globalSpec,
  140. shareContentSpec: data?.shareContentSpec
  141. }
  142. return bdSysMediaAdd(params as any)
  143. })
  144. Promise.all(ajax).then((res: any) => {
  145. setLoading(false)
  146. if (res && res.length > 0) {
  147. let data = res[res.length - 1]
  148. if (data?.code === 200) {
  149. onClose && onClose()
  150. ajaxHome && ajaxHome?.refresh()
  151. message.success('新增成功')
  152. }
  153. }
  154. }).catch(() => { setLoading(false) })
  155. }, [topData, elementType, sort, data, adLocation, outerStyle, loading, componentCount, parentId, belongUser])
  156. // 切换顶部素材类型
  157. const changeType = useCallback((value: string) => {
  158. setElementType(value)
  159. switch (value) {
  160. case 'TOP_IMAGE':
  161. setTopData([{ ...topimgContent }])
  162. setComponentCount(1)
  163. break;
  164. case 'TOP_SLIDER':
  165. setTopData([{ ...topsliderContent }])
  166. setComponentCount(3)
  167. break;
  168. case 'topvideo':
  169. setTopData([{ ...topvideoNewContent }])
  170. break;
  171. }
  172. }, [elementType, topData, componentCount])
  173. /** 轮播图位置拖动切换顺序 */
  174. const onSortEndSlider = useCallback(({ oldIndex, newIndex }: { oldIndex: number, newIndex: number }) => {
  175. let topDataNew = JSON.parse(JSON.stringify(topData))
  176. let selectCon = topDataNew[groupIndex]
  177. let imageUrlList = selectCon?.imageUrlList
  178. imageUrlList = arrayMove(imageUrlList, oldIndex, newIndex)
  179. selectCon = { ...selectCon, imageUrlList }
  180. topDataNew[groupIndex] = selectCon
  181. setTopData(topDataNew)
  182. }, [groupIndex, topData])
  183. /** 轮播图选择图片 */
  184. const sliderSelect = useCallback((index: number, indexGroup: number) => {
  185. let topDataNew = JSON.parse(JSON.stringify(topData))
  186. // 保存点击了第几组的选择图片
  187. setGroupIndex(indexGroup)
  188. // 设置activeIndex
  189. activeIndexHancdle(index, indexGroup)
  190. // 回填图片
  191. let selectCon = topDataNew[indexGroup]
  192. let imgList: any[] = []
  193. selectCon?.imageUrlList?.forEach((item: string) => {
  194. if (item) {
  195. imgList.push({ url: item })
  196. }
  197. })
  198. setSliderImgContent(imgList)
  199. setSelectImgVisible(true)
  200. }, [groupIndex, topData, sliderImgContent, selectImgVisible])
  201. /** 选择单张图片 */
  202. const clickUpdateImg = useCallback((index: number) => {
  203. setSliderImgContent([])
  204. setSelectImgVisible(true)
  205. setGroupIndex(index)
  206. }, [sliderImgContent, selectImgVisible, groupIndex])
  207. /** 添加素材组 */
  208. const addTopData = useCallback(() => {
  209. switch (elementType) {
  210. case 'TOP_IMAGE':
  211. topData.push({ ...topimgContent })
  212. setTopData([...topData])
  213. break
  214. case 'TOP_SLIDER':
  215. let imageUrlList = Array(Number(componentCount)).fill('').map(() => "")
  216. topData.push({
  217. ...topsliderContent,
  218. imageUrlList
  219. })
  220. setTopData([...topData])
  221. break
  222. case 'TOP_VIDEO':
  223. topData.push({ ...topvideoNewContent })
  224. setTopData([...topData])
  225. break
  226. }
  227. }, [elementType, topData, componentCount])
  228. /**删除组 */
  229. const del = useCallback((index: number) => {
  230. let newTopData = topData.filter((item, eq) => eq !== index)
  231. setTopData(newTopData)
  232. }, [topData])
  233. /** 设置轮播图个数 */
  234. const setCount = useCallback((value: number) => {
  235. setComponentCount(value)
  236. if (topData?.length > 0) {
  237. let selectCon = topData[0] as TopSlider
  238. if (selectCon?.elementType === 'TOP_SLIDER') {
  239. let imageUrlList = selectCon?.imageUrlList
  240. if (imageUrlList?.length > value) { // 减少
  241. let newTopData = topData.map((item: any) => {
  242. let imageUrlList = item?.imageUrlList
  243. return {
  244. ...item,
  245. imageUrlList: [...imageUrlList?.splice(0, Number(value))]
  246. }
  247. })
  248. setTopData([...newTopData])
  249. } else { // 增加
  250. let newList = Array(value - imageUrlList?.length).fill('').map(() => "")
  251. let newTopData = topData.map((item: any) => {
  252. let imageUrlList = item?.imageUrlList
  253. return {
  254. ...item,
  255. imageUrlList: [...imageUrlList, ...newList]
  256. }
  257. })
  258. setTopData([...newTopData])
  259. }
  260. }
  261. }
  262. }, [componentCount, topData])
  263. /** 设置图片外层样式 */
  264. const setImgViewType = useCallback((value: number) => {
  265. setOuterStyle(value)
  266. setTopData(topData.map((item: any) => ({ ...item, pureImageUrl: '' })))
  267. }, [outerStyle, topData])
  268. // 设置选择的图片
  269. const setImg = useCallback((value: any[]) => {
  270. let topDataNew = JSON.parse(JSON.stringify(topData))
  271. switch (elementType) {
  272. case 'TOP_IMAGE':
  273. topDataNew[groupIndex] = {
  274. ...topDataNew[groupIndex],
  275. imageUrl: value[0]?.url
  276. }
  277. break;
  278. case 'TOP_SLIDER':
  279. let imageUrlList = value?.map((item: { url: string }) => item.url)
  280. topDataNew[groupIndex] = {
  281. ...topDataNew[groupIndex],
  282. imageUrlList: topDataNew[groupIndex]?.imageUrlList?.reduce((prev: any[], cur: any, index: number) => {
  283. prev.push(imageUrlList[index] || "")
  284. return prev
  285. }, [])
  286. }
  287. break;
  288. case 'TOP_VIDEO':
  289. topDataNew[groupIndex] = {
  290. ...topDataNew[groupIndex],
  291. videoUrl: value[0]?.url
  292. }
  293. break;
  294. }
  295. setSelectImgVisible(false)
  296. setTopData(topDataNew)
  297. }, [elementType, groupIndex, topData, adLocation, outerStyle])
  298. /** 设置activeIndex */
  299. const activeIndexHancdle = useCallback((index: number, indexGroup: number) => {
  300. let topDataNew = JSON.parse(JSON.stringify(topData))
  301. // 设置activeIndex
  302. topDataNew[indexGroup] = {
  303. ...topDataNew[indexGroup],
  304. activeIndex: index
  305. }
  306. setTopData(topDataNew)
  307. }, [topData])
  308. return <Modal
  309. bodyStyle={{ height: 600, overflowY: 'auto' }}
  310. title="批量复制推广页"
  311. visible={visible}
  312. onCancel={hideHandle}
  313. confirmLoading={loading}
  314. onOk={handleOk}
  315. width={1000}
  316. className={style1.batchCopy}
  317. maskClosable={false}
  318. >
  319. {/* 选择素材 */}
  320. {selectImgVisible && <SelectCloud visible={selectImgVisible} sliderImgContent={sliderImgContent} onClose={() => setSelectImgVisible(false)} onChange={setImg} />}
  321. <Spin spinning={get.loading}>
  322. <div className={style1.info}>
  323. <div className={style1.items}>
  324. <div className={style1.item}>
  325. <label className={style1.label}>推广页名称:</label>
  326. <span>{data?.title}</span>
  327. </div>
  328. </div>
  329. <div className={style1.items}>
  330. <div className={style1.item}>
  331. <label className={style1.label}>分享标题:</label>
  332. <span>{data?.shareContentSpec?.shareTitle}</span>
  333. </div>
  334. <div className={style1.item}>
  335. <label className={style1.label}>分享描述:</label>
  336. <span>{data?.shareContentSpec?.shareDescription}</span>
  337. </div>
  338. </div>
  339. </div>
  340. <div className={style1.title}>顶部素材设置</div>
  341. <BcForm name="顶部素材类型">
  342. <Select value={elementType} style={{ width: 180 }} onChange={(e) => { changeType(e) }} placeholder="请选择顶部素材类型">
  343. <Select.Option value="TOP_IMAGE">顶部图片</Select.Option>
  344. <Select.Option value="TOP_SLIDER">顶部轮播图</Select.Option>
  345. <Select.Option value="TOP_VIDEO">顶部视频</Select.Option>
  346. </Select>
  347. </BcForm>
  348. {elementType === "TOP_IMAGE" ? <>
  349. <div className={style1.title}>广告位与样式</div>
  350. <BcForm name="广告位">
  351. <Radio.Group onChange={(e) => {
  352. setAdLocation(e.target.value)
  353. if (topData?.length > 0) {
  354. setTopData(topData?.map((item: any) => ({ ...item, imageUrl: '' })))
  355. }
  356. }} value={adLocation} size='small'>
  357. <Radio value='sns'>朋友圈信息流</Radio>
  358. <Radio value='gh'>公众号及其他</Radio>
  359. </Radio.Group>
  360. </BcForm>
  361. {adLocation === 'sns' && <BcForm name="外层样式">
  362. <Select value={outerStyle} style={{ width: 100 }} onChange={(e) => { setImgViewType(e) }}>
  363. <Select.Option value={0}>常规广告</Select.Option>
  364. <Select.Option value={1}>卡片广告</Select.Option>
  365. </Select>
  366. </BcForm>}
  367. </> : elementType === "TOP_SLIDER" ? <>
  368. <div className={style1.title}>素材设置</div>
  369. <BcForm name="图片数量">
  370. <Radio.Group onChange={(e) => { setCount(e.target.value) }} value={componentCount} size='small'>
  371. <Radio.Button value={3}>3张</Radio.Button>
  372. <Radio.Button value={4}>4张</Radio.Button>
  373. <Radio.Button value={6}>6张</Radio.Button>
  374. </Radio.Group>
  375. </BcForm>
  376. </> : elementType === "TOP_VIDEO" ? <>
  377. <div className={style1.title}>广告位与样式</div>
  378. <BcForm name="广告位">
  379. <Radio.Group onChange={(e) => {
  380. setAdLocation(e.target.value);
  381. if (topData?.length > 0) {
  382. setTopData(topData?.map((item: any) => ({ ...item, videoUrl: '' })))
  383. }
  384. setOuterStyle(0);
  385. }} value={adLocation} size='small'>
  386. <Radio value='sns'>朋友圈信息流</Radio>
  387. <Radio value='gh'>公众号及其他</Radio>
  388. </Radio.Group>
  389. </BcForm>
  390. {adLocation === 'sns' && <BcForm name="外层样式">
  391. <Select value={outerStyle} style={{ width: 100 }} onChange={(e) => { setImgViewType(e) }}>
  392. <Select.Option value={0}>常规广告</Select.Option>
  393. <Select.Option value={1} disabled>卡片广告</Select.Option>
  394. </Select>
  395. </BcForm>}
  396. </> : <></>
  397. }
  398. <BcForm name="排序">
  399. <InputNumber placeholder='输入排序' min={0} value={sort} onChange={(e) => { setSort(e) }} />
  400. </BcForm>
  401. <div style={{ height: 1, backgroundColor: '#e2e2e2', marginBottom: 10 }}></div>
  402. {
  403. elementType === "TOP_IMAGE" || elementType === "TOP_SLIDER" || elementType === "TOP_VIDEO" ? <>
  404. <div className={style1.title} style={{ display: 'flex', justifyContent: 'space-between' }}>
  405. <span>
  406. 顶部素材
  407. <span style={{ color: 'red' }}>*</span>
  408. <span style={{ fontSize: 14, color: '#696969', marginLeft: 10, fontWeight: 'normal' }}>素材组数量:{topData.length} 组</span>
  409. </span>
  410. <Button type="primary" icon={<PlusOutlined />} onClick={() => { addTopData() }}>添加素材组</Button>
  411. </div>
  412. {elementType === "TOP_IMAGE" ?
  413. <div className={style1.materials}>
  414. {
  415. topData?.map((item: any, index: number) => {
  416. return <div key={index} className={style1.materialImg}>
  417. <BcForm
  418. name={<div>
  419. <span>素材组{index >= 9 ? (index + 1).toString() : '0' + (index + 1).toString()}</span>
  420. <div style={{ fontSize: 12, color: '#169BD5', textAlign: 'center' }}>图片({item.imageUrl ? 1 : 0}/1)</div>
  421. </div>}
  422. flex='flex-start'
  423. >
  424. <div className={style1.box}>
  425. <div className="adui-form-control">
  426. <div className={`upload-img-item ${item.imageUrl ? 'upload-img-item_uploaded' : ''}`}>
  427. {item.imageUrl ? <div className="upload-img-item-inner" style={{ backgroundImage: `url(${item.imageUrl})` }}>
  428. <div className='upload-img-item-action' onClick={() => { clickUpdateImg(index) }}>
  429. <RetweetOutlined />
  430. </div>
  431. </div>
  432. :
  433. <div className="upload-img-item-inner" onClick={() => { clickUpdateImg(index) }}>
  434. <PlusOutlined />
  435. </div>}
  436. </div>
  437. </div>
  438. {topData?.length > 1 && <Popconfirm placement="topLeft" title="确定删除当前素材组?" onConfirm={() => { del(index) }} okText="Yes" cancelText="No">
  439. <Button type="link" danger icon={<DeleteOutlined />} size='small' className={style1.del}></Button>
  440. </Popconfirm>}
  441. </div>
  442. </BcForm>
  443. </div>
  444. })
  445. }
  446. </div>
  447. : elementType === "TOP_SLIDER" ?
  448. <div className={style1.materials}>
  449. {topData.map((item1: any, index1: number) => {
  450. return <div className={style1.material} key={index1} onMouseDown={() => { setGroupIndex(index1) }}>
  451. <BcForm
  452. name={<div>
  453. <span>素材组{index1 >= 9 ? (index1 + 1).toString() : '0' + (index1 + 1).toString()}</span>
  454. <div style={{ fontSize: 12, color: '#169BD5', textAlign: 'center' }}>图片({item1?.imageUrlList?.reduce((prev: number, cur: { url: string }) => cur?.url ? prev + 1 : prev, 0)}/{componentCount})</div>
  455. </div>}
  456. flex='flex-start'
  457. >
  458. <div className={style1.box}>
  459. <SortableUlList axis='xy' onSortEnd={onSortEndSlider} useDragHandle>
  460. {item1?.imageUrlList?.map((item: any, index: number) => {
  461. if (item) {
  462. return <SortableItemLi key={`slider-${index}`} index={index} isActive={item1?.activeIndex === index} pureImageUrl={item} click={() => { sliderSelect(index, index1) }} setActiveIndex={() => { activeIndexHancdle(index, index1) }}></SortableItemLi>
  463. } else {
  464. return <SortableItemNoLi key={`slider-${index}`} index={index} isActive={item1?.activeIndex === index} click={() => { sliderSelect(index, index1) }}></SortableItemNoLi>
  465. }
  466. })}
  467. </SortableUlList>
  468. {topData?.length > 1 && <Popconfirm placement="topLeft" title="确定删除当前素材组?" onConfirm={() => { del(index1) }} okText="Yes" cancelText="No">
  469. <Button type="link" danger icon={<DeleteOutlined />} size='small' className={style1.del}></Button>
  470. </Popconfirm>}
  471. </div>
  472. </BcForm>
  473. </div>
  474. })}
  475. </div> : <>
  476. {/* TOP_VIDEO */}
  477. <div className={style1.materials}>
  478. {
  479. topData?.map((item: any, index: number) => {
  480. return <div key={index} className={style1.materialImg}>
  481. <BcForm
  482. name={<div>
  483. <span>素材组{index >= 9 ? (index + 1).toString() : '0' + (index + 1).toString()}</span>
  484. <div style={{ fontSize: 12, color: '#169BD5', textAlign: 'center' }}>视频({item.videoUrl ? 1 : 0}/1)</div>
  485. </div>}
  486. flex='flex-start'
  487. >
  488. <div className={style1.box}>
  489. <div className="adui-form-control">
  490. <div className={`upload-img-item ${item.pureImageUrl ? 'upload-img-item_uploaded' : ''}`}>
  491. {item.videoUrl ? <div className="upload-img-item-inner">
  492. <video src={item.videoUrl} style={{ maxWidth: 70, maxHeight: 70 }}></video>
  493. <div className='upload-img-item-action' onClick={() => { clickUpdateImg(index) }}>
  494. <RetweetOutlined />
  495. </div>
  496. </div>
  497. :
  498. <div className="upload-img-item-inner" onClick={() => { clickUpdateImg(index) }}>
  499. <PlusOutlined />
  500. </div>}
  501. </div>
  502. </div>
  503. {topData?.length > 1 && <Popconfirm placement="topLeft" title="确定删除当前素材组?" onConfirm={() => { del(index) }} okText="Yes" cancelText="No">
  504. <Button type="link" danger icon={<DeleteOutlined />} size='small' className={style1.del}></Button>
  505. </Popconfirm>}
  506. </div>
  507. </BcForm>
  508. </div>
  509. })
  510. }
  511. </div>
  512. </>}
  513. </> : <></>
  514. }
  515. </Spin>
  516. </Modal>
  517. }
  518. export default React.memo(BathLauCopy)