Files
cunkebao_v3/Cunkebao/src/components/UploadVideo.tsx

94 lines
2.9 KiB
TypeScript
Raw Normal View History

import React, { useRef } from 'react';
import { Button } from 'tdesign-mobile-react';
import { X } from 'lucide-react';
import { uploadImage } from '@/api/upload';
interface UploadVideoProps {
value?: string;
onChange?: (url: string) => void;
accept?: string;
disabled?: boolean;
}
const VIDEO_BOX_CLASS =
'relative flex items-center justify-center w-full aspect-[16/9] rounded-2xl border-2 border-dashed border-blue-300 bg-gray-50 overflow-hidden';
const UploadVideo: React.FC<UploadVideoProps> = ({
value,
onChange,
accept = 'video/mp4,video/webm,video/ogg,video/quicktime,video/x-msvideo,video/x-ms-wmv,video/x-flv,video/x-matroska',
disabled,
}) => {
const inputRef = useRef<HTMLInputElement>(null);
// 选择文件并上传
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
try {
const url = await uploadImage(file);
onChange?.(url);
} catch (err: any) {
alert(err?.message || '上传失败');
} finally {
if (inputRef.current) inputRef.current.value = '';
}
};
// 触发文件选择
const handleClick = () => {
if (!disabled) inputRef.current?.click();
};
// 删除视频
const handleDelete = () => {
onChange?.('');
};
return (
<div className="flex flex-col items-center w-full">
{!value ? (
<div className={VIDEO_BOX_CLASS}>
<input
ref={inputRef}
type="file"
accept={accept}
style={{ display: 'none' }}
onChange={handleFileChange}
disabled={disabled}
/>
<button
type="button"
className="flex flex-col items-center justify-center w-full h-full bg-transparent border-none outline-none cursor-pointer"
onClick={handleClick}
disabled={disabled}
>
<span className="text-3xl mb-2">🎬</span>
<span className="text-base text-gray-500 font-medium"></span>
<span className="text-xs text-gray-400 mt-1">MP4WebMMOV等格式</span>
</button>
</div>
) : (
<div className={VIDEO_BOX_CLASS}>
<video
src={value}
controls
className="w-full h-full object-cover rounded-2xl bg-black"
style={{ background: '#000' }}
/>
<button
type="button"
className="absolute top-2 right-2 z-10 bg-white/80 hover:bg-white rounded-full p-1 shadow"
onClick={handleDelete}
disabled={disabled}
aria-label="删除视频"
>
<X className="w-5 h-5 text-gray-600" />
</button>
</div>
)}
</div>
);
};
export default UploadVideo;