anln_1.6 (#34)

Co-authored-by: al <al@cdhncy.com>
Reviewed-on: https://git.wishpal.cn/wishpal_ironfan/tiefen_space_h5/pulls/34
This commit is contained in:
yezian 2025-02-11 16:29:19 +08:00
parent bfdac91b0c
commit 40caa0a296
16 changed files with 668 additions and 53 deletions

3
app/found/index.css Normal file
View File

@ -0,0 +1,3 @@
.foundBox .adm-list-item-content-main{
padding: 0!important;
}

369
app/found/page.js Normal file
View File

@ -0,0 +1,369 @@
"use client";
import React, {
useEffect,
useRef,
useState,
useImperativeHandle,
forwardRef,
} from "react";
import { Tabs, Swiper, InfiniteScroll, List } from "antd-mobile";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faRefresh, faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import FoundItem from "@/components/FoundItem";
// import { sleep } from "antd-mobile/es/utils/sleep";
import "./index.css";
import PostItemSkeleton from "@/components/skeletons/PostItemSkeleton";
import Link from "next/link";
import requireAPI from "@/utils/requireAPI";
import Empty from "@/components/Empty";
import { get } from "@/utils/storeInfo";
import StreamerNavigator from "@/components/StreamerNavigator";
import AddToHome from "@/components/AddToHome";
import InfiniteScrollContent from "@/components/InfiniteScrollContent";
import { useRouter } from "next/navigation";
import OwnImage from "@/components/OwnImage";
const variables = {
"@active-line-color": "#f00", // 将主题色改为红色
};
const tabItems = [
{ key: "commend", title: "推荐" },
{ key: "follow", title: "关注" },
];
export default function Found() {
const router = useRouter();
const recommPostRef = useRef();
const followPostRef = useRef();
const swiperRef = useRef(null);
const [activeIndex, setActiveIndex] = useState(0);
const [account, setAccount] = useState(null);
const [scrollHeight, setScrollHeight] = useState(0);
// useEffect(() => {
// const info = get("account");
// console.log("info",info)
// if (info) {
// setStreamerInfo(info);
// }
// }, []
// )
const childrenFunc = () => {
if (!activeIndex) {
recommPostRef.current?.doRefresh();
} else {
followPostRef.current?.doRefresh();
}
};
useEffect(() => {
setAccount(get("account"));
}, []);
return (
<div className="foundBox">
<div className="bg-deepBg p-4 fixed top-0 z-10 w-full">
<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">
<div className="flex justify-between items-center px-2 custom-tabs text-gray-400 sticky top-14 z-10 bg-deepBg">
<Tabs
activeKey={tabItems[activeIndex].key}
onChange={(key) => {
const index = tabItems.findIndex((item) => item.key === key);
setActiveIndex(index);
swiperRef.current?.swipeTo(index);
}}
>
{tabItems.map((item) => (
<Tabs.Tab
destroyOnClose={true}
forceRender={false}
title={item.title}
key={item.key}
className="text-left"
/>
))}
</Tabs>
</div>
<Swiper
direction="horizontal"
allowTouchMove={false}
loop={false}
indicator={() => null}
ref={swiperRef}
defaultIndex={activeIndex}
onIndexChange={(index) => {
setActiveIndex(index);
}}
>
<Swiper.Item>
{!activeIndex && (
<RecommPostList scrollHeight={scrollHeight} ref={recommPostRef} />
)}
</Swiper.Item>
<Swiper.Item>
{!!activeIndex && (
<FollowPostList scrollHeight={scrollHeight} ref={followPostRef} />
)}
</Swiper.Item>
</Swiper>
<div
className={`fixed bottom-[50px] right-4 z-[50] w-10 h-10 flex items-center justify-center bg-[#1d1d1d71] rounded-full`}
style={{ zIndex: 999 }}
>
<FontAwesomeIcon
icon={faRefresh}
style={{ maxWidth: "32px" }}
size="2xl"
// onClick={() => {
// router.refresh();
// }}
onClick={childrenFunc}
/>
</div>
<StreamerNavigator />
</div>
</div>
);
}
const RecommPostList = forwardRef(({ scrollHeight }, ref) => {
const [loading, setLoading] = useState(false);
const [hasMore, setHasMore] = useState(true);
const [currentSearchKey, setCurrentSearchKey] = useState(2);
const [commenPostList, setCommenPostList] = useState([]);
useEffect(() => {
// getRecommPostList(2).then((res) => {
// setCommenPostList(res);
// setHasMore(true)
// });
}, []);
useImperativeHandle(
ref,
() => {
return { doRefresh };
},
[]
);
async function doRefresh() {
// await sleep(1000);
// Toast.show({
// icon: "fail",
// content: "刷新失败",
// });
// throw new Error("刷新失败");
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth", // 可选,平滑滚动效果
});
const list = await getRecommPostList(1);
setCommenPostList(list);
setHasMore(true);
}
async function loadMore() {
// debugger
const list = await getRecommPostList(!commenPostList.length ? 2 : 0);
if (list.length == 0) {
setHasMore(false);
}
setCommenPostList([...commenPostList, ...list]);
}
const getRecommPostList = async (type = 2) => {
setLoading(true);
try {
const data = await requireAPI("POST", "/api/streamer/recomm_list", {
body: { op_type: type },
});
setLoading(false);
if (data.ret == -1) {
// Toast.show({
// icon: "fail",
// content: data.msg,
// position: "top",
// });
return [];
} else {
return data.data.recomm_list;
}
} catch (error) {
setLoading(false);
}
};
return (
// <div className="px-4 pb-20 max-h-screen overflow-y-auto">
<div className="px-4 pb-20 min-h-screen">
<List>
{loading && !commenPostList.length && (
<div>
<PostItemSkeleton />
<PostItemSkeleton />
<PostItemSkeleton />
<PostItemSkeleton />
<PostItemSkeleton />
</div>
)}
{commenPostList?.map((item) => (
<List.Item key={item.id} className="!p-0">
<FoundItem data={item} />
</List.Item>
))}
{/* {commenPostList?.length == 0 && !loading && (
<div
className={`flex flex-col items-center justify-center h-screen`}
// style={{ height: `${scrollHeight}px` }}
>
<Empty type="nodata" />
</div>
)} */}
</List>
{/* {!!commenPostList?.length && (
<InfiniteScroll loadMore={loadMore} hasMore={hasMore} />
)} */}
<InfiniteScroll loadMore={loadMore} hasMore={hasMore}>
<InfiniteScrollContent
hasMore={hasMore}
isEmpty={commenPostList.length == 0}
showNoMore={commenPostList.length === 0}
/>
</InfiniteScroll>
</div>
);
});
const FollowPostList = forwardRef(({ scrollHeight }, ref) => {
const [loading, setLoading] = useState(false);
const [hasMore, setHasMore] = useState(false);
const [followPostList, setFollowPostList] = useState([]);
const [currentTime, setCurrentTime] = useState();
const [offset, setOffset] = useState(0);
const ids = useRef(null);
useEffect(() => {
getFollowIds().then((res) => {
ids.current = res;
getFollowPostList(res, 0);
});
}, []);
useImperativeHandle(
ref,
() => {
return { doRefresh };
},
[]
);
async function doRefresh() {
// await sleep(1000);
// Toast.show({
// icon: "fail",
// content: "刷新失败",
// });
// throw new Error("刷新失败");
// getRecommPostList(1);
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth", // 可选,平滑滚动效果
});
// setFollowPostList([]);
await getFollowPostList(ids.current, 0);
}
async function loadMore() {
await getFollowPostList(ids.current, offset);
// const newList = [...followPostList, ...list];
// setFollowPostList(newList);
}
const getFollowIds = async () => {
setLoading(true);
setCurrentTime(Math.floor(new Date().getTime() / 1000));
const data = await requireAPI(
"POST",
"/api/account_relation/list_follow",
{
body: { offset, limit: 4 },
},
true
);
return data;
};
const getFollowPostList = async (data, offset) => {
if (data.data.list.length > 0) {
//查关注主播展示资料
const followsResponse = await requireAPI(
"POST",
"/api/streamer/list_ext_by_mids",
{
body: {
offset,
limit: 4,
mids: data.data.list?.map((item) => item.obj_mid),
},
}
);
// debugger;
// console.log("offset", followsResponse.data.offset);
setOffset(followsResponse.data.offset);
setHasMore(followsResponse.data.more);
setLoading(false);
if (data.ret == -1) {
// Toast.show({
// icon: "fail",
// content: data.msg,
// position: "top",
// });
} else {
setFollowPostList((old) => {
if (!offset) {
return followsResponse.data.list;
} else {
return [...old, ...followsResponse.data.list];
}
});
}
} else {
setLoading(false);
}
};
return (
<div className="px-4 pb-20">
{/* <PullToRefresh onRefresh={doRefresh}> */}
<List>
{loading && !followPostList.length && (
<div className="my-[31px]">
<PostItemSkeleton />
<PostItemSkeleton />
<PostItemSkeleton />
<PostItemSkeleton />
<PostItemSkeleton />
</div>
)}
{followPostList?.map((item, index) => (
<List.Item key={item.id + "_" + index} className="!p-0">
<FoundItem data={item} />
</List.Item>
))}
{!followPostList?.length && (
<div
className={`flex flex-col items-center justify-center h-screen`}
style={{ height: `calc(100vh - 133px)` }}
>
<Empty type="nodata" />
</div>
)}
</List>
{!!followPostList?.length && (
<InfiniteScroll loadMore={loadMore} hasMore={hasMore} />
)}
{/* </PullToRefresh> */}
</div>
);
});

View File

@ -156,7 +156,7 @@ export default function BannedList() {
}}
/>
</div>
<p className="text-base text-center leading-9">名单</p>
<p className="text-base text-center leading-9">名单</p>
</div>
{/* 内容 */}
<div className="pt-16 p-4 flex flex-col justify-center items-center">

View File

@ -28,6 +28,7 @@ export default function PersonSpace() {
const router = useRouter();
const [streamerInfo, setStreamerInfo] = useState(null);
const [spaceData, setSpaceData] = useState(null);
const [postData, setPostData] = useState(null);
const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false);
const [isFollow, setIsFollow] = useState(false);
@ -91,7 +92,27 @@ export default function PersonSpace() {
});
return;
}
setSpaceData(data.data.list[0]);
if (data.data.list[0].previews.images.length === 0) {
const data2 = await requireAPI("POST", "/api/moment/list_by_mid", {
body: {
mid: Number(mid),
ct_upper_bound: Math.floor(new Date().getTime() / 1000),
offset: 0,
limit: 100,
},
});
if (data2.ret === -1) {
Toast.show({
icon: "fail",
content: data2.msg,
position: "top",
});
return;
}
setPostData(data2.data.list);
} else {
setSpaceData(data.data.list[0]);
}
} catch (error) {
// console.error(error);
}
@ -366,6 +387,7 @@ export default function PersonSpace() {
)}
</div>
</div>
{/* 空间动态 */}
{spaceData && !!spaceData?.previews?.images?.length && (
<>
<Divider />
@ -417,6 +439,53 @@ export default function PersonSpace() {
</div>
</>
)}
{/* 广场动态 */}
{postData && !!postData?.length && (
<>
<Divider />
<div>
<div
onClick={() => {
router.push(`/streamerPosts/${mid}`);
}}
>
<div className="flex justify-between items-center mb-2">
<span className="font-bold text-base">
动态{postData.length}
</span>
<div className="h-4 text-xs text-[#ffffff88]">
<FontAwesomeIcon
icon={faAngleRight}
size="xl"
style={{ maxWidth: "12px" }}
className="h-4"
/>
</div>
</div>
<div className="flex ">
{postData?.slice(0, 4).map((item, index) => (
<div
key={item.id}
className="w-20 h-20 overflow-hidden rounded mr-1"
>
<OwnImage
className={`w-[20vw] h-[20vw]`}
rounded="rounded"
outClassName="mr-2"
fit="cover"
src={
item.media_component.images.length !== 0
? item.media_component.images[0].urls[0]
: item.media_component.videos[0].cover_urls[0]
}
/>
</div>
))}
</div>
</div>
</div>
</>
)}
<>
<Divider />

View File

@ -83,15 +83,17 @@ export default function Banner() {
);
return (
<div className="flex-1 mt-6">
<Swiper
allowTouchMove
ref={ref}
loop
autoplay
style={{ "--border-radius": "8px" }}
>
{bannerList.map((item, index) => items(item, index))}
</Swiper>
{bannerList.length > 0 && (
<Swiper
allowTouchMove
ref={ref}
loop
autoplay
style={{ "--border-radius": "8px" }}
>
{bannerList.map((item, index) => items(item, index))}
</Swiper>
)}
</div>
);
}

View File

@ -1,3 +1,5 @@
"use client";
import React, { useEffect, useState } from "react";
import { List } from "antd-mobile";
import LoadingMask from "@/components/LoadingMask";
@ -7,6 +9,8 @@ import OwnImage from "@/components/OwnImage";
import OwnIcon from "@/components/OwnIcon";
import Banner from "../Banner";
import baseRequest from "@/utils/baseRequest";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleRight } from "@fortawesome/free-solid-svg-icons";
export default function HostList() {
const base = baseRequest();
const [hostList, setHostList] = useState([]);
@ -43,20 +47,17 @@ export default function HostList() {
<div className="flex-1 mt-6">
<div className="flex flex-row justify-between items-center">
<p className="text-xl font-medium">猜你想看</p>
{/* <div
onClick={() => navigation.navigate("Stream")}
className="flex flex-row justify-between items-center"
<div
onClick={() => router.push("/found")}
className="flex flex-row justify-between items-center text-[#FFFFFF80] "
>
<span className="text-[#FFFFFF80] text-sm font-medium">查看更多</span>
<span className="text-sm font-medium mr-1">查看更多</span>
<FontAwesomeIcon
icon={faAngleRight}
style={{ maxWidth: "12px" }}
size="xl"
onClick={() => {
router.back();
}}
size="lg"
/>
</div> */}
</div>
</div>
<LoadingMask isLoading={isLoading} />
<List>

View File

@ -158,7 +158,6 @@ export default function PersonSpace() {
)[0];
floatingPanel?.scrollTo(0, 0);
setOffset(0);
setHasMore(true);
if (!postList.length) return;
if (streamerInfo) {
getPostList(streamerInfo.id, currentKey, 0).then((res) => {
@ -504,7 +503,11 @@ export default function PersonSpace() {
ironfanship_price={streamerInfo.ironfanship_price}
closeMask={() => {
setMaskVisible({ visible: false, type: "" });
getStreamerInfo(Number(id)).then((res) => {
setStreamerInfo(res);
});
}}
id={streamerInfo.id}
handleClick={() => {
setCurrentKey("ironFan");
setMaskVisible({ visible: false, type: "" });

View File

@ -192,7 +192,7 @@ export default function CreateImagePost() {
//Toast
Toast.show({
icon: "success",
content: "发布成功",
content: "上传成功,请耐心等待审核",
position: "top",
});
router.back();

View File

@ -164,7 +164,7 @@ export default function CreateVideoPost() {
//Toast
Toast.show({
icon: "success",
content: "发布成功",
content: "上传成功,请耐心等待审核",
position: "top",
});
router.back();

View File

@ -75,7 +75,7 @@ export default function EditSpacePost() {
blurCover: is_blurring_cover == 1,
};
setFormData({
content: paid_text
content: is_creating_paid_text
? text.slice(0, text.length - paid_text.length)
: text,
paidText: paid_text,

View File

@ -2,7 +2,7 @@
import React, { useState, useEffect } from "react";
import { List, InfiniteScroll, Toast } from "antd-mobile";
import { useRouter } from "next/navigation";
import { useRouter, useParams } from "next/navigation";
import requireAPI from "@/utils/requireAPI";
import Empty from "@/components/Empty";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@ -10,7 +10,8 @@ import { faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import PostItem from "@/components/PostItem";
import { get } from "@/utils/storeInfo";
export default function StreamerPosts({ id }) {
export default function StreamerPosts() {
const { id } = useParams();
//
const [currentTime, setCurrentTime] = useState();
const [account, setAccount] = useState(null);
@ -33,7 +34,7 @@ export default function StreamerPosts({ id }) {
// if (!more) return;
try {
const body = {
mid: id,
mid: parseInt(id),
ct_upper_bound: currentTime,
offset: offset,
limit: 4,

View File

@ -103,7 +103,7 @@ export default function CreatePost() {
//Toast
Toast.show({
icon: "success",
content: "发布成功",
content: "上传成功,请耐心等待审核",
position: "top",
});
router.back();

View File

@ -132,7 +132,7 @@ export default function EditPost() {
//Toast
Toast.show({
icon: "success",
content: "更新成功",
content: "提交成功,等待审核!",
position: "top",
});
router.back();

View File

@ -0,0 +1,134 @@
"use client";
import React from "react";
import { useRouter } from "next/navigation";
import OwnImage from "../OwnImage";
import OwnIcon from "../OwnIcon";
export default function FoundItem({ data = {} }) {
const router = useRouter();
return (
<div
onClick={() => {
router.push("/profile/" + data.mid);
}}
>
<div className="h-max flex items-center mb-3">
<OwnImage
className="flex-none w-12 h-12 rounded-full"
outClassName="flex-none w-12 h-12 rounded-full mr-1"
roundedFull
src={data?.avatar.images[0].urls[0]}
/>
<div className="flex flex-col ml-2 items-start">
<div className="flex items-center">
<span className="text-base font-medium text-white">
{data?.name}
</span>
<div className="flex py-0.5 px-1 rounded-full items-center ml-1 bg-[#FFFFFF26]">
{data?.gender === 1 ? (
<OwnIcon
src="/icons/info/male.png"
className="w-[14px] h-[14px]"
outClassName="mr-1"
/>
) : (
<OwnIcon
src="/icons/info/female.png"
className="w-[14px] h-[14px]"
outClassName="mr-1"
/>
)}
<span className="text-xs">{data?.age}</span>
</div>
<div className="flex py-0.5 px-1 rounded-full items-center ml-1 bg-[#FFFFFF26]">
<OwnIcon
src="/icons/info/location.png"
className="w-[14px] h-full"
outClassName="mr-1"
/>
<span className="text-xs">{data?.city}</span>
</div>
</div>
<span className="text-xs text-[#FFFFFF80]">
全网粉丝{data?.fans}
</span>
</div>
</div>
<div className="grid grid-cols-2 grid-rows-[16rem] rounded-2xl overflow-hidden h-64">
<div className="rounded-r overflow-hidden">
<OwnImage
src={data?.cover?.images[0]?.urls[0]}
className="w-full h-full"
outClassName="w-full h-full"
/>
</div>
<div className="grid grid-rows-2 ml-1 gap-1">
{data?.album?.images.map((item, index) => {
if (index > 1) return;
return (
<div key={index} className="w-full h-full mb-1 relative">
<OwnImage
src={item?.urls[0]}
className="w-full h-full"
outClassName="w-full h-full"
rounded="rounded-l"
/>
{index === 1 && data?.album?.images.length > 2 && (
<div className="flex items-center justify-center absolute top-0 w-full h-full bg-[rgba(0,0,0,0.5)]">
<span className="text-3xl font-semibold">
+{data?.album?.images.length - 2}
</span>
</div>
)}
</div>
);
})}
</div>
</div>
{/* 下方标签区 */}
<div className="flex h-12 justify-between items-center">
<div className="flex gap-2">
{data?.is_active_within_a_week === 1 && (
<OwnIcon src="/images/space_new.png" className="h-6" />
)}
{data?.tag?.map((item, index) => {
if (index > 2) return;
if (data?.is_active_within_a_week === 1 && index > 1) return;
return (
<div
key={index}
className="px-2 rounded-full bg-[#FF61B030] flex items-center"
>
<span className="text-[#FF669E] text-[11px]">{item}</span>
</div>
);
})}
</div>
<div className="flex flex-nowrap gap-2">
{data?.platforms?.map((item, index) => {
if (index > 5) return;
return (
<div key={index} className="flex">
{index < 5 && (
<OwnImage
src={item?.icon?.images[0]?.urls[0]}
className="w-full h-[18px]"
/>
)}
{index === 5 && (
<div className="flex items-center justify-center w-full h-full rounded bg-[rgba(0,0,0,0.5)]">
<span className="text-xs font-semibold">
+{data?.platforms.length - 5}
</span>
</div>
)}
</div>
);
})}
</div>
</div>
{/* 分割线 */}
<div className="h-[3px] rounded-full bg-[#FFFFFF26] mb-3"></div>
</div>
);
}

View File

@ -14,6 +14,7 @@ import { get } from "@/utils/storeInfo";
import { Inter } from "next/font/google";
import requireAPI from "@/utils/requireAPI";
import { getcountLines } from "@/utils/tools";
import { formatTimestamp } from "@/utils/tools";
const inter = Inter({ subsets: ["latin"] });
export default function PostItem({
type,
@ -227,7 +228,7 @@ export default function PostItem({
) : (
<div>
<span
className={`mb-2 mt-2 whitespace-pre-wrap ${
className={`mb-2 mt-2 whitespace-pre-wrap block ${
!isOpenText ? "text-ellipsis-7" : ""
} ${inter.className}`}
dangerouslySetInnerHTML={{
@ -246,7 +247,7 @@ export default function PostItem({
!data?.is_zone_moment_unlocked && data?.text_visible_range < 999
) &&
(data.text?.length > 140 ||
getcountLines(data.paid_text || "") > 1) && (
getcountLines(data.text || "") > 7) && (
<div
className="font-bold text-btn my-4 text-base"
onClick={() => setIsOpenText(!isOpenText)}
@ -339,24 +340,10 @@ export default function PostItem({
</div>
) : (
<div className="text-[#ffffff88] text-xs">
<span className="mr-2">
{getDays < 3
? `${
getDays === 0 ? "今日" : "new" === 1 ? "昨日" : "前天"
}`
: date.getMonth() + 1 + "-" + date.getDate()}
</span>
<span>
{(date.getHours() > 9
? date.getHours()
: "0" + date.getHours()) +
":" +
(date.getMinutes() > 9
? date.getMinutes()
: "0" + date.getMinutes())}
</span>
{formatTimestamp(data.ct)}
</div>
)}
{isOwn && <div></div>}
<div className="flex items-center">
<div
className="flex items-center mr-4 h-[32px]"
@ -414,6 +401,15 @@ export default function PostItem({
</>
) : type == "post" && account?.mid == data?.mid ? (
<>
<li
className="py-1 px-4"
onClick={() => {
router.push(`/streamerPosts/editPost/${data.id}`);
}}
>
编辑
</li>
<hr className="border-[#ffffff2b] my-1" />
<li
className="py-1 px-4"
onClick={() => handleDelete("post")}

View File

@ -1,16 +1,45 @@
"use client";
import React, { useState } from "react";
import { Mask, ProgressBar } from "antd-mobile";
import { Mask, ProgressBar, Toast } from "antd-mobile";
import requireAPI from "@/utils/requireAPI";
export default function SeeTiefen({
visible,
closeMask,
handleClick,
ironFanProgress,
expenditure,
ironfanship_price
ironfanship_price,
id,
}) {
//刷新铁粉身份解决主播降价导致的进度满100但未成为铁粉
const handleFansIdentityRefresh = async () => {
try {
const body = {
zid: id,
};
const _data = await requireAPI(
"POST",
"/api/zone_moment/fans_identity_refresh",
{
body,
}
);
if (_data.ret == -1) {
Toast.show({
icon: "fail",
content: _data.msg,
position: 60,
});
return;
}
// await getData();
// setIsIronFanModalVisible(false);
closeMask(false);
} catch (error) {
console.error(error);
}
};
return (
<Mask visible={visible}>
<div className="relative w-screen h-screen">
@ -18,7 +47,9 @@ export default function SeeTiefen({
<div className="absolute top-1/2 left-1/2 -ml-[35vw] -mt-[35vw] w-[70vw] h-max flex flex-col justify-center items-center p-4 bg-[#261e30] rounded-2xl pointer-events-auto">
<p className="text-base text-left w-full">
当前铁粉解锁进度
<span className="text-2xl font-bold text-primary">{ironFanProgress}%</span>
<span className="text-2xl font-bold text-primary">
{ironFanProgress}%
</span>
</p>
<ProgressBar
percent={ironFanProgress}
@ -29,8 +60,8 @@ export default function SeeTiefen({
className="w-full mt-2 mb-4"
/>
<p className="text-sm text-[#FF669E] font-medium">{`${
expenditure / 100
} / ${ironfanship_price / 100}`}</p>
expenditure / 100
} / ${ironfanship_price / 100}`}</p>
<p className="text-left my-2 text-sm text-[#FFFFFF40]">
空间内累计消费达到{ironfanship_price / 100}即可成为
<span className="text-primary">铁粉</span>
@ -42,6 +73,12 @@ export default function SeeTiefen({
>
<span className="text-base">查看铁粉专享内容</span>
</div>
<p
onClick={handleFansIdentityRefresh}
className="text-sm font-medium text-[#FF669E] mt-2 underline"
>
进度已满但还未成为铁粉
</p>
</div>
</div>
</Mask>