index.tsx 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import { useModel } from 'umi'
  2. import { Modal, Button, Form, Select, message, Space, Image as AntImg, Upload } from 'antd'
  3. import { SelectValue } from 'antd/es/select'
  4. import Cropprt from '@/components/Cropper'
  5. import React, { useCallback, useEffect, useState } from "react"
  6. const { Option } = Select
  7. import style from './index.less'
  8. import { request } from 'umi'
  9. import { api } from '@/services/api'
  10. import { DeleteOutlined, InboxOutlined } from '@ant-design/icons'
  11. import { RcFile } from 'antd/lib/upload'
  12. import getMD5 from '@/components/MD5'
  13. import { dataURLtoFile, imgMessage } from '@/utils/compress'
  14. const { Dragger } = Upload
  15. type Props = {
  16. visible: boolean,
  17. num?: number, // 上传数量
  18. imgSize?: { width: number, height: number }
  19. // handleOk: () => void
  20. hideModal: (id?: number) => void,
  21. editData?: any,
  22. ajax: any,
  23. dataType: string,
  24. uploadType?: 'img' | 'video'
  25. }
  26. const channelCon = ['朋友圈信息流', '公众平台流量', '广点通', '小程序', '头条', '抖音']
  27. function AddCon(props: Props) {
  28. let { visible, hideModal, editData, ajax, dataType: typeData, uploadType, imgSize, num } = props
  29. const [imgs, setImgs] = useState<string[]>([])
  30. const [video, setVideo] = useState<RcFile>()
  31. const [imgLength, setImgLength] = useState<{ width: number, height: number }>({ width: imgSize?.width || 800, height: imgSize?.height || 800 })
  32. const [queryForm, setQueryForm] = useState<any>({ content: '', labelIds: [], type: 1, channel: '朋友圈信息流', id: undefined, dataType: 'personal' })
  33. const [loading, setLoading] = useState<boolean>(false)
  34. const [fileList, setFileList] = useState<any[]>([])
  35. const { addMedias, getLabels, dataLable } = useModel('useLaunch.useMaterial')
  36. useEffect(() => {
  37. if (editData && typeof editData === 'object' && Object.keys(editData).length > 0) {
  38. let { content, labelIds, type, channel, id, dataType } = editData
  39. setImgs(content?.split(','))
  40. setQueryForm({ content, labelIds: labelIds || [], type, id, channel, dataType })
  41. }
  42. }, [editData])
  43. useEffect(() => {
  44. getLabels.run({ pageNum: 1, pageSize: 200 })
  45. }, [])
  46. /** 选择了图片触发 */
  47. const setImgsHandle = useCallback(async (img: any) => {
  48. if (img) {
  49. if (imgs.length > 0) {
  50. let file = await dataURLtoFile(img, Math.round(new Date() as any / 1000))
  51. let md5 = await getMD5(file)
  52. for (let item of imgs) {
  53. let file = await dataURLtoFile(item, Math.round(new Date() as any / 1000))
  54. let md5s = await getMD5(file)
  55. if (md5 === md5s) {
  56. message.error('重复选择,请选择不同图片!')
  57. return
  58. }
  59. }
  60. let onesCk = await imgMessage([imgs[0]])
  61. let imgCK = await imgMessage([img])
  62. if ((onesCk[0]?.width !== imgCK[0]?.width) || (onesCk[0]?.height !== imgCK[0]?.height)) {
  63. message.error({
  64. content: '上传组图时,需要图片尺寸相同',
  65. duration: 5
  66. })
  67. return
  68. }
  69. }
  70. imgs.push(img)
  71. if (imgs.length > 12) {
  72. message.error('每次最多上传12张')
  73. return
  74. }
  75. setImgs([...imgs])
  76. imgMessage([...imgs]).then((res: any) => {
  77. if (res && res?.length > 0) {
  78. setImgLength({ width: res[0]?.width || 800, height: res[0]?.height })
  79. }
  80. })
  81. }
  82. }, [imgs, imgLength])
  83. /** 设置上传类型 */
  84. useEffect(() => {
  85. if (uploadType) {
  86. if (uploadType === 'img') {
  87. setQueryForm({ ...queryForm, type: 1 })
  88. } else {
  89. setQueryForm({ ...queryForm, type: 2 })
  90. }
  91. }
  92. }, [uploadType])
  93. /** 上传创意 确定 */
  94. const handleOk = useCallback(async () => {
  95. let { labelIds, id } = queryForm
  96. setLoading(true)
  97. if (labelIds.length === 0) { message.error('请选择标签'); return }
  98. dataLable.run({ labelIds: labelIds?.toString(), id, name: 'tagMedia' }).then(res => {
  99. setLoading(false)
  100. setQueryForm({ title: '', labelIds: [], type: 1 })
  101. hideModal()
  102. ajax?.refresh()
  103. })
  104. }, [queryForm, imgs, loading])
  105. const del = useCallback((src: string) => {
  106. let newImgs = imgs.filter((item: string) => item !== src)
  107. setImgs(newImgs)
  108. }, [imgs])
  109. return <Modal visible={visible} width={460} title={
  110. <Space>
  111. <span>修改标签</span>
  112. {/* <Select value={queryForm.type} disabled={queryForm?.id || uploadType} onChange={(value: SelectValue) => { setQueryForm({ ...queryForm, type: value }) }} placeholder="选择类型">
  113. <Option value={1}>图片</Option>
  114. <Option value={2}>视频</Option>
  115. </Select> */}
  116. </Space>
  117. }
  118. onOk={handleOk}
  119. onCancel={() => { hideModal() }}
  120. footer={
  121. <>
  122. <Space>
  123. <Button onClick={() => { hideModal() }}>取消</Button>
  124. <Button type="primary" onClick={handleOk} loading={addMedias?.loading || dataLable?.loading || loading}>{editData && typeof editData === 'object' && Object.keys(editData).length > 0 ? '修改' : '新增'}</Button>
  125. </Space>
  126. </>
  127. }
  128. >
  129. <Form labelCol={{ span: 4 }}>
  130. {/* {
  131. queryForm?.type === 1 ? <Form.Item >
  132. {
  133. !queryForm?.id && <Cropprt disabled={!!(num && num === imgs.length)} imgSize={imgSize} isChangeCropperSize={imgs.length > 0} isLaunch={imgSize && Object.keys(imgSize).length > 0} {...imgLength} callback={(img) => { setImgsHandle(img) }} />
  134. }
  135. {
  136. imgs.length > 0 && <div className={style.imgs}>
  137. <Space wrap>
  138. {imgs?.map((item: string, index: number) => (
  139. <div className={style.imgCon} key={index}>
  140. <AntImg width={60} src={item} preview={false} />
  141. {!queryForm?.id && <div className={style.handle}>
  142. <Space><div className={style.bt} onClick={() => { del(item) }}><DeleteOutlined style={{ color: 'red' }} /></div></Space>
  143. </div>}
  144. </div>
  145. ))}
  146. </Space>
  147. </div>
  148. }
  149. </Form.Item> :
  150. <Form.Item>
  151. {
  152. !queryForm?.id ? <Dragger
  153. accept="video/*"
  154. action=""
  155. maxCount={1}
  156. multiple={false}
  157. customRequest={()=>{}}
  158. fileList={fileList}
  159. beforeUpload={(file: RcFile, FileList: RcFile[]): any => {
  160. const isLt2M = file.size / 1024 / 1024 < 500;
  161. if (!isLt2M) {
  162. message.error('请上传视频小于 500MB!');
  163. return isLt2M;
  164. }
  165. setFileList(FileList)
  166. setVideo(file)
  167. }}
  168. >
  169. <p className="ant-upload-drag-icon">
  170. <InboxOutlined />
  171. </p>
  172. <p className="ant-upload-text">单击或拖动文件到此区域以上载</p>
  173. <p className="ant-upload-hint">
  174. 支持MP4....
  175. </p>
  176. </Dragger> :
  177. <video style={{ width: '100%' }} height={160} src={queryForm?.content} loop={true} autoPlay={false} controls></video>
  178. }
  179. </Form.Item>
  180. } */}
  181. <Form.Item label="标签">
  182. <Select value={queryForm.labelIds} onChange={(value: SelectValue) => { setQueryForm({ ...queryForm, labelIds: value }) }} placeholder="选择标签" mode="tags">
  183. {getLabels?.data?.records.map((item: any) => (<Option value={item?.id} key={item?.id}>{item?.label}</Option>))}
  184. </Select>
  185. </Form.Item>
  186. {/* <Form.Item label="渠道">
  187. <Select value={queryForm.channel} disabled={queryForm?.id} onChange={(value: SelectValue) => { setQueryForm({ ...queryForm, channel: value }) }} placeholder="选择投放渠道">
  188. {channelCon?.map((item: string, index: number) => <Option value={item} key={index}>{item}</Option>)}
  189. </Select>
  190. </Form.Item>
  191. <Form.Item label="数据类型">
  192. <Select value={queryForm.dataType} disabled={queryForm?.id && typeData === 'all'} onChange={(value: SelectValue) => { setQueryForm({ ...queryForm, dataType: value }) }} placeholder="选择数据类型">
  193. <Option value='personal' disabled={queryForm?.id && typeData === 'group'}>个人</Option>
  194. <Option value='group'>组内共享</Option>
  195. <Option value='all'>公司全员共享</Option>
  196. </Select>
  197. </Form.Item> */}
  198. </Form>
  199. </Modal>
  200. }
  201. export default React.memo(AddCon)