You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
362 lines
12 KiB
TypeScript
362 lines
12 KiB
TypeScript
import React, { useEffect, useRef, useState } from 'react';
|
|
import { DrawerForm, ProFormInstance, ProFormText, ProFormUploadButton, ProFormRadio, ProForm } from '@ant-design/pro-components';
|
|
import { message } from 'antd';
|
|
import Upload, { RcFile } from 'antd/es/upload';
|
|
import AdvancedEditor from '@/components/TinyMCEEditor/AdvancedEditor';
|
|
import { fullConfig } from '@/components/TinyMCEEditor/config';
|
|
|
|
export type FormValueType = {
|
|
target?: string;
|
|
template?: string;
|
|
type?: string;
|
|
time?: string;
|
|
frequency?: string;
|
|
} & Partial<API.PbcFashionTrend_>;
|
|
|
|
export type UpdateFormProps = {
|
|
onCancel: (flag?: boolean, formVals?: FormValueType) => void;
|
|
onSubmit: (values: FormValueType) => Promise<void>;
|
|
updateModalVisible: boolean;
|
|
values: Partial<API.PbcFashionTrend_>;
|
|
};
|
|
|
|
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
|
|
const formRef = useRef<ProFormInstance>();
|
|
const [pbcType, setPbcType] = useState<number>(1);
|
|
const [videoThumbnail, setVideoThumbnail] = useState<string>("");
|
|
|
|
useEffect(() => {
|
|
setPbcType(props.values.pbcType || 1)
|
|
setVideoThumbnail(props.values.pbcThumbNail || "")
|
|
}, [props.values.pbcId]);
|
|
|
|
// 生成视频缩略图的函数
|
|
const generateVideoThumbnail = async (videoUrl: string) => {
|
|
try {
|
|
// 创建视频元素
|
|
const video = document.createElement('video');
|
|
video.crossOrigin = 'anonymous';
|
|
video.src = videoUrl;
|
|
video.muted = true;
|
|
|
|
// 监听视频加载完成事件
|
|
await new Promise((resolve, reject) => {
|
|
video.onloadeddata = resolve;
|
|
video.onerror = reject;
|
|
// 设置超时
|
|
setTimeout(reject, 5000);
|
|
});
|
|
|
|
// 播放视频并暂停在第一帧
|
|
video.currentTime = 0;
|
|
await new Promise(resolve => {setTimeout(resolve, 200)});
|
|
|
|
// 创建canvas并绘制视频帧
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = video.videoWidth;
|
|
canvas.height = video.videoHeight;
|
|
const ctx = canvas.getContext('2d');
|
|
ctx?.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
|
|
// 将canvas转为blob
|
|
const blob = await new Promise<Blob>((resolve) => {
|
|
canvas.toBlob((b) => resolve(b as Blob), 'image/jpeg', 0.95);
|
|
});
|
|
|
|
// 创建FormData并上传
|
|
const formData = new FormData();
|
|
formData.append('file', blob, 'thumbnail.jpg');
|
|
|
|
// 发送请求上传缩略图
|
|
const response = await fetch(`${process.env.BASE_URL}/oss/imgUpload`, {
|
|
method: 'POST',
|
|
headers: {
|
|
authorization: localStorage.getItem('token') ?? '',
|
|
},
|
|
body: formData,
|
|
});
|
|
|
|
const result = await response.json();
|
|
if (result.retcode) {
|
|
setVideoThumbnail(result.data);
|
|
}
|
|
} catch (error) {
|
|
console.error('生成视频缩略图失败:', error);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<DrawerForm
|
|
width={640}
|
|
title={props.values.pbcId ? '编辑流行趋势' : '新增流行趋势'}
|
|
open={props.updateModalVisible}
|
|
formRef={formRef}
|
|
onFinish={async (value: any) => {
|
|
let pbcPicAddress = ""
|
|
let pbcThumbNail = "https://oss-xfc.popshejie.com/pop-b2b2c/pdf_fac16828-ea35-4034-9ad8-263605611960.png"
|
|
if (value.pbcType === 1 && value.pbcImage.length > 0) {
|
|
pbcThumbNail = value.pbcImage[0].url || value.pbcImage[0].response.data;
|
|
pbcPicAddress = value.pbcImage.map((e: any) => {
|
|
return e.url || e.response.data;
|
|
}).join(',');
|
|
} else if (value.pbcType === 2 && value.pbcVideo.length > 0) {
|
|
pbcPicAddress = value.pbcVideo[0].url || value.pbcVideo[0].response.data;
|
|
pbcThumbNail = videoThumbnail;
|
|
} else if (value.pbcType === 3 && value.pbcFile.length > 0) {
|
|
pbcPicAddress = value.pbcFile[0].url || value.pbcFile[0].response.data;
|
|
if (value.pbcThumbNail.length > 0) {
|
|
pbcThumbNail = value.pbcThumbNail[0].url || value.pbcThumbNail[0].response.data;
|
|
}
|
|
}
|
|
return props.onSubmit({ ...value, pbcPicAddress, pbcThumbNail, pbcContent: value.pbcType === 3 ? '预览文件' : value.pbcContent, pbcId: props.values.pbcId })
|
|
}}
|
|
drawerProps={{
|
|
destroyOnHidden: true,
|
|
}}
|
|
initialValues={{
|
|
pbcTitle: props.values.pbcTitle,
|
|
pbcType: props.values.pbcType || 1,
|
|
pbcImage: props.values.pbcType === 1 && props.values.pbcPicAddress ? props.values.pbcPicAddress.split(',').map((e, index) => {
|
|
return {
|
|
uid: '-' + index,
|
|
name: e.substring(e.lastIndexOf('/') + 1),
|
|
status: 'done',
|
|
url: e,
|
|
}
|
|
}) : [],
|
|
pbcVideo: props.values.pbcType === 2 && props.values.pbcPicAddress ? [{
|
|
uid: '-1',
|
|
name: props.values.pbcPicAddress.substring(props.values.pbcPicAddress.lastIndexOf('/') + 1),
|
|
status: 'done',
|
|
url: props.values.pbcPicAddress,
|
|
}] : [],
|
|
pbcFile: props.values.pbcType === 3 && props.values.pbcPicAddress ? [{
|
|
uid: '-1',
|
|
name: props.values.pbcPicAddress.substring(props.values.pbcPicAddress.lastIndexOf('/') + 1),
|
|
status: 'done',
|
|
url: props.values.pbcPicAddress,
|
|
}] : [],
|
|
pbcThumbNail: props.values.pbcType === 3 && props.values.pbcThumbNail ? [{
|
|
uid: '-1',
|
|
name: props.values.pbcThumbNail.substring(props.values.pbcThumbNail.lastIndexOf('/') + 1),
|
|
status: 'done',
|
|
url: props.values.pbcThumbNail,
|
|
}] : [],
|
|
pbcContent: props.values.pbcContent
|
|
}}
|
|
onOpenChange={(visible) => {
|
|
formRef.current?.resetFields();
|
|
if (!visible) {
|
|
props.onCancel();
|
|
}
|
|
}}
|
|
>
|
|
<ProFormText
|
|
placeholder={'请输入标题'}
|
|
label="标题"
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: '标题为必填项',
|
|
},
|
|
]}
|
|
width="md"
|
|
name="pbcTitle"
|
|
/>
|
|
<ProFormRadio.Group
|
|
name="pbcType"
|
|
label="类型"
|
|
options={[
|
|
{
|
|
label: '图片',
|
|
value: 1,
|
|
},
|
|
{
|
|
label: '视频',
|
|
value: 2,
|
|
},
|
|
{
|
|
label: '文件',
|
|
value: 3,
|
|
},
|
|
]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: '请选择类型',
|
|
},
|
|
]}
|
|
fieldProps={{
|
|
onChange: (e) => {
|
|
setPbcType(e.target.value)
|
|
formRef.current?.setFieldValue('pbcImage', []);
|
|
formRef.current?.setFieldValue('pbcThumbNail', []);
|
|
formRef.current?.setFieldValue('pbcVideo', []);
|
|
formRef.current?.setFieldValue('pbcFile', []);
|
|
},
|
|
}}
|
|
/>
|
|
{pbcType === 3 ? <ProFormUploadButton
|
|
label="缩略图"
|
|
name="pbcThumbNail"
|
|
max={1}
|
|
fieldProps={{
|
|
name: 'file',
|
|
accept: 'image/*',
|
|
multiple: true,
|
|
headers: {
|
|
authorization: localStorage.getItem('token') ?? '',
|
|
},
|
|
onChange: (info: any) => {
|
|
switch (info.file.status) {
|
|
case 'done':
|
|
if (info.file.response.retcode === 0) {
|
|
message.error(info.file.response.retmsg);
|
|
formRef.current?.setFieldValue('pbcThumbNail', [])
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
action: process.env.BASE_URL + '/oss/imgUpload',
|
|
beforeUpload(file: RcFile) {
|
|
const isLt10M = file.size / 1024 / 1024 < 10;
|
|
if (!isLt10M) {
|
|
message.error('图片大小不能超过10MB!');
|
|
}
|
|
return isLt10M || Upload.LIST_IGNORE;
|
|
},
|
|
onPreview: async (file) => {
|
|
if (file.uid.includes('-')) {
|
|
window.open(file.url);
|
|
}
|
|
if (file.response && file.response.retcode) {
|
|
window.open(file.response.data);
|
|
}
|
|
},
|
|
listType: 'picture-card',
|
|
}}
|
|
rules={[
|
|
{ required: true, message: '请上传缩略图' },
|
|
]}
|
|
/> : null}
|
|
{pbcType === 1 ? <ProFormUploadButton
|
|
label="上传图片"
|
|
name="pbcImage"
|
|
max={9}
|
|
fieldProps={{
|
|
name: 'file',
|
|
accept: 'image/*',
|
|
multiple: true,
|
|
headers: {
|
|
authorization: localStorage.getItem('token') ?? '',
|
|
},
|
|
onChange: (info: any) => {
|
|
switch (info.file.status) {
|
|
case 'done':
|
|
if (info.file.response.retcode === 0) {
|
|
message.error(info.file.response.retmsg);
|
|
formRef.current?.setFieldValue('pbcImage', [])
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
action: process.env.BASE_URL + '/oss/imgUpload',
|
|
beforeUpload(file: RcFile) {
|
|
const isLt10M = file.size / 1024 / 1024 < 10;
|
|
if (!isLt10M) {
|
|
message.error('图片大小不能超过10MB!');
|
|
}
|
|
return isLt10M || Upload.LIST_IGNORE;
|
|
},
|
|
onPreview: async (file) => {
|
|
if (file.uid.includes('-')) {
|
|
window.open(file.url);
|
|
}
|
|
if (file.response && file.response.retcode) {
|
|
window.open(file.response.data);
|
|
}
|
|
},
|
|
listType: 'picture-card',
|
|
}}
|
|
rules={[
|
|
{ required: true, message: '请上传图片' },
|
|
]}
|
|
/> :
|
|
<ProFormUploadButton
|
|
label={pbcType === 2 ? "上传视频" : "上传文件"}
|
|
name={pbcType === 2 ? "pbcVideo" : "pbcFile"}
|
|
max={1}
|
|
fieldProps={{
|
|
name: 'file',
|
|
accept: pbcType === 2 ? 'video/mp4' : '.pdf',
|
|
multiple: true,
|
|
headers: {
|
|
authorization: localStorage.getItem('token') ?? '',
|
|
},
|
|
onChange: (info: any) => {
|
|
switch (info.file.status) {
|
|
case 'done':
|
|
if (info.file.response.retcode === 0) {
|
|
message.error(info.file.response.retmsg);
|
|
if (pbcType === 2) {
|
|
formRef.current?.setFieldValue('pbcVideo', [])
|
|
} else {
|
|
formRef.current?.setFieldValue('pbcFile', [])
|
|
}
|
|
} else if (info.file.response && info.file.response.retcode && pbcType === 2) {
|
|
// 视频上传成功后,获取视频首帧作为缩略图
|
|
const videoUrl = info.file.response.data;
|
|
generateVideoThumbnail(videoUrl);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
action: process.env.BASE_URL + '/oss/imgUpload',
|
|
beforeUpload(file: RcFile) {
|
|
const isLt300M = file.size / 1024 / 1024 < 300;
|
|
if (!isLt300M) {
|
|
message.error(`${pbcType === 2 ? '视频' : '文件'}大小不能超过300MB!`);
|
|
}
|
|
return isLt300M || Upload.LIST_IGNORE;
|
|
},
|
|
onPreview: async (file) => {
|
|
if (file.uid === '-1') {
|
|
window.open(file.url);
|
|
}
|
|
if (file.response && file.response.retcode) {
|
|
window.open(file.response.data);
|
|
}
|
|
},
|
|
listType: 'picture-card',
|
|
}}
|
|
rules={[
|
|
{ required: true, message: `请上传${pbcType === 2 ? '视频' : '文件'}'` },
|
|
]}
|
|
/>}
|
|
{pbcType !== 3 ? <ProForm.Item
|
|
name="pbcContent"
|
|
label="趋势内容"
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: '趋势内容为必填项',
|
|
},
|
|
]}
|
|
>
|
|
<AdvancedEditor
|
|
height={500}
|
|
placeholder="请输入内容"
|
|
customConfig={fullConfig}
|
|
/>
|
|
</ProForm.Item>:null}
|
|
</DrawerForm>
|
|
);
|
|
};
|
|
|
|
export default UpdateForm; |