feat: 适配新版后端 API 并接入邮箱验证 (#9)
## 概述 本分支对前端进行了大规模适配与升级,核心是对齐新版后端 API 接口,并接入邮箱验证与密码找回流程。 ## 主要变更 - **API 适配**:对齐新版后端接口契约,重构 api 客户端与类型定义,移除前端臆造字段 - **认证流程**:接入邮箱验证(确认 / 重发确认)、密码找回(忘记密码 / 重置密码)全流程 - **管理后台**:前端对齐更新后的 API 契约 - **云图鉴**:展示云类型图标图片 - **UI 优化**:图片预览改为直角样式并调整关闭按钮 ## 影响范围 - API 层:src/lib/api.ts、src/types/api.ts、src/types/database.ts - 认证视图:src/views/auth/* - 管理后台:src/views/admin/AdminView.vue - 图鉴视图:src/views/encyclopedia/* - 状态管理:src/stores/* Reviewed-on: #9
This commit was merged in pull request #9.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { NAlert, NButton, NCard, NForm, NFormItem, NInput } from 'naive-ui'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
@@ -12,6 +12,7 @@ const email = ref(typeof route.query.email === 'string' ? route.query.email : ''
|
||||
const password = ref('')
|
||||
const error = ref('')
|
||||
const loading = ref(false)
|
||||
const needsEmailConfirmation = computed(() => error.value.includes('邮箱尚未验证'))
|
||||
|
||||
function getSafeRedirect(value: unknown) {
|
||||
if (typeof value !== 'string' || !value.startsWith('/')) return '/'
|
||||
@@ -51,19 +52,19 @@ async function handleLogin() {
|
||||
<span class="block text-teal-700">你眼中的每一朵云</span>
|
||||
</h1>
|
||||
<!-- <p class="mt-6 max-w-lg text-base leading-8 text-slate-600">
|
||||
在地图、图鉴和画廊之间同步你的观测记录。上传新的云图后,图鉴会自动点亮,画廊也会按时间收纳你的作品。
|
||||
在地图、百科和画廊之间浏览观测记录。上传新的云图后,审核通过的作品会进入公开画廊与地图。
|
||||
</p> -->
|
||||
</div>
|
||||
<div class="mt-8 grid min-w-0 grid-cols-2 gap-4">
|
||||
<div class="min-w-0 border border-slate-200 bg-white px-4 py-3">
|
||||
<div class="oc-stat-label">Collection</div>
|
||||
<div class="oc-stat-value">10</div>
|
||||
<div class="oc-field-help">基础云属待收集</div>
|
||||
<div class="oc-field-help">基础云属资料</div>
|
||||
</div>
|
||||
<div class="min-w-0 border border-slate-200 bg-white px-4 py-3">
|
||||
<div class="oc-stat-label">Mode</div>
|
||||
<div class="oc-stat-value">Atlas</div>
|
||||
<div class="oc-field-help">地图、图鉴、画廊一体</div>
|
||||
<div class="oc-field-help">地图、百科、画廊一体</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -106,6 +107,14 @@ async function handleLogin() {
|
||||
|
||||
<NAlert v-if="error" type="error" class="mb-4">
|
||||
{{ error }}
|
||||
<div v-if="needsEmailConfirmation" class="mt-2">
|
||||
<RouterLink
|
||||
:to="{ path: '/resend-confirmation', query: { email } }"
|
||||
class="font-semibold text-rose-700 underline underline-offset-2"
|
||||
>
|
||||
重新发送验证邮件
|
||||
</RouterLink>
|
||||
</div>
|
||||
</NAlert>
|
||||
|
||||
<NButton
|
||||
@@ -121,15 +130,15 @@ async function handleLogin() {
|
||||
</NForm>
|
||||
|
||||
<div class="mt-6 flex flex-wrap items-center justify-between gap-3 text-sm text-slate-500">
|
||||
<p>
|
||||
没有账号?
|
||||
<RouterLink to="/register" class="font-semibold text-teal-700 hover:text-teal-800">去注册</RouterLink>
|
||||
</p>
|
||||
<span>
|
||||
还没有账号?
|
||||
<RouterLink to="/register" class="font-semibold text-sky-700 hover:text-sky-800">立即注册</RouterLink>
|
||||
</span>
|
||||
<RouterLink
|
||||
:to="email ? { path: '/forgot-password', query: { email } } : { path: '/forgot-password' }"
|
||||
class="font-semibold text-teal-700 transition-colors hover:text-teal-800"
|
||||
:to="{ path: '/forgot-password', query: { email } }"
|
||||
class="font-semibold text-teal-700 hover:text-teal-800"
|
||||
>
|
||||
忘记密码?
|
||||
忘记密码
|
||||
</RouterLink>
|
||||
</div>
|
||||
</NCard>
|
||||
|
||||
Reference in New Issue
Block a user