514 lines
16 KiB
JavaScript
514 lines
16 KiB
JavaScript
"use client";
|
||
import React, { useState, useEffect, useMemo, useCallback } from "react";
|
||
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, useParams } from "next/navigation";
|
||
import { multiUploadImage } from "@/utils/upload";
|
||
import UploadImgs from "@/components/UploadImgs";
|
||
import OwnInput from "@/components/OwnInput";
|
||
export default function EditSpacePost() {
|
||
const params = useParams();
|
||
const [data, setData] = useState(null);
|
||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||
const [priceEdit, setPriceEdit] = useState(false);
|
||
//价格
|
||
const [formData, setFormData] = useState({
|
||
price: "",
|
||
content: "",
|
||
paidText: "",
|
||
imageAssets: [],
|
||
imageVisibleRange: 0,
|
||
isCreatingPaidText: false,
|
||
isFreeForIronfan: false,
|
||
});
|
||
const [priceEditData, setPriceEditData] = useState({
|
||
price: "",
|
||
imageVisibleRange: 1,
|
||
isCreatingPaidText: false,
|
||
isFreeForIronfan: false,
|
||
blurCover: true,
|
||
});
|
||
const router = useRouter();
|
||
useEffect(() => {
|
||
const { zid } = params;
|
||
getData(parseInt(zid, 10));
|
||
}, []);
|
||
const getData = async () => {
|
||
const ids = [parseInt(params.zid, 10)];
|
||
try {
|
||
const body = {
|
||
ids,
|
||
};
|
||
const _data = await requireAPI(
|
||
"POST",
|
||
"/api/zone_moment/list_by_ids_from_creater",
|
||
{
|
||
body,
|
||
},
|
||
true
|
||
);
|
||
if (_data.ret === -1) {
|
||
Toast.show({
|
||
icon: "fail",
|
||
content: _data.msg,
|
||
position: "top",
|
||
});
|
||
return;
|
||
}
|
||
setData(_data.data.list[0]);
|
||
const {
|
||
text,
|
||
paid_text,
|
||
price,
|
||
media_visible_range,
|
||
is_creating_paid_text,
|
||
is_ironfan_visible,
|
||
is_blurring_cover,
|
||
} = _data.data.list[0];
|
||
const publicData = {
|
||
price: price ? price / 100 : 0,
|
||
imageVisibleRange: media_visible_range,
|
||
isCreatingPaidText: is_creating_paid_text,
|
||
isFreeForIronfan: is_ironfan_visible,
|
||
blurCover: is_blurring_cover == 1,
|
||
};
|
||
setFormData({
|
||
content: paid_text
|
||
? text.slice(0, text.length - paid_text.length)
|
||
: text,
|
||
paidText: paid_text,
|
||
imageAssets: [],
|
||
...publicData,
|
||
});
|
||
setPriceEditData(publicData);
|
||
} catch (error) {
|
||
console.error(error);
|
||
} finally {
|
||
setIsSubmitting(false);
|
||
}
|
||
};
|
||
//发布内容
|
||
const handleSubmit = async () => {
|
||
if (formData.content == "") {
|
||
Toast.show({
|
||
icon: "fail",
|
||
content: "动态内容不能为空",
|
||
position: "top",
|
||
});
|
||
return;
|
||
}
|
||
if (data?.m_type && formData.imageAssets.length === 0) {
|
||
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,
|
||
];
|
||
}
|
||
|
||
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,
|
||
};
|
||
|
||
const _data = await requireAPI(
|
||
"POST",
|
||
"/api/zone_moment/update",
|
||
{
|
||
body,
|
||
},
|
||
false,
|
||
100000
|
||
);
|
||
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);
|
||
}
|
||
};
|
||
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]);
|
||
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">
|
||
{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 && (
|
||
<p className="text-sm font-medium text-white">
|
||
<span className="text-[#F53030]">文案违规原因:</span>
|
||
{data.text_audit_opinion}
|
||
</p>
|
||
)}
|
||
{data.image_audit_opinion && (
|
||
<p className="text-sm font-medium text-white">
|
||
<span className="text-[#F53030]">图片/视频违规原因:</span>
|
||
{data.image_audit_opinion}
|
||
</p>
|
||
)}
|
||
{data.manually_review_opinion && (
|
||
<p className="text-sm font-medium text-white">
|
||
<span className="text-[#F53030]">运营追加:</span>
|
||
{data.manually_review_opinion}
|
||
</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)}
|
||
<div className="mt-2">
|
||
<p className="text-base font-medium text-white">动态内容</p>
|
||
<div className="min-h-32 max-h-96">
|
||
<TextArea
|
||
placeholder="请遵守平台准则,严禁发布违规内容"
|
||
value={formData.content}
|
||
onChange={(value) =>
|
||
setFormData((old) => ({ ...old, content: value }))
|
||
}
|
||
autoSize={{ minRows: 6, maxRows: 15 }}
|
||
style={{ "--font-size": "16px" }}
|
||
className="h-full bg-[#FFFFFF1A] rounded-2xl mt-2 mb-4 p-2"
|
||
/>
|
||
</div>
|
||
{!!formData.isCreatingPaidText && formData.price > 0 && (
|
||
<div className="mt-2">
|
||
<span className="text-base font-medium text-white">付费文案</span>
|
||
<div className="min-h-32 max-h-96">
|
||
<TextArea
|
||
placeholder="仅在用户解锁后展示,请勿发布违规内容"
|
||
onChange={(value) =>
|
||
setFormData((old) => ({
|
||
...old,
|
||
paidText: value,
|
||
}))
|
||
}
|
||
autoSize={{ minRows: 6, maxRows: 15 }}
|
||
value={
|
||
formData.paidText.startsWith("\n")
|
||
? formData.paidText.slice(1)
|
||
: formData.paidText
|
||
}
|
||
style={{ "--font-size": "16px" }}
|
||
className="bg-[#FFFFFF1A] rounded-2xl mt-2 mb-4 p-2 h-full"
|
||
/>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
{data?.m_type && (
|
||
<div className="mt-2">
|
||
<UploadImgs
|
||
maxLength={data?.m_type == 2 ? 1 : 30}
|
||
type={data?.m_type}
|
||
existImages={getExistImgs}
|
||
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">
|
||
<span className="text-base font-medium whitespace-nowrap">
|
||
价格:¥
|
||
</span>
|
||
<div className="px-2 mx-1 rounded-full bg-[#ffffff1a]">
|
||
<OwnInput
|
||
placeholder="¥1~3000"
|
||
placeholderTextColor="#FFFFFF80"
|
||
keyboardType="numeric"
|
||
underlineColorAndroid="transparent"
|
||
onChange={(value) =>
|
||
setPriceEditData((old) => ({ ...old, price: value }))
|
||
}
|
||
value={priceEditData.price}
|
||
// className="flex-1 bg-[#FFFFFF1A] rounded-2xl px-4 h-8 mx-2"
|
||
/>
|
||
</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">
|
||
<span className="text-base font-medium mr-2 whitespace-nowrap">
|
||
可预览图片:
|
||
</span>
|
||
<span className="text-base font-medium">前</span>
|
||
<div className="px-2 mx-1 rounded-full max-w-[60px] bg-[#ffffff1a]">
|
||
<OwnInput
|
||
placeholder="0~3"
|
||
placeholderTextColor="#FFFFFF80"
|
||
onChange={(value) =>
|
||
setPriceEditData((old) => ({
|
||
...old,
|
||
imageVisibleRange: value,
|
||
}))
|
||
}
|
||
value={priceEditData.imageVisibleRange}
|
||
// className="bg-[#FFFFFF1A] rounded-2xl px-4 mx-2 h-8"
|
||
/>
|
||
</div>
|
||
<span className="text-base font-medium">张</span>
|
||
</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">
|
||
<span className="text-base font-medium mr-2">
|
||
添加付费文案:
|
||
</span>
|
||
<Switch
|
||
checked={priceEditData.isCreatingPaidText}
|
||
onChange={(value) => {
|
||
setPriceEditData((old) => ({
|
||
...old,
|
||
isCreatingPaidText: value,
|
||
}));
|
||
}}
|
||
style={{
|
||
"--checked-color": "#FF669E",
|
||
}}
|
||
/>
|
||
</div>
|
||
{data?.m_type === 2 && (
|
||
<div className="flex items-center my-1">
|
||
<span className="text-base font-medium mr-2">封面模糊:</span>
|
||
<Switch
|
||
checked={priceEditData.blurCover}
|
||
onChange={(value) => {
|
||
setPriceEditData((old) => ({
|
||
...old,
|
||
blurCover: value,
|
||
}));
|
||
}}
|
||
style={{
|
||
"--checked-color": "#FF669E",
|
||
}}
|
||
/>
|
||
</div>
|
||
)}
|
||
<div className="flex items-center my-1">
|
||
<span className="text-base font-medium mr-2">
|
||
铁粉免费查看:
|
||
</span>
|
||
<Switch
|
||
checked={priceEditData.isFreeForIronfan}
|
||
onChange={(value) =>
|
||
setPriceEditData((old) => ({
|
||
...old,
|
||
isFreeForIronfan: value,
|
||
}))
|
||
}
|
||
style={{
|
||
"--checked-color": "#FF669E",
|
||
}}
|
||
/>
|
||
</div>
|
||
</>
|
||
)}
|
||
</div>
|
||
<p
|
||
className="pt-4 text-center border-t border-[#ffffff40]"
|
||
onClick={() => {
|
||
setPriceEdit(false);
|
||
setFormData((old) => ({ ...old, ...priceEditData }));
|
||
}}
|
||
>
|
||
保存
|
||
</p>
|
||
</Popup>
|
||
</div>
|
||
);
|
||
}
|