From ab5e87ef421c3c34dfc6adc406df56d611063059 Mon Sep 17 00:00:00 2001 From: xmdhs Date: Tue, 3 Oct 2023 22:38:07 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9A=AE=E8=82=A4=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/Route.tsx | 3 +- frontend/src/apis/apis.ts | 17 ++++++++++++ frontend/src/apis/model.ts | 2 +- frontend/src/views/Layout.tsx | 4 +-- frontend/src/views/Login.tsx | 2 +- frontend/src/views/profile/Profile.tsx | 32 ++++++--------------- frontend/src/views/profile/Security.tsx | 6 ++++ frontend/src/views/profile/Textures.tsx | 37 +++++++++++++++++-------- 8 files changed, 63 insertions(+), 40 deletions(-) create mode 100644 frontend/src/views/profile/Security.tsx diff --git a/frontend/src/Route.tsx b/frontend/src/Route.tsx index ac3246a..7ef429d 100644 --- a/frontend/src/Route.tsx +++ b/frontend/src/Route.tsx @@ -4,6 +4,7 @@ import Login from '@/views/Login' import Register from '@/views/Register' import Profile from '@/views/profile/Profile' import Textures from '@/views/profile/Textures' +import Security from '@/views/profile/Security' import Layout from '@/views/Layout' const router = createBrowserRouter([ @@ -19,7 +20,7 @@ function Root() { } /> } /> } /> - + } /> diff --git a/frontend/src/apis/apis.ts b/frontend/src/apis/apis.ts index 4c50a00..334391e 100644 --- a/frontend/src/apis/apis.ts +++ b/frontend/src/apis/apis.ts @@ -53,4 +53,21 @@ export async function yggProfile(uuid: string) { throw new Error(data?.errorMessage) } return data as YggProfile +} + +export async function upTextures(uuid: string, token: string, textureType: 'skin' | 'cape', model: 'slim' | '', file: File) { + const f = new FormData() + f.set("file", file) + f.set("model", model) + + const r = await fetch(import.meta.env.VITE_APIADDR + "/api/yggdrasil/api/user/profile/" + uuid + "/" + textureType, { + method: "PUT", + body: f, + headers: { + "Authorization": "Bearer " + token + } + }) + if (r.status != 204) { + throw new Error("上传失败 " + String(r.status)) + } } \ No newline at end of file diff --git a/frontend/src/apis/model.ts b/frontend/src/apis/model.ts index 03b0342..b6e3e38 100644 --- a/frontend/src/apis/model.ts +++ b/frontend/src/apis/model.ts @@ -2,7 +2,7 @@ export interface tokenData { accessToken: string selectedProfile: { name: string - uuid: string + id: string } } diff --git a/frontend/src/views/Layout.tsx b/frontend/src/views/Layout.tsx index 31a0353..3b02627 100644 --- a/frontend/src/views/Layout.tsx +++ b/frontend/src/views/Layout.tsx @@ -110,7 +110,7 @@ const MyToolbar = memo(function MyToolbar() { setAnchorEl(null); setNowUser({ name: "", uuid: "" }) setToken("") - navigate("/") + navigate("/login") }) useTilg() @@ -240,7 +240,7 @@ const MyDrawer = function MyDrawer() { { icon: , title: '安全设置', - link: '/setting' + link: '/security' } ] as ListItem[], []) diff --git a/frontend/src/views/Login.tsx b/frontend/src/views/Login.tsx index 03acf69..8fd90bb 100644 --- a/frontend/src/views/Login.tsx +++ b/frontend/src/views/Login.tsx @@ -49,7 +49,7 @@ export default function SignIn() { if (!v) return setToken(v.accessToken) setUserInfo({ - uuid: v.selectedProfile.uuid, + uuid: v.selectedProfile.id, name: v.selectedProfile.name, }) navigate("/profile") diff --git a/frontend/src/views/profile/Profile.tsx b/frontend/src/views/profile/Profile.tsx index 73c3c3a..1be2283 100644 --- a/frontend/src/views/profile/Profile.tsx +++ b/frontend/src/views/profile/Profile.tsx @@ -5,10 +5,9 @@ import Button from '@mui/material/Button'; import Typography from '@mui/material/Typography'; import CardHeader from '@mui/material/CardHeader'; import { useHover, useRequest, useUnmount } from 'ahooks'; -import { ApiErr } from '@/apis/error'; -import { LayoutAlertErr, token } from '@/store/store'; +import { LayoutAlertErr, user } from '@/store/store'; import { useAtomValue, useSetAtom } from 'jotai'; -import { userInfo, yggProfile } from '@/apis/apis'; +import { yggProfile } from '@/apis/apis'; import { useNavigate } from 'react-router-dom'; import Box from '@mui/material/Box'; import { useEffect, useRef, useState } from 'react'; @@ -22,32 +21,21 @@ import useTilg from 'tilg'; import useTitle from '@/hooks/useTitle'; const Profile = function Profile() { - const nowToken = useAtomValue(token) const navigate = useNavigate(); const setErr = useSetAtom(LayoutAlertErr) + const userinfo = useAtomValue(user) + const [textures, setTextures] = useState({ skin: "", cape: "", model: "default" }) useTitle("个人信息") - const userinfo = useRequest(() => userInfo(nowToken), { - refreshDeps: [nowToken], - cacheKey: "/api/v1/user" + nowToken, - staleTime: 60000, - onError: e => { - if (e instanceof ApiErr && e.code == 5) { - navigate("/login") - } - console.warn(e) - setErr(String(e)) - } - }) - const SkinInfo = useRequest(() => yggProfile(userinfo.data?.uuid ?? ""), { - cacheKey: "/api/yggdrasil/sessionserver/session/minecraft/profile/" + userinfo.data?.uuid, + const SkinInfo = useRequest(() => yggProfile(userinfo.uuid ?? ""), { + cacheKey: "/api/yggdrasil/sessionserver/session/minecraft/profile/" + userinfo?.uuid, onError: e => { console.warn(e) setErr(String(e)) }, - refreshDeps: [userinfo.data?.uuid], + refreshDeps: [userinfo?.uuid], }) useEffect(() => { @@ -70,12 +58,10 @@ const Profile = function Profile() { - uid - {(userinfo.loading && !userinfo.data) ? : userinfo.data?.uid} name - {(SkinInfo.loading || userinfo.loading) && !SkinInfo.data ? : SkinInfo.data?.name} + {userinfo.name} uuid - {(userinfo.loading && !userinfo.data) ? : userinfo.data?.uuid} + {userinfo.uuid} {/* diff --git a/frontend/src/views/profile/Security.tsx b/frontend/src/views/profile/Security.tsx new file mode 100644 index 0000000..f508280 --- /dev/null +++ b/frontend/src/views/profile/Security.tsx @@ -0,0 +1,6 @@ + +export default function Security() { + return (<> +

密码设置

+ ) +} \ No newline at end of file diff --git a/frontend/src/views/profile/Textures.tsx b/frontend/src/views/profile/Textures.tsx index 714d291..b49a4a4 100644 --- a/frontend/src/views/profile/Textures.tsx +++ b/frontend/src/views/profile/Textures.tsx @@ -16,45 +16,48 @@ import Box from "@mui/material/Box"; import ReactSkinview3d from "react-skinview3d"; import { useUnmount } from "ahooks"; import { SkinViewer } from "skinview3d"; +import { useAtomValue, useSetAtom } from "jotai"; +import { LayoutAlertErr, token, user } from "@/store/store"; +import { upTextures } from "@/apis/apis"; +import Loading from "@/components/Loading"; const Textures = function Textures() { const [redioValue, setRedioValue] = useState("skin") useTitle("上传皮肤") const [file, setFile] = useState(null) - const skin = useRef({ - skinUrl: "", - capeUrl: "", - }) + const skin = useRef("") const skinview3dView = useRef(null); + const setErr = useSetAtom(LayoutAlertErr) + const [loading, setLoading] = useState(false) + const userinfo = useAtomValue(user) + const nowToken = useAtomValue(token) useUnmount(() => { - skin.current.skinUrl && URL.revokeObjectURL(skin.current.skinUrl) - skin.current.capeUrl && URL.revokeObjectURL(skin.current.capeUrl) + skin.current && URL.revokeObjectURL(skin.current) skinview3dView.current?.dispose() }) useEffect(() => { if (file) { const nu = URL.createObjectURL(file) - skin.current.skinUrl && URL.revokeObjectURL(skin.current.skinUrl) - skin.current.capeUrl && URL.revokeObjectURL(skin.current.capeUrl) + skin.current && URL.revokeObjectURL(skin.current) skinview3dView.current?.loadSkin(null) skinview3dView.current?.loadCape(null) switch (redioValue) { case "skin": - skin.current.skinUrl = nu + skin.current = nu skinview3dView.current?.loadSkin(nu, { model: "default" }).then(() => skinview3dView.current?.loadSkin(nu, { model: "default" }) ) break case "slim": - skin.current.skinUrl = nu + skin.current = nu skinview3dView.current?.loadSkin(nu, { model: "slim" }).then(() => skinview3dView.current?.loadSkin(nu, { model: "slim" }) ) break case "cape": - skin.current.capeUrl = nu + skin.current = nu skinview3dView.current?.loadCape(nu).then(() => { skinview3dView.current?.loadCape(nu) }) @@ -70,6 +73,15 @@ const Textures = function Textures() { setFile(newFile) } + const handleToUpload = () => { + if (!file || loading) return + setLoading(true) + const textureType = redioValue == "cape" ? "cape" : "skin" + const model = redioValue == "slim" ? "slim" : "" + upTextures(userinfo.uuid, nowToken, textureType, model, file).catch(e => [setErr(String(e)), console.warn(e)]). + finally(() => setLoading(false)) + } + useTilg() return (<> @@ -98,7 +110,7 @@ const Textures = function Textures() { - +
@@ -114,6 +126,7 @@ const Textures = function Textures() { + {loading && } ) }