feat(web): 前端逻辑骨架——http/router/stores/queries 与薄壳路由

This commit is contained in:
2026-10-07 14:36:06 +08:00
parent 9ecf817df2
commit fbb989c3fb
39 changed files with 1431 additions and 175 deletions
+10
View File
@@ -0,0 +1,10 @@
<script setup lang="ts">
/** 成员单页占位——聚合 + 来源徽章 + 明细(交互设计-成员视图) */
</script>
<template>
<section>
<h1>我的用量</h1>
<p>总用量、来源分解、key 窄卡、支付参数与明细(占位,待 UI 设计)。</p>
</section>
</template>
+58
View File
@@ -0,0 +1,58 @@
<script setup lang="ts">
/** 成员令牌登录壳——明文仅存 sessionStorage(交互登录篇 §4) */
import { ref } from "vue";
import { useRouter } from "vue-router";
import { useMemberTokenStore } from "@/stores/member-token.ts";
import { fetchMe } from "@/api/member/me.ts";
const router = useRouter();
const tokenStore = useMemberTokenStore();
const token = ref("");
const error = ref("");
const pending = ref(false);
async function onSubmit() {
error.value = "";
pending.value = true;
try {
tokenStore.setToken(token.value.trim());
const me = await fetchMe();
tokenStore.setMemberName(me.name);
void router.replace({ name: "member-home" });
} catch {
tokenStore.clearToken();
error.value = "令牌无效或已停用";
} finally {
pending.value = false;
}
}
</script>
<template>
<div class="member-login">
<h1>成员入口</h1>
<form @submit.prevent="onSubmit">
<label>
令牌
<input v-model="token" name="token" type="password" required />
</label>
<button type="submit" :disabled="pending">进入</button>
</form>
<p v-if="error" role="alert">{{ error }}</p>
</div>
</template>
<style scoped>
.member-login {
max-width: 360px;
margin: 12vh auto;
display: flex;
flex-direction: column;
gap: 12px;
}
.member-login label {
display: flex;
flex-direction: column;
gap: 4px;
}
</style>