Эх сурвалжийг харах

feat:更新readme文档和其他的开发文档

yangyi 4 сар өмнө
parent
commit
007d0d547e
6 өөрчлөгдсөн 2977 нэмэгдсэн , 228 устгасан
  1. 48 0
      AGENTS.md
  2. 201 228
      README.md
  3. 1311 0
      detailDesign.md
  4. 173 0
      nextWork.md
  5. 1081 0
      uiDesign.md
  6. 163 0
      work.md

+ 48 - 0
AGENTS.md

@@ -0,0 +1,48 @@
+# AGENTS.md
+
+## Commands
+
+| Script | Command | Purpose |
+|--------|---------|---------|
+| `dev` | `vite` | Dev server with HMR, proxies `/api` → `http://localhost:8080` (strips prefix) |
+| `build` | `vue-tsc -b && vite build` | Type-check (project references mode) then production build |
+| `preview` | `vite preview` | Preview production build locally |
+| `api:gen` | `orval` | Generate API client + models from `http://localhost:8080/v3/api-docs` |
+
+Build order matters: `npm run build` runs `vue-tsc -b` before `vite build`. After changes, always run `npm run build` (not just `vue-tsc`).
+
+## Architecture
+
+- **Vue 3** `<script setup>` SFCs, **Vite 6**, **TypeScript 5.8**, **Element Plus 2**, **Pinia 3**, **Vue Router 4**
+- Two layouts: `UserLayout` (public, horizontal nav), `AdminLayout` (sidebar + header)
+- Router guard checks `meta.requiresAdmin` → must be logged in + role `admin`, else redirect
+- Auth: JWT token in `localStorage` key `token`; Pinia `useLoginUserStore` persists via `pinia-plugin-persistedstate`
+- Path alias `@` → `./src/*`
+
+## API / Codegen
+
+- `npm run api:gen` fetches OpenAPI spec from live backend at `localhost:8080`, writes to `src/api/`
+- Generated controllers (`auth-controller.ts`, `user-controller.ts`) use `customAxiosInstance` from `src/util/axios-instance.ts`
+- Custom mutator handles Bearer token injection, response unwrapping, and 401 → `/login` redirect
+- Generated models under `src/api/models/` — re-exported via `index.ts`
+- Run `api:gen` when backend API changes. `orval` is a runtime dep (unconventional but works).
+
+## Conventions
+
+- **Use Orval-generated API only** — never write raw axios/fetch calls. Re-export from `src/api/` controllers or models as needed.
+- **Responsive design** — all views and layouts must work on both PC and mobile. Use Element Plus responsive utilities and CSS media queries.
+- **Theme color** is `#e34889` — set as CSS variable `--el-color-primary` and Element Plus primary color. Apply consistently across all components.
+
+## Code quality
+
+- **No test framework, no test files** — do not add or expect tests
+- **No ESLint** — only Prettier 3 (defaults, no config), invoked automatically after `api:gen`
+- Format manually: `npx prettier --write <file>`
+- `tsconfig.app.json`: `strict: true`, `noUnusedLocals: true`, `noUnusedParameters: true`
+- Prefer `@/` imports over relative paths
+
+## Known quirks
+
+- `/admin/other` route has `component: AdminLayout` (self-referencing stub — avoid using)
+- No `.env` files; base URL defaults to `/api` (Vite proxy). Override via `VITE_API_BASE_URL` env var
+- Backend expects JWT. Without a running backend, login/register and API calls will fail

+ 201 - 228
README.md

@@ -1,237 +1,210 @@
-# Vue 3 + TypeScript + Vite
+# 宠物服务管理系统
+
+<p align="center">
+  <img src="https://img.shields.io/badge/Vue-3.5+-brightgreen.svg" alt="Vue">
+  <img src="https://img.shields.io/badge/Vite-6.3+-blue.svg" alt="Vite">
+  <img src="https://img.shields.io/badge/TypeScript-5.8+-blue.svg" alt="TypeScript">
+  <img src="https://img.shields.io/badge/ElementPlus-2.13+-409eff.svg" alt="Element Plus">
+</p>
+
+一个功能完善的宠物服务管理前端应用,支持寄养、洗护服务预约,订单管理,宠物档案维护等功能。包含用户端和商家后台两套界面。
+
+## 功能特性
+
+### 用户端功能
+
+- 用户认证:登录/注册、JWT Token 认证
+- 服务预约:寄养预约、洗护预约(支持分步表单)
+- 订单管理:订单列表、订单详情、状态追踪
+- 宠物档案:宠物列表、新增/编辑/查看宠物信息、疫苗和驱虫记录
+- 个人中心:个人信息查看与编辑、密码修改
+
+### 商家后台功能
+
+- 订单审核:预约订单审核、取消处理
+- 房态管理:日历视图查看房间占用情况
+- 排班管理:员工排班设置与查看
+- 套餐配置:服务套餐的增删改查
+- 用户管理:用户列表、用户详情、状态管理
+
+## 技术栈
+
+| 技术 | 版本 | 用途 |
+|------|------|------|
+| Vue | ^3.5.13 | 前端框架(Composition API + `<script setup>`) |
+| Vite | ^6.3.5 | 构建工具 |
+| TypeScript | ~5.8.3 | 类型安全 |
+| Element Plus | ^2.13.6 | UI 组件库 |
+| Pinia | ^3.0.4 | 状态管理 |
+| Pinia Persistedstate | ^4.7.1 | Store 持久化 |
+| Vue Router | ^4.6.4 | 路由管理 |
+| Axios | ^1.15.2 | HTTP 请求 |
+| Orval | 7.0 | OpenAPI → API 代码生成 |
+
+## 项目结构
+
+```
+src/
+├── api/                    # Orval 生成的 API 客户端
+│   ├── auth-controller.ts
+│   ├── user-controller.ts
+│   ├── pet-controller.ts
+│   ├── appointment-controller.ts
+│   ├── boarding-room-controller.ts
+│   ├── admin-*.ts          # 商家后台相关 API
+│   └── models/             # TypeScript 类型定义
+│
+├── store/                  # Pinia 状态管理
+│   ├── user.ts             # 用户登录状态
+│   ├── meta.ts             # 全局元数据
+│   ├── pet.ts              # 宠物数据缓存
+│   └── appointment.ts      # 预约流程状态
+│
+├── router/
+│   └── index.ts            # 路由配置 + 导航守卫
+│
+├── layout/
+│   ├── UserLayout.vue      # 用户端布局(顶部导航)
+│   └── AdminLayout.vue     # 商家后台布局(侧边栏+顶栏)
+│
+├── view/                   # 页面组件
+│   ├── LoginView.vue
+│   ├── booking/            # 服务预约模块
+│   ├── order/              # 订单管理模块
+│   ├── pet/                # 宠物档案模块
+│   ├── profile/            # 个人中心模块
+│   └── admin/              # 商家后台模块
+│
+├── components/             # 公共组件
+│   ├── PaymentDialog.vue   # 模拟支付弹窗
+│   ├── RoomCalendar.vue    # 房态日历组件
+│   └── PetSelector.vue     # 宠物选择器
+│
+├── util/
+│   └── axios-instance.ts   # Axios 配置(拦截器、Token 注入)
+│
+└── type/
+    └── index.ts            # 自定义类型定义
+```
+
+## 快速开始
+
+### 环境要求
+
+- Node.js 18+
+- 后端服务运行在 `http://localhost:8080`
+
+### 安装依赖
+
+```bash
+npm install
+```
+
+### 启动开发服务器
+
+```bash
+npm run dev
+```
+
+应用将在 `http://localhost:5173` 启动,API 请求通过 Vite 代理转发到后端 `http://localhost:8080`。
+
+### 构建生产版本
+
+```bash
+npm run build
+```
+
+### 预览生产构建
+
+```bash
+npm run preview
+```
+
+## API 代码生成
+
+本项目使用 [Orval](https://orval.dev/) 根据后端 OpenAPI 规范自动生成 API 客户端代码:
+
+```bash
+npm run api:gen
+```
+
+> 运行前请确保后端服务已启动在 `http://localhost:8080`
+
+Orval 配置在 `orval.config.ts` 中,生成规则:
+- 按标签拆分文件
+- 使用自定义 Axios 实例
+- 生成 TypeScript 类型定义到 `src/api/models/`
+- 生成后自动使用 Prettier 格式化
+
+## 主要特性
+
+### 路由守卫
+
+- 登录校验:部分页面需要登录才能访问
+- 权限控制:商家后台需要 `admin` 角色
+- 未授权自动跳转登录页
+
+### 状态持久化
+
+使用 `pinia-plugin-persistedstate` 实现登录状态持久化,刷新页面后保持登录。
+
+### 响应式设计
+
+- 适配桌面端和移动端
+- Element Plus 响应式布局
+- 自定义媒体查询优化移动端体验
+
+### 主题色
+
+主色调:`#e34889`(粉色系),统一应用于按钮、输入框、卡片等组件。
 
-This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
+## 路由说明
 
-Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).
+### 用户端路由
 
-# 前端模板项目
+| 路径 | 说明 | 需登录 |
+|------|------|--------|
+| `/login` | 登录/注册 | 否 |
+| `/booking` | 服务预约首页 | 否 |
+| `/booking/boarding` | 寄养预约 | 是 |
+| `/booking/grooming` | 洗护预约 | 是 |
+| `/orders` | 我的订单 | 是 |
+| `/orders/:id` | 订单详情 | 是 |
+| `/pets` | 宠物档案 | 是 |
+| `/pets/new` | 新增宠物 | 是 |
+| `/pets/:id` | 宠物详情 | 是 |
+| `/pets/:id/edit` | 编辑宠物 | 是 |
+| `/profile` | 个人中心 | 是 |
 
-> node18
->
-> Vue 3 + TypeScript + Vite6
+### 商家后台路由
 
-## 构建过程
+| 路径 | 说明 |
+|------|------|
+| `/admin/orders` | 订单审核列表 |
+| `/admin/orders/:id` | 订单审核详情 |
+| `/admin/rooms` | 房态日历管理 |
+| `/admin/schedules` | 排班管理 |
+| `/admin/packages` | 套餐配置列表 |
+| `/admin/packages/new` | 新增套餐 |
+| `/admin/packages/:id/edit` | 编辑套餐 |
+| `/admin/users` | 用户管理 |
+| `/admin/users/:id` | 用户详情 |
 
-1. 项目初始化
+## 开发规范
 
-   ```shell
-   npm create vite@6
-   ```
+- 使用 `<script setup>` 语法
+- 使用 `@/` 路径别名导入模块
+- 优先使用 Orval 生成的 API,避免手写 Axios 请求
+- 启用 TypeScript `strict` 模式
+- 代码格式化使用 Prettier
 
-   
+## 浏览器支持
 
-2. 添加vue-router和elementPlus依赖
-
-   - 安装
-
-   ```shell
-   npm install vue-router@4
-   npm install element-plus --save
-   ```
-
-   - 配置
-
-   ```typescript
-   const routes:RouteRecordRaw[] = [
-       {
-           path: '/',
-           name: 'commonLayout',
-           component: CommonLayout,
-           children: [
-               {
-                   path: '/',
-                   name: 'home',
-                   component: HomeView
-               },
-               {
-                   path: '/about',
-                   name: 'about',
-                   component: AboutView
-               },
-           ],
-       },
-   ]
-   
-   const router : Router = createRouter({
-       history: createWebHistory(),
-       routes: routes,
-   });
-   export default router
-   ```
-
-   
-
-   - 使用
-
-   ```typescript
-   app.use(router)
-   app.use(ElementPlus)
-   ```
-
-   
-
-3. 添加状态管理依赖
-
-   - 安装
-
-   ```shell
-   npm install pinia
-   ```
-
-   - 配置
-
-   ```
-   
-   ```
-
-   
-
-   - 使用
-
-   ```typescript
-   import { createPinia } from 'pinia'
-   const pinia = createPinia()
-   app.use(pinia)
-   ```
-
-   
-
-4. 添加axios依赖
-
-   ```shell
-   npm install axios
-   ```
-
-   配置axios-instance.ts
-
-   ```typescript
-   import axios, {type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios';
-   
-   // 自定义配置接口
-   export interface CustomInstanceConfig extends AxiosRequestConfig {
-       // 可以添加自定义配置
-       skipAuth?: boolean; // 是否跳过鉴权
-   }
-   
-   // 创建 Axios 实例
-   const axiosInstance: AxiosInstance = axios.create({
-       baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
-       timeout: 30000,
-       headers: {
-           'Content-Type': 'application/json',
-       },
-   });
-   
-   // 请求拦截器
-   axiosInstance.interceptors.request.use(
-       (config) => {
-           // 添加 token
-           const token = localStorage.getItem('token');
-           if (token) {
-               config.headers.Authorization = `Bearer ${token}`;
-           }
-           return config;
-       },
-       (error) => {
-           return Promise.reject(error);
-       }
-   );
-   
-   // 响应拦截器
-   axiosInstance.interceptors.response.use(
-       (response: AxiosResponse) => {
-           // 根据后端返回格式调整
-           if (response.data.code !== 0) {
-               return Promise.reject(new Error(response.data.message || '请求失败'));
-           }
-           return response.data;
-       },
-       (error) => {
-           // 统一错误处理
-           if (error.response?.status === 401) {
-               // 未授权,跳转登录
-               window.location.href = '/login';
-           }
-           return Promise.reject(error);
-       }
-   );
-   
-   // 自定义实例函数(供 Orval 使用)
-   export const customAxiosInstance = <T>(config: CustomInstanceConfig): Promise<T> => {
-       return axiosInstance(config);
-   };
-   
-   // 也可以导出第二参数形式(如需处理完整响应)
-   export const customAxiosInstanceWithFullResponse = <T>(
-       config: CustomInstanceConfig
-   ): Promise<AxiosResponse<T>> => {
-       return axiosInstance(config);
-   };
-   ```
-
-   
-
-5. openAPI自动生成接口调用
-
-   使用orval进行API生成
-
-   ```shell
-   npm install orval
-   ```
-
-   编写orval.config.ts配置文件
-
-   ```typescript
-   import { defineConfig } from 'orval';
-   
-   export default defineConfig({
-       'your-api': {
-           // OpenAPI 规范文件路径(支持本地文件或 URL)
-           input: {
-               target: 'http://localhost:8080/v3/api-docs', // 可改为你的 Swagger JSON 地址,如:http://localhost:8000/openapi.json
-           },
-           output: {
-               // 生成代码的模式:tags-按接口标签拆分文件
-               mode: 'tags',
-               // 客户端类型:使用 axios
-               client: 'axios',
-               // 生成 vue-query hooks
-               target: './src/api/client.ts',
-               // 生成的 TypeScript 类型存放目录
-               schemas: './src/api/models',
-               // 每次生成前自动清理旧文件
-               clean: true,
-               // 覆盖默认配置
-               override: {
-                   // 自定义 axios 实例
-                   mutator: {
-                       path: './src/util/axios-instance.ts',
-                       name: 'customAxiosInstance',
-                   },
-                   // 为每个接口生成 vue-query hooks
-                   query: {
-                       useQuery: true,      // 生成 useGetXXX hooks
-                       useMutation: true,   // 生成 usePostXXX hooks
-                   },
-               },
-           },
-           // 生成后自动格式化代码
-           hooks: {
-               afterAllFilesWrite: 'prettier --write',
-           },
-       },
-   });
-   ```
-
-   配置package.json文件中
-
-   ```json
-   {
-     "scripts": {
-      	...,
-       "api:gen": "orval"
-     },
-   }
-   ```
-
-   
+- Chrome 90+
+- Firefox 90+
+- Safari 14+
+- Edge 90+
+
+## 许可证
+
+[MIT](LICENSE)

+ 1311 - 0
detailDesign.md

@@ -0,0 +1,1311 @@
+# 宠物服务管理系统 — 客户端详细设计文档
+
+## 1. 技术栈
+
+| 技术 | 版本 | 用途 |
+|------|------|------|
+| Vue 3 | ^3.5.13 | 前端框架(Composition API + `<script setup>`) |
+| Vite | ^6.3.5 | 构建工具(HMR、代理配置) |
+| TypeScript | ~5.8.3 | 类型安全(strict: true, noUnusedLocals: true) |
+| Element Plus | ^2.13.6 | UI 组件库(主题色 #e34889) |
+| Pinia | ^3.0.4 | 状态管理(Composition API 风格) |
+| Pinia Persistedstate | ^4.7.1 | Store 自动持久化到 localStorage |
+| Vue Router | ^4.6.4 | 路由管理(嵌套路由 + 导航守卫) |
+| Axios | ^1.15.2 | HTTP 请求(withCredentials: true, 响应拦截) |
+| Orval | 7.0 | OpenAPI → TypeScript API 代码生成 |
+| Prettier | ^3.8.3 | 代码格式化 |
+
+## 2. 项目结构
+
+```
+ui/src/
+├── main.ts                        # 入口文件(createApp, use pinia/router/element-plus)
+├── App.vue                        # 根组件(仅 <router-view/>)
+├── style.css                      # 全局样式(CSS 变量、主题色定义)
+├── vite-env.d.ts                  # Vite 环境类型声明
+│
+├── type/
+│   └── index.ts                   # 自定义类型定义
+│       - User { id, name, avatar?, role }
+│       - LoginUser { isLogin, token?, user? }
+│       - Pet { id, name, breed, age, weight, gender, notes? }
+│       - Package { id, type, name, price, description?, durationDays?, isActive }
+│       - BoardingRoom { id, name, capacity, pricePerNight, description? }
+│       - RoomStatus { date, status: 'AVAILABLE'|'OCCUPIED' }
+│       - Appointment { id, userId, petId, packageId, roomId?, type, startDate?,
+│           endDate?, appointmentTime?, status, deposit, depositPaid,
+│           totalPrice, cancelReason?, rejectReason?, createdAt }
+│       - Schedule { id, designerName, workDate, timeSlot, isAvailable }
+│
+├── util/
+│   ├── index.ts                   # 工具函数(当前为空)
+│   └── axios-instance.ts          # Axios 实例配置
+│       - baseURL: '/api'(Vite 代理 /api → localhost:8080)
+│       - withCredentials: true(自动携带 Cookie/JSESSIONID)
+│       - 响应拦截器:校验 code !== 0/200 → reject;401 → window.location.href='/login'
+│       - customAxiosInstance<T>(config): Promise<T>(供 Orval 使用)
+│
+├── api/                           # Orval 生成的 API 控制器(按标签拆分)
+│   ├── auth-controller.ts         # getAuthController() → { login, register, logout }
+│   ├── user-controller.ts         # getUserController() → { queryByPage, add, edit, delete, ... }
+│   ├── pet-controller.ts          # getPetController() → { list, add, getById, update, delete, ... }
+│   ├── appointment-controller.ts  # getAppointmentController() → { create, list, getById, cancel, payDeposit }
+│   ├── admin-appointment-controller.ts  # getAdminAppointmentController() → { listAll, review, handleCancel }
+│   ├── boarding-room-controller.ts      # getBoardingRoomController() → { listRooms, getStatus }
+│   ├── admin-boarding-room-controller.ts # getAdminBoardingRoomController() → { updateStatus, ... }
+│   ├── package-controller.ts            # getPackageController() → { list, getById }
+│   ├── admin-package-controller.ts      # getAdminPackageController() → { create, update, delete }
+│   ├── admin-schedule-controller.ts     # getAdminScheduleController() → { list, create, delete }
+│   ├── admin-user-controller.ts         # getAdminUserController() → { list, getDetail }
+│   ├── schedule-controller.ts           # getScheduleController()(预留)
+│   └── models/                    # Orval 生成的 TypeScript 类型
+│       ├── index.ts               # 统一导出
+│       ├── response.ts            # Response<T> { code, message, data }
+│       ├── responseUserVo.ts, responseBoolean.ts, ...
+│       ├── userVo.ts, userDto.ts, loginDto.ts, registerDto.ts
+│       ├── updateUserPasswordDto.ts, updateUserAvatarDto.ts, updateUserStatusDto.ts
+│       ├── deleteByIdParams.ts, queryByPageParams.ts, pageVoListUserVo.ts
+│       ├── appointmentDto.ts, reviewDto.ts, handleCancelDto.ts
+│       └── ...
+│
+├── store/                         # Pinia 状态管理
+│   ├── index.ts                   # 统一导出 { useLoginUserStore, useMetaStore, useAppointmentStore, usePetStore }
+│   ├── user.ts                    # useLoginUserStore — 用户登录状态
+│   ├── meta.ts                    # useMetaStore — 站点元数据
+│   ├── appointment.ts             # useAppointmentStore — 预约流程临时状态
+│   └── pet.ts                     # usePetStore — 宠物列表缓存
+│
+├── router/
+│   └── index.ts                   # Vue Router 配置 + 导航守卫
+│       - 公共路由: /login
+│       - 用户侧: UserLayout + children(预约/订单/宠物/个人中心)
+│       - 管理侧: AdminLayout + children(订单审核/房态/排班/套餐/用户)
+│       - beforeEach 守卫: requiresAuth → 登录校验, requiresAdmin → 角色校验
+│
+├── layout/
+│   ├── UserLayout.vue             # 用户侧布局(水平 TopNav + 内容区)
+│   └── AdminLayout.vue            # 商家后台侧布局(可折叠侧边栏 + 顶栏 + 内容区)
+│
+├── view/
+│   ├── HomeView.vue               # 首页(品牌展示,快速入口卡片)
+│   ├── LoginView.vue              # 登录/注册(Tab 切换,毛玻璃卡片,渐变背景)
+│   ├── AboutView.vue              # 关于页面(占位)
+│   ├── UserView.vue               # 用户管理(后台,搜索/表格/CRUD/分页/状态切换)
+│   │
+│   ├── booking/                   # 服务预约模块
+│   │   ├── BookingView.vue               # 预约首页(选择寄养/洗护)
+│   │   ├── BoardingBookingView.vue       # 寄养预约(4 步 Stepper:套餐→房型日期→宠物→提交)
+│   │   └── GroomingBookingView.vue       # 洗护预约(4 步 Stepper:套餐→时段→宠物→提交)
+│   │
+│   ├── order/                     # 订单管理模块
+│   │   ├── OrderListView.vue             # 我的订单列表(Tab 筛选,状态标签)
+│   │   └── OrderDetailView.vue           # 订单详情(信息展示,支付/取消按钮)
+│   │
+│   ├── pet/                       # 宠物档案模块
+│   │   ├── PetListView.vue               # 宠物列表(卡片展示,增删查改)
+│   │   ├── PetCreateView.vue             # 新增宠物表单
+│   │   ├── PetDetailView.vue             # 宠物详情(基本信息+疫苗记录+驱虫记录)
+│   │   └── PetEditView.vue               # 编辑宠物表单
+│   │
+│   ├── profile/                   # 个人中心模块
+│   │   ├── ProfileView.vue               # 个人资料展示
+│   │   ├── ProfileEditView.vue           # 修改个人资料
+│   │   └── PasswordEditView.vue          # 修改密码
+│   │
+│   └── admin/                     # 商家后台模块
+│       ├── AdminOrderListView.vue        # 订单审核列表(表格+筛选+审核/取消处理弹窗)
+│       ├── AdminOrderDetailView.vue      # 订单审核详情
+│       ├── AdminRoomCalendarView.vue     # 宠物房间管理(房型选择+月份选择+日历)
+│       ├── AdminScheduleListView.vue     # 排班管理(表格+新增弹窗+删除)
+│       ├── AdminPackageListView.vue      # 套餐配置列表
+│       ├── AdminPackageCreateView.vue    # 新增套餐表单
+│       ├── AdminPackageEditView.vue      # 编辑套餐表单
+│       └── AdminUserDetailView.vue       # 用户详情(含宠物档案列表)
+│
+└── components/                    # 公共可复用组件
+    ├── RoomCalendar.vue           # 宠物房间日历(props: roomId/month/statusList, events: date-click)
+    ├── PaymentDialog.vue          # 模拟支付弹窗(props: visible/amount/orderId, events: success/close)
+    └── PetSelector.vue            # 宠物选择器(props: petList/selected, events: update:selected)
+```
+
+## 3. 路由设计
+
+### 3.1 路由总览
+
+```mermaid
+flowchart TD
+    A["/login<br/>(LoginView)"] --- B[""/""]
+
+    B --> C["UserLayout<br/>用户侧布局"]
+    C --> C1["/booking<br/>服务预约"]
+    C --> C2["/booking/boarding<br/>寄养预约*"]
+    C --> C3["/booking/grooming<br/>洗护预约*"]
+    C --> C4["/orders<br/>我的订单*"]
+    C --> C5["/orders/:id<br/>订单详情*"]
+    C --> C6["/pets<br/>宠物档案*"]
+    C --> C7["/pets/new<br/>新增宠物*"]
+    C --> C8["/pets/:id<br/>宠物详情*"]
+    C --> C9["/pets/:id/edit<br/>编辑宠物*"]
+    C --> C10["/profile<br/>个人中心*"]
+    C --> C11["/profile/edit<br/>修改资料*"]
+    C --> C12["/profile/password<br/>修改密码*"]
+
+    B --> D["AdminLayout<br/>商家后台布局*"]
+    D --> D1["/admin/orders<br/>订单审核"]
+    D --> D2["/admin/orders/:id<br/>审核详情"]
+    D --> D3["/admin/rooms<br/>宠物房间管理"]
+    D --> D4["/admin/schedules<br/>排班管理"]
+    D --> D5["/admin/packages<br/>套餐配置"]
+    D --> D6["/admin/packages/new<br/>新增套餐"]
+    D --> D7["/admin/packages/:id/edit<br/>编辑套餐"]
+    D --> D8["/admin/users<br/>用户管理"]
+    D --> D9["/admin/users/:id<br/>用户详情"]
+
+    style D fill:#fce7f3,stroke:#db2777
+    style C fill:#e8f5e9,stroke:#2e7d32
+    style A fill:#fff3e0,stroke:#f57c00
+```
+
+> `*` 标记的路由需要 `requiresAuth: true`(登录校验)
+>
+> `/admin` 前缀下的所有路由需要 `requiresAdmin: true`(管理员角色校验)
+
+### 3.2 路由守卫
+
+```mermaid
+flowchart TD
+    A["Router Navigation"] --> B{"to.matched<br/>有 requiresAuth<br/>或 requiresAdmin?"}
+    B -- 否 --> C["next()<br/>放行"]
+    B -- 是 --> D{"loginUserStore<br/>.isLogin?"}
+    D -- 否 --> E["ElMessage.warning('请先登录')"]
+    E --> F["next({ path: '/login',<br/>  query: { redirect } })"]
+    D -- 是 --> G{"requiresAdmin &&<br/>role !== 'admin'?"}
+    G -- 是 --> H["ElMessage.error('无权访问')"]
+    H --> I["next('/booking')"]
+    G -- 否 --> C
+```
+
+**守卫逻辑摘要:**
+- `requiresAuth` 标记在需要登录的路由 meta 上(预约、订单、宠物、个人中心等)
+- `requiresAdmin` 标记在 `/admin` 布局路由的 meta 上,子路由自动继承
+- `redirect` 参数在登录后导航回原始目标页面
+- 登录页本身无需守卫,已登录用户可自由访问
+
+### 3.3 用户侧路由表
+
+| 路径 | 名称 | 组件 | meta.title | meta.icon | requiresAuth |
+|------|------|------|-----------|-----------|-------------|
+| `/login` | `login` | LoginView | - | - | ❌ |
+| `/` | - | UserLayout (布局) | - | - | ❌ |
+| `/booking` | `booking` | BookingView | 服务预约 | Calendar | ❌ |
+| `/booking/boarding` | `boardingBooking` | BoardingBookingView | 寄养预约 | - | ✅ |
+| `/booking/grooming` | `groomingBooking` | GroomingBookingView | 洗护预约 | - | ✅ |
+| `/orders` | `orderList` | OrderListView | 我的订单 | Tickets | ✅ |
+| `/orders/:id` | `orderDetail` | OrderDetailView | 订单详情 | - | ✅ |
+| `/pets` | `petList` | PetListView | 宠物档案 | Avatar | ✅ |
+| `/pets/new` | `petCreate` | PetCreateView | 新增宠物 | - | ✅ |
+| `/pets/:id` | `petDetail` | PetDetailView | 宠物详情 | - | ✅ |
+| `/pets/:id/edit` | `petEdit` | PetEditView | 编辑宠物 | - | ✅ |
+| `/profile` | `profile` | ProfileView | 个人中心 | User | ✅ |
+| `/profile/edit` | `profileEdit` | ProfileEditView | 修改资料 | - | ✅ |
+| `/profile/password` | `passwordEdit` | PasswordEditView | 修改密码 | - | ✅ |
+
+### 3.4 商家后台侧路由表
+
+| 路径 | 名称 | 组件 | meta.title | meta.icon | requiresAdmin |
+|------|------|------|-----------|-----------|-------------|
+| `/admin` | `adminLayout` | AdminLayout (布局) | - | - | ✅ |
+| `/admin/orders` | `adminOrderList` | AdminOrderListView | 订单审核 | List | ✅ |
+| `/admin/orders/:id` | `adminOrderDetail` | AdminOrderDetailView | 订单审核详情 | - | ✅ |
+| `/admin/rooms` | `adminRooms` | AdminRoomCalendarView | 房态管理 | Calendar | ✅ |
+| `/admin/schedules` | `adminSchedules` | AdminScheduleListView | 排班管理 | EditPen | ✅ |
+| `/admin/packages` | `adminPackageList` | AdminPackageListView | 套餐配置 | Coin | ✅ |
+| `/admin/packages/new` | `adminPackageCreate` | AdminPackageCreateView | 新增套餐 | - | ✅ |
+| `/admin/packages/:id/edit` | `adminPackageEdit` | AdminPackageEditView | 编辑套餐 | - | ✅ |
+| `/admin/users` | `adminUsers` | UserView | 用户管理 | User | ✅ |
+| `/admin/users/:id` | `adminUserDetail` | AdminUserDetailView | 用户详情 | - | ✅ |
+
+## 4. 布局组件
+
+### 4.1 UserLayout
+
+```
+┌──────────────────────────────────────────────────────────────────┐
+│ [Logo] 宠物服务管理系统   [服务预约] [我的订单] [宠物档案] [个人中心]  │ ← el-header
+│                            [后台管理]         [用户名 ▼] [登录/注册] │
+├──────────────────────────────────────────────────────────────────┤
+│                                                                  │
+│                         <router-view />                          │ ← el-main
+│                                                                  │
+└──────────────────────────────────────────────────────────────────┘
+```
+
+**导航菜单渲染:**
+- 从 `userRoutes[0].children` 中筛选出有 `meta.icon` 的菜单项(过滤掉无图标的详情页)
+- 当前激活项根据 `route.path` 高亮
+- 管理员用户额外显示"后台管理"入口,跳转 `/admin`
+
+**用户状态区域:**
+- 未登录:显示「登录」「注册」两个按钮
+- 已登录:显示用户头像 + 用户名下拉菜单(个人信息、我的订单、宠物档案、退出登录)
+
+**退出逻辑:**
+```typescript
+const logoutHandler = async () => {
+  await getAuthController().logout()  // 服务端销毁 Session
+  loginUserStore.logoutUser()        // 清除 Pinia 状态
+  router.push('/login')
+}
+```
+
+### 4.2 AdminLayout
+
+```
+┌──────────────────────────────────────────────────────────────────┐
+│ [Logo] 宠物服务管理系统         后台管理           [用户名 ▼]     │ ← el-header
+├────────────┬─────────────────────────────────────────────────────┤
+│  [展开/收起]│                                                     │
+│            │                <router-view />                       │ ← el-main
+│  订单审核   │                                                     │
+│  房态管理   │                                                     │
+│  排班管理   │                                                     │
+│  套餐配置   │                                                     │
+│  用户管理   │                                                     │
+└────────────┴─────────────────────────────────────────────────────┘
+```
+
+**可折叠侧边栏:**
+- `el-aside` 宽度默认 200px,收起时 64px
+- `el-radio-group` 展开/收起切换(`isCollapse` ref)
+- 侧边栏菜单从 `adminRoutes[0].children` 中筛选有 `meta.icon` 的项
+
+**顶部栏右侧用户下拉:**
+- 用户名显示 + 下拉菜单(个人信息、返回前台、退出)
+
+## 5. 公共组件
+
+### 5.1 RoomCalendar.vue — 宠物房间日历
+
+**用途:** 在寄养预约和宠物房间管理页面中展示指定房型某月的每日状态。
+
+```
+┌──────────────────────────────┐
+│   <   2026年7月   >          │
+├──────────────────────────────┤
+│ 日  一  二  三  四  五  六   │
+│              1   2   3   4  │
+│  5   6   7   8   9  10  11  │
+│ ...                        │
+└──────────────────────────────┘
+  绿色=AVAILABLE  红色=OCCUPIED
+```
+
+**Props:**
+
+| prop | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `roomId` | `string` | ✅ | 房型 ID,用于标识当前展示的房型 |
+| `month` | `string` | ✅ | 格式 `YYYY-MM`,如 `2026-07` |
+| `statusList` | `{ date: string; status: 'AVAILABLE' \| 'OCCUPIED' }[]` | ✅ | 当月每日状态列表 |
+
+**Emits:**
+
+| event | 参数 | 说明 |
+|-------|------|------|
+| `date-click` | `(date: string, status: 'AVAILABLE' \| 'OCCUPIED')` | 点击某天时触发 |
+| `month-change` | `(month: string)` | 月份切换时触发(TODO: 当前组件中 prevMonth/nextMonth 为占位实现) |
+
+**渲染逻辑:**
+- 根据 `month` 计算当月天数、第一天是星期几
+- 构造 6×7 的日历网格(`(DayInfo | null)[][]`)
+- 空白天数用 `null` 填充
+- 每一天根据 `statusMap` 查找状态,应用 CSS 类:`available`(绿色 `#e8f5e9`)、`occupied`(红色 `#ffebee`)
+
+### 5.2 PaymentDialog.vue — 模拟支付弹窗
+
+**用途:** 预约提交成功后弹出,模拟支付定金流程。
+
+**Props:**
+
+| prop | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `visible` | `boolean` | ✅ | 弹窗显隐(v-model:visible) |
+| `amount` | `number` | ✅ | 定金金额 |
+| `orderId` | `string` | ✅ | 订单 ID,用于调用支付接口 |
+
+**Emits:**
+
+| event | 参数 | 说明 |
+|-------|------|------|
+| `update:visible` | `(value: boolean)` | 弹窗显隐变化 |
+| `success` | 无 | 支付成功后触发 |
+| `close` | 无 | 弹窗关闭时触发 |
+
+**插槽:** 无
+
+**交互流程:**
+1. 显示定金金额 `¥{{ amount }}`
+2. 支付方式选择:微信支付 / 支付宝(`el-radio-group`)
+3. 点击「确认支付」→ `POST /api/appointments/{orderId}/pay-deposit`
+4. 成功 → `ElMessage.success('支付成功')` → `emit('success')` → 关闭弹窗
+5. 失败 → `ElMessage.error` 显示错误信息
+
+### 5.3 PetSelector.vue — 宠物选择器
+
+**用途:** 在预约流程中选择宠物。
+
+**Props:**
+
+| prop | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `petList` | `Pet[]` | ✅ | 用户的所有宠物列表 |
+| `selected` | `Pet \| null` | ✅ | 当前选中的宠物 |
+
+**Emits:**
+
+| event | 参数 | 说明 |
+|-------|------|------|
+| `update:selected` | `(pet: Pet)` | 选择宠物时触发 |
+
+**插槽:** 无
+
+**渲染逻辑:**
+- 宠物列表为空 → 显示 `el-empty` +「新增宠物」按钮(跳转 `/pets/new`)
+- 有宠物 → `el-card` 列表,每张卡片显示宠物首字母头像、名称、品种、年龄
+- 选中卡片高亮(`border-color: var(--el-color-primary)`)+ 勾选图标
+
+## 6. 页面详细设计
+
+### 6.1 登录/注册页 (LoginView)
+
+**布局:**
+```
+┌──────────────────────────────────────┐
+│  ← 返回主页                           │
+│                                      │
+│          欢  迎                       │
+│     请登录或注册您的账号               │
+│                                      │
+│    ┌────────────┬────────────┐       │
+│    │    登录     │    注册    │       │  ← el-tabs
+│    └────────────┴────────────┘       │
+│                                      │
+│    ┌────────────────────────┐        │
+│    │  👤 请输入账号          │        │
+│    ├────────────────────────┤        │
+│    │  🔒 请输入密码          │        │
+│    ├────────────────────────┤        │
+│    │     [    登录    ]      │        │  ← 渐变粉色按钮
+│    └────────────────────────┘        │
+└──────────────────────────────────────┘
+```
+
+**数据流:**
+
+```mermaid
+sequenceDiagram
+    actor U as User
+    participant V as LoginView
+    participant S as useLoginUserStore
+    participant A as auth-controller
+    participant B as Backend
+
+    U->>V: 填写账号密码
+    U->>V: 点击登录
+    V->>V: formRef.validate()
+    alt 校验失败
+        V->>U: 显示错误提示
+    else 校验通过
+        V->>A: authApi.login({ account, password })
+        A->>B: POST /api/auth/login
+        B->>B: 校验账号密码
+        B->>B: 存入 HttpSession
+        B-->>A: Response<UserVo>
+        A-->>V: res.data
+        V->>S: loginSuccess({ id, name, role })
+        V->>V: router.push(redirect || '/booking')
+        V->>U: ElMessage.success('登录成功')
+    end
+```
+
+**表单校验规则:**
+
+| 表单 | 字段 | 规则 |
+|------|------|------|
+| 登录 | account | required |
+| 登录 | password | required, min:4 |
+| 注册 | account | required, min:4, max:20 |
+| 注册 | username | required, min:2, max:32 |
+| 注册 | password | required, min:4, max:20 |
+| 注册 | confirmPassword | required, 自定义校验器:必须等于 password |
+
+**API 调用:**
+- `getAuthController().login(LoginDto)` → `POST /api/auth/login` → 服务端存入 Session → 返回 `UserVo`
+- `getAuthController().register(RegisterDto)` → `POST /api/auth/register` → 返回成功 → 切换到登录 tab
+
+**状态管理:**
+- `activeTab`: `ref('login')` — 当前 tab
+- `loginForm`: `reactive({ account, password })`
+- `registerForm`: `reactive({ account, username, password, confirmPassword })`
+- `loginLoading`, `registerLoading`: `ref(false)`
+
+### 6.2 首页 (HomeView)
+
+**布局:**
+```
+┌──────────────────────────────────────┐
+│                                      │
+│    宠物服务管理系统                     │
+│    专业宠物寄养与洗护服务平台            │
+│                                      │
+│  ┌──────────────┐ ┌──────────────┐  │
+│  │  🏠 寄养服务  │ │  ✂️ 洗护服务  │  │
+│  │  专业宠物寄养  │ │  专业宠物洗护  │  │
+│  │  安心托管     │ │  焕然一新     │  │
+│  │  [查看详情]   │ │  [查看详情]   │  │
+│  └──────────────┘ └──────────────┘  │
+│                                      │
+│  功能介绍 / 平台优势展示               │
+│                                      │
+└──────────────────────────────────────┘
+```
+
+**交互逻辑:**
+- 点击「寄养服务」卡片 → `router.push('/booking/boarding')`
+- 点击「洗护服务」卡片 → `router.push('/booking/grooming')`
+- 未登录用户点击预约需登录(由路由守卫 `requiresAuth` 拦截)
+
+**数据依赖:** 无(纯展示页面)
+
+### 6.3 预约模块
+
+#### 6.3.1 服务预约首页 (BookingView)
+
+```
+┌──────────────────────────────────────┐
+│        选择服务类型                     │
+│                                      │
+│  ┌────────────────┐ ┌────────────────┐│
+│  │  寄养服务       │ │  洗护服务       ││
+│  │  专业宠物寄养   │ │  专业宠物洗护   ││
+│  │  安心托管       │ │  焕然一新       ││
+│  │                │ │                ││
+│  │ [查看详情]      │ │ [查看详情]      ││
+│  └────────────────┘ └────────────────┘│
+└──────────────────────────────────────┘
+```
+
+**数据流:** 无 API 调用,纯导航跳转
+
+#### 6.3.2 寄养预约页 (BoardingBookingView)
+
+**多步表单流程(el-steps 4 步):**
+
+```mermaid
+sequenceDiagram
+    actor U as User
+    participant V as BoardingBookingView
+    participant A as API Layer
+    participant B as Backend
+
+    Note over U,V: Step 1 — 选择套餐
+    V->>A: getPackageController().list4({ type: 'BOARDING' })
+    A->>B: GET /api/packages?type=BOARDING
+    B-->>A: PackageVo[]
+    A-->>V: packages[]
+    U->>V: 选中一个套餐
+
+    Note over U,V: Step 2 — 选择房型与日期
+    V->>A: getBoardingRoomController().listRooms()
+    A->>B: GET /api/boarding-rooms
+    B-->>A: BoardingRoomVo[]
+    A-->>V: rooms[]
+    U->>V: 选中房型
+    V->>A: getBoardingRoomController().getStatus(roomId, { month })
+    A->>B: GET /api/boarding-rooms/{id}/status?month=2026-07
+    B-->>A: RoomStatusVo[]
+    A-->>V: roomStatusList[]
+    V->>V: RoomCalendar 渲染日历
+    U->>V: 选择入住/离店日期
+    V->>V: calcTotal() — 计算总价(天数 × pricePerNight)
+
+    Note over U,V: Step 3 — 选择宠物
+    V->>A: getPetController().list()
+    A->>B: GET /api/pets
+    B-->>A: PetVo[]
+    A-->>V: myPets[]
+    U->>V: PetSelector 选中宠物
+
+    Note over U,V: Step 4 — 确认提交
+    V->>V: 展示订单摘要
+    U->>V: 点击提交预约
+    V->>A: getAppointmentController().create(AppointmentDto)
+    A->>B: POST /api/appointments { packageId, roomId, petId, startDate, endDate }
+    B-->>A: AppointmentVo { id, deposit, ... }
+    A-->>V: createdOrderId, depositAmount
+    V->>V: PaymentDialog 弹窗
+    U->>V: 支付定金
+    V->>A: getAppointmentController().payDeposit(orderId)
+    A->>B: POST /api/appointments/{id}/pay-deposit
+    B-->>A: success
+    V->>V: router.push('/orders')
+```
+
+**组件树:**
+
+```mermaid
+flowchart TD
+    V["BoardingBookingView"]
+    V --> S["el-steps (4步)"]
+    V --> Step1["Step1: 套餐选择"]
+    Step1 --> PkgList["el-radio-group > el-card<br/>(API: GET packages)"]
+    V --> Step2["Step2: 房型与日期"]
+    Step2 --> RoomSel["el-select 房型列表<br/>(API: GET rooms)"]
+    Step2 --> DatePicker["el-date-picker daterange"]
+    Step2 --> Calendar["RoomCalendar 宠物房间日历<br/>(API: GET room status)"]
+    Step2 --> Price["总价显示 ¥xxx"]
+    V --> Step3["Step3: 宠物选择"]
+    Step3 --> PetSel["PetSelector<br/>(API: GET pets)"]
+    V --> Step4["Step4: 确认提交"]
+    Step4 --> Summary["el-descriptions 订单摘要"]
+    Step4 --> Btn["提交预约"]
+    V --> Payment["PaymentDialog<br/>支付弹窗 (API: payDeposit)"]
+```
+
+**价格计算逻辑:**
+```typescript
+const calcTotal = () => {
+  if (dateRange.value && selectedRoom.value) {
+    const days = Math.ceil(
+      (dateRange.value[1].getTime() - dateRange.value[0].getTime()) / 86400000
+    )
+    totalPrice.value = days * selectedRoom.value.pricePerNight
+  }
+}
+// 定金 = totalPrice × 30%
+```
+
+**API 调用列表:**
+- `GET /api/packages?type=BOARDING` — 获取寄养套餐
+- `GET /api/boarding-rooms` — 获取所有启用房型
+- `GET /api/boarding-rooms/{id}/status?month=YYYY-MM` — 获取房态
+- `GET /api/pets` — 获取用户宠物
+- `POST /api/appointments` — 提交预约
+- `POST /api/appointments/{id}/pay-deposit` — 支付定金
+
+#### 6.3.3 洗护预约页 (GroomingBookingView)
+
+```mermaid
+sequenceDiagram
+    actor U as User
+    participant V as GroomingBookingView
+    participant A as API Layer
+
+    Note over U,V: Step 1 — 选择套餐
+    V->>A: getPackageController().list4({ type: 'GROOMING' })
+    A-->>V: packages[]
+    U->>V: 选中套餐
+
+    Note over U,V: Step 2 — 选择时间
+    U->>V: 选择日期 + 时段(上午/下午)
+
+    Note over U,V: Step 3 — 选择宠物
+    V->>A: getPetController().list()
+    A-->>V: myPets[]
+    U->>V: PetSelector 选中宠物
+
+    Note over U,V: Step 4 — 确认提交
+    V->>A: getAppointmentController().create(AppointmentDto)
+    A-->>V: createdOrderId
+    V->>V: PaymentDialog 弹窗
+    U->>V: 支付定金
+```
+
+**组件树:**
+
+```mermaid
+flowchart TD
+    V["GroomingBookingView"]
+    V --> S["el-steps (4步)"]
+    V --> Step1["Step1: 套餐选择"]
+    Step1 --> PkgList["el-radio-group > el-card<br/>(API: GET packages?type=GROOMING)"]
+    V --> Step2["Step2: 时段选择"]
+    Step2 --> Date["el-date-picker"]
+    Step2 --> Slot["el-radio-group MORNING/AFTERNOON"]
+    V --> Step3["Step3: 宠物选择"]
+    Step3 --> PetSel["PetSelector<br/>(API: GET pets)"]
+    V --> Step4["Step4: 确认提交"]
+    Step4 --> Summary["el-descriptions 订单摘要"]
+    Step4 --> Btn["提交预约"]
+    V --> Payment["PaymentDialog<br/>(API: payDeposit)"]
+```
+
+**API 调用列表:**
+- `GET /api/packages?type=GROOMING` — 获取洗护套餐
+- `GET /api/pets` — 获取宠物列表
+- `POST /api/appointments` — 提交预约(type=GROOMING)
+- `POST /api/appointments/{id}/pay-deposit` — 支付定金
+
+### 6.4 订单模块
+
+#### 6.4.1 订单列表 (OrderListView)
+
+**布局:**
+```
+┌──────────────────────────────────────┐
+│  我的预约                              │
+│  [全部] [待确认] [已确认] [已完成] [已取消]│ ← el-tabs
+├──────────────────────────────────────┤
+│  ┌──────────────────────────────────┐│
+│  │ 订单 ID: 1       [PENDING] 待审核 ││
+│  │                  [查看详情]       ││
+│  └──────────────────────────────────┘│
+│  ┌──────────────────────────────────┐│
+│  │ 订单 ID: 2      [CONFIRMED] 已确认││
+│  │                  [查看详情]       ││
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+**组件树:**
+
+```mermaid
+flowchart TD
+    V["OrderListView"]
+    V --> Tabs["el-tabs 状态筛选"]
+    V --> Cards["el-card 列表"]
+    Cards --> Card["el-card × N"]
+    Card --> Tag["el-tag 状态标签"]
+    Card --> Btn["查看详情 → router.push /orders/:id"]
+```
+
+**状态标签颜色映射:**
+
+| 状态 | el-tag type | 中文 |
+|------|------------|------|
+| PENDING | warning | 待审核 |
+| CONFIRMED | success | 已确认 |
+| CANCELLED | info | 已取消 |
+| COMPLETED | primary | 已完成 |
+| CANCEL_REQUESTED | danger | 取消申请 |
+
+**API 调用:**
+- `GET /api/appointments` → 返回所有用户预约列表 → 前端按 activeStatus 客户端过滤
+
+#### 6.4.2 订单详情 (OrderDetailView)
+
+**布局:**
+```
+┌──────────────────────────────────────┐
+│  ← 返回                               │
+├──────────────────────────────────────┤
+│  订单详情                              │
+│  ┌──────────────────────────────────┐│
+│  │ 订单编号: 1    状态: [PENDING]    ││
+│  │ 服务类型: BOARDING                ││
+│  │ 总价: ¥450                       ││
+│  │ 定金: ¥135   定金支付: 未支付      ││
+│  │ 创建时间: 2026-07-01 10:00       ││
+│  │                                  ││
+│  │   [支付定金]  [申请取消]           ││
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+**条件按钮逻辑:**
+- `showPayDeposit`: `depositPaid === false && status === 'PENDING'`
+- `showCancel`: `status === 'PENDING' || status === 'CONFIRMED'`
+
+**API 调用:**
+- `GET /api/appointments/{id}` — 获取订单详情
+- `POST /api/appointments/{id}/cancel` — 申请取消(`ElMessageBox.confirm` + 输入原因)
+- `POST /api/appointments/{id}/pay-deposit` — 支付定金
+
+### 6.5 宠物档案模块
+
+#### 6.5.1 宠物列表 (PetListView)
+
+```
+┌──────────────────────────────────────┐
+│  宠物档案              [+ 新增宠物]   │
+├──────────────────────────────────────┤
+│  ┌──────────────────────────────────┐│
+│  │ [W] 旺财 - 金毛                  ││
+│  │ 2岁 | 公                         ││
+│  │ [查看详情] [编辑] [删除]          ││
+│  └──────────────────────────────────┘│
+│  ┌──────────────────────────────────┐│
+│  │  ...                             ││
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+**API 调用:**
+- `GET /api/pets` — 获取所有宠物
+- `DELETE /api/pets/{id}` — 删除宠物(`ElMessageBox.confirm` 确认)
+
+#### 6.5.2 宠物详情 (PetDetailView)
+
+```
+┌──────────────────────────────────────┐
+│  ← 返回                  [编辑] [删除]│
+├──────────────────────────────────────┤
+│  基本信息                             │
+│  名称: 旺财 | 品种: 金毛              │
+│  年龄: 2岁 | 体重: 25kg              │
+│  性别: 公   | 备注: 活泼好动          │
+├──────────────────────────────────────┤
+│  疫苗记录                 [+ 新增]   │
+│  ┌──────────────────────────────────┐│
+│  │ 狂犬疫苗 | 2026-01-01 | 安心医院  ││
+│  └──────────────────────────────────┘│
+├──────────────────────────────────────┤
+│  驱虫记录                 [+ 新增]   │
+│  ┌──────────────────────────────────┐│
+│  │ 体外驱虫 | 2026-03-15 | 福来恩   ││
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+**API 调用:**
+- `GET /api/pets/{id}` — 获取宠物详情(含疫苗/驱虫记录)
+- `DELETE /api/pets/{id}` — 删除宠物
+- `POST /api/pets/{id}/vaccinations` — 新增疫苗记录
+- `POST /api/pets/{id}/deworming` — 新增驱虫记录
+
+**新增记录弹窗表单字段:**
+- 疫苗:疫苗名称、接种日期、医院、医生、备注
+- 驱虫:驱虫名称、驱虫日期、医院、医生、备注
+
+#### 6.5.3 新增/编辑宠物 (PetCreateView / PetEditView)
+
+```
+┌──────────────────────────────────────┐
+│  ← 返回                               │
+│  新增宠物 / 编辑宠物                    │
+│                                      │
+│  宠物名: [__________]                 │
+│  品种:   [__________]                 │
+│  年龄:   [0]                         │
+│  体重:   [0.0]                       │
+│  性别:   ○ 公  ○ 母                  │
+│  备注:   [__________]                 │
+│                                      │
+│         [保存]  [取消]                │
+└──────────────────────────────────────┘
+```
+
+**API 调用(PetCreateView):**
+- `POST /api/pets` — 新增宠物
+
+**API 调用(PetEditView):**
+- `GET /api/pets/{id}` — 加载宠物数据填充表单
+- `PUT /api/pets/{id}` — 更新宠物信息
+
+### 6.6 个人中心 (ProfileView / ProfileEditView / PasswordEditView)
+
+**ProfileView 布局:**
+```
+┌──────────────────────────────────────┐
+│  个人中心                              │
+│  ┌──────────────────────────────────┐│
+│  │         [大头像]                  ││
+│  │         用户名                    ││
+│  │        [admin/user]              ││
+│  ├──────────────────────────────────┤│
+│  │ ID: 1                            ││
+│  │ 昵称: 张三            [编辑]      ││
+│  ├──────────────────────────────────┤│
+│  │         [修改密码]                ││
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+**ProfileEditView:**
+- 表单:昵称输入
+- `PUT /api/user` — 更新用户信息 → 更新 Pinia store
+
+**PasswordEditView:**
+- 表单:原密码、新密码、确认密码
+- `PUT /api/user/updatePassword` — 修改密码
+
+### 6.7 商家后台
+
+#### 6.7.1 订单审核 (AdminOrderListView + AdminOrderDetailView)
+
+```mermaid
+sequenceDiagram
+    actor A as Admin
+    participant V as AdminOrderListView
+    participant API as API Layer
+    participant B as Backend
+
+    Note over V: 页面加载
+    V->>API: getAdminAppointmentController().listAll({ pageNum, pageSize, status? })
+    API->>B: GET /api/admin/appointments?pageNum=1&pageSize=10
+    B-->>API: PageVo<AppointmentVo>
+    API-->>V: orders[]
+
+    Note over A,V: 审核操作
+    A->>V: 点击"审核"
+    V->>V: 打开审核弹窗
+    A->>V: 选择通过/拒绝 + 填写原因
+    V->>API: review(appointmentId, { action, rejectReason? })
+    API->>B: PUT /api/admin/appointments/{id}/review
+    B-->>API: success
+    API-->>V: ElMessage.success
+    V->>V: 刷新列表
+
+    Note over A,V: 处理取消申请
+    A->>V: 点击"处理取消"
+    V->>V: 打开取消处理弹窗
+    A->>V: 选择同意/拒绝
+    V->>API: handleCancel(appointmentId, { action })
+    API->>B: PUT /api/admin/appointments/{id}/handle-cancel
+    B-->>API: success
+    V->>V: 刷新列表
+```
+
+**AdminOrderListView 组件树:**
+
+```mermaid
+flowchart TD
+    V["AdminOrderListView"]
+    V --> Filter["el-select 状态筛选"]
+    V --> Table["el-table 订单列表"]
+    Table --> Cols["ID | 用户 | 类型 | 总价 | 状态标签 | 操作"]
+    Table --> Pagination["el-pagination"]
+    V --> ReviewDlg["审核弹窗"]
+    ReviewDlg --> Radio["通过/拒绝 radio"]
+    ReviewDlg --> Reason["原因 textarea"]
+    V --> CancelDlg["取消处理弹窗"]
+    CancelDlg --> CancelRadio["同意/拒绝 radio"]
+    CancelDlg --> Opinion["处理意见 textarea"]
+```
+
+**AdminOrderDetailView:** 与 AdminOrderListView 共享审核/取消弹窗逻辑,以详情页形式展示完整订单信息。
+
+#### 6.7.2 宠物房间管理 (AdminRoomCalendarView)
+
+```mermaid
+flowchart TD
+    A["商家进入宠物房间管理"]
+    A --> B["选择房型<br/>el-select 切换"]
+    A --> C["选择月份<br/>el-date-picker type=month"]
+    B --> D["RoomCalendar 宠物房间日历"]
+    C --> D
+    D --> E["点击某天"]
+    E --> F{"当前状态?"}
+    F -->|"AVAILABLE"| G["切换为 OCCUPIED<br/>PUT /api/admin/rooms/{id}/status"]
+    F -->|"OCCUPIED"| H["切换为 AVAILABLE<br/>PUT /api/admin/rooms/{id}/status"]
+    G --> I["刷新日历 + ElMessage.success"]
+    H --> I
+```
+
+**布局:**
+```
+┌──────────────────────────────────────────────┐
+│  宠物房间管理                                  │
+│  [房型选择 ▼]     [2026年07月 ▼]              │
+├──────────────────────────────────────────────┤
+│  ┌──────────────────────────────────────────┐│
+│  │           宠物房间日历                     ││
+│  │  日   一   二   三   四   五   六          ││
+│  │             1    2    3    4              ││
+│  │  5    6    7    8    9   10   11          ││
+│  │  12  13   14   15   16   17   18          ││
+│  │  ...                                     ││
+│  │  绿色=空闲  红色=占用                     ││
+│  └──────────────────────────────────────────┘│
+└──────────────────────────────────────────────┘
+```
+
+**CRITICAL: 使用"宠物房间管理" / "宠物房间日历" 术语:**
+- 页面标题为「宠物房间管理」
+- 日历组件使用「宠物房间日历」称谓
+- 菜单项 meta.title 为「房态管理」(但页面内统一使用"宠物房间"术语)
+
+**API 调用:**
+- `GET /api/boarding-rooms` — 获取所有房型
+- `GET /api/boarding-rooms/{id}/status?month=YYYY-MM` — 获取房态
+- `PUT /api/admin/boarding-rooms/{roomId}/status` — 修改单日状态(切换 AVAILABLE/OCCUPIED)
+- `PUT /api/admin/boarding-rooms/{roomId}/status/batch` — 批量修改(预留,当前 UI 暂未实现多选)
+
+**状态切换逻辑(handleDateClick):**
+```typescript
+const handleDateClick = async (date: string, status: 'AVAILABLE' | 'OCCUPIED') => {
+  const newStatus = status === 'AVAILABLE' ? 'OCCUPIED' : 'AVAILABLE'
+  // PUT /api/admin/boarding-rooms/{roomId}/status { date, status: newStatus }
+  // 刷新日历
+}
+```
+
+#### 6.7.3 排班管理 (AdminScheduleListView)
+
+```
+┌──────────────────────────────────────────────┐
+│  排班管理                      [+ 新增]       │
+│  [2026年07月 ▼]                               │
+├──────────────────────────────────────────────┤
+│  ┌──────────────────────────────────────────┐│
+│  │ 设计师 | 日期 | 时段 | 状态 | 操作       ││
+│  │ 张三   | 07-01 | 上午 | 可用 | [删除]    ││
+│  │ 李四   | 07-01 | 下午 | 可用 | [删除]    ││
+│  │ ...                                      ││
+│  └──────────────────────────────────────────┘│
+└──────────────────────────────────────────────┘
+```
+
+**新增弹窗:**
+```
+┌──────────────────────────┐
+│    新增排班               │
+│  设计师: [__________]     │
+│  日期:   [date ▼]        │
+│  时段:   [上午 ▼]        │
+│  是否可用: [🟢]          │
+│                          │
+│    [取消]    [保存]      │
+└──────────────────────────┘
+```
+
+**API 调用:**
+- `GET /api/admin/schedules?month=YYYY-MM` — 获取排班列表
+- `POST /api/admin/schedules` — 新增排班
+- `DELETE /api/admin/schedules/{id}` — 删除排班
+
+#### 6.7.4 套餐配置 (AdminPackageListView + Create + Edit)
+
+```
+┌──────────────────────────────────────────────┐
+│  套餐配置                       [+ 新增套餐]  │
+├──────────────────────────────────────────────┤
+│  ┌──────────────────────────────────────────┐│
+│  │ 名称 | 类型 | 价格 | 天数 | 状态 | 操作  ││
+│  │ 标准寄养 | 寄养 | ¥100 | 7天 | 启用 | [编辑][删]││
+│  │ 基础洗护 | 洗护 | ¥80  | -   | 启用 | [编辑][删]││
+│  └──────────────────────────────────────────┘│
+└──────────────────────────────────────────────┘
+```
+
+**新增/编辑表单:**
+```
+┌──────────────────────────────────┐
+│  新增套餐 / 编辑套餐               │
+│  套餐类型: ○ 寄养  ○ 洗护         │
+│  套餐名称: [______________]       │
+│  价格:     [0.00]                │
+│  描述:     [______________]       │
+│  寄养天数: [1]   (仅寄养显示)     │
+│  是否启用: [🟢]                   │
+│                                  │
+│     [取消]        [保存]         │
+└──────────────────────────────────┘
+```
+
+**API 调用:**
+- `GET /api/packages` — 获取套餐列表
+- `GET /api/packages/{id}` — 获取单个套餐
+- `POST /api/admin/packages` — 新增套餐
+- `PUT /api/admin/packages/{id}` — 更新套餐
+- `DELETE /api/admin/packages/{id}` — 删除套餐(逻辑删除)
+
+#### 6.7.5 用户管理 (AdminUserListView + AdminUserDetailView)
+
+**AdminUserListView 复用 UserView.vue:**
+- 搜索区域:用户名、账号、角色、状态
+- el-table:ID、用户名、账号、角色标签、启用/禁用 switch、头像、操作(编辑/删除)
+- 新增/编辑弹窗:用户名、账号、密码、角色
+- 分页、批量删除、单条删除
+
+**AdminUserDetailView:**
+```
+┌──────────────────────────────────────────────┐
+│  ← 用户管理                                   │
+├──────────────────────────────────────────────┤
+│  用户信息                                     │
+│  ┌──────────────────────────────────────────┐│
+│  │ 用户名: 张三 | 账号: zhangsan            ││
+│  │ 角色: user   | 邮箱: z@x.com             ││
+│  │ 手机: 138xxxx |                           ││
+│  └──────────────────────────────────────────┘│
+├──────────────────────────────────────────────┤
+│  该用户的宠物档案                             │
+│  ┌──────────────────────────────────────────┐│
+│  │ 名称 | 品种 | 性别 | 体重                ││
+│  │ 旺财 | 金毛 | 公   | 25kg               ││
+│  └──────────────────────────────────────────┘│
+└──────────────────────────────────────────────┘
+```
+
+**API 调用:**
+- `GET /api/admin/users/{id}` — 获取用户详情(含用户信息 + 宠物列表)
+- UserView 使用的 `GET /api/user` 分页查询
+
+## 7. 状态管理 (Pinia Store)
+
+### 7.1 useLoginUserStore (`store/user.ts`)
+
+| 分类 | 名称 | 类型 | 说明 |
+|------|------|------|------|
+| **State** | `loginUser` | `Reactive<LoginUser>` | `{ isLogin: false, user: { id, name, role } }` |
+| **Getter** | `userId` | `ComputedRef<string>` | `loginUser.user?.id` |
+| **Action** | `updateUser(user: User)` | `void` | 替换 user 对象 |
+| **Action** | `loginSuccess(user: User)` | `void` | 设置 isLogin=true + 更新 user |
+| **Action** | `logoutUser()` | `void` | 重置为未登录状态 |
+
+**持久化:** `persist: true` — 通过 pinia-plugin-persistedstate 自动同步到 localStorage
+
+### 7.2 useMetaStore (`store/meta.ts`)
+
+| 分类 | 名称 | 类型 | 说明 |
+|------|------|------|------|
+| **State** | `title` | `Ref<string>` | 网站标题(默认"标题") |
+| **State** | `logo` | `Ref<string>` | Logo 路径(默认 `/logo.svg`) |
+| **State** | `baseUrl` | `Ref<string>` | 后端地址(默认 `http://localhost:8080/`) |
+
+**持久化:** `persist: true`
+
+### 7.3 usePetStore (`store/pet.ts`)
+
+| 分类 | 名称 | 类型 | 说明 |
+|------|------|------|------|
+| **State** | `pets` | `Ref<Pet[]>` | 宠物列表缓存 |
+| **Action** | `setPets(list: Pet[])` | `void` | 覆盖设置宠物列表 |
+| **Action** | `addPet(pet: Pet)` | `void` | 追加一只宠物 |
+| **Action** | `updatePet(updated: Pet)` | `void` | 按 id 更新宠物 |
+| **Action** | `removePet(id: string)` | `void` | 按 id 删除宠物 |
+
+### 7.4 useAppointmentStore (`store/appointment.ts`)
+
+| 分类 | 名称 | 类型 | 说明 |
+|------|------|------|------|
+| **State** | `currentPackage` | `Ref<Package \| null>` | 当前选中套餐 |
+| **State** | `selectedPet` | `Ref<Pet \| null>` | 当前选中宠物 |
+| **State** | `selectedRoom` | `Ref<BoardingRoom \| null>` | 当前选中房型 |
+| **State** | `dateRange` | `Ref<[Date, Date] \| null>` | 入住/离店日期范围 |
+| **Action** | `reset()` | `void` | 重置所有状态为 null |
+
+> 注意:目前 BoardingBookingView 使用局部 ref 而非此 store 管理状态。
+
+## 8. API 层设计
+
+### 8.1 Axios 实例配置
+
+```typescript
+// util/axios-instance.ts
+const axiosInstance = axios.create({
+  baseURL: import.meta.env.VITE_API_BASE_URL || '/api',  // Vite 代理前缀
+  timeout: 30000,
+  withCredentials: true,        // 自动携带 JSESSIONID Cookie
+  headers: { 'Content-Type': 'application/json' }
+})
+
+// 响应拦截器
+axiosInstance.interceptors.response.use(
+  (response) => {
+    if (response.data.code !== 0 && response.data.code !== 200) {
+      return Promise.reject(new Error(response.data.message || '请求失败'))
+    }
+    return response.data    // 解包,直接返回 { code, message, data }
+  },
+  (error) => {
+    if (error.response?.status === 401) {
+      window.location.href = '/login'  // Session 过期 → 跳转登录
+    }
+    return Promise.reject(error)
+  }
+)
+
+// Orval 自定义实例
+export const customAxiosInstance = <T>(config: CustomInstanceConfig): Promise<T> => {
+  return axiosInstance(config)
+}
+```
+
+### 8.2 Orval 生成的控制器
+
+| 文件 | 工厂函数 | 主要方法 | 对应 API 端点 |
+|------|---------|---------|-------------|
+| `auth-controller.ts` | `getAuthController()` | `login`, `register`, `logout` | `POST /api/auth/login`, `POST /api/auth/register`, ... |
+| `user-controller.ts` | `getUserController()` | `queryByPageUsers`, `add`, `edit`, `deleteById`, `updateStatus`, `updatePassword`, `updateAvatar`, `queryById` | `GET/POST/PUT/DELETE /api/user/**` |
+| `pet-controller.ts` | `getPetController()` | `list`, `add1`, `getById`, `update`, `_delete`, `addVaccination`, `addDeworming` | `GET/POST/PUT/DELETE /api/pets/**` |
+| `appointment-controller.ts` | `getAppointmentController()` | `create`, `list1`, `getById2`, `cancel`, `payDeposit` | `POST/GET /api/appointments/**` |
+| `admin-appointment-controller.ts` | `getAdminAppointmentController()` | `listAll`, `review`, `handleCancel` | `GET/PUT /api/admin/appointments/**` |
+| `boarding-room-controller.ts` | `getBoardingRoomController()` | `listRooms`, `getStatus` | `GET /api/boarding-rooms/**` |
+| `admin-boarding-room-controller.ts` | `getAdminBoardingRoomController()` | `updateStatus1`, `batchUpdateStatus` | `PUT /api/admin/boarding-rooms/**` |
+| `package-controller.ts` | `getPackageController()` | `list4`, `getById1` | `GET /api/packages/**` |
+| `admin-package-controller.ts` | `getAdminPackageController()` | `create2`, `update1`, `delete1` | `POST/PUT/DELETE /api/admin/packages/**` |
+| `admin-schedule-controller.ts` | `getAdminScheduleController()` | `list2`, `create1`, `delete2` | `GET/POST/DELETE /api/admin/schedules/**` |
+| `admin-user-controller.ts` | `getAdminUserController()` | `listAllUsers`, `getDetail` | `GET /api/admin/users/**` |
+| `schedule-controller.ts` | `getScheduleController()` | (预留) | - |
+
+## 9. 关键数据流
+
+### 9.1 登录数据流
+
+```mermaid
+sequenceDiagram
+    actor U as User
+    participant V as LoginView
+    participant S as useLoginUserStore
+    participant A as Axios Instance
+    participant B as Backend
+
+    U->>V: 输入账号密码
+    U->>V: 点击登录
+    V->>V: formRef.validate()
+    alt 校验失败
+        V->>U: 显示表单错误
+    else 校验通过
+        V->>A: authApi.login({ account, password })
+        A->>B: POST /api/auth/login<br/>withCredentials: true
+        B->>B: MD5 校验密码
+        B->>B: request.getSession().setAttribute("user", userInfo)
+        B-->>A: Set-Cookie: JSESSIONID=xxx<br/>Response<UserVo>
+        A-->>V: res.data (UserVo)
+        V->>S: loginSuccess({ id, name, role })
+        S->>S: loginUser.isLogin = true
+        S->>S: persist → localStorage
+        V->>V: router.push(redirect || '/booking')
+        V->>U: ElMessage.success('登录成功')
+    end
+
+    Note over U,B: 后续请求
+    U->>V: 访问需登录页面
+    V->>A: 任意 API 请求
+    A->>B: Cookie: JSESSIONID=xxx
+    B->>B: session.getAttribute("user")
+    B-->>A: 正常响应
+```
+
+### 9.2 预约数据流
+
+```mermaid
+sequenceDiagram
+    actor U as User
+    participant V as BoardingBookingView
+    participant S as useAppointmentStore
+    participant A as API Layer
+    participant B as Backend
+
+    Note over V: Step 1 — 选择套餐
+    V->>A: GET /api/packages?type=BOARDING
+    A->>B: 查询套餐表
+    B-->>A: PackageVo[] (is_active=true)
+    A-->>V: 卡片列表渲染
+    U->>V: 点击选择套餐
+    V->>S: currentPackage = selected
+
+    Note over V: Step 2 — 选择房型与日期
+    V->>A: GET /api/boarding-rooms
+    A-->>V: BoardingRoomVo[]
+    U->>V: 选择房型
+    V->>A: GET /api/boarding-rooms/{id}/status?month=2026-07
+    A-->>V: RoomStatusVo[]
+    V->>V: 渲染 RoomCalendar 宠物房间日历
+    U->>V: 选择入住/离店日期
+    V->>V: 计算天数、总价
+    V->>S: selectedRoom, dateRange
+
+    Note over V: Step 3 — 选择宠物
+    V->>A: GET /api/pets
+    A-->>V: PetVo[]
+    V->>V: 渲染 PetSelector
+    U->>V: 选择宠物
+    V->>S: selectedPet
+
+    Note over V: Step 4 — 提交 + 支付
+    U->>V: 点击提交预约
+    V->>A: POST /api/appointments<br/>{ packageId, roomId, petId, startDate, endDate }
+    A->>B: 创建预约记录 (status=PENDING)
+    B-->>A: AppointmentVo { id, deposit, totalPrice }
+    A-->>V: createdOrderId, depositAmount
+    V->>V: 打开 PaymentDialog
+    U->>V: 选择支付方式
+    U->>V: 点击确认支付
+    V->>A: POST /api/appointments/{id}/pay-deposit
+    A->>B: 更新 depositPaid=true
+    B-->>A: success
+    V->>U: ElMessage.success('支付成功')
+    V->>V: router.push('/orders')
+```
+
+### 9.3 订单取消数据流
+
+```mermaid
+sequenceDiagram
+    actor U as User
+    participant V as OrderDetailView
+    participant A as API Layer
+    participant B as Backend
+
+    alt PENDING 状态取消
+        U->>V: 点击"申请取消"
+        V->>V: ElMessageBox.confirm
+        U->>V: 确认 + 填写原因
+        V->>A: POST /api/appointments/{id}/cancel<br/>{ cancelReason }
+        A->>B: 校验状态为 PENDING
+        B->>B: status → CANCELLED
+        alt 已支付定金
+            B->>B: depositRefunded = true
+        end
+        B->>B: 释放房间状态 (若有)
+        B-->>A: success
+        A-->>V: ElMessage.success('取消成功')
+        V->>V: 刷新订单详情
+
+    else CONFIRMED 状态申请取消
+        U->>V: 点击"申请取消"
+        V->>A: POST /api/appointments/{id}/cancel
+        A->>B: 校验状态为 CONFIRMED
+        B->>B: status → CANCEL_REQUESTED
+        B-->>A: success
+        A-->>V: ElMessage.success('取消申请已提交')
+    end
+```
+
+### 9.4 后台审核数据流
+
+```mermaid
+sequenceDiagram
+    actor A as Admin
+    participant V as AdminOrderListView
+    participant API as API Layer
+    participant B as Backend
+
+    Note over V: 页面加载
+    V->>API: GET /api/admin/appointments?pageNum=1&pageSize=10
+    API->>B: 分页查询所有预约
+    B-->>API: PageVo<AppointmentVo>
+    API-->>V: 表格渲染
+
+    Note over A,V: 审核通过
+    A->>V: 点击 PENDING 订单的"审核"
+    V->>V: 打开审核弹窗
+    A->>V: 选择"通过"
+    V->>API: PUT /api/admin/appointments/{id}/review<br/>{ action: 'CONFIRMED' }
+    API->>B: 校验订单
+    B->>B: status → CONFIRMED
+    B->>B: 批量插入 boarding_room_status (OCCUPIED)
+    B->>B: 关联 appointment_id
+    B-->>API: success
+    API-->>V: ElMessage.success
+    V->>V: 刷新列表
+
+    Note over A,V: 审核拒绝
+    A->>V: 选择"拒绝" + 填写原因
+    V->>API: PUT /api/admin/appointments/{id}/review<br/>{ action: 'CANCELLED', rejectReason }
+    API->>B: status → CANCELLED
+    B->>B: 保存 rejectReason
+    B-->>API: success
+
+    Note over A,V: 处理取消申请
+    A->>V: 点击 CANCEL_REQUESTED 的"处理取消"
+    V->>V: 打开处理弹窗
+    A->>V: 同意/拒绝
+    V->>API: PUT /api/admin/appointments/{id}/handle-cancel<br/>{ action: 'CANCELLED'|'CONFIRMED' }
+    API->>B: 更新 status + 释放房间
+    B-->>API: success
+    V->>V: 刷新列表
+```

+ 173 - 0
nextWork.md

@@ -0,0 +1,173 @@
+# 下一步开发任务计划
+
+基于 `detailDesign.md` 与当前项目完整实现状态的对比分析,按优先级规划开发任务。
+
+---
+
+## 当前已实现状态
+
+| 模块 | 文件 | 状态 |
+|------|------|------|
+| 类型定义 | `src/type/index.ts` | **已完善** — Pet, Package, BoardingRoom, RoomStatus, Appointment, Schedule 完整 |
+| 路由配置 | `src/router/index.ts` | **已完善** — 用户侧 13 条路由 + 管理侧 10 条路由,含导航守卫 |
+| 布局组件 | `UserLayout.vue`, `AdminLayout.vue` | **已完善** — 导航菜单、用户下拉、侧边栏展开/收起 |
+| API 控制器 | `src/api/` (13 个文件) | **已完善** — Orval 生成,覆盖全部端点 |
+| Pinia Store | 4 个 store | **已完善** — user, meta, pet, appointment |
+| 公共组件 | RoomCalendar, PaymentDialog, PetSelector | **已完善** |
+| 用户页面 | BookingView, BoardingBookingView, GroomingBookingView | **已实现** — 4 步 Stepper, API 集成, 支付弹窗 |
+| 用户订单 | OrderListView, OrderDetailView | **已实现** — Tab 筛选, 支付/取消功能 |
+| 宠物档案 | PetListView, PetCreateView, PetDetailView, PetEditView | **已实现** — CRUD, 疫苗/驱虫记录管理 |
+| 个人中心 | ProfileView, ProfileEditView, PasswordEditView | **已实现** — 资料展示, 昵称修改, 密码修改 |
+| 后台订单 | AdminOrderListView, AdminOrderDetailView | **已实现** — 审核/取消弹窗 |
+| 后台房态 | AdminRoomCalendarView | **已实现** — 房型切换 + 日历 + 状态切换 |
+| 后台排班 | AdminScheduleListView | **已实现** — CRUD |
+| 后台套餐 | AdminPackageListView, CreateView, EditView | **已实现** — CRUD |
+| 后台用户 | AdminUserDetailView | **已实现** — 用户信息 + 宠物列表 |
+| 登录页面 | LoginView | **已实现** — Tab 切换, 表单校验, 毛玻璃卡片 |
+| 构建 | `npm run build` | **通过** — vue-tsc + vite build 无错误 |
+
+---
+
+## 待完成任务清单
+
+### 阶段一:P0 — 缺陷修复(高优先级)
+
+#### 任务 1.1:RoomCalendar 月份切换功能实现
+- **文件**: `src/components/RoomCalendar.vue`
+- **问题**: `prevMonth()` / `nextMonth()` 为空实现(标记 TODO),无法切换月份
+- **改动**:
+  - 将 `currentYear`, `currentMonth` 从 `const` 改为 `computed`(派生自 props.month)
+  - `prevMonth()` / `nextMonth()` 中 `emit('month-change', newMonth)`
+  - 父组件监听 `month-change` 重新请求房态数据
+- **参考**: detailDesign.md §5.1
+
+#### 任务 1.2:PaymentDialog `visible` 双向绑定修复
+- **文件**: `src/components/PaymentDialog.vue`
+- **问题**: `visible` prop 被复制到本地 `ref( props.visible )`,但不会随父组件更新而同步变化(`v-model:visible` 可能失效)
+- **改动**: 使用 `computed` getter/setter 或 `watch` 同步,移除本地 `const visible = ref(props.visible)`,直接使用 `computed` 绑定
+- **参考**: detailDesign.md §5.2
+
+#### 任务 1.3:OrderDetailView 取消原因弹窗
+- **文件**: `src/view/order/OrderDetailView.vue`
+- **问题**: `handleCancel` 中取消原因硬编码为 `{ reason: '用户申请取消' }`,用户无法输入
+- **改动**: 使用 `ElMessageBox.prompt` 替代 `ElMessageBox.confirm`,收集用户输入的取消原因后提交 API
+- **参考**: detailDesign.md §6.4.2 & §9.3
+
+#### 任务 1.4:OrderListView 状态标签国际化
+- **文件**: `src/view/order/OrderListView.vue`
+- **问题**: 状态标签显示英文(`PENDING`, `CONFIRMED` 等),detailDesign 要求显示中文(待审核、已确认)
+- **改动**: 添加 `statusLabel()` 映射函数,`el-tag` 内显示中文 + 对应 `type` 颜色
+- **参考**: detailDesign.md §6.4.1
+
+#### 任务 1.5:AdminRoomCalendarView 术语修正
+- **文件**: `src/view/admin/AdminRoomCalendarView.vue`
+- **问题**: 模版中 `h1` 标题为「房态管理」,detailDesign 要求使用「宠物房间管理」术语
+- **改动**: 页面标题改为「宠物房间管理」,保持菜单项 meta.title 仍为「房态管理」
+- **参考**: detailDesign.md §6.7.2
+
+### 阶段二:P1 — 表单校验增强(高优先级)
+
+#### 任务 2.1:PetCreateView / PetEditView 添加表单校验
+- **文件**: `src/view/pet/PetCreateView.vue`, `src/view/pet/PetEditView.vue`
+- **问题**: 两个表单均无 `el-form` 的 `:rules` 校验,用户可提交空数据
+- **改动**: 添加 `FormRules`,至少 `name` 为必填,`weight` > 0,提交前调用 `formRef.validate()`
+- **参考**: detailDesign.md §6.5.3
+
+#### 任务 2.2:ProfileEditView 添加表单校验
+- **文件**: `src/view/profile/ProfileEditView.vue`
+- **问题**: 昵称输入无必填校验,可提交空值
+- **改动**: 添加 `:rules` 必填校验 + 最小长度 2
+- **参考**: detailDesign.md §6.6
+
+#### 任务 2.3:PasswordEditView 添加表单校验规则
+- **文件**: `src/view/profile/PasswordEditView.vue`
+- **问题**: 使用手动 `if` 判断密码一致性而非表单校验规则,缺少密码长度校验
+- **改动**: 添加 `FormRules`(原密码必填、新密码 min:4、确认密码自定义校验器)
+- **参考**: detailDesign.md §6.6
+
+### 阶段三:P2 — 响应式适配(中优先级)
+
+#### 任务 3.1:布局组件响应式
+- **文件**: `src/layout/UserLayout.vue`, `src/layout/AdminLayout.vue`
+- **问题**: 当前无移动端媒体查询,小屏设备导航/侧边栏溢出
+- **改动**:
+  - UserLayout: `< 768px` 时 TopNav 折叠为汉堡菜单
+  - AdminLayout: `< 768px` 时侧边栏自动收起,菜单变为 Drawer
+- **参考**: AGENTS.md 响应式设计要求
+
+#### 任务 3.2:主要业务页面响应式
+- **文件**: 所有 view 文件(BookingView, OrderListView, PetListView, AdminOrderListView 等)
+- **问题**: 大多使用固定 `max-width` 和 `flex` 布局,小屏无适配
+- **改动**: 为每个页面添加 `@media (max-width: 768px)` 样式覆盖:
+  - 表格在小屏切换为卡片布局
+  - 多列 grid/flex 变为单列
+  - `el-steps` 在小屏调整字号/间距
+
+### 阶段四:P3 — 主题色统一(中优先级)
+
+#### 任务 4.1:LoginView 颜色主题化
+- **文件**: `src/view/LoginView.vue`
+- **问题**: 大量硬编码粉色色值(`#db2777`, `#be185d`, `#831843`),与 `var(--el-color-primary)` 不一致
+- **改动**: 将颜色引用替换为 CSS 变量 `var(--el-color-primary)` / `var(--el-color-primary-light-*)` / `var(--el-color-primary-dark-2)`
+- **参考**: detailDesign.md §1 主题色 `#e34889`
+
+#### 任务 4.2:style.css 按钮样式使用 CSS 变量
+- **文件**: `src/style.css`
+- **问题**: `.el-button--primary` 中硬编码了渐变颜色 `linear-gradient(135deg, #db2777, #be185d)`
+- **改动**: 使用 `var(--el-color-primary)` 和 `var(--el-color-primary-dark-2)` 构建渐变
+
+### 阶段五:P4 — UI 完善与 Code Quality(低优先级)
+
+#### 任务 5.1:HomeView 品牌首页改造
+- **文件**: `src/view/HomeView.vue`
+- **问题**: 当前仅占位文字,detailDesign 要求品牌展示 + 服务入口卡片
+- **改动**: 实现完整品牌首页(logo + 品牌标语 + 寄养/洗护服务卡片 + 平台优势介绍区)
+- **参考**: detailDesign.md §6.2
+
+#### 任务 5.2:Axios 配置补充 withCredentials
+- **文件**: `src/util/axios-instance.ts`
+- **问题**: 缺少 `withCredentials: true`(detailDesign 要求自动携带 Cookie/JSESSIONID)
+- **改动**: 在 `axios.create` 配置中添加 `withCredentials: true`
+- **参考**: detailDesign.md §8.1
+
+#### 任务 5.3:BoardingBookingView 代码复用提取
+- **文件**: `src/view/booking/BoardingBookingView.vue`
+- **问题**: API 响应到内部类型的 map 逻辑(`list4` / `listRooms` / `list`)分散在各视图重复
+- **改动**: 将重复的 map 逻辑抽象为工具函数或 composable
+- **参考**: 代码整洁性
+
+#### 任务 5.4:OrderListView 添加 CANCEL_REQUESTED Tab
+- **文件**: `src/view/order/OrderListView.vue`
+- **问题**: 设计文档订单状态包含 `CANCEL_REQUESTED`,但 Tab 中缺少该筛选
+- **改动**: 新增「取消申请」Tab
+
+#### 任务 5.5:chunk 体积优化
+- **文件**: `vite.config.ts`(需修改)
+- **问题**: 构建产物 `index.js` 1.15MB > 500KB 阈值
+- **改动**: 配置 `build.rollupOptions.output.manualChunks` 将 Element Plus / 三方库拆分
+
+---
+
+## 执行顺序建议
+
+```
+阶段一 (P0 缺陷修复) → 阶段二 (P1 表单校验) → 阶段三 (P2 响应式) → 阶段四 (P3 主题色) → 阶段五 (P4 完善)
+```
+
+### 并行开发建议
+
+| 批次 | 任务 | 说明 |
+|------|------|------|
+| 第一批 | 1.1 + 1.2 + 1.3 | 互不影响,可同步进行 |
+| 第二批 | 1.4 + 1.5 + 2.1 + 2.2 + 2.3 | 全部为独立文件修改 |
+| 第三批 | 3.1 + 3.2 | 布局 + 多页面响应式 |
+| 第四批 | 4.1 + 4.2 + 5.1 | 主题色 + 首页改造 |
+| 第五批 | 5.2 + 5.3 + 5.4 + 5.5 | 工具函数 + 构建优化 |
+
+---
+
+## 每个阶段的提交建议
+
+- 每个批次完成后运行 `npm run build` 确保无 TypeScript / 构建错误
+- 每个任务粒度在 1-3 个文件改动,便于 Code Review
+- 所有 CSS 改动后检查 PC / Mobile 双端表现

+ 1081 - 0
uiDesign.md

@@ -0,0 +1,1081 @@
+# 宠物服务管理系统 — 客户端详细设计文档
+
+## 1. 技术栈
+
+| 技术 | 版本 | 用途 |
+|------|------|------|
+| Vue 3 | ^3.5.13 | 前端框架(Composition API + `<script setup>`) |
+| Vite | ^6.3.5 | 构建工具 |
+| TypeScript | ~5.8.3 | 类型安全 |
+| Element Plus | ^2.13.6 | UI 组件库 |
+| Pinia | ^3.0.4 | 状态管理 |
+| Pinia Persistedstate | ^4.7.1 | Store 持久化 |
+| Vue Router | ^4.6.4 | 路由管理 |
+| Axios | ^1.15.2 | HTTP 请求 |
+| Orval | 7.0 | OpenAPI → API 代码生成 |
+| Prettier | ^3.8.3 | 代码格式化 |
+
+---
+
+## 2. 项目结构(完整)
+
+```
+ui/
+├── index.html
+├── package.json
+├── vite.config.ts              # Vite 配置(代理 /api → localhost:8080)
+├── tsconfig.json
+├── tsconfig.app.json
+├── tsconfig.node.json
+├── orval.config.ts             # Orval 代码生成配置
+├── .gitignore
+├── public/
+│   ├── logo.svg
+│   └── vite.svg
+├── src/
+│   ├── main.ts                 # 入口文件
+│   ├── App.vue                 # 根组件(<router-view />)
+│   ├── style.css               # 全局样式
+│   ├── vite-env.d.ts
+│   │
+│   ├── type/
+│   │   └── index.ts            # 自定义类型定义
+│   │       - User { id, name, avatar, role }
+│   │       - LoginUser { isLogin, user? }
+│   │
+│   ├── util/
+│   │   ├── index.ts            # 工具函数(当前为空)
+│   │   └── axios-instance.ts   # Axios 实例 + 拦截器配置
+│   │       - withCredentials: true(自动携带 Cookie)
+│   │       - 响应拦截器:统一错误处理 + 401 → /login
+│   │       - customAxiosInstance(供 Orval 使用)
+│   │
+│   ├── api/                    # Orval 生成的 API 代码
+│   │   ├── auth-controller.ts  # 认证 API
+│   │   ├── user-controller.ts  # 用户管理 API
+│   │   ├── pet-controller.ts   # 宠物 API(待生成)
+│   │   ├── appointment-controller.ts  # 预约 API(待生成)
+│   │   ├── boarding-room-controller.ts # 房态 API(待生成)
+│   │   ├── package-controller.ts       # 套餐 API(待生成)
+│   │   ├── schedule-controller.ts      # 排班 API(待生成)
+│   │   └── models/             # 数据模型类型定义
+│   │       ├── index.ts        # 统一导出
+│   │       ├── response.ts     # 统一响应
+│   │       ├── responseUserVo.ts
+│   │       ├── responseBoolean.ts
+│   │       ├── responsePageVoListUserVo.ts
+│   │       ├── responseListFieldError.ts
+│   │       ├── userVo.ts
+│   │       ├── userDto.ts
+│   │       ├── loginDto.ts
+│   │       ├── registerDto.ts
+│   │       ├── updateUserPasswordDto.ts
+│   │       ├── updateUserAvatarDto.ts
+│   │       ├── updateUserStatusDto.ts
+│   │       ├── deleteByIdParams.ts
+│   │       ├── queryByPageParams.ts
+│   │       ├── pageVoListUserVo.ts
+│   │       └── fieldError.ts
+│   │
+│   ├── store/                  # Pinia 状态管理
+│   │   ├── index.ts            # 统一导出
+│   │   ├── user.ts             # useLoginUserStore
+│   │   └── meta.ts             # useMetaStore
+│   │
+│   ├── router/
+│   │   └── index.ts            # 路由配置 + 导航守卫
+│   │
+│   ├── layout/
+│   │   ├── UserLayout.vue      # 用户侧布局(水平 TopNav)
+│   │   └── AdminLayout.vue     # 商家后台侧布局(侧边栏 + 顶栏)
+│   │
+│   ├── view/                   # 页面组件
+│   │   ├── HomeView.vue        # 首页
+│   │   ├── LoginView.vue       # 登录/注册(tab 切换)
+│   │   ├── AboutView.vue       # 关于页面
+│   │   ├── UserView.vue        # 用户管理(后台)
+│   │   │
+│   │   ├── booking/            # 服务预约模块
+│   │   │   ├── BookingView.vue           # 预约首页(选择服务类型)
+│   │   │   ├── BoardingBookingView.vue   # 寄养预约表单
+│   │   │   └── GroomingBookingView.vue   # 洗护预约表单
+│   │   │
+│   │   ├── order/              # 订单管理模块
+│   │   │   ├── OrderListView.vue         # 我的订单列表
+│   │   │   └── OrderDetailView.vue       # 订单详情
+│   │   │
+│   │   ├── pet/                # 宠物档案模块
+│   │   │   ├── PetListView.vue           # 宠物列表
+│   │   │   ├── PetCreateView.vue         # 新增宠物
+│   │   │   ├── PetDetailView.vue         # 宠物详情(含疫苗/驱虫)
+│   │   │   └── PetEditView.vue           # 编辑宠物
+│   │   │
+│   │   ├── profile/            # 个人中心模块
+│   │   │   ├── ProfileView.vue           # 个人信息展示
+│   │   │   ├── ProfileEditView.vue       # 修改个人资料
+│   │   │   └── PasswordEditView.vue      # 修改密码
+│   │   │
+│   │   └── admin/              # 商家后台模块
+│   │       ├── AdminOrderListView.vue     # 订单审核列表
+│   │       ├── AdminOrderDetailView.vue   # 订单审核详情
+│   │       ├── AdminRoomCalendarView.vue  # 房态日历管理
+│   │       ├── AdminScheduleListView.vue  # 排班管理列表
+│   │       ├── AdminPackageListView.vue   # 套餐配置列表
+│   │       ├── AdminPackageCreateView.vue # 新增套餐
+│   │       ├── AdminPackageEditView.vue   # 编辑套餐
+│   │       ├── AdminUserListView.vue      # 用户管理列表(复用的 UserView)
+│   │       └── AdminUserDetailView.vue    # 用户详情(含宠物档案)
+│   │
+│   └── components/             # 公共组件
+│       ├── PaymentDialog.vue   # 模拟支付弹窗
+│       ├── RoomCalendar.vue    # 房态日历组件
+│       ├── PetSelector.vue     # 宠物选择器
+│       └── ...
+```
+
+---
+
+## 3. 路由详细设计
+
+### 3.1 路由配置
+
+```typescript
+// router/index.ts
+const routes = [
+  // 公共路由
+  {
+    path: '/login',
+    name: 'login',
+    component: LoginView
+  },
+
+  // 用户侧路由(嵌套在 UserLayout 下)
+  {
+    path: '/',
+    component: UserLayout,
+    children: [
+      { path: '', name: 'home', component: HomeView },
+      { path: 'about', name: 'about', component: AboutView },
+      // 预约
+      { path: 'booking', name: 'booking', component: BookingView },
+      { path: 'booking/boarding', name: 'boardingBooking', component: BoardingBookingView },
+      { path: 'booking/grooming', name: 'groomingBooking', component: GroomingBookingView },
+      // 订单
+      { path: 'orders', name: 'orderList', component: OrderListView },
+      { path: 'orders/:id', name: 'orderDetail', component: OrderDetailView },
+      // 宠物
+      { path: 'pets', name: 'petList', component: PetListView },
+      { path: 'pets/new', name: 'petCreate', component: PetCreateView },
+      { path: 'pets/:id', name: 'petDetail', component: PetDetailView },
+      { path: 'pets/:id/edit', name: 'petEdit', component: PetEditView },
+      // 个人中心
+      { path: 'profile', name: 'profile', component: ProfileView },
+      { path: 'profile/edit', name: 'profileEdit', component: ProfileEditView },
+      { path: 'profile/password', name: 'passwordEdit', component: PasswordEditView },
+    ]
+  },
+
+  // 商家后台路由(嵌套在 AdminLayout 下)
+  {
+    path: '/admin',
+    component: AdminLayout,
+    meta: { requiresAdmin: true },
+    children: [
+      { path: '', name: 'adminDashboard', component: AdminDashboardView },
+      { path: 'orders', name: 'adminOrderList', component: AdminOrderListView },
+      { path: 'orders/:id', name: 'adminOrderDetail', component: AdminOrderDetailView },
+      { path: 'rooms', name: 'adminRooms', component: AdminRoomCalendarView },
+      { path: 'schedules', name: 'adminSchedules', component: AdminScheduleListView },
+      { path: 'packages', name: 'adminPackageList', component: AdminPackageListView },
+      { path: 'packages/new', name: 'adminPackageCreate', component: AdminPackageCreateView },
+      { path: 'packages/:id/edit', name: 'adminPackageEdit', component: AdminPackageEditView },
+      { path: 'users', name: 'adminUsers', component: AdminUserListView },
+      { path: 'users/:id', name: 'adminUserDetail', component: AdminUserDetailView },
+    ]
+  }
+]
+```
+
+### 3.2 导航守卫
+
+```typescript
+router.beforeEach((to, _from, next) => {
+  // 检查是否需要管理员权限
+  if (to.matched.some(record => record.meta.requiresAdmin)) {
+    const loginUserStore = useLoginUserStore()
+    if (!loginUserStore.loginUser.isLogin) {
+      // 未登录 → 跳转登录页,携带 redirect
+      ElMessage.warning('请先登录')
+      next({ path: '/login', query: { redirect: to.fullPath } })
+    } else if (loginUserStore.loginUser.user?.role !== 'admin') {
+      // 非管理员 → 跳转首页
+      ElMessage.error('无权访问')
+      next('/')
+    } else {
+      next() // 放行
+    }
+  } else {
+    next() // 无需权限 → 放行
+  }
+})
+```
+
+### 3.3 路由元信息
+
+| route | meta.title | meta.icon | meta.requiresAdmin |
+|-------|-----------|-----------|-------------------|
+| / | 首页 | HomeFilled | - |
+| /about | 关于 | Menu | - |
+| /admin/users | 用户管理 | User | true |
+| /admin/other | 其他 | Menu | true |
+
+> 其余路由的 meta 待补充完整。
+
+---
+
+## 4. 布局详细设计
+
+### 4.1 UserLayout(用户侧布局)
+
+```
+┌─────────────────────────────────────────────────────────┐
+│  [Logo]  标题        [首页] [关于]   [后台管理]  [登录]  │  ← el-header(水平)
+├─────────────────────────────────────────────────────────┤
+│                                                         │
+│                    <router-view />                       │  ← el-main(内容区)
+│                                                         │
+├─────────────────────────────────────────────────────────┤
+│                       Footer                            │  ← el-footer
+└─────────────────────────────────────────────────────────┘
+```
+
+**功能说明:**
+- 顶部导航栏:左侧 Logo + 标题,中间水平导航菜单(从 userRoutes 动态渲染),右侧用户状态(登录显示头像+下拉菜单/未登录显示登录注册按钮)
+- 管理员用户额外显示"后台管理"入口
+- 内容区渲染子路由
+
+**状态判断:**
+```typescript
+const login = computed(() => loginUserStore.loginUser.isLogin)
+const isAdmin = computed(() => loginUserStore.loginUser.user?.role === 'admin')
+```
+
+### 4.2 AdminLayout(商家后台侧布局)
+
+```
+┌──────────────────────────────────────────────────────────┐
+│  [Logo]  标题         后台管理          [用户名 ▼]       │  ← el-header
+├──────────┬───────────────────────────────────────────────┤
+│  可折叠   │                                              │
+│  侧边栏   │            <router-view />                   │  ← el-main
+│  导航菜单  │                                              │
+│          │                                              │
+└──────────┴───────────────────────────────────────────────┘
+```
+
+**功能说明:**
+- 顶部栏:左侧 Logo+标题,中间"后台管理"标题,右侧用户信息下拉
+- 左侧可折叠菜单(从 adminRoutes 动态渲染)
+- 内容区渲染子路由
+
+**可折叠菜单:**
+```typescript
+const isCollapse = ref(false)
+// el-menu 的 :collapse="isCollapse" 控制展开/收起
+```
+
+---
+
+## 5. 状态管理详细设计(Pinia Store)
+
+### 5.1 useLoginUserStore
+
+```typescript
+// store/user.ts
+export const useLoginUserStore = defineStore('loginUser', () => {
+  // === State ===
+  const loginUser = reactive<LoginUser>({
+    isLogin: false,
+    user: {
+      id: '',
+      name: '未登录',
+      role: 'guest'
+    }
+  })
+
+  // === Getters ===
+  const userId = computed(() => loginUser.user?.id)
+
+  // === Actions ===
+  function updateUser(user: User) {
+    loginUser.user = { ...user }
+  }
+  function loginSuccess(user: User) {
+    updateUser(user)
+    loginUser.isLogin = true
+  }
+  function logoutUser() {
+    loginUser.isLogin = false
+    loginUser.user = { id: '', name: '未登录', role: 'guest' }
+    // 清除登录状态(服务端 session 通过 logout API 销毁)
+    // 前端仅清除本地 store 状态
+  }
+
+  return { loginUser, userId, updateUser, loginSuccess, logoutUser }
+}, { persist: true })  // pinia-plugin-persistedstate
+```
+
+**持久化存储:**
+- 通过 `pinia-plugin-persistedstate` 自动持久化到 localStorage
+- 刷新页面后登录状态自动恢复
+
+### 5.2 useMetaStore
+
+```typescript
+// store/meta.ts
+export const useMetaStore = defineStore('meta', () => {
+  const title = ref('标题')          // 网站标题
+  const logo = ref('/logo.svg')     // 网站 Logo
+  const baseUrl = ref('http://localhost:8080/')  // 后端地址
+
+  return { title, logo, baseUrl }
+}, { persist: true })
+```
+
+### 5.3 新建 Store 规划
+
+| Store 名称 | 用途 | 状态字段 |
+|-----------|------|---------|
+| useAppointmentStore | 预约流程状态 | currentPackage, selectedPet, selectedRoom, dateRange |
+| usePetStore | 宠物列表缓存 | pets: PetVo[] |
+
+---
+
+## 6. Axios 配置详细设计
+
+```typescript
+// util/axios-instance.ts
+
+const axiosInstance = axios.create({
+  baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
+  timeout: 30000,
+  withCredentials: true,  // 跨域请求自动携带 Cookie(JSESSIONID)
+  headers: { 'Content-Type': 'application/json' }
+})
+
+// 响应拦截器
+axiosInstance.interceptors.response.use(
+  (response) => {
+    // 后端返回格式: { code, message, data }
+    if (response.data.code !== 0 && response.data.code !== 200) {
+      return Promise.reject(new Error(response.data.message || '请求失败'))
+    }
+    return response.data  // 直接返回 data,不需要 .data.data
+  },
+  (error) => {
+    if (error.response?.status === 401) {
+      // Session 过期或未登录,跳转登录页
+      window.location.href = '/login'
+    }
+    return Promise.reject(error)
+  }
+)
+
+// Orval 使用的自定义实例
+export const customAxiosInstance = <T>(config: CustomInstanceConfig): Promise<T> => {
+  return axiosInstance(config)
+}
+```
+
+---
+
+## 7. 页面详细设计
+
+### 7.1 登录/注册页(LoginView)
+
+**功能:**
+- Tab 切换:登录 / 注册
+- 登录表单:账号 + 密码
+- 注册表单:账号 + 用户名 + 密码 + 确认密码
+- 表单校验(Element Plus Form Rules)
+- 登录成功:服务端将用户信息存入 HttpSession,前端更新 Pinia store → 跳转首页/redirect
+- 注册成功:自动切换到登录 tab
+
+**状态管理:**
+- activeTab: ref('login') — 当前激活的 tab
+- loginForm: reactive({ account, password })
+- registerForm: reactive({ account, username, password, confirmPassword })
+- loginLoading, registerLoading: ref(false)
+
+**校验规则:**
+- 登录:account 非空, password 非空且≥4位
+- 注册:account 4-20位, username 2-32位, password 4-20位, confirmPassword 需与 password 一致
+
+**交互流程:**
+```
+用户输入 → 点击登录/注册 → validate() → API 调用
+  → 成功 → 更新 store(服务端已存入 Session) → 跳转
+  → 失败 → ElMessage.error 显示错误信息
+```
+
+### 7.2 首页(HomeView)
+
+**功能:**
+- 展示宠物服务管理系统的品牌介绍
+- 快速入口:寄养服务、洗护服务、我的订单、宠物档案
+
+**布局建议:**
+```
+┌──────────────────────────────────────┐
+│  品牌 Banner + 宣传语                  │
+├────────────┬──────────┬──────────────┤
+│ 寄养服务    │ 洗护服务  │ 更多服务      │  ← 功能卡片入口
+├────────────┴──────────┴──────────────┤
+│  功能介绍 / 优势展示                    │
+└──────────────────────────────────────┘
+```
+
+### 7.3 服务预约页(BookingView / BoardingBookingView / GroomingBookingView)
+
+#### 7.3.1 BookingView(服务类型选择)
+
+```
+┌──────────────────────────────────────┐
+│  选择服务类型                          │
+│                                      │
+│  ┌──────────┐  ┌──────────┐          │
+│  │  寄养服务  │  │  洗护服务  │          │  ← 两大服务卡片
+│  │  🏠       │  │  ✂️       │          │
+│  │  查看详情  │  │  查看详情  │          │
+│  └──────────┘  └──────────┘          │
+└──────────────────────────────────────┘
+```
+
+#### 7.3.2 BoardingBookingView(寄养预约)
+
+**步骤流程(Stepper 组件):**
+
+```
+Step 1: 选择寄养套餐
+  → GET /api/packages?type=BOARDING
+  → 卡片列表展示套餐(名称、价格、天数、描述)
+  → 用户选择一个套餐
+
+Step 2: 选择房型与日期
+  → GET /api/boarding-rooms
+  → 选择房型 → GET /api/boarding-rooms/{id}/status?month=YYYY-MM
+  → 日历展示房态(绿色=空闲,红色=占用)
+  → 用户选择入住/离店日期
+  → 实时计算总价(每晚价格 × 天数)
+
+Step 3: 选择宠物
+  → GET /api/pets
+  → 下拉选择或卡片选择已有的宠物
+
+Step 4: 确认提交
+  → 展示订单摘要:套餐、房型、日期、宠物、总价
+  → 点击"提交预约"
+  → POST /api/appointments
+  → 成功 → 弹出 PaymentDialog(支付定金)
+```
+
+#### 7.3.3 GroomingBookingView(洗护预约)
+
+**步骤流程:**
+
+```
+Step 1: 选择洗护套餐
+  → GET /api/packages?type=GROOMING
+  → 卡片列表展示
+
+Step 2: 选择预约时间
+  → GET /api/admin/schedules?month=YYYY-MM
+  → 日历展示设计师排班(可选的日期+时段)
+  → 选择时间段
+
+Step 3: 选择宠物
+  → GET /api/pets
+  → 选择宠物
+
+Step 4: 确认提交
+  → 提交预约 → 支付定金
+```
+
+### 7.4 订单管理(OrderListView / OrderDetailView)
+
+#### 7.4.1 OrderListView
+
+```
+┌──────────────────────────────────────┐
+│  我的预约           [状态筛选 Tab]      │
+├──────────────────────────────────────┤
+│  ┌──────────────────────────────────┐│
+│  │ 订单卡片:                        ││
+│  │ 宠物名 | 套餐名 | 日期            ││
+│  │ 状态标签 | 总价                   ││
+│  │ [申请取消] [查看详情]              ││
+│  └──────────────────────────────────┘│
+│  ┌──────────────────────────────────┐│
+│  │ 订单卡片 2...                     ││
+│  └──────────────────────────────────┘│
+│            ... 分页 ...              │
+└──────────────────────────────────────┘
+```
+
+#### 7.4.2 OrderDetailView
+
+```
+┌──────────────────────────────────────┐
+│  ← 返回                              │
+├──────────────────────────────────────┤
+│  订单编号:xxx                        │
+│  状态:[PENDING/CONFIRMED/CANCELLED]  │
+│                                      │
+│  服务类型:寄养/洗护                    │
+│  套餐名称:xxx                        │
+│  宠物:xxx(品种/年龄)                │
+│  房型:xxx(仅寄养)                   │
+│  日期:2026-06-01 ~ 2026-06-03        │
+│  总价:¥600                           │
+│  定金:¥180(已支付/未支付)            │
+│  创建时间:2026-06-01 10:00           │
+│                                      │
+│  [申请取消] [支付定金] [联系客服]        │
+└──────────────────────────────────────┘
+```
+
+**条件按钮逻辑:**
+- 显示"支付定金":仅当 deposit_paid = false 且 status = PENDING
+- 显示"申请取消":仅当 status 为 PENDING 或 CONFIRMED
+- 显示弹窗填写取消原因
+
+### 7.5 宠物档案(PetListView / PetCreateView / PetDetailView / PetEditView)
+
+#### 7.5.1 PetListView
+
+```
+┌──────────────────────────────────────┐
+│  宠物档案          [+ 新增宠物]        │
+├──────────────────────────────────────┤
+│  ┌──────────────────────────────────┐│
+│  │ [头像] 宠物名 - 品种              ││
+│  │ 年龄: 2岁 | 性别: 公             ││
+│  │ [编辑] [删除] [查看详情]          ││
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+#### 7.5.2 PetDetailView
+
+```
+┌──────────────────────────────────────┐
+│  ← 返回          [编辑] [删除]       │
+├──────────────────────────────────────┤
+│  基本信息                            │
+│  名称: 旺财 | 品种: 金毛             │
+│  年龄: 2岁 | 体重: 25kg             │
+│  性别: 公   | 备注: 活泼好动         │
+├──────────────────────────────────────┤
+│  疫苗记录          [+ 新增]          │
+│  ┌──────────────────────────────────┐│
+│  │ 狂犬疫苗  2026-01-01  2027-01-01 ││
+│  │ 接种机构: 安心宠物医院            ││
+│  └──────────────────────────────────┘│
+├──────────────────────────────────────┤
+│  驱虫记录          [+ 新增]          │
+│  ┌──────────────────────────────────┐│
+│  │ 体外驱虫  2026-03-15  2026-06-15 ││
+│  │ 药物: 福来恩                      ││
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+### 7.6 个人中心(ProfileView / ProfileEditView / PasswordEditView)
+
+#### 7.6.1 ProfileView
+
+```
+┌──────────────────────────────────────┐
+│  个人中心                             │
+│                                      │
+│  [大头像]  用户名                     │
+│  角色:普通用户                       │
+├──────────────────────────────────────┤
+│  账号:xxx                   [不可改] │
+│  昵称:xxx                   [编辑]   │
+│  手机:138xxxxxxx           [编辑]   │
+│  邮箱:xxx@xxx.com         [编辑]   │
+├──────────────────────────────────────┤
+│  [修改密码]                           │
+└──────────────────────────────────────┘
+```
+
+#### 7.6.2 PasswordEditView
+
+```
+┌──────────────────────────────────────┐
+│  ← 个人中心                           │
+├──────────────────────────────────────┤
+│  原密码:[input]                      │
+│  新密码:[input]                      │
+│  确认密码:[input]                     │
+│                                      │
+│  [确认修改]                           │
+└──────────────────────────────────────┘
+```
+
+### 7.7 商家后台页面
+
+#### 7.7.1 AdminOrderListView
+
+```
+┌──────────────────────────────────────┐
+│  订单审核            [状态筛选] [搜索] │
+├──────────────────────────────────────┤
+│  ┌──────────────────────────────────┐│
+│  │ 表格:                            ││
+│  │ ID | 用户 | 宠物 | 套餐 | 类型     ││
+│  │ 日期 | 总价 | 定金 | 状态 | 操作   ││
+│  │ 操作:[审核] [详情]               ││
+│  └──────────────────────────────────┘│
+│  ... 分页 ...                        │
+└──────────────────────────────────────┘
+```
+
+**操作:**
+- 审核按钮:仅对 PENDING 状态的订单 → 打开审核对话框(通过/拒绝+原因)
+- 处理取消按钮:仅对 CANCEL_REQUESTED 状态的订单 → 打开处理对话框(同意/拒绝+原因)
+
+#### 7.7.2 AdminOrderDetailView
+
+展示订单全部信息 + 审核操作按钮 + 订单状态变更历史。
+
+#### 7.7.3 AdminRoomCalendarView
+
+```
+┌──────────────────────────────────────┐
+│  房态管理          [房型选择] [月份选择]│
+├──────────────────────────────────────┤
+│  ┌──────────────────────────────────┐│
+│  │  日历视图:                       ││
+│  │  日  一  二  三  四  五  六       ││
+│  │             1     2     3     4  ││
+│  │   5     6     7     8     9  10  ││
+│  │  ...                             ││
+│  │  点击日期切换: [空闲] [占用]       ││
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+**交互:**
+- 选择房型 → 日历刷新显示该房型月状态
+- 点击某天 → 切换空闲/占用状态
+- 颜色标识:绿色=空闲,红色=占用
+
+#### 7.7.4 AdminScheduleListView
+
+```
+┌──────────────────────────────────────┐
+│  排班管理          [月份选择] [+ 新增] │
+├──────────────────────────────────────┤
+│  ┌──────────────────────────────────┐│
+│  │ 表格:                            ││
+│  │ 设计师 | 日期 | 时段 | 状态 | 操作 ││
+│  │ 张三   | 06-01 | 上午  | 可用 | [删]│
+│  │ 李四   | 06-01 | 全天  | 可用 | [删]│
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+**新增弹窗:**
+- 设计师姓名(输入)
+- 日期(日期选择器)
+- 时段(下拉:上午/下午/全天)
+- 是否可用(开关)
+
+#### 7.7.5 AdminPackageListView / AdminPackageCreateView / AdminPackageEditView
+
+```
+┌──────────────────────────────────────┐
+│  套餐配置          [+ 新增套餐]       │
+├──────────────────────────────────────┤
+│  ┌──────────────────────────────────┐│
+│  │ 表格:                            ││
+│  │ 名称 | 类型 | 价格 | 天数 | 状态 | 操 │
+│  │ 标准寄养 | 寄养 | ¥100/天 | 1-7 | ✅ | [编辑][删]│
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+**新增/编辑表单:**
+- 套餐类型(寄养/洗护 → radio)
+- 套餐名称(input)
+- 价格(input number)
+- 描述/项目内容(textarea)
+- 寄养天数(input number,仅寄养时显示)
+- 是否启用(switch)
+
+#### 7.7.6 AdminUserListView
+
+复用现有的 UserView.vue 组件,功能包括:
+- 搜索筛选(用户名/账号/角色/状态)
+- 表格展示(ID/用户名/账号/角色/状态/头像/操作)
+- 新增/编辑用户弹窗
+- 启用/禁用用户开关
+- 批量删除
+
+#### 7.7.7 AdminUserDetailView
+
+```
+┌──────────────────────────────────────┐
+│  ← 用户管理                           │
+├──────────────────────────────────────┤
+│  用户信息                             │
+│  [头像] 用户名 | 账号 | 角色 | 状态    │
+│  注册时间: 2026-01-01                 │
+├──────────────────────────────────────┤
+│  该用户的宠物档案                      │
+│  ┌──────────────────────────────────┐│
+│  │ 宠物名 | 品种 | 年龄 | 操作       ││
+│  │ 旺财   | 金毛 | 2岁 | [查看详情]  ││
+│  └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+---
+
+## 8. 公共组件详细设计
+
+### 8.1 PaymentDialog(模拟支付弹窗)
+
+```vue
+<!-- 用法 -->
+<PaymentDialog v-model:visible="showPayment" :amount="deposit" :order-id="orderId"
+  @success="onPaymentSuccess" @close="onPaymentClose" />
+```
+
+**功能:**
+- 显示定金金额
+- 支付方式选择:微信支付 / 支付宝(纯 UI 模拟)
+- 点击"确认支付" → POST /api/appointments/{orderId}/pay-deposit
+- 成功 → 显示支付成功动画/提示 → emit('success')
+- 失败 → 显示错误提示
+
+### 8.2 RoomCalendar(房态日历组件)
+
+```vue
+<!-- 用法 -->
+<RoomCalendar :room-id="roomId" :month="currentMonth" :status-list="statusList"
+  @date-click="handleDateClick" />
+```
+
+**功能:**
+- 展示月历视图(7列 × 6行)
+- 每天显示状态(AVAILABLE=绿色, OCCUPIED=红色)
+- 点击某天 → emit('date-click', date, currentStatus)
+- 支持切换月份
+
+### 8.3 PetSelector(宠物选择器)
+
+```vue
+<!-- 用法 -->
+<PetSelector :pet-list="pets" v-model:selected="selectedPet" />
+```
+
+**功能:**
+- 卡片列表展示用户的宠物
+- 点击选择一只宠物(高亮选中状态)
+
+---
+
+## 9. API 调用模式
+
+### 9.1 Orval 生成代码的使用
+
+```typescript
+// 调用认证 API
+import { getAuthController } from '@/api/auth-controller'
+
+const authApi = getAuthController()
+const res = await authApi.login({ account, password })
+
+// res 已经是解包后的数据(响应拦截器已处理)
+// 登录成功后服务端已将用户信息存入 HttpSession
+// 前端仅需更新 Pinia store
+if (res.code === 200) {
+  loginUserStore.loginSuccess({
+    id: String(res.data.id),
+    name: res.data.username,
+    role: res.data.role
+  })
+  // 后续请求通过 Cookie(JSESSIONID)自动携带 Session
+}
+```
+
+### 9.2 新建 API 控制器规划
+
+按模块拆分,每个模块一个文件:
+
+| 文件 | 包含接口 |
+|------|---------|
+| auth-controller.ts | register, login |
+| user-controller.ts | queryByPage, add, edit, delete, updateStatus, updatePassword, updateAvatar, queryById |
+| pet-controller.ts | list, add, getById, update, delete, getVaccinations, addVaccination, getDeworming, addDeworming |
+| appointment-controller.ts | create, list, getById, cancel, payDeposit |
+| admin-appointment-controller.ts | listAll, review, handleCancel |
+| boarding-room-controller.ts | listRooms, getStatus |
+| admin-boarding-room-controller.ts | updateStatus |
+| package-controller.ts | listPackages, getPackageById |
+| admin-package-controller.ts | createPackage, updatePackage, deletePackage |
+| admin-schedule-controller.ts | listSchedules, createSchedule, deleteSchedule |
+| admin-user-controller.ts | listUsers, getUserDetail |
+
+---
+
+## 10. 设计主题
+
+### 10.1 主题色
+
+| 变量 | 值 | 用途 |
+|------|-----|------|
+| --el-color-primary | #e34889 | Element Plus 主色调 |
+| --el-color-primary-light | #f06292 | 浅色变体 |
+| --el-color-primary-dark | #c2185b | 深色变体 |
+| 渐变 | linear-gradient(135deg, #db2777, #be185d) | 按钮/重点元素 |
+
+### 10.2 已在 LoginView 中的设计模式
+
+- 背景:渐变色 `linear-gradient(135deg, #fdf2f8, #fce7f3, #fbcfe8)`
+- 卡片:毛玻璃效果(background: rgba(255,255,255,0.9) + backdrop-filter)
+- 输入框:粉色边框 `rgba(219, 39, 119, 0.15)`
+- 按钮:粉色渐变
+- 装饰:浮动渐变色圆形装饰
+
+---
+
+## 11. 构建与开发配置
+
+### 11.1 Vite 代理配置
+
+```typescript
+// vite.config.ts
+server: {
+  proxy: {
+    '/api': {
+      target: 'http://localhost:8080',
+      changeOrigin: true,
+      rewrite: (path) => path.replace(/^\/api/, '')
+    }
+  }
+}
+```
+
+> 注意:后端 context-path 也设为 `/api`,所以 Vite 代理会将 `/api/xxx` 转发到 `http://localhost:8080/xxx`。当后端 context-path 与前端代理前缀都为 `/api` 时,rewrite 会剥离一个 `/api`,导致请求变为 `http://localhost:8080/auth/login` 而非 `http://localhost:8080/api/auth/login`。需确认后端实际路径。
+
+### 11.2 开发命令
+
+| 命令 | 说明 |
+|------|------|
+| npm run dev | 启动开发服务器(HMR) |
+| npm run build | 类型检查 + 生产构建 |
+| npm run preview | 预览生产构建 |
+| npm run api:gen | 从 OpenAPI 规范生成 API 代码 |
+
+### 11.3 Orval 配置
+
+```typescript
+// orval.config.ts
+export default defineConfig({
+  'your-api': {
+    input: {
+      target: 'http://localhost:8080/v3/api-docs',  // OpenAPI JSON 地址
+    },
+    output: {
+      mode: 'tags',           // 按标签拆分
+      client: 'axios',
+      target: './src/api/client.ts',
+      schemas: './src/api/models',
+      clean: true,
+      override: {
+        mutator: {
+          path: './src/util/axios-instance.ts',
+          name: 'customAxiosInstance',
+        },
+      },
+    },
+    hooks: {
+      afterAllFilesWrite: 'prettier --write',
+    },
+  },
+})
+```
+
+---
+
+## 12. 现有代码适配说明
+
+### 12.1 当前已实现的功能
+
+| 模块 | 已实现 | 待实现 |
+|------|--------|--------|
+| 路由 | userRoutes + adminRoutes 基础结构 | 完整路由表(预约/订单/宠物/个人中心) |
+| 布局 | UserLayout(顶部导航) + AdminLayout(侧边栏+顶栏) | 完善菜单项 |
+| 登录 | LoginView(登录+注册 tab) | - |
+| 用户管理 | UserView(CRUD + 搜索 + 分页 + 状态切换) | - |
+| 状态管理 | useLoginUserStore + useMetaStore | - |
+| API | auth-controller + user-controller | pet/appointment/boarding-room/package/schedule controllers |
+| 导航守卫 | requiresAdmin 校验 | 普通页面登录校验 |
+
+### 12.2 待实现模块优先级
+
+| 优先级 | 模块 | 说明 |
+|--------|------|------|
+| P0 | 服务预约(寄养+洗护) | 核心业务 |
+| P0 | 订单管理(用户侧+后台) | 核心业务 |
+| P0 | 宠物档案 CRUD | 核心业务 |
+| P1 | 房态管理(后台日历) | 商家必备 |
+| P1 | 套餐配置(后台) | 商家必备 |
+| P1 | 排班管理(后台) | 商家必备 |
+| P2 | 个人中心 | 用户信息管理 |
+| P2 | 商家用户详情 | 查看用户宠物 |
+
+---
+
+## 13. 组件交互数据流
+
+### 13.1 寄养预约完整数据流
+
+```
+BookingView
+  └─→ 用户点击"寄养服务"
+      └─→ router.push('/booking/boarding')
+          └─→ BoardingBookingView (Step 1: 选择套餐)
+              ├─→ API: GET /api/packages?type=BOARDING
+              ├─→ 用户选择套餐 → 保存到局部状态
+              └─→ Step 2: 选择房型与日期
+                  ├─→ API: GET /api/boarding-rooms
+                  ├─→ RoomCalendar 组件展示房态
+                  │   └─→ 用户选择日期
+                  ├─→ 实时计算总价
+                  └─→ Step 3: 选择宠物
+                      ├─→ API: GET /api/pets
+                      ├─→ PetSelector 组件
+                      └─→ Step 4: 确认提交
+                          ├─→ API: POST /api/appointments
+                          └─→ PaymentDialog 弹窗
+                              └─→ API: POST /api/appointments/{id}/pay-deposit
+                                  └─→ 成功 → router.push('/orders')
+```
+
+### 13.2 订单取消数据流
+
+```
+OrderListView
+  └─→ 用户点击"申请取消"
+      └─→ ElMessageBox.prompt("请输入取消原因")
+          └─→ 确认 → API: POST /api/appointments/{id}/cancel
+              └─→ 成功 → ElMessage.success → 刷新列表
+```
+
+### 13.3 后台审核数据流
+
+```
+AdminOrderListView
+  └─→ 管理员点击"审核"
+      └─→ 对话框:通过(默认)/ 拒绝 + 填写原因
+          └─→ 确认 → API: PUT /api/admin/appointments/{id}/review
+              └─→ 成功 → ElMessage.success → 刷新列表
+```
+
+---
+
+## 14. 类型定义汇总
+
+### 14.1 自定义类型(type/index.ts)
+
+```typescript
+// 当前已定义
+export interface User {
+  id: string
+  name: string
+  avatar?: string
+  role: 'admin' | 'user' | 'guest'
+}
+
+export interface LoginUser {
+  isLogin: boolean
+  user?: User
+}
+```
+
+### 14.2 待补充类型
+
+> **注意**: 后端 Java 实体类 `Package` 已重命名为 `ServicePackage`(与 `java.lang.Package` 冲突),`dto/package/` 和 `vo/package/` 已重命名为 `servicePackage/`(`package` 为 Java 关键字)。但这些变更不影响 API 端点路径(仍为 `/api/packages/**`)和 Orval 生成的 TypeScript 类型,前端无需调整。
+
+```typescript
+// 宠物相关
+export interface Pet {
+  id: string
+  name: string
+  breed: string
+  age: number
+  weight: number
+  gender: 'MALE' | 'FEMALE'
+  notes?: string
+}
+
+// 套餐相关
+export interface Package {
+  id: string
+  type: 'BOARDING' | 'GROOMING'
+  name: string
+  price: number
+  description?: string
+  durationDays?: number
+  isActive: boolean
+}
+
+// 房型相关
+export interface BoardingRoom {
+  id: string
+  name: string
+  capacity: number
+  pricePerNight: number
+  description?: string
+}
+
+// 房态相关
+export interface RoomStatus {
+  date: string
+  status: 'AVAILABLE' | 'OCCUPIED'
+}
+
+// 预约订单相关
+export interface Appointment {
+  id: string
+  userId: string
+  petId: string
+  packageId: string
+  roomId?: string
+  type: 'BOARDING' | 'GROOMING'
+  startDate?: string
+  endDate?: string
+  appointmentTime?: string
+  status: 'PENDING' | 'CONFIRMED' | 'CANCELLED' | 'COMPLETED' | 'CANCEL_REQUESTED'
+  deposit: number
+  depositPaid: boolean
+  totalPrice: number
+  cancelReason?: string
+  rejectReason?: string
+  createdAt: string
+}
+
+// 排班相关
+export interface Schedule {
+  id: string
+  designerName: string
+  workDate: string
+  timeSlot: 'MORNING' | 'AFTERNOON' | 'FULL_DAY'
+  isAvailable: boolean
+}
+```

+ 163 - 0
work.md

@@ -0,0 +1,163 @@
+# 开发任务计划
+
+基于 `uiDesign.md` 分析当前项目状态,按优先级规划开发任务。
+
+---
+
+## 当前已实现功能
+
+| 模块 | 内容 |
+|------|------|
+| 路由 | userRoutes(首页/关于)+ adminRoutes(用户管理/其他)基础结构 |
+| 布局 | UserLayout(顶部导航) + AdminLayout(侧边栏+顶栏) |
+| 登录 | LoginView(登录+注册 tab) |
+| 用户管理 | UserView(CRUD + 搜索 + 分页 + 状态切换) |
+| 状态管理 | useLoginUserStore + useMetaStore |
+| API | auth-controller + user-controller |
+| 导航守卫 | requiresAdmin 校验 |
+| 类型 | User / LoginUser |
+
+---
+
+## 任务清单
+
+### 阶段一:P0 — 核心业务(优先级最高)
+
+#### 任务 1.1:补充类型定义
+- **文件**: `src/type/index.ts`
+- **内容**: 补充 Pet、Package、BoardingRoom、RoomStatus、Appointment、Schedule 接口定义
+- **参考**: uiDesign.md §14.2
+
+#### 任务 1.2:扩展路由表
+- **文件**: `src/router/index.ts`
+- **内容**:
+  - userRoutes 新增:预约(booking/boarding/grooming)、订单列表/详情、宠物 CRUD、个人中心
+  - adminRoutes 新增:订单审核、房态管理、排班管理、套餐配置、用户详情
+  - 补充各路由 meta.title / meta.icon
+
+#### 任务 1.3:新建 API 控制器
+- **文件**:
+  - `src/api/pet-controller.ts`
+  - `src/api/appointment-controller.ts`
+  - `src/api/boarding-room-controller.ts`
+  - `src/api/package-controller.ts`
+  - `src/api/schedule-controller.ts`
+  - 以及 admin 前缀的对应控制器
+- **方式**: 待后端就绪后运行 `npm run api:gen` 生成;或先行手动编写接口定义
+- **参考**: uiDesign.md §9.2
+
+#### 任务 1.4:公共组件开发
+- **文件**: `src/components/`
+  - `PaymentDialog.vue` — 模拟支付弹窗
+  - `RoomCalendar.vue` — 房态日历组件
+  - `PetSelector.vue` — 宠物选择器
+- **参考**: uiDesign.md §8
+
+#### 任务 1.5:服务预约模块
+- **文件**: `src/view/booking/`
+  - `BookingView.vue` — 选择服务类型(寄养/洗护)
+  - `BoardingBookingView.vue` — 寄养预约(4 步 Stepper)
+  - `GroomingBookingView.vue` — 洗护预约(4 步 Stepper)
+- **参考**: uiDesign.md §7.3
+
+#### 任务 1.6:订单管理模块(用户侧)
+- **文件**: `src/view/order/`
+  - `OrderListView.vue` — 我的预约列表(卡片+状态筛选+分页)
+  - `OrderDetailView.vue` — 订单详情(含条件按钮逻辑)
+- **参考**: uiDesign.md §7.4
+
+#### 任务 1.7:宠物档案模块
+- **文件**: `src/view/pet/`
+  - `PetListView.vue` — 宠物列表
+  - `PetCreateView.vue` — 新增宠物
+  - `PetDetailView.vue` — 宠物详情(含疫苗/驱虫记录)
+  - `PetEditView.vue` — 编辑宠物
+- **参考**: uiDesign.md §7.5
+
+---
+
+### 阶段二:P1 — 商家必备
+
+#### 任务 2.1:商家后台 — 订单审核
+- **文件**: `src/view/admin/`
+  - `AdminOrderListView.vue` — 订单审核列表(表格+筛选+审核/处理取消对话框)
+  - `AdminOrderDetailView.vue` — 订单审核详情
+- **参考**: uiDesign.md §7.7.1 ~ §7.7.2
+
+#### 任务 2.2:商家后台 — 房态管理
+- **文件**: `src/view/admin/AdminRoomCalendarView.vue`
+- **内容**: 房型选择 + 月份选择 + 日历视图(引用 RoomCalendar 组件)
+- **参考**: uiDesign.md §7.7.3
+
+#### 任务 2.3:商家后台 — 排班管理
+- **文件**: `src/view/admin/AdminScheduleListView.vue`
+- **内容**: 月份筛选 + 排班表格 + 新增弹窗 + 删除
+- **参考**: uiDesign.md §7.7.4
+
+#### 任务 2.4:商家后台 — 套餐配置
+- **文件**: `src/view/admin/`
+  - `AdminPackageListView.vue` — 套餐列表
+  - `AdminPackageCreateView.vue` — 新增套餐
+  - `AdminPackageEditView.vue` — 编辑套餐
+- **参考**: uiDesign.md §7.7.5
+
+---
+
+### 阶段三:P2 — 用户信息
+
+#### 任务 3.1:个人中心模块
+- **文件**: `src/view/profile/`
+  - `ProfileView.vue` — 个人信息展示
+  - `ProfileEditView.vue` — 修改个人资料
+  - `PasswordEditView.vue` — 修改密码
+- **参考**: uiDesign.md §7.6
+
+#### 任务 3.2:商家后台 — 用户详情
+- **文件**: `src/view/admin/AdminUserDetailView.vue`
+- **内容**: 用户信息 + 该用户的宠物档案列表
+- **参考**: uiDesign.md §7.7.7
+
+---
+
+### 阶段四:完善与优化
+
+#### 任务 4.1:布局完善
+- 梳理 UserLayout 导航菜单项(添加订单/宠物/个人中心入口)
+- 完善 AdminLayout 侧边栏菜单项
+- 响应式适配
+
+#### 任务 4.2:导航守卫增强
+- 添加普通页面登录校验(非 admin 页面也需登录才能访问预约/订单/宠物等功能)
+- 参考: uiDesign.md §3.2
+
+#### 任务 4.3:主题色统一
+- 将 `#e34889` 主题色应用到所有页面
+- 统一按钮、输入框、卡片样式风格
+- 参考: uiDesign.md §10
+
+#### 任务 4.4:新建 Store
+- `useAppointmentStore` — 预约流程状态管理
+- `usePetStore` — 宠物列表缓存
+- 参考: uiDesign.md §5.3
+
+---
+
+## 执行顺序建议
+
+```
+阶段一 (P0) → 阶段二 (P1) → 阶段三 (P2) → 阶段四 (优化)
+```
+
+每个阶段内部按任务编号顺序执行,但同一阶段内的独立任务可并行开发。
+
+---
+
+## 后端设计变更(需知晓)
+
+| 变更项 | 原名称 | 现名称 | 影响 |
+|--------|--------|--------|------|
+| Entity 类名 | `Package` | `ServicePackage` | 不影响 API 端点 `/api/packages/**` |
+| DTO 包路径 | `dto/package/` | `dto/servicePackage/` | Orval 生成的 schema 名称可能含 `ServicePackage` |
+| VO 包路径 | `vo/package/` | `vo/servicePackage/` | 同上 |
+
+> 以上变更**不**影响前端开发的 API 调用和类型定义。API 端点、请求/响应 JSON 结构均保持不变。