mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-06 08:32:51 +08:00
✨ 完成扫码获取 ck,closes #18
This commit is contained in:
@@ -11,21 +11,23 @@
|
||||
<div class="tog-bottom">
|
||||
<v-btn class="tog-btn" @click="onCancel">取消</v-btn>
|
||||
<v-btn class="tog-btn" @click="freshQr">刷新</v-btn>
|
||||
<v-btn class="tog-btn" @click="getData">已扫码</v-btn>
|
||||
<v-btn class="tog-btn" :loading="loading" @click="getData">已扫码</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</TOverlay>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// vue
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { computed, reactive, ref, watch } from "vue";
|
||||
import showSnackbar from "../func/snackbar";
|
||||
import TOverlay from "../main/t-overlay.vue";
|
||||
import QrcodeVue from "qrcode.vue";
|
||||
// store
|
||||
import { useUserStore } from "../../store/modules/user";
|
||||
// utils
|
||||
import { getLoginQr, getLoginStatus } from "../../plugins/Mys/utils/doGameLogin";
|
||||
import Mys from "../../plugins/Mys";
|
||||
import TGRequest from "../../web/request/TGRequest";
|
||||
import TGSqlite from "../../plugins/Sqlite";
|
||||
|
||||
interface ToWebLoginProps {
|
||||
modelValue: boolean;
|
||||
@@ -45,8 +47,19 @@ const visible = computed({
|
||||
emits("update:modelValue", value);
|
||||
},
|
||||
});
|
||||
const loading = ref<boolean>(false);
|
||||
const qrCode = ref<string>("");
|
||||
const ticket = ref<string>("");
|
||||
const cookie = reactive<Record<string, string>>({
|
||||
account_id: "",
|
||||
ltuid: "",
|
||||
stuid: "",
|
||||
mid: "",
|
||||
game_token: "",
|
||||
cookie_token: "",
|
||||
stoken: "",
|
||||
ltoken: "",
|
||||
});
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
@@ -57,7 +70,7 @@ watch(visible, async (value) => {
|
||||
});
|
||||
|
||||
async function freshQr(): Promise<void> {
|
||||
const res = await getLoginQr();
|
||||
const res = await Mys.User.getQr();
|
||||
if ("retcode" in res) {
|
||||
showSnackbar({
|
||||
text: `[${res.retcode}] ${res.message}`,
|
||||
@@ -79,7 +92,8 @@ async function freshQr(): Promise<void> {
|
||||
}
|
||||
|
||||
async function getData(): Promise<void> {
|
||||
const res = await getLoginStatus(ticket.value);
|
||||
loading.value = true;
|
||||
const res = await Mys.User.getData(ticket.value);
|
||||
if ("retcode" in res) {
|
||||
showSnackbar({
|
||||
text: `[${res.retcode}] ${res.message}`,
|
||||
@@ -97,10 +111,11 @@ async function getData(): Promise<void> {
|
||||
});
|
||||
} else {
|
||||
const data: TGApp.Plugins.Mys.GameLogin.StatusPayloadRaw = JSON.parse(res.payload.raw);
|
||||
await userStore.saveCookie("account_id", data.uid);
|
||||
await userStore.saveCookie("ltuid", data.uid);
|
||||
await userStore.saveCookie("stuid", data.uid);
|
||||
await userStore.saveCookie("game_token", data.token);
|
||||
cookie.account_id = data.uid;
|
||||
cookie.ltuid = data.uid;
|
||||
cookie.stuid = data.uid;
|
||||
cookie.game_token = data.token;
|
||||
await getTokens();
|
||||
showSnackbar({
|
||||
text: "登录成功",
|
||||
color: "success",
|
||||
@@ -112,6 +127,26 @@ async function getData(): Promise<void> {
|
||||
function onCancel(): void {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
async function getTokens(): Promise<void> {
|
||||
const stokenRes = await TGRequest.User.bgGameToken.getStoken(
|
||||
cookie.account_id,
|
||||
cookie.game_token,
|
||||
);
|
||||
if (!("retcode" in stokenRes)) {
|
||||
cookie.stoken = stokenRes.token.token;
|
||||
cookie.mid = stokenRes.user_info.mid;
|
||||
}
|
||||
const cookieTokenRes = await TGRequest.User.bgGameToken.getCookieToken(
|
||||
cookie.account_id,
|
||||
cookie.game_token,
|
||||
);
|
||||
if (typeof cookieTokenRes === "string") cookie.cookie_token = cookieTokenRes;
|
||||
const ltokenRes = await TGRequest.User.bySToken.getLToken(cookie.mid, cookie.stoken);
|
||||
if (typeof ltokenRes === "string") cookie.ltoken = ltokenRes;
|
||||
userStore.cookie = cookie;
|
||||
await TGSqlite.saveAppData("cookie", JSON.stringify(cookie));
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tog-box {
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
<template>
|
||||
<TOverlay v-model="visible" hide blur-val="20px">
|
||||
<div class="tow-box">
|
||||
<div class="tow-top">
|
||||
<div class="tow-title">请使用米游社APP进行扫码操作</div>
|
||||
<div class="tow-subtitle">所需米游社版本 >= 2.57.1</div>
|
||||
</div>
|
||||
<div class="tow-mid">
|
||||
<qrcode-vue class="tow-qr" :value="qrCode" render-as="svg" />
|
||||
</div>
|
||||
<div class="tow-bottom">
|
||||
<v-btn class="tow-btn" @click="onCancel">取消</v-btn>
|
||||
<v-btn class="tow-btn" @click="freshQr">刷新</v-btn>
|
||||
<v-btn class="tow-btn" @click="getData">已扫码</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</TOverlay>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// vue
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import showSnackbar from "../func/snackbar";
|
||||
import TOverlay from "../main/t-overlay.vue";
|
||||
import QrcodeVue from "qrcode.vue";
|
||||
// utils
|
||||
import { getLoginQr, getLoginStatus } from "../../plugins/Mys/utils/doWebLogin";
|
||||
|
||||
interface ToWebLoginProps {
|
||||
modelValue: boolean;
|
||||
}
|
||||
|
||||
type ToWebLoginEmits = (e: "update:modelValue", value: boolean) => void;
|
||||
|
||||
const props = withDefaults(defineProps<ToWebLoginProps>(), {
|
||||
modelValue: false,
|
||||
});
|
||||
|
||||
const emits = defineEmits<ToWebLoginEmits>();
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => {
|
||||
emits("update:modelValue", value);
|
||||
},
|
||||
});
|
||||
const qrCode = ref<string>("");
|
||||
const ticket = ref<string>("");
|
||||
|
||||
onMounted(async () => {
|
||||
await freshQr();
|
||||
});
|
||||
|
||||
async function freshQr(): Promise<void> {
|
||||
const res = await getLoginQr();
|
||||
if ("retcode" in res) {
|
||||
showSnackbar({
|
||||
text: `[${res.retcode}] ${res.message}`,
|
||||
color: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
ticket.value = res.ticket;
|
||||
qrCode.value = res.url;
|
||||
}
|
||||
|
||||
async function getData(): Promise<void> {
|
||||
const res = await getLoginStatus(ticket.value);
|
||||
if ("retcode" in res) {
|
||||
showSnackbar({
|
||||
text: `[${res.retcode}] ${res.message}`,
|
||||
color: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
// todo 后续处理
|
||||
console.log(res);
|
||||
}
|
||||
|
||||
function onCancel(): void {
|
||||
visible.value = false;
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tow-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
background-color: var(--box-bg-1);
|
||||
color: var(--app-page-content);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.tow-top {
|
||||
border-bottom: 1px solid var(--common-shadow-4);
|
||||
font-family: var(--font-title);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tow-title {
|
||||
color: var(--common-text-title);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.tow-subtitle {
|
||||
font-size: 14px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.tow-mid {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
border: 1px solid var(--common-shadow-2);
|
||||
border-radius: 5px;
|
||||
aspect-ratio: 1;
|
||||
background: var(--box-bg-2);
|
||||
}
|
||||
|
||||
.tow-qr {
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
}
|
||||
|
||||
.tow-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.tow-btn {
|
||||
background: var(--tgc-btn-1);
|
||||
color: var(--btn-text);
|
||||
}
|
||||
</style>
|
||||
@@ -43,25 +43,14 @@
|
||||
{{ userInfo.nickname }} uid:{{ userInfo.uid }}
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-subtitle v-show="userInfo.nickname === '未登录'">
|
||||
未登录,请输入 Cookie 登录!
|
||||
未登录,请扫码登录!
|
||||
</v-list-item-subtitle>
|
||||
<template #prepend>
|
||||
<img class="config-icon" :src="userInfo.avatar" alt="Login" />
|
||||
</template>
|
||||
<template #append>
|
||||
<v-btn v-show="userInfo.nickname === '未登录'" class="config-btn" @click="confirmScanLogin">
|
||||
扫码登录</v-btn
|
||||
>
|
||||
<v-btn v-show="userInfo.nickname === '未登录'" class="config-btn" @click="confirmInitUser">
|
||||
刷新数据</v-btn
|
||||
>
|
||||
<v-btn
|
||||
v-show="userInfo.nickname !== '未登录'"
|
||||
class="config-btn"
|
||||
@click="confirmRefreshUser"
|
||||
>
|
||||
刷新数据</v-btn
|
||||
>
|
||||
<v-btn class="config-btn" @click="confirmScanLogin">扫码登录</v-btn>
|
||||
<v-btn class="config-btn" @click="confirmRefreshUser"> 刷新数据 </v-btn>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-subheader :inset="true" class="config-header">系统信息</v-list-subheader>
|
||||
@@ -143,24 +132,6 @@
|
||||
/>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item @click="confirmScan">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-cookie</v-icon>
|
||||
</template>
|
||||
<template #title>
|
||||
<span style="cursor: pointer">重新扫码</span>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-icon
|
||||
style="cursor: pointer"
|
||||
title="如何获取 Cookie?"
|
||||
@click="toOuter('https://github.com/BTMuli/Tauri.Genshin/issues/18')"
|
||||
@click.prevent.stop
|
||||
>
|
||||
mdi-help-circle-outline
|
||||
</v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="重置数据库" prepend-icon="mdi-delete" @click="confirmResetDB()" />
|
||||
<v-list-item
|
||||
title="检测 SQLite 数据库完整性"
|
||||
@@ -249,19 +220,6 @@ onMounted(async () => {
|
||||
osPlatform.value = `${await os.platform()}`;
|
||||
loadingSub.value = "正在获取系统版本";
|
||||
osVersion.value = await os.version();
|
||||
loadingSub.value = "正在获取数据库信息";
|
||||
try {
|
||||
dbInfo.value = await TGSqlite.getAppData();
|
||||
const ck = dbInfo.value.find((v) => v.key === "cookie");
|
||||
if (ck) {
|
||||
userStore.cookie = JSON.parse(ck.value);
|
||||
}
|
||||
} catch (e) {
|
||||
showSnackbar({
|
||||
color: "error",
|
||||
text: "读取数据库失败!",
|
||||
});
|
||||
}
|
||||
loadingSub.value = "";
|
||||
loading.value = false;
|
||||
});
|
||||
@@ -287,105 +245,6 @@ async function confirmScanLogin(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
// 初次获取用户信息
|
||||
async function confirmInitUser(): Promise<void> {
|
||||
const cookieTemp = {
|
||||
account_id: userStore.getCookieItem("account_id"),
|
||||
game_token: userStore.getCookieItem("game_token"),
|
||||
ltuid: userStore.getCookieItem("ltuid"),
|
||||
ltoken: "",
|
||||
stoken: "",
|
||||
cookie_token: "",
|
||||
stuid: "",
|
||||
mid: "",
|
||||
};
|
||||
loadingTitle.value = "正在获取 tokens";
|
||||
loading.value = true;
|
||||
loadingSub.value = "正在获取 stoken_v2";
|
||||
const stokenRes = await TGRequest.User.bgGameToken.getStoken(
|
||||
cookieTemp.account_id,
|
||||
cookieTemp.game_token,
|
||||
);
|
||||
if ("retcode" in stokenRes) {
|
||||
showSnackbar({
|
||||
color: "error",
|
||||
text: `[${stokenRes.retcode}] ${stokenRes.message}`,
|
||||
});
|
||||
console.error("获取 stoken_v2 失败", stokenRes);
|
||||
} else {
|
||||
const stoken = stokenRes.token.token;
|
||||
const mid = stokenRes.user_info.mid;
|
||||
await userStore.saveCookie("stoken", stoken);
|
||||
await userStore.saveCookie("mid", mid);
|
||||
cookieTemp.stoken = stoken;
|
||||
cookieTemp.mid = mid;
|
||||
}
|
||||
loadingSub.value = "正在获取 cookie_token";
|
||||
const cookieTokenRes = await TGRequest.User.bgGameToken.getCookieToken(
|
||||
cookieTemp.account_id,
|
||||
cookieTemp.game_token,
|
||||
);
|
||||
if (typeof cookieTokenRes !== "string") {
|
||||
showSnackbar({
|
||||
color: "error",
|
||||
text: `[${cookieTokenRes.retcode}] ${cookieTokenRes.message}`,
|
||||
});
|
||||
loadingSub.value = "获取 cookie_token 失败";
|
||||
console.error("获取 cookie_token 失败", cookieTokenRes);
|
||||
} else {
|
||||
await userStore.saveCookie("cookie_token", cookieTokenRes);
|
||||
cookieTemp.cookie_token = cookieTokenRes;
|
||||
}
|
||||
loadingSub.value = "正在获取 ltoken";
|
||||
const lTokenRes = await TGRequest.User.bySToken.getLToken(cookieTemp.mid, cookieTemp.stoken);
|
||||
if (typeof lTokenRes === "string") {
|
||||
await userStore.saveCookie("ltoken", lTokenRes);
|
||||
cookieTemp.ltoken = lTokenRes;
|
||||
} else {
|
||||
showSnackbar({
|
||||
color: "error",
|
||||
text: `[${lTokenRes.retcode}] ${lTokenRes.message}`,
|
||||
});
|
||||
loadingSub.value = "获取 ltoken 失败";
|
||||
console.error("获取 ltoken 失败", lTokenRes);
|
||||
}
|
||||
loadingTitle.value = "正在获取用户信息";
|
||||
loadingSub.value = "正在获取 用户信息";
|
||||
const infoRes = await TGRequest.User.byCookie.getUserInfo(
|
||||
cookieTemp.cookie_token,
|
||||
cookieTemp.account_id,
|
||||
);
|
||||
console.log(infoRes);
|
||||
if ("nickname" in infoRes) {
|
||||
userStore.setBriefInfo(infoRes);
|
||||
} else {
|
||||
showSnackbar({
|
||||
color: "error",
|
||||
text: `[${infoRes.retcode}] ${infoRes.message}`,
|
||||
});
|
||||
loadingSub.value = "获取用户信息失败";
|
||||
console.error("获取用户信息失败", infoRes);
|
||||
}
|
||||
const accountRes = await TGRequest.User.byCookie.getAccounts(
|
||||
cookieTemp.cookie_token,
|
||||
cookieTemp.account_id,
|
||||
);
|
||||
console.log(accountRes);
|
||||
if (Array.isArray(accountRes)) {
|
||||
loadingTitle.value = "获取成功!正在保存到数据库!";
|
||||
await TGSqlite.saveAccount(accountRes);
|
||||
} else {
|
||||
showSnackbar({
|
||||
color: "error",
|
||||
text: `[${accountRes.retcode}] ${accountRes.message}`,
|
||||
});
|
||||
loadingSub.value = "获取用户信息失败";
|
||||
console.error("获取用户信息失败", accountRes);
|
||||
}
|
||||
loadingSub.value = "";
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
// 刷新用户信息
|
||||
async function confirmRefreshUser(): Promise<void> {
|
||||
const res = await showConfirm({
|
||||
@@ -419,7 +278,6 @@ async function confirmRefreshUser(): Promise<void> {
|
||||
const ltokenRes = await TGRequest.User.bySToken.getLToken(ck.mid, ck.stoken);
|
||||
if (typeof ltokenRes === "string") {
|
||||
ck.ltoken = ltokenRes;
|
||||
await TGSqlite.saveAppData("cookie", JSON.stringify(ck));
|
||||
loadingTitle.value = "刷新成功!正在获取用户头像、昵称信息";
|
||||
} else {
|
||||
console.error(ltokenRes);
|
||||
@@ -430,7 +288,6 @@ async function confirmRefreshUser(): Promise<void> {
|
||||
const cookieTokenRes = await TGRequest.User.bySToken.getCookieToken(ck.mid, ck.stoken);
|
||||
if (typeof cookieTokenRes === "string") {
|
||||
ck.cookie_token = cookieTokenRes;
|
||||
await TGSqlite.saveAppData("cookie", JSON.stringify(ck));
|
||||
console.log(JSON.stringify(ck));
|
||||
loadingTitle.value = "刷新成功!正在获取用户头像、昵称信息";
|
||||
} else {
|
||||
@@ -438,6 +295,7 @@ async function confirmRefreshUser(): Promise<void> {
|
||||
loadingTitle.value = "刷新失败!正在获取用户头像、昵称信息";
|
||||
failCount++;
|
||||
}
|
||||
await TGSqlite.saveAppData("cookie", JSON.stringify(ck));
|
||||
const infoRes = await TGRequest.User.byCookie.getUserInfo(ck.cookie_token, ck.account_id);
|
||||
if ("nickname" in infoRes) {
|
||||
userStore.setBriefInfo(infoRes);
|
||||
@@ -460,7 +318,7 @@ async function confirmRefreshUser(): Promise<void> {
|
||||
if (failCount > 0) {
|
||||
showSnackbar({
|
||||
color: "error",
|
||||
text: "刷新失败!请重新输入 cookie!",
|
||||
text: "刷新失败!重试或者重新扫码登录!",
|
||||
});
|
||||
} else {
|
||||
showSnackbar({ text: "刷新成功!" });
|
||||
@@ -625,22 +483,6 @@ async function confirmResetApp(): Promise<void> {
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
// 输入 cookie
|
||||
async function confirmScan(): Promise<void> {
|
||||
await confirmScanLogin();
|
||||
const confirmRes = await showConfirm({
|
||||
title: "是否刷新数据?",
|
||||
});
|
||||
if (confirmRes) {
|
||||
await confirmInitUser();
|
||||
} else {
|
||||
showSnackbar({
|
||||
color: "grey",
|
||||
text: "已取消刷新数据",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 重置数据库
|
||||
async function confirmResetDB(title?: string): Promise<void> {
|
||||
const res = await showConfirm({
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { markRaw, onBeforeMount, onMounted, onUnmounted, onUpdated, ref } from "vue";
|
||||
import { markRaw, onMounted, onUnmounted, onUpdated, ref } from "vue";
|
||||
import ToLoading from "../../components/overlay/to-loading.vue";
|
||||
import TPool from "../../components/home/t-pool.vue";
|
||||
import TPosition from "../../components/home/t-position.vue";
|
||||
@@ -15,10 +15,8 @@ import TCalendar from "../../components/home/t-calendar.vue";
|
||||
// store
|
||||
import { useHomeStore } from "../../store/modules/home";
|
||||
import { useAppStore } from "../../store/modules/app";
|
||||
import { useUserStore } from "../../store/modules/user";
|
||||
// utils
|
||||
import { getBuildTime } from "../../utils/TGBuild";
|
||||
import TGSqlite from "../../plugins/Sqlite";
|
||||
|
||||
// store
|
||||
const appStore = useAppStore();
|
||||
@@ -47,15 +45,6 @@ function readLoading(): void {
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(async () => {
|
||||
// 获取当前用户
|
||||
const user = await TGSqlite.getCurAccount();
|
||||
// 存储当前用户
|
||||
if (user) {
|
||||
useUserStore().setCurAccount(user);
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
loadingTitle.value = "正在加载首页";
|
||||
loading.value = true;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file plugins Mys index.ts
|
||||
* @description Mys plugin index
|
||||
* @author BTMuli <bt-muli@outlook.com>
|
||||
* @since Alpha v0.2.1
|
||||
* @since Beta v0.3.0
|
||||
*/
|
||||
|
||||
// Api
|
||||
@@ -22,6 +22,8 @@ import { getNoticeCard, getActivityCard, getNewsCard } from "./utils/getNewsCard
|
||||
// Lottery
|
||||
import getLotteryData from "./request/getLotteryData";
|
||||
import getLotteryCard from "./utils/getLotteryCard";
|
||||
// User
|
||||
import { getLoginQr, getLoginStatus } from "./request/doGameLogin";
|
||||
|
||||
const Mys = {
|
||||
Api: MysApi,
|
||||
@@ -49,6 +51,10 @@ const Mys = {
|
||||
get: getLotteryData,
|
||||
card: getLotteryCard,
|
||||
},
|
||||
User: {
|
||||
getQr: getLoginQr,
|
||||
getData: getLoginStatus,
|
||||
},
|
||||
};
|
||||
|
||||
export default Mys;
|
||||
|
||||
134
src/plugins/Mys/types/WebLogin.d.ts
vendored
134
src/plugins/Mys/types/WebLogin.d.ts
vendored
@@ -1,134 +0,0 @@
|
||||
/**
|
||||
* @file plugins Mys types WebLogin.d.ts
|
||||
* @description Mys 插件 Web 登录类型定义文件
|
||||
* @author BTMuli <bt-muli@outlook.com>
|
||||
* @since Beta v0.3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description Mys 插件 Web 登录类型
|
||||
* @since Beta v0.3.0
|
||||
* @namespace WebLogin
|
||||
* @return WebLogin
|
||||
*/
|
||||
declare namespace TGApp.Plugins.Mys.WebLogin {
|
||||
/**
|
||||
* @description 获取登录二维码返回数据
|
||||
* @since Beta v0.3.0
|
||||
* @interface GetLoginQrResponse
|
||||
* @extends TGApp.Plugins.Mys.Base.Response
|
||||
* @property {GetLoginQrData} data 数据
|
||||
* @return GetLoginQrResponse
|
||||
*/
|
||||
export interface GetLoginQrResponse extends TGApp.Plugins.Mys.Base.Response {
|
||||
data: GetLoginQrData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取登录二维码返回数据
|
||||
* @since Beta v0.3.0
|
||||
* @interface GetLoginQrData
|
||||
* @property {string} ticket 二维码票据
|
||||
* @property {string} url 二维码链接
|
||||
* @return GetLoginQrData
|
||||
*/
|
||||
export interface GetLoginQrData {
|
||||
ticket: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取登录状态返回数据
|
||||
* @since Beta v0.3.0
|
||||
* @interface GetLoginStatusResponse
|
||||
* @extends TGApp.Plugins.Mys.Base.Response
|
||||
* @property {GetLoginStatusData} data 数据
|
||||
* @return GetLoginStatusResponse
|
||||
*/
|
||||
export interface GetLoginStatusResponse extends TGApp.Plugins.Mys.Base.Response {
|
||||
data: GetLoginStatusData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取登录状态返回数据
|
||||
* @since Beta v0.3.0
|
||||
* @interface GetLoginStatusData
|
||||
* @property {string} app_id 应用 ID
|
||||
* @property {number} client_type 客户端类型
|
||||
* @property {string} created_at 创建时间
|
||||
* @property {boolean} need_realperson 是否需要人机验证
|
||||
* @property {RealNameInfo} realname_info 实名信息
|
||||
* @property {string} scanned_at 扫码时间
|
||||
* @property {string} status 状态
|
||||
* @property {unknown[]} tokens 令牌
|
||||
* @property {UserInfo} user_info 用户信息
|
||||
* @return GetLoginStatusData
|
||||
*/
|
||||
export interface GetLoginStatusData {
|
||||
app_id: string;
|
||||
client_type: number;
|
||||
created_at: string;
|
||||
need_realperson: boolean;
|
||||
realname_info: RealNameInfo;
|
||||
scanned_at: string;
|
||||
status: string;
|
||||
tokens: unknown[];
|
||||
user_info: UserInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 实名信息
|
||||
* @since Beta v0.3.0
|
||||
* @interface RealNameInfo
|
||||
* @property {string} action_ticket 动作票据
|
||||
* @property {string} action_type 动作类型
|
||||
* @property {boolean} required 是否必须
|
||||
* @return RealNameInfo
|
||||
*/
|
||||
interface RealNameInfo {
|
||||
action_ticket: string;
|
||||
action_type: string;
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 用户信息
|
||||
* @since Beta v0.3.0
|
||||
* @interface UserInfo
|
||||
* @property {string} account_name 账户名
|
||||
* @property {string} aid 账户 ID
|
||||
* @property {string} area_code 区域代码
|
||||
* @property {string} country 国家
|
||||
* @property {string} email 邮箱 // 为加密后的邮箱包含 * 号
|
||||
* @property {string} identity_code 身份证号 // 为加密后的身份证号包含 * 号
|
||||
* @property {number} is_email_verify 是否邮箱验证 // 1 为已验证
|
||||
* @property {unknown[]} links 链接
|
||||
* @property {string} mid 用户 ID
|
||||
* @property {string} mobile 手机号 // 为加密后的手机号包含 * 号
|
||||
* @property {string} realname 真实姓名 // 为加密后的真实姓名包含 * 号
|
||||
* @property {string} rebind_area_code 重新绑定区域代码
|
||||
* @property {string} rebind_mobile 重新绑定手机号
|
||||
* @property {string} rebind_mobile_time 重新绑定手机号时间
|
||||
* @property {string} safe_area_code 安全区域代码
|
||||
* @property {string} safe_mobile 安全手机号
|
||||
* @return UserInfo
|
||||
*/
|
||||
interface UserInfo {
|
||||
account_name: string;
|
||||
aid: string;
|
||||
area_code: string;
|
||||
country: string;
|
||||
email: string;
|
||||
identity_code: string;
|
||||
is_email_verify: number;
|
||||
links: unknown[];
|
||||
mid: string;
|
||||
mobile: string;
|
||||
realname: string;
|
||||
rebind_area_code: string;
|
||||
rebind_mobile: string;
|
||||
rebind_mobile_time: string;
|
||||
safe_area_code: string;
|
||||
safe_mobile: string;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/**
|
||||
* @file plugins Mys utils getLoginQr
|
||||
* @description 获取登录二维码
|
||||
* @author BTMuli <bt-muli@outlook.com>
|
||||
* @since Beta v0.3.0
|
||||
*/
|
||||
|
||||
// tauri
|
||||
import { http } from "@tauri-apps/api";
|
||||
|
||||
const uuid = crypto.randomUUID();
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
Accept: "application/json, text/plain, */*",
|
||||
"Accept-Encoding": "gzip, deflate, br",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9",
|
||||
Connection: "keep-alive",
|
||||
Origin: "https://user.miyoushe.com",
|
||||
Referer: "https://user.miyoushe.com/",
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",
|
||||
"x-rpc-app_id": "bll8iq97cem8",
|
||||
"X-Rpc-Device_id": uuid,
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 获取登录二维码
|
||||
* @since Beta v0.3.0
|
||||
* @returns {Promise<TGApp.Plugins.Mys.WebLogin.GetLoginQrData|TGApp.Plugins.Mys.Base.Response>}
|
||||
*/
|
||||
export async function getLoginQr(): Promise<
|
||||
TGApp.Plugins.Mys.WebLogin.GetLoginQrData | TGApp.Plugins.Mys.Base.Response
|
||||
> {
|
||||
const url = "https://passport-api.miyoushe.com/account/ma-cn-passport/web/createQRLogin";
|
||||
return await http
|
||||
.fetch<TGApp.Plugins.Mys.WebLogin.GetLoginQrResponse>(url, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: http.Body.json({}),
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data.retcode === 0) {
|
||||
return res.data.data;
|
||||
} else {
|
||||
return res.data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取登录状态
|
||||
* @since Beta v0.3.0
|
||||
* @param {string} ticket 二维码票据
|
||||
* @returns {Promise<Record<string, string[]>}
|
||||
*/
|
||||
export async function getLoginStatus(
|
||||
ticket: string,
|
||||
): Promise<TGApp.Plugins.Mys.WebLogin.GetLoginStatusResponse | Record<string, string>> {
|
||||
const url = "https://passport-api.miyoushe.com/account/ma-cn-passport/web/queryQRLoginStatus";
|
||||
const resp = await http.fetch<TGApp.Plugins.Mys.WebLogin.GetLoginStatusResponse>(url, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: http.Body.json({ ticket }),
|
||||
});
|
||||
const data = resp.data;
|
||||
if (data.retcode !== 0) return resp.data;
|
||||
if (data.data.status === "Created" || data.data.status === "Scanned") {
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||
return await getLoginStatus(ticket);
|
||||
}
|
||||
if (data.data.status === "Confirmed") {
|
||||
const cookieList = resp.rawHeaders["set-cookie"].map((cookie) => cookie.split(";")[0]);
|
||||
const cookieRecord: Record<string, string> = {};
|
||||
cookieList.forEach((cookie) => {
|
||||
const [key, value] = cookie.split("=");
|
||||
cookieRecord[key] = value;
|
||||
});
|
||||
return cookieRecord;
|
||||
}
|
||||
return resp.data;
|
||||
}
|
||||
@@ -9,8 +9,6 @@
|
||||
import { ref } from "vue";
|
||||
// pinia
|
||||
import { defineStore } from "pinia";
|
||||
// sqlite
|
||||
import TGSqlite from "../../plugins/Sqlite";
|
||||
|
||||
export const useUserStore = defineStore(
|
||||
"user",
|
||||
@@ -33,27 +31,6 @@ export const useUserStore = defineStore(
|
||||
});
|
||||
const cookie = ref<Record<string, string>>({});
|
||||
|
||||
// 判断当前用户是否已经登录
|
||||
function isLogin(): boolean {
|
||||
return cookie.value?.account_id !== "";
|
||||
}
|
||||
|
||||
// 加载用户数据,用于应用启动时
|
||||
async function loadUserData(): Promise<void> {
|
||||
if (isLogin()) {
|
||||
const accountDB = await TGSqlite.getCurAccount();
|
||||
if (accountDB) {
|
||||
setCurAccount(accountDB);
|
||||
}
|
||||
} else {
|
||||
const cookieDB = await TGSqlite.getCookie();
|
||||
if (Object.keys(cookieDB).length > 0) {
|
||||
cookie.value = cookieDB;
|
||||
await loadUserData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setBriefInfo(info: TGApp.App.Account.BriefInfo): void {
|
||||
briefInfo.value = info;
|
||||
}
|
||||
@@ -104,27 +81,18 @@ export const useUserStore = defineStore(
|
||||
};
|
||||
}
|
||||
|
||||
async function saveCookie(type: string, val: string): Promise<void> {
|
||||
cookie.value[type] = val;
|
||||
await TGSqlite.saveAppData("cookie", JSON.stringify(cookie.value));
|
||||
}
|
||||
|
||||
return {
|
||||
briefInfo,
|
||||
cookie,
|
||||
account,
|
||||
getBriefInfo,
|
||||
setBriefInfo,
|
||||
getCookieItem,
|
||||
setCurAccount,
|
||||
getCurAccount,
|
||||
getCookieGroup1,
|
||||
getCookieGroup2,
|
||||
getCookieGroup3,
|
||||
getCookieGroup4,
|
||||
saveCookie,
|
||||
isLogin,
|
||||
loadUserData,
|
||||
};
|
||||
},
|
||||
{
|
||||
|
||||
@@ -14,21 +14,21 @@ import TGUtils from "../utils/TGUtils";
|
||||
|
||||
/**
|
||||
* @description 根据 stoken 获取 cookie_token
|
||||
* @since Alpha v0.1.5
|
||||
* @param {string} stuid 登录用户 uid
|
||||
* @param {string} stoken stoken
|
||||
* @since Beta v0.3.0
|
||||
* @param {string} Mid 登录用户的 mid
|
||||
* @param {string} Stoken stoken_v2
|
||||
* @returns {Promise<string|TGApp.BBS.Response.Base>}
|
||||
*/
|
||||
export async function getCookieTokenBySToken(
|
||||
stuid: string,
|
||||
stoken: string,
|
||||
Mid: string,
|
||||
Stoken: string,
|
||||
): Promise<string | TGApp.BBS.Response.Base> {
|
||||
const url = TGApi.GameTokens.getCookieToken;
|
||||
const cookie = {
|
||||
stuid,
|
||||
stoken,
|
||||
mid: Mid,
|
||||
stoken: Stoken,
|
||||
};
|
||||
const params = { stoken };
|
||||
const params = { stoken: Stoken };
|
||||
const header = TGUtils.User.getHeader(cookie, "GET", params, "common");
|
||||
return await http
|
||||
.fetch<TGApp.BBS.Response.getCookieTokenBySToken>(url, {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file web request getLToken.ts
|
||||
* @description 获取 ltoken 的请求
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.5
|
||||
* @since Beta v0.3.0
|
||||
*/
|
||||
|
||||
// tauri
|
||||
@@ -13,23 +13,22 @@ import TGApi from "../api/TGApi";
|
||||
import TGUtils from "../utils/TGUtils";
|
||||
|
||||
/**
|
||||
* @description 根据 stoken 获取 ltoken
|
||||
* @since Alpha v0.1.5
|
||||
* @param {string} mid 登录用户 mid
|
||||
* @param {string} stoken stoken_v2
|
||||
* @description 根据 stoken_v2 获取 ltoken
|
||||
* @since Beta v0.3.0
|
||||
* @param {string} Mid 登录用户 mid
|
||||
* @param {string} Stoken stoken_v2
|
||||
* @returns {Promise<string|TGApp.BBS.Response.Base>}
|
||||
*/
|
||||
export async function getLTokenBySToken(
|
||||
mid: string,
|
||||
stoken: string,
|
||||
Mid: string,
|
||||
Stoken: string,
|
||||
): Promise<string | TGApp.BBS.Response.Base> {
|
||||
const url = TGApi.GameTokens.getLToken;
|
||||
const cookie = {
|
||||
mid,
|
||||
stoken,
|
||||
mid: Mid,
|
||||
stoken: Stoken,
|
||||
};
|
||||
console.log(cookie);
|
||||
const params = { stoken };
|
||||
const params = { stoken: Stoken };
|
||||
const header = TGUtils.User.getHeader(cookie, "GET", params, "common");
|
||||
return await http
|
||||
.fetch<TGApp.BBS.Response.getLTokenBySToken>(url, {
|
||||
|
||||
Reference in New Issue
Block a user