tiefen_space_h5/app/space/setting/spacePaymentSetting/page.jsx

600 lines
20 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, useRef, useMemo, Fragment } from "react";
import { Switch, Space, Checkbox, Button, Toast, Form } from "antd-mobile";
import { useRouter, useSearchParams } from "next/navigation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import OwnInput from "@/components/OwnInput";
import requireAPI from "@/utils/requireAPI";
import { get } from "@/utils/storeInfo";
import { getStreamerInfo } from "@/api/space";
const superSingles = [
{ key: 0, index: 0, text: "永久" },
{ key: 4, index: 1, text: "按年生效" },
{ key: 3, index: 2, text: "按半年生效" },
{ key: 2, index: 3, text: "按季度生效" },
{ key: 1, index: 4, text: "按月生效" },
];
// const superSingles = [
// { key: 0, text: "永久" },
// { key: 1, text: "按年生效" },
// { key: 2, text: "按半年生效" },
// { key: 3, text: "按季度生效" },
// { key: 4, text: "按月生效" },
// ];
const ListItemWithCheckbox = ({
superSingle,
superSinglesContr,
setSuperSinglesContr,
superSingleCheckeds,
index,
}) => {
return (
<li className="mt-4" onClick={() => {}}>
<div onClick={(e) => e.stopPropagation()}>
{/* <Radio
value={index}
onChange={(value) => {
const newFormData = { ...formData };
newFormData.superSingle.forEach((el) => {
el.enable = 0;
});
newFormData.superSingle[index].enable = value;
// newFormData.superSingle[index].price = 0;
// newFormData.superSingle[index].wechatFree = false;
setFormData(newFormData);
}}
>
{superSingle.text}
</Radio> */}
<Checkbox
value={index}
onChange={(value) => {
const newSuperSinglesContr = [...superSinglesContr];
newSuperSinglesContr[index].enable = value;
// newSuperSinglesContr[index].price = 0;
// newSuperSinglesContr[index].wechatFree = false;
setSuperSinglesContr(newSuperSinglesContr);
}}
>
{superSingle.text}
</Checkbox>
<div
// className={`mt-2 px-4 h-12 py-3 rounded-[0.8rem] bg-[#FFFFFF1a] flex justify-between items-center ${
// superSingleCheckeds != index
// ? "mt-0 px-0 py-0 hidden"
// : ""
// }`}
className={`mt-2 px-4 h-12 py-3 rounded-[0.8rem] bg-[#FFFFFF1a] flex justify-between items-center ${
!superSingleCheckeds.includes(index) ? "mt-0 px-0 py-0 hidden" : ""
}`}
>
<div className="flex items-center">
<span className="mr-1 text-[#ffffffae] text-sm">¥</span>
<OwnInput
type="number"
className="text-2xl"
value={superSinglesContr[index].price}
onChange={(value) => {
const newSuperSinglesContr = [...superSinglesContr];
newSuperSinglesContr[index].price = value;
setSuperSinglesContr(newSuperSinglesContr);
}}
/>
</div>
<div className="flex items-center">
<span className="text-[#ffffff26] mr-2">|</span>
<Checkbox
block
checked={superSinglesContr[index].wechatFree}
onChange={(value) => {
const newSuperSinglesContr = [...superSinglesContr];
newSuperSinglesContr[index].wechatFree = value;
setSuperSinglesContr(newSuperSinglesContr);
}}
>
<p className="text-sm whitespace-nowrap">赠送微信</p>
</Checkbox>
</div>
</div>
</div>
</li>
);
};
export default function SpacePaymentSetting() {
const [form] = Form.useForm();
const router = useRouter();
const searchParams = useSearchParams();
const [openSuper, setOpenSuper] = useState(false);
const [spacePriceAble, setSpacePriceAble] = useState(false);
const [tiefenPriceAble, setTiefenPriceAble] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const [superSingleCheckeds, setSuperSingleCheckeds] = useState([]);
const [superSinglesContr, setSuperSinglesContr] = useState([
{ enable: false, price: 0, wechatFree: false, key: 0 },
{ enable: false, price: 0, wechatFree: false, key: 4 },
{ enable: false, price: 0, wechatFree: false, key: 3 },
{ enable: false, price: 0, wechatFree: false, key: 2 },
{ enable: false, price: 0, wechatFree: false, key: 1 },
]);
const [spacePriceInfo, setSpacePriceInfo] = useState(null);
useEffect(() => {
const account = get("account");
getStreamerInfo(Number(account.mid)).then((res) => {
// 新版本
const priceList = res.superfan_price_list ?? [
{ enable: false, price: 0, is_superfanship_give_wechat: false, key: 0 },
{ enable: false, price: 0, is_superfanship_give_wechat: false, key: 4 },
{ enable: false, price: 0, is_superfanship_give_wechat: false, key: 3 },
{ enable: false, price: 0, is_superfanship_give_wechat: false, key: 2 },
{ enable: false, price: 0, is_superfanship_give_wechat: false, key: 1 },
];
const haveChecked = priceList
.map((it, index) => ({ ...it, index }))
.filter((it) => it.enable);
// if (haveChecked.length > 0) {
// setSuperSingleChecked(haveChecked[0].period);
// }
setSuperSingleCheckeds(
priceList
.map((it, index) => ({ ...it, index }))
.filter((it) => it.enable)
.map((it) => superSingles[it.index].index)
);
setOpenSuper(!!res.is_superfanship_enabled);
setSuperSinglesContr(
priceList.map((it, index) => ({
enable: !!it.enable,
price: it.price / 100,
wechatFree: !!it.is_superfanship_give_wechat,
key: index ? 5 - index : index,
}))
);
setSpacePriceInfo(res);
});
}, []);
useEffect(() => {
if (!spacePriceInfo) return;
form.setFieldsValue({
spacePrice: spacePriceInfo.admission_price / 100,
ironFanPrice: spacePriceInfo.ironfanship_price / 100,
});
}, [form, spacePriceInfo]);
const listItemWithCheckboxMemo = useMemo(() => {
return superSingles.map((item, index) => (
<Fragment key={item.key}>
<ListItemWithCheckbox
superSingle={item}
superSinglesContr={superSinglesContr}
setSuperSinglesContr={setSuperSinglesContr}
// superSingleCheckeds={superSingleChecked}
superSingleCheckeds={superSingleCheckeds}
index={index}
/>
</Fragment>
));
}, [superSingleCheckeds, superSinglesContr]);
const handleSubmit = async (newFormData) => {
const { spacePrice, ironFanPrice } = newFormData;
const superSingle = [...superSinglesContr];
const openSuperEveryFalse = Object.values(superSingle).every(
(it) => !it.enable
);
if (openSuper && openSuperEveryFalse) {
Toast.show({
icon: "fail",
content: "请完善档位内容后提交",
position: "top",
});
return;
}
const _spacePrice = parseInt(spacePrice * 100, 10);
if (isNaN(_spacePrice) || _spacePrice < 0 || _spacePrice > 388800) {
Toast.show({
icon: "fail",
content: "请输入有效的解锁空间价格",
position: "top",
});
return;
}
const _ironFanPrice = parseInt(ironFanPrice * 100, 10);
if (isNaN(_ironFanPrice) || _ironFanPrice < 100 || _ironFanPrice > 388800) {
Toast.show({
icon: "fail",
content: "请输入有效的铁粉价格",
position: "top",
});
return;
}
let isPrice = false;
if (openSuper) {
Object.values(superSingle).forEach((it) => {
if (it.enable) {
const superFanPrice = it.price;
if (!superFanPrice) {
Toast.show({
icon: "fail",
content: "请填写超粉价格",
position: "top",
});
isPrice = true;
return;
} else {
const _superFanPrice = parseInt(superFanPrice * 100, 10);
if (
openSuper &&
(isNaN(_superFanPrice) ||
_superFanPrice < 100 ||
_superFanPrice > 388800)
) {
isPrice = true;
Toast.show({
icon: "fail",
content: "请输入有效的超粉价格",
position: "top",
});
return;
}
if (openSuper && _superFanPrice <= _ironFanPrice) {
isPrice = true;
Toast.show({
icon: "fail",
content: "请输入大于铁粉价格的超粉价格",
position: "top",
});
return;
}
}
}
});
// if (superSingleChecked == null) {
// Toast.show({
// icon: "fail",
// content: "请选择铁粉类型",
// position: "top",
// });
// } else {
// const superChecked = superSingle.filter(
// (_, index) => index == superSingleChecked
// )[0];
// if (superChecked) {
// const superFanPrice = superChecked.price;
// if (!superFanPrice) {
// Toast.show({
// icon: "fail",
// content: "请填写超粉价格",
// position: "top",
// });
// isPrice = true;
// return;
// } else {
// const _superFanPrice = parseInt(superFanPrice * 100, 10);
// if (
// openSuper &&
// (isNaN(_superFanPrice) ||
// _superFanPrice < 100 ||
// _superFanPrice > 388800)
// ) {
// isPrice = true;
// Toast.show({
// icon: "fail",
// content: "请输入有效的超粉价格",
// position: "top",
// });
// return;
// }
// if (openSuper && _superFanPrice <= _ironFanPrice) {
// isPrice = true;
// Toast.show({
// icon: "fail",
// content: "请输入大于铁粉价格的超粉价格",
// position: "top",
// });
// return;
// }
// }
// }
// }
}
if (isPrice) return;
// if (
// openSuper &&
// superFanExpiration !== 0 &&
// superFanExpiration !== 1 &&
// superFanExpiration !== 2 &&
// superFanExpiration !== 3 &&
// superFanExpiration !== 4
// ) {
// Toast.show({
// icon: "error",
// content: "请选择超粉有效期",
// position: "top",
// });
// return;
// }
if (isSubmitting) return;
// 旧版本
// const superfanList = superSingle.map((it, index) => ({
// period: index,
// enable: it.enable ? 1 : 0,
// price: parseInt(it.price * 100, 10),
// is_superfanship_give_wechat: it.wechatFree ? 1 : 0,
// }));
// const superfanObj = superfanList.filter((it) => it.enable)[0];
// 新版本
const superfan_price_list = superSinglesContr.map((it, index) => ({
period: it.key,
enable: it.enable ? 1 : 0,
price: parseInt(it.price * 100, 10),
is_superfanship_give_wechat: it.wechatFree ? 1 : 0,
}));
setIsSubmitting(true);
try {
const body = {
id: parseInt(searchParams.get("zid"), 10),
admission_price: parseInt(spacePrice * 100, 10),
ironfanship_price: parseInt(ironFanPrice * 100, 10),
is_superfanship_enabled: openSuper ? 1 : 0,
// 旧版本
// superfanship_price: superfanObj.price,
// superfanship_valid_period: superfanObj.period,
// is_superfanship_give_wechat: superfanObj.is_superfanship_give_wechat,
// 新版本
superfan_price_list,
};
const _data = await requireAPI(
"POST",
"/api/zone/update",
{
body,
},
true
);
if (_data.ret === -1) {
Toast.show({
icon: "error",
content: _data.msg,
position: "top",
});
return;
}
Toast.show({
icon: "success",
content: "修改成功,请重进空间刷新查看",
position: "top",
});
router.back();
} catch (error) {
console.error(error);
} finally {
setIsSubmitting(false);
}
};
const messageEle = (message) => <p className="text-right">{message}</p>;
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 mt-4">
<Form
requiredMarkStyle="none"
form={form}
initialValues={{
spacePrice: 0,
ironFanPrice: 0,
}}
onFinishFailed={(error) => {
Toast.show({
icon: "fail",
content: "请检查所填内容",
position: "top",
});
}}
onFinish={handleSubmit}
onValuesChange={(values) => {
console.log("onValuesChange:", values);
// setFormData(values);
}}
// hasFeedback={false}
validateMessages={{
required: (name) => {
return <p className="text-right">{`请输入${name}`}</p>;
},
}}
>
<div className="flex justify-between items-center">
<p className="text-sm whitespace-nowrap">
<span className="text-white">解锁空间价格</span>
<span className="text-[#f00]">*</span>
</p>
<p className="text-[#ffffffb3] text-xs">
成为空间成员可查看免费帖
</p>
</div>
<div className="mt-2 px-4 py-3 h-12 rounded-[0.8rem] bg-[#FFFFFF1a] flex justify-between items-center">
<div className="flex items-center">
<span className="mr-1 text-[#ffffffae] text-sm">¥</span>
<Form.Item
required
name="spacePrice"
// childElementPosition="left"
layout="vertical"
rules={[
{
required: true,
message: messageEle("请填写解锁空间的价格"),
pattern: /^[1-9]\d*$/,
// validator: (rule, value) => {
// if (value.length === 0) {
// return Promise.reject(messageEle("请选择性别"));
// }
// },
},
]}
>
<OwnInput
id="spacePrice"
type="number"
placeholder="0~3888仅支持整数"
inputClassName="placeholder:text-[14px]"
/>
</Form.Item>
</div>
<label
htmlFor="spacePrice"
className="text-[#ffffff40] text-xs whitespace-nowrap"
onClick={() => setSpacePriceAble(true)}
>
点击编辑
</label>
</div>
<Form.Item
name="ironFanPrice"
// childElementPosition="left"
label={
<div className="flex justify-between items-center">
<p className="text-sm whitespace-nowrap">
<span className="text-white">铁粉价格</span>
<span className="text-[#f00]">*</span>
</p>
<p className="text-[#ffffffb3] text-xs">
累计消费达成后解锁铁粉权益
</p>
</div>
}
layout="vertical"
rules={[
{
required: true,
message: messageEle("请填写铁粉价格"),
// validator: (rule, value) => {
// if (value.length === 0) {
// return Promise.reject(messageEle("请选择性别"));
// }
// },
},
]}
>
<div className="mt-2 px-4 py-3 h-12 rounded-[0.8rem] bg-[#FFFFFF1a] flex justify-between items-center">
<div className="flex items-center">
<span className="mr-1 text-[#ffffffae] text-sm">¥</span>
<Form.Item name="ironFanPrice">
<OwnInput
id="ironFanPrice"
type="number"
placeholder="1~3888仅支持整数"
inputClassName="placeholder:text-[14px]"
/>
</Form.Item>
</div>
<label
htmlFor="ironFanPrice"
className="text-[#ffffff40] text-xs whitespace-nowrap"
onClick={() => setTiefenPriceAble(true)}
>
点击编辑
</label>
</div>
</Form.Item>
<div className="flex justify-between items-center">
<p className="text-sm">
<span className="text-white">超粉功能</span>
</p>
<div className="flex items-center">
<p className="text-[#ffffffae] text-xs mr-2">是否启用</p>
<Form.Item>
<Switch
checked={openSuper}
onChange={() => setOpenSuper((old) => !old)}
style={{
"--checked-color": "#FF669E",
"--height": "24px",
"--width": "36px",
}}
/>
</Form.Item>
</div>
</div>
{openSuper && (
<Form.Item
name="superSingleCheckeds"
// childElementPosition="left"
label={
<div className="flex justify-between items-center">
<p className="text-sm">
<span className="text-white">超粉单次开通类型</span>
<span className="text-[#f00]">*</span>
</p>
<p className="text-[#ffffffb3] text-xs">
付费后解锁对应期限超粉权益
</p>
</div>
}
layout="vertical"
>
<Space direction="vertical" block>
{/* <Radio.Group
value={superSingleChecked}
// value={superSingleCheckeds}
onChange={(values) => {
setSuperSingleChecked(values);
// setSuperSingleCheckeds(values);
}}
>
<ul>{listItemWithCheckboxMemo}</ul>
</Radio.Group> */}
<Checkbox.Group
value={superSingleCheckeds}
onChange={(values) => {
setSuperSingleCheckeds(values);
}}
>
<ul>{listItemWithCheckboxMemo}</ul>
</Checkbox.Group>
</Space>
</Form.Item>
)}
<Form.Item label={null} className="mt-10 flex-1 flex justify-center">
<Button
size="middle"
shape="rounded"
block
style={{
"--background-color": "#FF669E",
paddingLeft: "32px",
paddingRight: "32px",
}}
type="primary"
htmlType="submit"
disabled={isSubmitting}
>
{isSubmitting ? "正在保存..." : "保存设置"}
</Button>
</Form.Item>
</Form>
</div>
</div>
);
}