tiefen_space_h5/app/space/setting/spaceIntroSetting/editStreamerMedia/page.jsx

370 lines
11 KiB
React
Raw Normal View History

2024-10-22 17:24:02 +08:00
"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">
请上传29张照片
</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>
);
}