处理存在问题和新的需求

This commit is contained in:
al 2024-08-02 22:12:54 +08:00
parent e2f5dcde80
commit b6c212569e
16 changed files with 203 additions and 44 deletions

View File

@ -1,6 +1,7 @@
import requireAPI from "@/utils/requireAPI";
import {Toast} from "antd-mobile"
export const getStreamerInfo = async (mid) => {
try {
const data = await requireAPI("POST", "/api/zone/list_by_mid", {
body: {

View File

@ -35,6 +35,7 @@ function Login({ handleLogin }) {
const [veriCode, setVeriCode] = useState("");
const [isCounting, setIsCounting] = useState(false);
const [seconds, setSeconds] = useState(60);
const [deviceType, setDeviceType] = useState("");
const [loginInfo, setLoginInfo] = useState({
mobilePhone: "",
regionCode: "86",
@ -44,6 +45,15 @@ function Login({ handleLogin }) {
const router = useRouter();
const swiperRef = useRef(null);
useEffect(() => {
const userAgent = navigator.userAgent;
//区分设备类型
if (/Android/i.test(userAgent)) {
setDeviceType("Android");
} else if (/iPhone|iPad|iPod/i.test(userAgent)) {
setDeviceType("ios");
} else {
setDeviceType("pc");
}
handleLogin({ isSignin: false, userToken: null });
signOut();
removeUserInfo();
@ -154,7 +164,7 @@ function Login({ handleLogin }) {
handleLogin({ isSignin: true, userToken: data.data.token });
router.push(
(!data?.data?.is_enabled && type != "password")
!data?.data?.is_enabled && type != "password"
? "/my/setting/editPassword?is_enabled=" + data?.data?.is_enabled
: "/"
);
@ -206,7 +216,9 @@ function Login({ handleLogin }) {
};
return (
<div className="lg:flex flex-col items-center ">
<div className={`lg:max-w-[450px] overflow-hidden pt-20 flex flex-col items-center `}>
<div
className={`lg:max-w-[450px] overflow-hidden pt-20 flex flex-col items-center `}
>
<Image
src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL + "/images/slogan.png"}
alt=""
@ -350,7 +362,9 @@ function Login({ handleLogin }) {
</div>
</div>
<div
onClick={() => router.push(`/my/setting/editPassword?forgetPassword=true`)}
onClick={() =>
router.push(`/my/setting/editPassword?forgetPassword=true`)
}
className="w-full text-[#FF669E] text-xs mt-2 text-right"
>
忘记密码
@ -364,6 +378,7 @@ function Login({ handleLogin }) {
</Swiper.Item>
</Swiper>
</div>
{deviceType == "ios" && <BottomBox />}
</div>
);
}
@ -389,7 +404,9 @@ const LoginBtn = ({ loginInfo, setLoginInfo, type, handleSubmit }) => {
我已阅读并同意
<span
onClick={() =>
router.push(`/webView/${encodeURIComponent("/doc/useragreement")}`)
router.push(
`/webView/${encodeURIComponent("/doc/useragreement")}`
)
}
className="text-[#FF669E] text-xs"
>
@ -398,7 +415,9 @@ const LoginBtn = ({ loginInfo, setLoginInfo, type, handleSubmit }) => {
<span
onClick={() =>
router.push(`/webView/${encodeURIComponent("/doc/privatypolicy")}`)
router.push(
`/webView/${encodeURIComponent("/doc/privatypolicy")}`
)
}
className="text-[#FF669E] text-xs"
>
@ -416,6 +435,22 @@ const LoginBtn = ({ loginInfo, setLoginInfo, type, handleSubmit }) => {
>
登录
</Button>
</div>
);
};
const BottomBox = () => {
const router = useRouter();
return (
<div className="fixed bottom-0 w-full p-6 ">
<div className="p-3 rounded-md flex justify-between items-center bg-[#ffffff17]">
<div>
<p className="">铁粉空间APP可以下载啦</p>
<p className="text-xs text-[#FFFFFF80]">立即下载APP体验更好的服务</p>
</div>
<div className="px-2 py-1 rounded-full bg-[#FF669E]" onClick={()=>router.push("https://tiefen.fun")}>下载APP</div>
</div>
</div>
);
};

View File

@ -139,6 +139,7 @@ export default function Relationship() {
<Avatar
src={item?.avatar?.images[0].urls[0]}
style={{ "--border-radius": "50px" }}
onClick={()=>router.push("/profile/"+item.mid)}
/>
<div>
<p>{item.name}</p>

View File

@ -24,6 +24,10 @@ 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 {useSearchParams} from "next/navigation"
import StreamerNavigator from "@/components/StreamerNavigator";
import { checkAuth } from "@/utils/auth";
const variables = {
"@active-line-color": "#f00", // 将主题色改为红色
};
@ -37,9 +41,10 @@ const tabItems = [
export default function Home() {
const recommPostRef = useRef();
const followPostRef = useRef();
const searchParams = useSearchParams();
const swiperRef = useRef(null);
const [activeIndex, setActiveIndex] = useState(0);
const [data, setData] = useState([]);
const [visible, setVisible] = useState(false);
const [scrollHeight, setScrollHeight] = useState(0);
// 获取屏幕高度
@ -47,6 +52,11 @@ export default function Home() {
useEffect(() => {
setScrollHeight(window.innerHeight);
// getData(0)
checkAuth().then(res=>{
if(res && get("inviter")){
setVisible(true)
}
})
}, []);
const childrenFunc = () => {
if (!activeIndex) {
@ -115,6 +125,7 @@ export default function Home() {
>
<FontAwesomeIcon icon={faRefresh} size="xl" />
</div>
<StreamerNavigator visible={visible} setVisible={setVisible} mid={Number(get("inviter"))}/>
</div>
);
}
@ -300,4 +311,4 @@ const FollowPostList = forwardRef(({ scrollHeight }, ref) => {
{/* </PullToRefresh> */}
</div>
);
});
});

View File

@ -333,10 +333,7 @@ export default function PersonSpace() {
)}
</ul>
{streamerInfo?.streamer_ext?.bio && (
<div>
<span className="text-[#ffffff88]">个性签名</span>
<span className="break-words">{streamerInfo?.streamer_ext?.bio}</span>
</div>
<div className="whitespace-pre-wrap" style={{overflowWrap:"anywhere"}}><span className="text-[#ffffff88]">个性签名</span>{streamerInfo?.streamer_ext?.bio}</div>
)}
</div>
</div>
@ -370,7 +367,7 @@ export default function PersonSpace() {
</div>
</div>
<div className="flex ">
{spaceData?.previews?.images?.map((item, index) => (
{spaceData?.previews?.images?.slice(0,4).map((item, index) => (
<div
key={item.id}
className="w-20 h-20 overflow-hidden rounded mr-1"
@ -420,7 +417,8 @@ export default function PersonSpace() {
{streamerInfo?.streamer_ext?.platforms?.map((item) => (
<li
key={item.id}
className="flex justify-between border-[1.5px] border-[#ffffff43] rounded-xl p-2"
className="grid gap-1 justify-between border-[1.5px] border-[#ffffff43] rounded-xl p-2"
style={{gridTemplateColumns:"calc(100% - 130px) 130px"}}
>
<div className="flex justify-between items-center">
<Image
@ -429,32 +427,43 @@ export default function PersonSpace() {
className="mr-2"
src={item?.icon.images[0].urls[0]}
/>
<div className="text-base">
<span>{item?.link_name}</span>
<span>{item?.nickname}</span>
<div className="text-base truncate">
{item?.link_name}{item?.nickname}
</div>
</div>
<div className="flex text-sm">
<div className="flex justify-between text-sm">
<div
className="flex items-center mr-6"
className="flex items-center"
onClick={() => {
copy(item.url);
}}
>
<FontAwesomeIcon
{/* <FontAwesomeIcon
icon={faCopy}
size="xl"
className="h-3 mr-1"
/>
<span>复制</span>
/> */}
<Image
height={24}
width={24}
className="mr-1"
src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/icons/copy.png"}
/>
<span className="whitespace-nowrap">复制</span>
</div>
<div className="flex items-center">
<FontAwesomeIcon
{/* <FontAwesomeIcon
icon={faAngleRight}
size="xl"
className="h-3 mr-1"
/>
<Link href={item?.url}>前往</Link>
/> */}
<Image
height={24}
width={24}
className="mr-1"
src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/icons/goto.png"}
/>
<Link href={item?.url} className="whitespace-nowrap">前往</Link>
</div>
</div>
</li>

View File

@ -18,7 +18,7 @@ import PostItem from "@/components/PostItem";
import PostItemSkeleton from "@/components/skeletons/PostItemSkeleton";
import requireAPI from "@/utils/requireAPI";
import AddWeChat from "@/components/AddWeChat";
import SeeTiefen from "@/components/SeeTiefen";
import SeeTiefen from "@/components/StreamerNavigator";
import DefaultMask from "@/components/DefaultMask";
import { getSpaceData, getStreamerInfo } from "@/api/space";
import baseRequest from "@/utils/baseRequest";

View File

@ -10,6 +10,7 @@ import {
faCalendar,
} from "@fortawesome/free-solid-svg-icons";
import { getSpaceData } from "@/api/space";
import requireAPI from "@/utils/requireAPI";
export default function Setting() {
const router = useRouter();
const searchParams = useSearchParams();
@ -79,8 +80,9 @@ export default function Setting() {
return `${year}/${month}/${day}`;
}, []);
const handleExitSpace = async () => {
try {
const _data = await requireAPI("POST", "/api/account_relation/count", {
const _data = await requireAPI("POST", "/api/zone/exit", {
body: {
zid: streamerInfo?.id,
},
@ -98,7 +100,7 @@ export default function Setting() {
content: "退出空间成功",
position: "top",
});
setTimeout(() => redirect("/"), 500);
setTimeout(() => router.replace("/"), 500);
} catch (error) {
console.error(error);
}

View File

@ -1,6 +1,6 @@
"use client";
import React, { useState, useEffect } from "react";
import { redirect, useRouter, useSearchParams } from "next/navigation";
import { useRouter, useSearchParams } from "next/navigation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import { TextArea, Divider, Button, Toast,DotLoading,Input } from "antd-mobile";
@ -73,7 +73,7 @@ export default function SpaceRefund() {
content: "提交成功,请关注原支付渠道通知",
position: "top",
});
redirect("/");
router.replace("/");
} catch (error) {
console.error(error);
} finally {

View File

@ -27,14 +27,15 @@ export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, medi
let arr = [...imgArr, ...videoArr];
let newPhotos = [...arr];
if (mediaAmount && !isUnlocked) {
console.log("newPhotos",newPhotos)
newPhotos = Array(mediaAmount)
.fill(null)
.map((item, index) => {
return newPhotos[index]
&& mediaVisibleRange ? newPhotos[index]
: { url: newPhotos[0]?.url, type: "hid" };
: { mp4:newPhotos[0]?.type==="video", url: newPhotos[0]?.url, type: "hid" };
});
console.log("newPhotos",newPhotos)
}
setPhotos(newPhotos);
if (newPhotos.length > 9) {
@ -89,7 +90,7 @@ export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, medi
controls
className="w-screen h-[70vh] rounded-lg object-contain"
poster={video?.url}
autoPlay={true}
// autoPlay={true}
>
<source src={video.mp4} type="video/mp4" />
您的浏览器不支持 Video 标签
@ -203,7 +204,7 @@ export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, medi
/>
</div>
}
{item?.type == "video" && (
{item?.mp4 && (
<div className="absolute top-0 w-full h-full rounded flex justify-center items-center bg-[#33333348]">
<Image
className=""

View File

@ -1,6 +1,6 @@
"use client";
import React, { useEffect, useState, useMemo } from "react";
import React, { useEffect, useState, useMemo,useCallback } from "react";
import Photos from "../Photos";
import { useRouter } from "next/navigation";
import PaySpacePost from "../PaySpacePost";
@ -66,7 +66,11 @@ export default function PostItem({
// 返回找到的链接数组
return text;
}
const formatZoneUpdateTime = useCallback((time) => {
if (time === 0) return "今日";
if (time === 1) return "昨日";
return `${time}日前`;
}, []);
return (
<div>
{type == "space" && data?.is_headed === 1 && (
@ -74,6 +78,7 @@ export default function PostItem({
src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL + "/images/top_post.png"}
width={76}
className="mb-2"
/>
)}
<div className="flex">
@ -188,7 +193,7 @@ export default function PostItem({
router.push("/space/person_space_introduce/" + data.mid)
}
>
{data.is_active_within_a_week ? (
{data.streamer_ext.is_active_within_a_week ? (
<>
<Image
src={
@ -200,17 +205,23 @@ export default function PostItem({
placeholder=""
/>
<span className="mr-1 text-primary text-xs">
{data.days_elapsed_since_the_last_zones_update < 7 &&
{/* {data.streamer_ext.days_elapsed_since_the_last_zones_update < 7 &&
`空间${
data.days_elapsed_since_the_last_zones_update === 0
data.streamer_ext.days_elapsed_since_the_last_zones_update === 0
? "今日"
: "new" === 1
? "昨日"
: "new" === 2
? "前天"
: data.days_elapsed_since_the_last_zones_update +
: data.streamer_ext.days_elapsed_since_the_last_zones_update +
"天前"
}有更新`}
空间 */}
{formatZoneUpdateTime(
data?.streamer_ext
?.days_elapsed_since_the_last_zones_update
)}
有更新
</span>
<FontAwesomeIcon
icon={faAngleRight}

View File

@ -0,0 +1,77 @@
"use client";
import React, { useEffect, useState } from "react";
import { Mask, Image,Button } from "antd-mobile";
import {getStreamerInfo} from "@/api/space";
import { useRouter } from "next/navigation";
import {remove} from "@/utils/storeInfo"
export default function StreamerNavigator({
visible,
mid,
setVisible
}) {
const [streamerInfo,setStreamerInfo] = useState(null);
const router = useRouter();
useEffect(()=>{
getStreamerInfo(mid).then(res=>{
setStreamerInfo(res);
})
},[])
const handleCloseMask = ()=>{
remove("inviter")
setVisible(false)
}
return (
<Mask visible={visible} onMaskClick={handleCloseMask}>
<div
className="fixed top-[12.5%] left-[12.5%] w-3/4 flex-1 justify-center items-center bg-[#00000080]"
>
<div
className="rounded-2xl bg-[#1E1C29] items-center overflow-hidden"
>
<div className="flex flex-col w-full">
<Image
src={streamerInfo?.streamer_ext?.cover?.images[0]?.urls[0]}
fit="cover"
style={{ aspectRatio: 1}}
className="w-full"
/>
<div className="p-4">
<div className="flex flex-row items-center">
<p
className="text-xl text-white font-medium mr-1"
>
{streamerInfo?.streamer_ext?.name}
</p>
<div className="w-5 h-5">
<Image src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/icons/verification.png"} />
</div>
</div>
<p className="text-sm text-[#FFFFFFB2] mt-1 truncate ">
{streamerInfo?.streamer_ext?.bio}
</p>
<div
onClick={
streamerInfo?.streamer_ext?.zones?.length === 0
? () => {
handleCloseMask();
router.push("/profile/"+streamerInfo?.mid);
}
: () => {
handleCloseMask();
router.push("/space/person_space_introduce/"+streamerInfo?.mid);
}
}
className="w-full p-2 mt-4 text-base rounded-full bg-[#FF669E] text-center"
>
{streamerInfo?.streamer_ext?.zones?.length === 0 ? "查看主页" : "查看空间"}
</div>
</div>
</div>
</div>
</div>
</Mask>
);
}

View File

@ -3,13 +3,16 @@ import { useRouter, usePathname, useSearchParams } from "next/navigation";
import { useEffect } from "react";
import { get } from "@/utils/storeInfo";
import { Toast } from "antd-mobile";
import {save} from "@/utils/storeInfo"
export default function WithAuth(WrappedComponent) {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if(searchParams.get("inviter")){
save("inviter",Number(searchParams.get("inviter")))
}
if(!pathname.includes("webView") && !pathname.includes("login") ){
checkLogin();
}
@ -32,6 +35,7 @@ export default function WithAuth(WrappedComponent) {
});
router.push("/login");
}else{
if(pathname.includes("login")){
router.replace("/")
}
@ -42,4 +46,4 @@ export default function WithAuth(WrappedComponent) {
}
};
return WrappedComponent;
}
}

View File

@ -3,5 +3,9 @@ export const handleLogin = (data) => ({
type: 'HANDLOGIN',
data
});
export const handleSaveRecommendMid = (data) => ({
type: 'HANDLESAVERECOMMENMID',
data
});

View File

@ -6,6 +6,7 @@ const initialState = {
authInfo: {
isSignin: false,
userToken: null,
recommendMid:null
},
};
let text = (data) => {
@ -15,6 +16,8 @@ const reducer = (state = initialState, action) => {
switch (action.type) {
case "HANDLOGIN":
return { ...state, authInfo: action.data };
case "HANDLESAVERECOMMENMID":
return { ...state, recommendMid: action.data };
default:
return state;
}

View File

@ -24,7 +24,7 @@ export default function customFetch(method, url, options = {}, mid) {
newBody.mid = mid;
}
const body = JSON.stringify({ ...base, ...newBody });
// console.log("newBody", body,url);
console.log("newBody", body,url);
// 合并选项
const mergedOptions = { ...defaultOptions, body };

View File

@ -179,7 +179,7 @@ export async function uploadImage(asset) {
});
return;
}
return data.data.ret_item;
return data.data.ret_item.id;
} else {
Toast.show({
content: "上传图片失败",
@ -289,7 +289,7 @@ export async function multiUploadImage(assets) {
await Promise.all(
assets.map(async (asset) => {
const id = await uploadImage(asset.src);
debugger;
// debugger;
ids.image_ids.push(id);
})
);