tiefen_space_h5/app/space/editSpacePost/page.jsx

467 lines
15 KiB
React
Raw Normal View History

2024-10-22 17:24:02 +08:00
"use client";
2024-10-25 19:19:41 +08:00
import React, { useState, useEffect, useMemo, useCallback } from "react";
2024-10-22 17:24:02 +08:00
import { DotLoading, Popup, Toast, TextArea, Switch } from "antd-mobile";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import requireAPI from "@/utils/requireAPI";
import { useRouter, useSearchParams } from "next/navigation";
import { multiUploadImage } from "@/utils/upload";
import UploadImgs from "@/components/UploadImgs";
import OwnInput from "@/components/OwnInput";
export default function EditSpacePost() {
const searchParams = useSearchParams();
const [data, setData] = useState(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const [priceEdit, setPriceEdit] = useState(false);
//价格
const [formData, setFormData] = useState({
2024-10-29 18:55:18 +08:00
price: "",
2024-10-22 17:24:02 +08:00
content: "",
paidText: "",
imageAssets: [],
imageVisibleRange: 0,
isCreatingPaidText: false,
isFreeForIronfan: false,
});
const [priceEditData, setPriceEditData] = useState({
2024-10-29 18:55:18 +08:00
price: "",
2024-10-22 17:24:02 +08:00
imageVisibleRange: 1,
isCreatingPaidText: false,
isFreeForIronfan: false,
blurCover: true,
});
const router = useRouter();
useEffect(() => {
const dataStr = searchParams.get("data");
const data = JSON.parse(decodeURIComponent(dataStr));
setData(data);
const publicData = {
price: data?.price ? data?.price / 100 : 0,
imageVisibleRange: data?.media_visible_range,
isCreatingPaidText: data?.is_creating_paid_text,
isFreeForIronfan: data?.is_ironfan_visible,
blurCover: data?.is_blurring_cover == 1,
};
2024-10-25 19:19:41 +08:00
// const imgs = getExistImgs(data);
2024-10-22 17:24:02 +08:00
setFormData({
content: data?.paid_text
? data?.text.slice(0, data?.text.length - data?.paid_text.length)
: data?.text,
paidText: data?.paid_text,
imageAssets: [],
...publicData,
});
setPriceEditData(publicData);
}, []);
//发布内容
const handleSubmit = async () => {
if (formData.content == "") {
Toast.show({
icon: "fail",
content: "动态内容不能为空",
position: "top",
});
return;
}
2024-10-25 19:19:41 +08:00
if (data?.m_type && formData.imageAssets.length === 0) {
2024-10-22 17:24:02 +08:00
Toast.show({
icon: "fail",
content: "请上传至少一张图片",
position: "top",
});
return;
}
if (data?.m_type == 1) {
if (
parseFloat(formData.price) &&
formData.imageAssets.length <= parseInt(formData.imageVisibleRange, 10)
) {
Toast.show({
icon: "fail",
content: "预览图片数不得大于等于上传图片数",
position: "top",
});
return;
}
}
if (
formData.isCreatingPaidText &&
formData.price > 0 &&
formData.paidText == ""
) {
Toast.show({
icon: "fail",
content: "请填写付费文案",
position: "top",
});
return;
}
//提交数据
if (isSubmitting) return;
setIsSubmitting(true);
const {
price,
isFreeForIronfan,
content,
imageAssets,
textVisibleRange,
imageVisibleRange,
isCreatingPaidText,
paidText,
blurCover,
} = formData;
const mType = data?.m_type;
const newMedia = imageAssets.filter((it) => it.id == undefined);
const media = await multiUploadImage(newMedia, mType);
if (mType == 1) {
media.image_ids = [
...imageAssets.filter((it) => it.id != undefined).map((it) => it.id),
...media.image_ids,
];
} else {
media.video_ids = [
...imageAssets.filter((it) => it.id != undefined).map((it) => it.id),
...media.video_ids,
];
}
2024-10-25 19:19:41 +08:00
2024-10-22 17:24:02 +08:00
try {
const body = {
id: data.id,
c_type: parseInt(price) ? 1 : 0,
is_ironfan_visible: isFreeForIronfan ? 1 : 0,
m_type: mType,
text: content,
media_component: media,
text_visible_range: textVisibleRange
? parseInt(textVisibleRange, 10)
: 999,
media_visible_range: imageVisibleRange
? parseInt(imageVisibleRange, 10)
: 1,
is_blurring_cover: blurCover ? 1 : 0,
price: parseFloat(price) ? parseInt(parseFloat(price) * 100, 10) : null,
is_creating_paid_text: isCreatingPaidText && price > 0 ? 1 : 0,
paid_text: isCreatingPaidText && price > 0 ? paidText : null,
};
2024-10-25 19:19:41 +08:00
2024-10-22 17:24:02 +08:00
const _data = await requireAPI("POST", "/api/zone_moment/update", {
body,
});
if (_data.ret === -1) {
Toast.show({
icon: "fail",
content: _data.msg,
position: "top",
});
return;
}
//提交成功后显示Toast并返回上一页
Toast.show({
icon: "success",
content: "提交成功,等耐心等待审核",
position: "top",
});
router.back();
} catch (error) {
console.error(error);
} finally {
setIsSubmitting(false);
}
};
2024-10-25 19:19:41 +08:00
const getExistImgs = useMemo(() => {
if (data) {
const list =
data?.m_type === 1
? data.media_component.images
: data.media_component.videos;
const imgs = list.map((it, index) =>
data?.m_type === 1
? {
url: it.urls[0],
id: data.media_component.image_ids[index],
}
: {
url: it.cover_urls[0],
id: data.media_component.video_ids[index],
}
);
return imgs;
}
return [];
}, [data]);
useEffect(() => {
setFormData((old) => ({ ...old, imageAssets: getExistImgs }));
}, [getExistImgs]);
2024-10-22 17:24:02 +08:00
return (
<div className="flex-1">
{/* 头部标题 */}
<div className="p-4 fixed top-0 z-10 w-full flex justify-between items-center bg-black">
<div className="w-9 h-9 flex items-center justify-center bg-[#FFFFFF1A] rounded-full">
<FontAwesomeIcon
icon={faAngleLeft}
style={{ maxWidth: "12px" }}
size="xl"
onClick={() => {
router.back();
}}
/>
</div>
<p className="text-base text-center leading-9">重新编辑</p>
{isSubmitting ? (
<DotLoading />
) : (
<span className="text-primary text-lg" onClick={handleSubmit}>
发布
</span>
)}
</div>
{/* 内容 */}
<div className="pt-16 p-4">
2024-10-25 19:19:41 +08:00
{data?.status === 3 &&
(data.text_audit_opinion ||
data.image_audit_opinion ||
data.manually_review_opinion) && (
<div className="mb-4">
<span className="text-base font-medium text-[#F53030] mb-2">
违规详情
</span>
<div className="mt-2 p-4 rounded-2xl bg-[#FFFFFF1A]">
{data.text_audit_opinion && (
<span className="text-sm font-medium text-white">
<span className="text-[#F53030]">文案违规原因</span>
{data.text_audit_opinion}
</span>
)}
{data.image_audit_opinion && (
<span className="text-sm font-medium text-white">
<span className="text-[#F53030]">图片/视频违规原因</span>
{data.image_audit_opinion}
</span>
)}
{data.manually_review_opinion && (
<span className="text-sm font-medium text-white">
<span className="text-[#F53030]">运营追加</span>
{data.manually_review_opinion}
</span>
)}
</div>
2024-10-22 17:24:02 +08:00
</div>
2024-10-25 19:19:41 +08:00
)}
2024-10-22 17:24:02 +08:00
<div className="mt-2">
<p className="text-base font-medium text-white">动态内容</p>
2024-10-29 18:55:18 +08:00
<div className="h-32">
<TextArea
placeholder="请遵守平台准则,严禁发布违规内容"
value={formData.content}
onChange={(value) =>
setFormData((old) => ({ ...old, content: value }))
}
autoSize={{ minRows: 6, maxRows: 15 }}
style={{ "--font-size": "14px" }}
className="h-full bg-[#FFFFFF1A] rounded-2xl mt-2 mb-4 p-2"
/>
</div>
2024-10-22 17:24:02 +08:00
{!!formData.isCreatingPaidText && formData.price > 0 && (
2024-10-29 18:55:18 +08:00
<div className="mt-2">
2024-10-22 17:24:02 +08:00
<span className="text-base font-medium text-white">付费文案</span>
2024-10-29 18:55:18 +08:00
<div className="h-32">
<TextArea
placeholder="仅在用户解锁后展示,请勿发布违规内容"
onChange={(value) =>
setFormData((old) => ({
...old,
paidText: value,
}))
}
autoSize={{ minRows: 6, maxRows: 15 }}
value={formData.paidText && formData.paidText.slice(2)}
style={{ "--font-size": "14px" }}
className="bg-[#FFFFFF1A] rounded-2xl mt-2 mb-4 p-2 h-full"
/>
</div>
</div>
2024-10-22 17:24:02 +08:00
)}
</div>
{data?.m_type && (
2024-10-29 18:55:18 +08:00
<div className="mt-2">
2024-10-22 17:24:02 +08:00
<UploadImgs
type={data?.m_type}
2024-10-25 19:19:41 +08:00
existImages={getExistImgs}
2024-10-22 17:24:02 +08:00
accept={
data?.m_type === 1
? "image/png, image/jpeg, image/jpg"
: "video/*"
}
assets={formData.imageAssets}
videoSrc={data.media_component?.videos[0]?.urls[0]}
getImgs={(imgs) =>
setFormData((old) => ({ ...old, imageAssets: imgs }))
}
/>
</div>
)}
{data?.c_type === 1 && (
<div
color="#FF669E"
radius="999"
size="md"
className="mt-4 w-28 bg-primary rounded-full text-center text-base py-2"
onClick={() => setPriceEdit(true)}
>
付费设置
</div>
)}
</div>
<Popup
visible={priceEdit}
onMaskClick={() => {
setPriceEdit(false);
}}
className="p-4"
bodyStyle={{
borderRadius: "16px",
width: "calc(100% - 48px)",
margin: "24px",
padding: "14px",
}}
>
<div
style={{
gap: 8,
}}
className="flex flex-col py-2"
>
<div className="flex flex-row items-center">
2024-10-25 19:19:41 +08:00
<span className="text-base font-medium whitespace-nowrap">
2024-10-22 17:24:02 +08:00
价格¥
</span>
2024-10-25 19:19:41 +08:00
<div className="px-2 mx-1 rounded-full bg-[#ffffff1a]">
2024-10-22 17:24:02 +08:00
<OwnInput
placeholder="¥13000"
placeholderTextColor="#FFFFFF80"
keyboardType="numeric"
underlineColorAndroid="transparent"
onChange={(value) =>
setPriceEditData((old) => ({ ...old, price: value }))
}
value={priceEditData.price}
2024-10-25 19:19:41 +08:00
// className="flex-1 bg-[#FFFFFF1A] rounded-2xl px-4 h-8 mx-2"
2024-10-22 17:24:02 +08:00
/>
</div>
<span
onClick={() =>
setPriceEditData((old) => ({ ...old, price: "0" }))
}
className="text-[#FF669E] text-base font-medium whitespace-nowrap"
>
免费
</span>
</div>
{Math.floor(priceEditData.price) > 0 && (
<>
{data?.m_type === 1 && (
<div className="flex justify-between items-center my-1">
<div className="flex items-center">
2024-10-25 19:19:41 +08:00
<span className="text-base font-medium mr-2 whitespace-nowrap">
2024-10-22 17:24:02 +08:00
可预览图片
</span>
2024-10-25 19:19:41 +08:00
<span className="text-base font-medium"></span>
<div className="px-2 mx-1 rounded-full max-w-[60px] bg-[#ffffff1a]">
2024-10-22 17:24:02 +08:00
<OwnInput
placeholder="0~3"
placeholderTextColor="#FFFFFF80"
onChange={(value) =>
setPriceEditData((old) => ({
...old,
imageVisibleRange: value,
}))
}
value={priceEditData.imageVisibleRange}
2024-10-25 19:19:41 +08:00
// className="bg-[#FFFFFF1A] rounded-2xl px-4 mx-2 h-8"
2024-10-22 17:24:02 +08:00
/>
</div>
2024-10-25 19:19:41 +08:00
<span className="text-base font-medium"></span>
2024-10-22 17:24:02 +08:00
</div>
<span
onClick={() =>
setPriceEditData((old) => ({
...old,
imageVisibleRange: "0",
}))
}
className="text-[#FF669E] text-base font-medium ml-auto whitespace-nowrap"
>
不可预览
</span>
</div>
)}
<div className="flex items-center my-1">
2024-10-25 19:19:41 +08:00
<span className="text-base font-medium mr-2">
2024-10-22 17:24:02 +08:00
添加付费文案
</span>
<Switch
checked={priceEditData.isCreatingPaidText}
onChange={(value) => {
setPriceEditData((old) => ({
...old,
isCreatingPaidText: value,
}));
}}
2024-10-25 19:19:41 +08:00
style={{
"--checked-color": "#FF669E",
}}
2024-10-22 17:24:02 +08:00
/>
</div>
{data?.m_type === 2 && (
<div className="flex items-center my-1">
2024-10-25 19:19:41 +08:00
<span className="text-base font-medium mr-2">封面模糊</span>
2024-10-22 17:24:02 +08:00
<Switch
checked={priceEditData.blurCover}
onChange={(value) => {
setPriceEditData((old) => ({
...old,
blurCover: value,
}));
}}
2024-10-25 19:19:41 +08:00
style={{
"--checked-color": "#FF669E",
}}
2024-10-22 17:24:02 +08:00
/>
</div>
)}
<div className="flex items-center my-1">
2024-10-25 19:19:41 +08:00
<span className="text-base font-medium mr-2">
2024-10-22 17:24:02 +08:00
铁粉免费查看
</span>
<Switch
checked={priceEditData.isFreeForIronfan}
onChange={(value) =>
setPriceEditData((old) => ({
...old,
isFreeForIronfan: value,
}))
}
2024-10-25 19:19:41 +08:00
style={{
"--checked-color": "#FF669E",
}}
2024-10-22 17:24:02 +08:00
/>
</div>
</>
)}
</div>
<p
className="pt-4 text-center border-t border-[#ffffff40]"
onClick={() => {
setPriceEdit(false);
setFormData((old) => ({ ...old, ...priceEditData }));
}}
>
保存
</p>
</Popup>
</div>
);
}