diff --git a/AGENTS.md b/AGENTS.md
index ffe1bad..9bc3121 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -37,8 +37,8 @@
| `/` | MapView | No |
| `/login`, `/register`, `/forgot-password`, `/auth/confirm`, `/auth/reset-password` | Auth views | No |
| `/upload` | UploadView | Yes |
-| `/encyclopedia` | EncyclopediaView | No |
-| `/encyclopedia/:id` | CloudTypeView | No |
+| `/encyclopedia` | EncyclopediaView | Yes |
+| `/encyclopedia/:id` | CloudTypeView | Yes |
| `/gallery` | GalleryView | No |
| `/community` | CommunityView | No |
| `/profile` | ProfileView (own) | Yes |
@@ -109,7 +109,8 @@
## Build & Deploy
- **Vercel** with `vercel.json`: SPA rewrites, security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy). No CSP or HSTS configured.
-- **SEO plugin** in `vite.config.ts`: generates `robots.txt` and `sitemap.xml` at build time. Disallows `/admin`, `/auth/`, `/login`, `/register`, `/upload`, `/profile/settings`.
+- Vite dev and preview servers both use strict port `5173`, matching the backend's default `CORS_ORIGINS` and `FRONTEND_URL`.
+- **SEO plugin** in `vite.config.ts`: generates `robots.txt` and `sitemap.xml` at build time. Auth-only routes, including `/encyclopedia`, are excluded from the sitemap and disallowed in `robots.txt`.
- **`lib/canvas.ts`**: patches `HTMLCanvasElement.getContext('2d')` to always pass `willReadFrequently: true` — needed for the badge card renderer in `lib/cloudBadges.ts`.
## Environment Variables
diff --git a/README.md b/README.md
index 216bd10..578c93a 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ npm run dev
```
默认后端地址为 `http://localhost:8000/api/v1`。
+开发服务器和本地 Preview 都固定使用 `http://localhost:5173`,与后端默认 CORS 配置保持一致。运行 Preview 前请先停止开发服务器。
## 检查与构建
diff --git a/src/components/layout/AppHeader.vue b/src/components/layout/AppHeader.vue
index 26069af..1b16a27 100644
--- a/src/components/layout/AppHeader.vue
+++ b/src/components/layout/AppHeader.vue
@@ -193,6 +193,7 @@ async function handleLogout() {
画廊
-
+
@@ -356,6 +357,7 @@ async function handleLogout() {
画廊
import('@/views/encyclopedia/EncyclopediaView.vue'),
meta: {
+ requiresAuth: true,
title: '云朵图鉴',
description: '浏览 10 种基础云属,了解云型特征,并通过拍摄云图点亮个人图鉴。',
+ noindex: true,
},
},
{
@@ -65,8 +67,10 @@ const router = createRouter({
name: 'cloud-type',
component: () => import('@/views/encyclopedia/CloudTypeView.vue'),
meta: {
+ requiresAuth: true,
title: route => getCloudTypeName(route.params.id),
description: route => `查看 ${getCloudTypeName(route.params.id)} 的识别要点、公开云图和社区观测记录。`,
+ noindex: true,
},
},
{
diff --git a/src/types/router.d.ts b/src/types/router.d.ts
index c4bb06f..6dcaa7e 100644
--- a/src/types/router.d.ts
+++ b/src/types/router.d.ts
@@ -6,5 +6,7 @@ declare module 'vue-router' {
description?: string | ((route: RouteLocationNormalizedLoaded) => string)
canonicalPath?: string
noindex?: boolean
+ requiresAuth?: boolean
+ requiresAdmin?: boolean
}
}
diff --git a/src/views/profile/ProfileView.vue b/src/views/profile/ProfileView.vue
index 9b51b23..ca02037 100644
--- a/src/views/profile/ProfileView.vue
+++ b/src/views/profile/ProfileView.vue
@@ -1,7 +1,7 @@