刷新token&获取信息

#202
This commit is contained in:
BTMuli
2026-01-04 04:43:42 +08:00
parent 0aae714455
commit f0c78a3b03
5 changed files with 131 additions and 16 deletions

View File

@@ -19,27 +19,28 @@
</div>
</template>
<script lang="ts" setup>
import showDialog from "@comp/func/dialog.js";
import showSnackbar from "@comp/func/snackbar.js";
import hutao from "@Hutao/index.js";
import useHutaoStore from "@store/hutao.js";
import { storeToRefs } from "pinia";
const { userName, accessToken, refreshToken } = storeToRefs(useHutaoStore());
const hutaoStore = useHutaoStore();
const { accessToken } = storeToRefs(hutaoStore);
async function test() {
const inputN = await showDialog.input("UserName");
const inputP = await showDialog.input("Pwd");
if (!inputN || !inputP) return;
const resp = await hutao.Account.login(inputN, inputP);
if (!hutaoStore.checkIsValid()) {
await hutaoStore.tryRefreshToken();
}
const resp = await hutao.Account.info(accessToken.value!);
if ("retcode" in resp) {
showSnackbar.warn(`${resp.retcode}-${resp.message}`);
return;
}
userName.value = inputN;
accessToken.value = resp.AccessToken;
refreshToken.value = resp.RefreshToken;
showSnackbar.success("登录成功!");
console.log(resp);
// userName.value = inputN;
// accessToken.value = resp.AccessToken;
// refreshToken.value = resp.RefreshToken;
// showSnackbar.success("登录成功!");
}
</script>
<style lang="css" scoped>

View File

@@ -12,7 +12,7 @@ import {
getTeamCollect,
uploadAbyssData,
} from "./request/abyssReq.js";
import { loginPassport } from "./request/accountReq.js";
import { getUserInfo, loginPassport, refreshToken } from "./request/accountReq.js";
import { getCombatStatistic, uploadCombatData } from "./request/combatReq.js";
import { transAbyssAvatars, transAbyssLocal } from "./utils/abyssUtil.js";
import { transCombatLocal } from "./utils/combatUtil.js";
@@ -50,11 +50,11 @@ const Hutao = {
password: _,
},
token: {
refresh: _,
refresh: refreshToken,
revoke: _,
revokeAll: _,
},
info: _,
info: getUserInfo,
},
Gacha: {
log: _,

View File

@@ -62,5 +62,39 @@ export async function loginPassport(
body: JSON.stringify(data),
});
if (resp.retcode !== 0) return <TGApp.Plugins.Hutao.Base.Resp>resp;
return resp.data;
return <TGApp.Plugins.Hutao.Account.LoginRes>resp.data;
}
/**
* 刷新访问令牌
* @since Beta v0.9.1
*/
export async function refreshToken(token: string) {
const url = `${PassportUrl}RefreshToken`;
const header = await getReqHeader();
const data = { RefreshToken: rsaEncrypt(token) };
const resp = await TGHttp<TGApp.Plugins.Hutao.Account.RefreshTokenResp>(url, {
method: "POST",
headers: header,
body: JSON.stringify(data),
});
if (resp.retcode !== 0) return <TGApp.Plugins.Hutao.Base.Resp>resp;
return <TGApp.Plugins.Hutao.Account.RefreshTokenRes>resp.data;
}
/**
* 获取用户信息
* @since Beta v0.9.1
*/
export async function getUserInfo(
token: string,
): Promise<TGApp.Plugins.Hutao.Account.InfoRes | TGApp.Plugins.Hutao.Base.Resp> {
const url = `${PassportUrl}UserInfo`;
const header = await getReqHeader(token);
const resp = await TGHttp<TGApp.Plugins.Hutao.Account.InfoResp>(url, {
method: "GET",
headers: header,
});
if (resp.retcode !== 0) return <TGApp.Plugins.Hutao.Base.Resp>resp;
return <TGApp.Plugins.Hutao.Account.InfoRes>resp.data;
}

View File

@@ -55,4 +55,47 @@ declare namespace TGApp.Plugins.Hutao.Account {
/** refresh */
RefreshToken: string;
};
/**
* 刷新Token返回响应
* @since Beta v0.9.1
*/
type RefreshTokenResp = TGApp.Plugins.Hutao.Base.Resp<RefreshTokenRes>;
/**
* 刷新Token返回
* @since Beta v0.9.1
*/
type RefreshTokenRes = LoginRes;
/**
* 信息返回响应
* @since Beta v0.9.1
*/
type InfoResp = TGApp.Plugins.Hutao.Base.Resp<InfoRes>;
/**
* 信息返回
* @since Beta v0.9.1
*/
type InfoRes = {
/**
* CDN 过期时间
* @example 2025-09-18T01:01:39+00:00
*/
CdnExpireAt: string;
/**
* 胡桃云祈愿过期时间
* @remarks 与 CDN 过期时间格式一致
*/
GachaLogExpireAt: string;
/** 是否是开发者 */
IsLicenseDeveloper: boolean;
/** 是否是主开发 */
IsMaintainer: boolean;
/** 常规用户名 */
NormalizedUserName: string;
/** 用户名 */
UserName: string;
};
}

View File

@@ -21,6 +21,18 @@ const useHutaoStore = defineStore(
const refreshToken = ref<string>();
/** 超时时间 */
const accessExpire = ref<number>(0);
/** 用户信息 */
const userInfo = ref<TGApp.Plugins.Hutao.Account.InfoRes>();
/**
* 检测是否超时
*/
function checkIsValid(): boolean {
if (accessExpire.value === 0 || !refreshToken.value || refreshToken.value === "") {
return false;
}
return Date.now() < accessExpire.value;
}
async function tryLogin(): Promise<void> {
const inputN = await showDialog.input("请输入胡桃云账号", "邮箱:");
@@ -50,8 +62,8 @@ const useHutaoStore = defineStore(
userName.value = inputN;
accessToken.value = resp.AccessToken;
refreshToken.value = resp.RefreshToken;
// TODO: 判断返回单位处理expire
// accessExpire.value = Date.now();
accessExpire.value = Date.now() + resp.ExpiresIn * 1000;
showSnackbar.success("成功登录胡桃云");
} catch (err) {
console.error(err);
showSnackbar.error("登录胡桃云失败");
@@ -60,12 +72,37 @@ const useHutaoStore = defineStore(
}
}
async function tryRefreshToken(): Promise<void> {
if (!refreshToken.value || refreshToken.value == "") {
showSnackbar.warn("未找到胡桃云RefreshToken");
return;
}
try {
const resp = await hutao.Account.token.refresh(refreshToken.value);
if ("retcode" in resp) {
showSnackbar.warn(`[${resp.retcode}] ${resp.message}`);
console.error(resp);
return;
}
accessToken.value = resp.AccessToken;
refreshToken.value = resp.RefreshToken;
accessExpire.value = Date.now() + resp.ExpiresIn * 1000;
showSnackbar.success("成功刷新胡桃云Token");
} catch (e) {
console.error(e);
showSnackbar.error("刷新胡桃云Token失败");
}
}
return {
userName,
accessToken,
refreshToken,
accessExpire,
userInfo,
checkIsValid,
tryLogin,
tryRefreshToken,
};
},
{