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

370 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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>
);
}