完善我的页面功能

This commit is contained in:
anln 2024-07-10 00:48:37 +08:00
parent 343f0efb94
commit 4cae50bd67
8 changed files with 314 additions and 101 deletions

View File

@ -110,3 +110,20 @@ export async function checkRelation(subMid, objMid, predicate) {
console.error(error);
}
}
export async function getUserInfo() {
try {
const data =
await require("POST", `/api/account/list_by_mid`, null, true);
if (data.ret === -1) {
Toast.show({
icon: "fail",
content: data.msg,
position: "top",
});
return;
}
return data.data.account;
} catch (error) {
console.error(error);
}
}

View File

@ -1,12 +1,60 @@
"use client";
import React from "react";
import { Avatar, Divider } from "antd-mobile";
import React, { useEffect, useState } from "react";
import { Avatar, Divider, Input } from "antd-mobile";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleLeft, faAngleRight } from "@fortawesome/free-solid-svg-icons";
import { useRouter } from "next/navigation";
import { get, save } from "@/utils/storeInfo";
import { uploadImage } from "@/utils/upload";
import { getUserInfo } from "@/api/public";
import require from "@/utils/require";
export default function SelectUserProfileItem() {
const router = useRouter();
const [userInfo, setUserInfo] = useState({});
useEffect(() => {
const userInfo = get("account");
if (setUserInfo) {
setUserInfo(userInfo);
}
}, []);
const uploadImg = async (e) => {
console.log(e.target.files[0]);
const file = e.target.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
if (file) {
reader.onload = (e) => {
uploadHead();
};
}
// return {
// url: URL.createObjectURL(file),
// };
};
const uploadHead = async () => {
const avatarId = await uploadImage(userInfo?.avatar?.images[0]?.urls[0]);
try {
const data = await require("POST", "/api/account/update", {
body: { avatar: { image_ids: [avatarId] } },
}, true);
if (data.ret === -1) {
Toast.show({
icon: "fail",
content: data.msg,
position: "top",
});
return;
}
//向服务器请求新的账号信息并保存到本地
const account = await getUserInfo();
save("account", JSON.stringify(account));
setUserInfo(account);
} catch (error) {
console.error(error);
}
};
return (
<div>
<div className="p-4 fixed top-0 z-10 w-full">
@ -25,13 +73,32 @@ export default function SelectUserProfileItem() {
<div className="pt-16 px-4">
<div className="flex justify-between items-center mt-2">
<span className="text-base font-medium">头像</span>
<div className="flex items-center">
<Avatar
src="https://picsum.photos/seed/picsum/200/300"
style={{ "--border-radius": "50px", "--size": "2rem" }}
/>
<FontAwesomeIcon icon={faAngleRight} size="xl" className=" ml-2" />
</div>
{/* <CustomUploadButton img={userInfo?.avatar?.images[0]?.urls[0]} /> */}
<label htmlFor="uploadAvatarBtn">
<div
className="flex items-center"
// onClick={() => setMediaPickerModalVisible(!mediaPickerModalVisible)}
>
<Avatar
src={userInfo?.avatar?.images[0]?.urls[0]}
style={{ "--border-radius": "50px", "--size": "2rem" }}
/>
<FontAwesomeIcon
icon={faAngleRight}
size="xl"
className=" ml-2"
/>
</div>
</label>
<input
type="file"
id="uploadAvatarBtn"
style={{ display: "none" }}
accept="image/png, image/jpeg"
capture="camera"
onChange={uploadImg}
/>
</div>
<Divider className="my-2" />
<div
@ -42,7 +109,7 @@ export default function SelectUserProfileItem() {
>
<span className="text-base font-medium">昵称</span>
<div>
<span className="text-base font-medium">铁粉空间</span>
<span className="text-base font-medium">{userInfo?.name}</span>
<FontAwesomeIcon
icon={faAngleRight}
size="xl"
@ -57,7 +124,7 @@ export default function SelectUserProfileItem() {
<div className="flex justify-between items-center mt-2">
<span className="text-base font-medium">ID</span>
<span className="text-base text-[#FFFFFF80] font-medium">
45676456
{userInfo?.user_id}
</span>
</div>
<Divider className="my-2" />
@ -65,3 +132,46 @@ export default function SelectUserProfileItem() {
</div>
);
}
// const CustomUploadButton = ({ img }) => {
// const [fileList, setFileList] = useState([
// {
// url: img,
// },
// ]);
// const uploadImg = async (file) => {
// console.log(file);
// return {
// url: URL.createObjectURL(file),
// };
// };
// return (
// <ImageUploader
// value={fileList}
// onChange={setFileList}
// upload={uploadImg}
// maxCount={1}
// preview={false}
// deletable={false}
// style={{ "--cell-size": "50px" }}
// >
// <div
// style={{
// width: 50,
// height: 50,
// borderRadius: 40,
// backgroundColor: "#f5f5f5",
// display: "flex",
// justifyContent: "center",
// alignItems: "center",
// color: "#999999",
// }}
// >
// <Avatar
// src={img}
// style={{ "--border-radius": "50px", "--size": "2rem" }}
// />
// </div>
// </ImageUploader>
// );
// };

View File

@ -1,12 +1,13 @@
"use client";
import React,{useEffect,useState} from "react";
import React, { useEffect, useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleRight } from "@fortawesome/free-solid-svg-icons";
import { Avatar, Image } from "antd-mobile";
import { useRouter,useSearchParams } from "next/navigation";
import { Avatar, Image, Toast } from "antd-mobile";
import { useRouter, useSearchParams } from "next/navigation";
import withAuth from "@/components/WithAuth";
import {get} from "@/utils/storeInfo";
import { get } from "@/utils/storeInfo";
import require from "@/utils/require";
const My = () => {
const [userInfo, setUserInfo] = useState({});
const searchParams = useSearchParams();
@ -15,12 +16,31 @@ const My = () => {
const userInfo = get("account");
if (userInfo) {
setUserInfo(userInfo);
getData(userInfo);
}
},[])
}, []);
const getData = async (oldUserInfo) => {
const data =
await require("POST", "/api/account_relation/count", null, true);
if (data.ret === -1) {
Toast.show({
icon: "fail",
content: data.msg,
position: "top",
});
return;
}
setUserInfo({ ...oldUserInfo, ...data.data });
};
return (
<div className="h-screen p-4 pb-20 bg-no-repeat bg-contain bg-top bg-[url(/images/profilebackground.png)]">
<div className="flex justify-end items-center z-10 w-full mb-4">
<div className="w-9 h-9 flex items-center justify-center bg-[#FFFFFF1A] rounded-full mr-2" onClick={()=>router.push("my/editUserProfile/selectUserProfileItem")}>
<div
className="w-9 h-9 flex items-center justify-center bg-[#FFFFFF1A] rounded-full mr-2"
onClick={() =>
router.push("my/editUserProfile/selectUserProfileItem")
}
>
<Image
src="/icons/32DP/edit.png"
width={32}
@ -28,7 +48,10 @@ const My = () => {
placeholder=""
/>
</div>
<div className="w-9 h-9 flex items-center justify-center bg-[#FFFFFF1A] rounded-full" onClick={()=>router.push("my/setting")}>
<div
className="w-9 h-9 flex items-center justify-center bg-[#FFFFFF1A] rounded-full"
onClick={() => router.push("my/setting")}
>
<Image
src="/icons/32DP/setting.png"
width={32}
@ -37,7 +60,10 @@ const My = () => {
/>
</div>
</div>
<div className="flex items-center justify-between mb-4" onClick={()=>router.push("profile/"+userInfo.mid)}>
<div
className="flex items-center justify-between mb-4"
onClick={() => router.push("profile/" + userInfo.mid)}
>
<div className="flex items-center">
<Avatar
rounded-full
@ -65,25 +91,31 @@ const My = () => {
size="xl"
className="h-6 mr-2"
onClick={() => {
searchParams.append()
searchParams.append();
router.back();
}}
/>
</div>
<ul className="grid grid-cols-4 mb-4">
<li className="text-center" onClick={()=>router.push("my/relationship?key=follow")}>
<p className="text-2xl">1</p>
<li
className="text-center"
onClick={() => router.push("my/relationship?key=follow")}
>
<p className="text-2xl">{userInfo?.follow_count}</p>
<p className="text-[#ffffff88]">关注</p>
</li>
<li className="text-center" onClick={()=>router.push("my/relationship?key=fans")}>
<p className="text-2xl">0</p>
<li
className="text-center"
onClick={() => router.push("my/relationship?key=fans")}
>
<p className="text-2xl">{userInfo?.is_followed_count}</p>
<p className="text-[#ffffff88]">粉丝</p>
</li>
<li className="text-center" onClick={()=>router.push("my/wallet")}>
<li className="text-center" onClick={() => router.push("my/wallet")}>
<p className="text-2xl">{userInfo.gold_num}</p>
<p className="text-[#ffffff88]">金币</p>
</li>
<li className="text-center" onClick={()=>router.push("my/wallet")}>
<li className="text-center" onClick={() => router.push("my/wallet")}>
<p className="text-2xl">{userInfo.diamond_num}</p>
<p className="text-[#ffffff88]">钻石</p>
</li>
@ -206,7 +238,10 @@ const My = () => {
{/* 普通用户 */}
<div className="rounded-xl p-2 border-2 border-[#2c2b2f]">
<ul>
<li className="flex justify-between items-center p-3 py-2" onClick={()=>router.push("my/wallet")}>
<li
className="flex justify-between items-center p-3 py-2"
onClick={() => router.push("my/wallet")}
>
<div className="flex items-center">
<Image
className="mr-2"
@ -274,7 +309,6 @@ const My = () => {
</div>
</div>
);
}
};
export default withAuth(My)
export default withAuth(My);

View File

@ -1,16 +1,17 @@
"use client";
import React, { useEffect, useRef, useState } from "react";
import { JumboTabs, List, InfiniteScroll, Avatar } from "antd-mobile";
import { JumboTabs, List, InfiniteScroll, Avatar, Toast } from "antd-mobile";
// import { useRouter } from "next/navigation";
import { useRouter } from "next/navigation";
import {useSearchParams, usePathname,useParams} from "next/navigation"
import { useSearchParams, usePathname, useParams } from "next/navigation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import Empty from "@/components/Empty";
import styles from "./index.module.scss"
import styles from "./index.module.scss";
import webviewBaseRequest from "@/utils/webviewBaseRequest";
import { generateSignature } from "@/utils/crypto";
import require from "@/utils/require";
export default function Relationship() {
const [currentKey, setCurrentKey] = useState("follow");
const [hasMore, setHasMore] = useState(true);
@ -20,41 +21,68 @@ export default function Relationship() {
const pathname = usePathname();
const params = useParams();
const [scrollHeight, setScrollHeight] = useState(0);
const [data, setData] = useState([]);
const [offset, setOffset] = useState(0);
// 获取屏幕高度
// const scrollHeight = 600;
useEffect(() => {
const data = getData();
console.log("getData",getData)
}, []);
if(currentKey){
setOffset(0);
setData([]);
getData(currentKey).then(res=>{
setData(res);
})
}
}, [currentKey]);
useEffect(() => {
const key = searchParams.get("key");
// console.log('nnnnn',searchParams.get("key"))
key && setCurrentKey(key)
}, [searchParams])
async function loadMore() {
const append = await mockRequest();
key && setCurrentKey(key);
}, [searchParams]);
async function loadMore(key) {
const append = await getData(key);
setData((val) => [...val, ...append]);
setHasMore(append.length > 0);
}
const getData = async () => {
const base = webviewBaseRequest();
const signature = generateSignature({
...base,
b_mid:182308
});
return await fetch(
`/api/vas/income_page?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...base,
b_mid:182308
}),
}
)
const getData = async (key) => {
// api/account_relation/list_is_followed
const followIds = await require("POST", `/api/account_relation/${
key == "follow" ? "list_follow" : "list_is_followed"
}`, {
body: { offset: offset, limit: 12 },
}, true);
if (followIds.ret === -1) {
Toast.show({
icon: "fail",
content: data.msg,
position: "top",
});
return;
}
if (!followIds.data.list.length) return [];
const followsMids = followIds.data.list.map((item) => item.obj_mid);
const streamers = await require("POST", `/api/streamer/${
key == "follow" ? "list_ext_by_mids" : "list_others_by_mids"
}`, {
body: { mids: followsMids, offset: 0, limit: 12 },
}, true);
if (streamers.ret === -1) {
Toast.show({
icon: "fail",
content: data.msg,
position: "top",
});
return;
}
const followsDataList = streamers.data.list.map((item) => ({
...item,
isFollowed: true,
}));
setOffset(streamers.data.offset);
return [...data, ...followsDataList];
// setMore(temData.data.more);
};
return (
<div className={styles.relationshipBox}>
@ -88,35 +116,35 @@ export default function Relationship() {
destroyOnClose={true}
>
<List className="overflow-y-auto scrollbarBox_hidden">
<List.Item className={`!p-0 ${styles.listTimeBox}`}>
<div className="grid gap-2 items-center" style={{gridTemplateColumns:"48px calc(100% - 128px) 64px"}}>
<Avatar src="https://picsum.photos/seed/picsum/200/300" style={{"--border-radius":"50px"}}/>
<div>
<p>XXXXXX</p>
<p className="text-xs truncate">
专属圈内容都在空间里永久更新外面看不到哟
</p>
{data.map((item, index) => (
<List.Item
key={item.id + "_" + index}
className={`!p-0 ${styles.listTimeBox}`}
>
<div
className="grid gap-2 items-center"
style={{
gridTemplateColumns: "48px calc(100% - 128px) 64px",
}}
>
<Avatar
src={item?.avatar?.images[0].urls[0]}
style={{ "--border-radius": "50px" }}
/>
<div>
<p>{item.name}</p>
<p className="text-xs truncate">{item.bio}</p>
</div>
<div className="text-sm leading-9 h-max bg-[#FFFFFF1A] px-2 rounded-full whitespace-nowrap flex items-center justify-center">
{item.isFollowed ? "已关注" : "关注"}
</div>
</div>
<div className="text-sm leading-9 h-max bg-[#FFFFFF1A] px-2 rounded-full whitespace-nowrap flex items-center justify-center">
关注
</div>
</div>
</List.Item>
<List.Item className={`!p-0 ${styles.listTimeBox}`}>
<div className="grid gap-2 items-center" style={{gridTemplateColumns:"48px calc(100% - 128px) 64px"}}>
<Avatar src="https://picsum.photos/seed/picsum/200/300" style={{"--border-radius":"50px"}}/>
<div>
<p>XXXXXX</p>
<p className="text-sm truncate">
专属圈内容都在空间里永久更新外面看不到哟
</p>
</div>
<div className="text-sm leading-9 h-max bg-[#FFFFFF1A] px-2 rounded-full whitespace-nowrap flex items-center justify-center">
已关注
</div>
</div>
</List.Item>
<InfiniteScroll loadMore={loadMore} hasMore={hasMore} />
</List.Item>
))}
<InfiniteScroll
loadMore={() => loadMore("follow")}
hasMore={hasMore}
/>
</List>
</JumboTabs.Tab>
<JumboTabs.Tab
@ -129,6 +157,37 @@ export default function Relationship() {
}
destroyOnClose={true}
>
<List className="overflow-y-auto scrollbarBox_hidden">
{data.map((item, index) => (
<List.Item
key={item.id + "_" + index}
className={`!p-0 ${styles.listTimeBox}`}
>
<div
className="grid gap-2 items-center"
style={{
gridTemplateColumns: "48px calc(100% - 128px) 64px",
}}
>
<Avatar
src={item?.avatar?.images[0].urls[0]}
style={{ "--border-radius": "50px" }}
/>
<div>
<p>{item.name}</p>
<p className="text-xs truncate">{item.bio}</p>
</div>
<div className="text-sm leading-9 h-max bg-[#FFFFFF1A] px-2 rounded-full whitespace-nowrap flex items-center justify-center">
{item.isFollowed ? "已关注" : "关注"}
</div>
</div>
</List.Item>
))}
<InfiniteScroll
loadMore={() => loadMore("fans")}
hasMore={hasMore}
/>
</List>
<div
className={`flex flex-col items-center mt-20`}
style={{ height: `${scrollHeight}px` }}

View File

@ -46,9 +46,6 @@ export default function AboutUs() {
icon={faHandshakeSimple}
size="sm"
className="h-4 text-white mr-2"
onClick={() => {
router.back();
}}
/>
<span className="text-base text-white">用户协议</span>
</div>
@ -56,20 +53,14 @@ export default function AboutUs() {
icon={faAngleRight}
size="sm"
className="h-4 text-gray-300"
onClick={() => {
router.back();
}}
/>
</li>
<li className="flex justify-between items-center p-3">
<li className="flex justify-between items-center p-3" >
<div className="flex items-center">
<FontAwesomeIcon
icon={faEye}
size="sm"
className="h-4 text-white mr-2"
onClick={() => {
router.back();
}}
/>
<span className="text-base text-white">隐私政策</span>
</div>

View File

@ -11,12 +11,12 @@ export default function customFetch(method, url, options = {},mid) {
headers: {
'Content-Type': 'application/json',
'X-Req-Source-TF': 'wittgenstein',
...options.headers
...options?.headers
// 可以添加其他默认头部信息
}
// 可以添加其他默认选项
};
let newBody = {...options.body}
let newBody = {...options?.body}
if(mid){
newBody.mid=get("account").mid
}

View File

@ -2,7 +2,9 @@ export function save(key,value){
localStorage.setItem(key,value)
}
export function get(key){
let data = localStorage.getItem(key);
let data = localStorage.getItem("account");
console.log(key,data)
return data ? JSON.parse(data) : {};
}
export function remove(key){

View File

@ -84,7 +84,7 @@ async function calculateFileMetadata(file) {
reject(error);
};
file.type.startsWith("image/")
file.type?.startsWith("image/")
? reader.readAsDataURL(file)
: reader.readAsArrayBuffer(file);
});