370 lines
11 KiB
React
370 lines
11 KiB
React
|
"use client";
|
|||
|
import React, { useState, useRef, useEffect } from "react";
|
|||
|
import { Toast, Button, Divider, Image } from "antd-mobile";
|
|||
|
import { useRouter } from "next/navigation";
|
|||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||
|
import { faAngleRight, faAngleLeft } from "@fortawesome/free-solid-svg-icons";
|
|||
|
import UploadImgs from "@/components/UploadImgs";
|
|||
|
import requireAPI from "@/utils/requireAPI";
|
|||
|
import { multiUploadImage } from "@/utils/upload";
|
|||
|
export default function EditStreamerMedia() {
|
|||
|
const router = useRouter();
|
|||
|
//保存封面图
|
|||
|
const [loading, setLoading] = useState(false);
|
|||
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|||
|
const [oldPhotos, setOldPhotos] = useState([]);
|
|||
|
const [frameImageUrl, setFrameImageUrl] = useState(null);
|
|||
|
const [formData, setFormData] = useState({
|
|||
|
imageAssets: [],
|
|||
|
displayImage: null,
|
|||
|
displayVideo: null,
|
|||
|
});
|
|||
|
const ref = useRef(null);
|
|||
|
useEffect(() => {
|
|||
|
getData();
|
|||
|
}, []);
|
|||
|
const getData = async () => {
|
|||
|
try {
|
|||
|
//获取主播数据
|
|||
|
const streamerData = await requireAPI(
|
|||
|
"POST",
|
|||
|
"/api/streamer/list_by_mid",
|
|||
|
{},
|
|||
|
true
|
|||
|
);
|
|||
|
if (streamerData.ret === -1) {
|
|||
|
Toast.show({
|
|||
|
icon: "fail",
|
|||
|
content: streamerData.msg,
|
|||
|
position: "top",
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
// setDisplayImage([
|
|||
|
// {
|
|||
|
// notChanged: true,
|
|||
|
// id: { image_ids: streamerData.data.streamer.cover.image_ids },
|
|||
|
// uri: streamerData.data.streamer.cover.images[0].urls[0],
|
|||
|
// },
|
|||
|
// ]);
|
|||
|
// setDisplayVideo([
|
|||
|
// {
|
|||
|
// notChanged: true,
|
|||
|
// id: { video_ids: streamerData.data.streamer.shorts.video_ids },
|
|||
|
// cover: streamerData?.data?.streamer?.shorts?.videos[0]?.cover_urls[0],
|
|||
|
// },
|
|||
|
// ]);
|
|||
|
// setOldPhotos(streamerData.data.streamer.album.images);
|
|||
|
setFormData((old) => ({
|
|||
|
...old,
|
|||
|
displayImage: {
|
|||
|
url: streamerData.data.streamer.cover.images[0].urls[0],
|
|||
|
id: streamerData.data.streamer.cover.images[0].id,
|
|||
|
image_ids: [streamerData.data.streamer.cover.images[0].id],
|
|||
|
},
|
|||
|
displayVideo: {
|
|||
|
url: streamerData?.data?.streamer?.shorts?.videos[0]?.cover_urls[0],
|
|||
|
id: streamerData?.data?.streamer?.shorts?.videos[0]?.id,
|
|||
|
video_ids: [streamerData?.data?.streamer?.shorts?.videos[0]?.id],
|
|||
|
},
|
|||
|
}));
|
|||
|
setOldPhotos(
|
|||
|
streamerData.data.streamer.album.images.map((item) => ({
|
|||
|
url: item.urls[0],
|
|||
|
id: item.id,
|
|||
|
}))
|
|||
|
);
|
|||
|
setLoading(false);
|
|||
|
} catch (error) {
|
|||
|
console.error(error);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const handleUploadImage = async (e, type) => {
|
|||
|
let file = e.target.files[0];
|
|||
|
if (!file) return;
|
|||
|
setLoading(true);
|
|||
|
if (type == 1) {
|
|||
|
setFormData((old) => ({
|
|||
|
...old,
|
|||
|
displayImage: {
|
|||
|
url: URL.createObjectURL(file),
|
|||
|
file: Array.from(e.target.files),
|
|||
|
},
|
|||
|
}));
|
|||
|
} else {
|
|||
|
creatVideoCanvas(file);
|
|||
|
setFormData((old) => ({
|
|||
|
...old,
|
|||
|
displayVideo: {
|
|||
|
url: frameImageUrl,
|
|||
|
file: Array.from(e.target.files),
|
|||
|
},
|
|||
|
}));
|
|||
|
}
|
|||
|
setLoading(false);
|
|||
|
};
|
|||
|
|
|||
|
const handleSubmit = async () => {
|
|||
|
//相册不得低于2张
|
|||
|
if (formData.imageAssets.length < 2) {
|
|||
|
Toast.show({
|
|||
|
icon: "fail",
|
|||
|
content: "相册至少需要上传2张照片哦!",
|
|||
|
position: "top",
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
//相册不得超过9张
|
|||
|
if (formData.imageAssets.length > 9) {
|
|||
|
Toast.show({
|
|||
|
icon: "fail",
|
|||
|
content: "相册最多只能上传9张照片哦!",
|
|||
|
position: "top",
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
setIsSubmitting(true);
|
|||
|
const { displayImage, displayVideo, imageAssets } = formData;
|
|||
|
const cover = displayImage?.id
|
|||
|
? displayImage
|
|||
|
: await multiUploadImage(displayImage.file, 1);
|
|||
|
const shorts = displayVideo?.id
|
|||
|
? displayVideo
|
|||
|
: await multiUploadImage(displayVideo.file, 2);
|
|||
|
const newMedia = imageAssets.filter((it) => it.id == undefined);
|
|||
|
const media = await multiUploadImage(newMedia, 1);
|
|||
|
const album = {
|
|||
|
image_ids: [
|
|||
|
...imageAssets.filter((it) => it.id != undefined).map((it) => it.id),
|
|||
|
...media.image_ids,
|
|||
|
],
|
|||
|
};
|
|||
|
if (
|
|||
|
!cover.image_ids.length ||
|
|||
|
!shorts.video_ids.length ||
|
|||
|
!album.image_ids.length
|
|||
|
) {
|
|||
|
Toast.show({
|
|||
|
icon: "fail",
|
|||
|
content: "上传失败,请联系客服进行上传",
|
|||
|
position: "top",
|
|||
|
});
|
|||
|
setIsSubmitting(false);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//上传表单
|
|||
|
try {
|
|||
|
const streamerData = await requireAPI(
|
|||
|
"POST",
|
|||
|
"/api/streamer/update",
|
|||
|
{
|
|||
|
body: {
|
|||
|
cover: cover,
|
|||
|
shorts: shorts,
|
|||
|
album: album,
|
|||
|
},
|
|||
|
},
|
|||
|
true
|
|||
|
);
|
|||
|
if (streamerData.ret === -1) {
|
|||
|
Toast.show({
|
|||
|
icon: "fail",
|
|||
|
content: streamerData.msg,
|
|||
|
position: "top",
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
//提交成功后弹窗提示并返回上级
|
|||
|
Toast.show({
|
|||
|
icon: "fail",
|
|||
|
content: "提交成功,等耐心等待审核",
|
|||
|
position: "top",
|
|||
|
});
|
|||
|
router.back();
|
|||
|
} catch (error) {
|
|||
|
console.error(error);
|
|||
|
} finally {
|
|||
|
setIsSubmitting(false);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const creatVideoCanvas = (file) => {
|
|||
|
if (typeof window == "undefined") return;
|
|||
|
const videoD = document.getElementById("videoD");
|
|||
|
const url = URL.createObjectURL(file);
|
|||
|
videoD.src = url;
|
|||
|
videoD.addEventListener("loadeddata", function () {
|
|||
|
const canvas = document.createElement("canvas");
|
|||
|
canvas.width = videoD.videoWidth;
|
|||
|
canvas.height = videoD.videoHeight;
|
|||
|
canvas
|
|||
|
.getContext("2d")
|
|||
|
.drawImage(videoD, 0, 0, canvas.width, canvas.height);
|
|||
|
const canvasImg = canvas.toDataURL();
|
|||
|
setFrameImageUrl(canvasImg);
|
|||
|
|
|||
|
// 释放URL对象
|
|||
|
URL.revokeObjectURL(url);
|
|||
|
});
|
|||
|
};
|
|||
|
return (
|
|||
|
<div>
|
|||
|
{/* 头部标题 */}
|
|||
|
<div className="p-4 fixed top-0 z-10 w-full bg-black">
|
|||
|
<div className="w-9 h-9 flex items-center justify-center bg-[#FFFFFF1A] rounded-full absolute">
|
|||
|
<FontAwesomeIcon
|
|||
|
icon={faAngleLeft}
|
|||
|
style={{ maxWidth: "12px" }}
|
|||
|
size="xl"
|
|||
|
onClick={() => {
|
|||
|
router.back();
|
|||
|
}}
|
|||
|
/>
|
|||
|
</div>
|
|||
|
<p className="text-base text-center leading-9">照片墙</p>
|
|||
|
</div>
|
|||
|
{/* 内容 */}
|
|||
|
<div className="pt-16 p-4">
|
|||
|
<p className="text-sm text-[#F53030] font-medium">
|
|||
|
将展示在“推荐”、“主页”、“空间”,请认真完善
|
|||
|
</p>
|
|||
|
<div className=" my-2 py-4 bg-[#FFFFFF1A] px-3 rounded-2xl">
|
|||
|
<ul>
|
|||
|
<li className="flex justify-between items-center">
|
|||
|
<p className="text-base font-medium">
|
|||
|
<span className="text-[#F53030]">*</span>
|
|||
|
封面图
|
|||
|
</p>
|
|||
|
<label htmlFor="uploadBtn1">
|
|||
|
<div className="flex items-center">
|
|||
|
{formData?.displayImage ? (
|
|||
|
<Image
|
|||
|
width={36}
|
|||
|
height={36}
|
|||
|
className="rounded-lg"
|
|||
|
src={formData.displayImage?.url}
|
|||
|
fit="cover"
|
|||
|
/>
|
|||
|
) : (
|
|||
|
<span className="text-xs text-[#FFFFFF80] font-medium whitespace-nowrap">
|
|||
|
请尽量选择横屏照片
|
|||
|
</span>
|
|||
|
)}
|
|||
|
<div className="ml-2">
|
|||
|
<FontAwesomeIcon
|
|||
|
icon={faAngleRight}
|
|||
|
style={{ maxWidth: "12px" }}
|
|||
|
size="xl"
|
|||
|
/>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</label>
|
|||
|
<div className="hidden">
|
|||
|
<input
|
|||
|
type="file"
|
|||
|
accept="image/png, image/jpeg, image/jpg"
|
|||
|
ref={ref}
|
|||
|
id="uploadBtn1"
|
|||
|
onChange={(e) => handleUploadImage(e, 1)}
|
|||
|
/>
|
|||
|
</div>
|
|||
|
</li>
|
|||
|
<Divider />
|
|||
|
<li className="flex justify-between items-center">
|
|||
|
<p className="text-base font-medium">
|
|||
|
<span className="text-[#F53030]">*</span>
|
|||
|
展示视频
|
|||
|
</p>
|
|||
|
<label htmlFor="uploadBtn2">
|
|||
|
<div
|
|||
|
// onClick={() => pickDisPlayImage()}
|
|||
|
className="flex items-center"
|
|||
|
>
|
|||
|
{formData?.displayVideo ? (
|
|||
|
<Image
|
|||
|
width={36}
|
|||
|
height={36}
|
|||
|
className="rounded-lg"
|
|||
|
src={frameImageUrl || formData.displayVideo.url}
|
|||
|
fit="cover"
|
|||
|
/>
|
|||
|
) : (
|
|||
|
<span className="text-xs text-[#FFFFFF80] font-medium whitespace-nowrap">
|
|||
|
请尽量选择横屏照片
|
|||
|
</span>
|
|||
|
)}
|
|||
|
<div className="ml-2">
|
|||
|
<FontAwesomeIcon
|
|||
|
icon={faAngleRight}
|
|||
|
style={{ maxWidth: "12px" }}
|
|||
|
size="xl"
|
|||
|
/>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</label>
|
|||
|
|
|||
|
<div className="hidden">
|
|||
|
<input
|
|||
|
type="file"
|
|||
|
accept="video/*"
|
|||
|
ref={ref}
|
|||
|
id="uploadBtn2"
|
|||
|
onChange={(e) => handleUploadImage(e, 2)}
|
|||
|
/>
|
|||
|
</div>
|
|||
|
</li>
|
|||
|
<Divider />
|
|||
|
<li>
|
|||
|
<div className="flex justify-between items-center">
|
|||
|
<p className="text-base font-medium">
|
|||
|
<span className="text-[#F53030]">*</span>
|
|||
|
相册
|
|||
|
</p>
|
|||
|
<div
|
|||
|
// onClick={() => pickDisPlayImage()}
|
|||
|
>
|
|||
|
<span className="text-xs text-[#FFFFFF80] font-medium">
|
|||
|
请上传2~9张照片
|
|||
|
</span>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div className="mt-2">
|
|||
|
<UploadImgs
|
|||
|
type={1}
|
|||
|
existImages={oldPhotos}
|
|||
|
assets={formData.imageAssets}
|
|||
|
getImgs={(imgs) =>
|
|||
|
setFormData((old) => ({ ...old, imageAssets: imgs }))
|
|||
|
}
|
|||
|
/>
|
|||
|
</div>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
<div className="mt-16">
|
|||
|
<Button
|
|||
|
shape="rounded"
|
|||
|
size="middle"
|
|||
|
block
|
|||
|
disabled={isSubmitting}
|
|||
|
// disabledStyle={tailwind("bg-[#FFFFFF80]")}
|
|||
|
onClick={handleSubmit}
|
|||
|
style={{ "--background-color": "#FF669E" }}
|
|||
|
>
|
|||
|
{/* {isSubmitting && <ActivityIndicator size="small" color="white" />} */}
|
|||
|
{isSubmitting ? "正在保存..." : "保存设置"}
|
|||
|
</Button>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div className="hidden">
|
|||
|
<video id="videoD" controls autoPlay name="media">
|
|||
|
<source />
|
|||
|
您的浏览器不支持 Video 标签。
|
|||
|
</video>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
);
|
|||
|
}
|