tiefen_space_h5/app/space/createVideoPost/page.jsx

392 lines
12 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, useEffect } from "react";
import { DotLoading, Popup, Toast, TextArea, Switch, Modal } from "antd-mobile";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import requireAPI from "@/utils/requireAPI";
import { useRouter } from "next/navigation";
import { multiUploadImage } from "@/utils/upload";
import UploadImgs from "@/components/UploadImgs";
import OwnInput from "@/components/OwnInput";
import DefaultMask from "@/components/DefaultMask";
export default function CreateVideoPost() {
const [isSubmitting, setIsSubmitting] = useState(false);
const [priceEdit, setPriceEdit] = useState(false);
// const [isFreeForIronfan, setIsFreeForIronfan] = useState(false);
const [postCount, setPostCount] = useState(null);
const [isBlockModalVisible, setIsBlockModalVisible] = useState(false);
//价格
const [formData, setFormData] = useState({
price: "",
content: "",
paidText: "",
imageAssets: [],
blurCover: true,
isCreatingPaidText: true,
isFreeForIronfan: false,
});
const [priceEditData, setPriceEditData] = useState({
price: "",
blurCover: true,
isCreatingPaidText: false,
isFreeForIronfan: false,
});
const router = useRouter();
useEffect(() => {
getPostCountData();
}, []);
const getPostCountData = async () => {
try {
const _data = await requireAPI(
"POST",
"/api/zone_moment/list_statistics_by_creater_mid"
);
if (_data.ret === -1) {
Toast.show({
icon: "fail",
content: _data.msg,
position: "top",
});
return;
}
setPostCount(_data.data);
if (_data.data.rejected_count >= 5) setIsBlockModalVisible(true);
} catch (error) {
console.error(error);
}
};
//保存付费设置
const handleSavePaymentSetting = ({ price }) => {
const intPrice = parseFloat(price);
if (intPrice < 0) {
Toast.show({
icon: "fail",
content: "请输入正确区间的价格",
position: "top",
});
return;
}
if (intPrice > 0 && intPrice * 100 < 100) {
Toast.show({
icon: "fail",
content: "请输入正确区间的价格",
position: "top",
});
return;
}
if (intPrice * 100 > 300000) {
Toast.show({
icon: "fail",
content: "请输入正确区间的价格",
position: "top",
});
return;
}
setPriceEdit(false);
setFormData((old) => ({ ...old, ...priceEditData }));
};
//发布内容
const handleSubmit = async () => {
if (formData.content == "") {
Toast.show({
icon: "fail",
content: "动态内容不能为空",
position: "top",
});
return;
}
if (formData.imageAssets.length === 0) {
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,
blurCover,
isCreatingPaidText,
paidText,
} = formData;
const media = await multiUploadImage(imageAssets, 2);
try {
const body = {
c_type: parseInt(price) ? 1 : 0,
is_ironfan_visible: isFreeForIronfan ? 1 : 0,
m_type: 2,
text: content,
media_component: media,
text_visible_range: textVisibleRange
? parseInt(textVisibleRange, 10)
: 999,
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/create", {
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);
}
};
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">
<DefaultMask
visible={isBlockModalVisible}
closeMask={setIsBlockModalVisible}
title="当前无法发帖"
content="您当前审核未通过动态过多,请修改后再试"
handleClick={() => {
setIsBlockModalVisible(false);
setTimeout(() => router.back(), 500);
}}
/>
<div>
<p className="text-sm font-medium text-[#27F5B7] mb-2">
为了空间良性发展请保持免费/付费比例为1/1
</p>
<div className="flex flex-row flex-wrap justify-between p-4 rounded-2xl bg-[#FFFFFF1A]">
<p className="text-xs font-medium text-white basis-1/2">
已发布免费动态{postCount?.free_count || 0}
</p>
<p className="text-xs font-medium text-white basis-1/2">
已发布付费动态{postCount?.paid_count || 0}
</p>
<p className="text-xs font-medium text-white basis-1/2 mt-1">
<span className="text-[#27F5B7]">可发布付费动态</span>
{postCount?.paid_limit || 0}
</p>
<p className="text-xs font-medium text-white basis-1/2 mt-1">
<span className="text-[#F53030]">审核未通过动态</span>
{postCount?.rejected_count || 0}
</p>
</div>
</div>
<div className="mt-2">
<p className="text-base font-medium text-white">动态内容</p>
<TextArea
placeholder="请遵守平台准则,严禁发布违规内容"
value={formData.content}
onChange={(value) =>
setFormData((old) => ({ ...old, content: value }))
}
autoSize={{ minRows: 6, maxRows: 15 }}
style={{ "--font-size": "14px" }}
className="h-32 bg-[#FFFFFF1A] text-white rounded-2xl mt-2 mb-4 p-2"
/>
{formData.isCreatingPaidText && formData.price > 0 && (
<>
<span className="text-base font-medium text-white">付费文案</span>
<TextArea
placeholder="仅在用户解锁后展示,请勿发布违规内容"
onChange={(value) =>
setFormData((old) => ({ ...old, paidText: value }))
}
autoSize={{ minRows: 6, maxRows: 15 }}
value={formData.paidText}
style={{ "--font-size": "14px" }}
className="h-32 bg-[#FFFFFF1A] text-white rounded-2xl mt-2 mb-4 p-2"
/>
</>
)}
</div>
<UploadImgs
type={2}
assets={formData.imageAssets}
getImgs={(imgs) =>
setFormData((old) => ({ ...old, imageAssets: imgs }))
}
accept="video/*"
/>
<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);
setPriceEditData({
price: formData.price,
blurCover: formData.blurCover,
isCreatingPaidText: formData.isCreatingPaidText,
isFreeForIronfan: formData.isFreeForIronfan,
});
}}
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-white text-base font-medium whitespace-nowrap">
价格¥
</span>
<div className="px-2 mx-1 rounded-full bg-[#ffffff1a]">
<OwnInput
placeholder="¥13000"
placeholderTextColor="#FFFFFF80"
keyboardType="numeric"
underlineColorAndroid="transparent"
onChange={(value) =>
setPriceEditData((old) => ({ ...old, price: value }))
}
value={priceEditData.price}
className="flex-1 bg-transparent text-white rounded-2xl 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 && (
<>
<div className="flex items-center my-1">
<span className="text-white text-base font-medium mr-2">
添加付费文案
</span>
<Switch
checked={priceEditData.isCreatingPaidText}
onChange={(value) => {
setPriceEditData((old) => ({
...old,
isCreatingPaidText: value,
}));
}}
style={{
"--checked-color": "#FF669E",
}}
/>
</div>
<div className="flex items-center my-1">
<span className="text-white 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-white 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={() => {
handleSavePaymentSetting(priceEditData);
}}
>
保存
</p>
</Popup>
</div>
);
}