hookehuyr

docs: 添加项目开发文档和 Claude 配置

- 添加项目根目录 CLAUDE.md
- 添加各模块 CLAUDE.md (api, store, utils)
- 添加 Claude Code 本地配置

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
{
"enableAllProjectMcpServers": true,
"enabledMcpjsonServers": [
"chrome-devtools"
],
"permissions": {
"allow": [
"Bash(git add:*)"
]
}
}
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a Vue 3 + Vite map demo application for interactive maps with integrated audio guides, QR code scanning, and WeChat integration. The project supports multiple deployment targets (dev/oa/walk/xys) and includes features like VR panorama viewing, check-in systems, and audio background playback.
**Tech Stack:**
- Vue 3.2.36 with Composition API
- Vite 2.9.9 for build tooling
- Pinia for state management
- Vue Router 4 with Hash mode
- Vant 4.9.6 (mobile UI components)
- Element Plus (additional UI components)
- AMap (高德地图) integration
- WeChat JS-SDK integration
## Development Commands
### Local Development
```bash
npm run dev # Start dev server (localhost:8006)
npm run start # Start with network access (0.0.0.0:8006)
```
### Build & Deploy
```bash
npm run build # Production build
npm run build-watch # Build with file watch
npm run build_ts # Build with TypeScript checking
npm run serve # Preview production build
```
### Deployment Scripts (automated pipelines)
```bash
npm run dev_upload # Build & deploy to dev server
npm run oa_upload # Build & deploy to OA server
npm run walk_upload # Build & deploy to walk server
npm run xys_upload # Build & deploy to xys server (SSH port 12101)
```
Each upload script:
1. Builds the project
2. Creates `dist.tar.gz` archive
3. SCPs to target server
4. Extracts on remote server
5. Cleans up local files
### Testing
```bash
npm run cypress:open # Open Cypress E2E test runner
```
## Project Architecture
### Directory Structure
```
src/
├── api/ # API endpoint definitions organized by feature
│ ├── B/ # B-side (business) APIs
│ ├── C/ # C-side (customer) APIs
│ ├── common.js # Shared APIs (SMS, upload, tokens)
│ ├── map.js # Map data APIs
│ └── fn.js # API wrapper with error handling
├── components/ # Reusable Vue components
│ ├── Floor/ # Interactive floor plan component
│ ├── VRViewer/ # 360° panorama viewer
│ └── InfoWindow*.vue # Various map info window styles
├── views/ # Page components
│ ├── bieyuan/ # Villa (别院) map views
│ ├── by/ # BY area views
│ ├── checkin/ # Check-in system views
│ └── xys/ # XYS area views
├── store/ # Pinia state management
│ └── index.js # Main store with keep-alive page cache
├── router/ # Vue Router configuration
│ ├── routes/ # Route modules
│ └── methods/ # Router utility functions
├── utils/ # Utility functions
│ ├── axios.js # Axios instance with interceptors
│ └── tools.js # Common helper functions
├── common/ # Shared constants and mixins
├── hooks/ # Vue composables
└── packages/ # Multi-page app entries (mono1, mono2)
```
### Key Architectural Patterns
**API Layer Pattern:**
All API calls follow a consistent pattern using `fn()` wrapper from `@/api/fn.js`:
```javascript
import { fn, fetch } from '@/api/fn';
export const mapAPI = (params) => fn(fetch.get('/srv/?a=map', params));
```
The `fn()` wrapper handles:
- Response validation
- Error handling
- Loading states
- Data transformation
**State Management Pattern:**
Pinia store (`mainStore`) manages:
- `keepPages`: Array of page names to cache with `<keep-alive>`
- Audio player state (single & playlist modes)
- Scroll position restoration for multiple views
- Authentication state
**Routing Pattern:**
- Uses `createWebHashHistory('/index.html')` - all URLs include `#/index.html`
- Dynamic route generation via `generateRoutes()` utility
- Route modules auto-imported from `@/router/routes/modules/**/*.js`
- 404 page used as intermediate for dynamic route injection
**Component Auto-Import:**
Vant and Element Plus components are auto-imported via `unplugin-vue-components`. No manual imports needed.
## Important Configuration
### Path Aliases (configured in vite.config.js)
```javascript
@/ src/
@components/ src/components/
@composables/ src/composables/
@utils/ src/utils/
@images/ images/
@css/ src/assets/css/
@mock/ src/assets/mock/
common/ src/common/
```
### Environment Variables
Key variables in `.env` and `.env.development`:
- `VITE_PORT`: Dev server port (default: 8006)
- `VITE_PROXY_TARGET`: Backend API proxy target
- `VITE_PROXY_PREFIX`: API request prefix (`/srv/`)
- `VITE_OUTDIR`: Build output directory name (`map`)
- `VITE_APPID`: WeChat app ID
- `VITE_OPENID`: Test WeChat open ID
### Axios Interceptors (src/utils/axios.js)
**Request interceptor:**
- Adds default param `f: 'tools'`
- Adds timestamp to GET requests (cache busting)
- Serializes POST data with `qs.stringify()` (except upload endpoints)
- Merges URL params with config params
**Response interceptor:**
- Handles authentication failures
- Redirects to login on 401/403
- Global error handling
## Key Features & Components
### Map Integration
- **AMap (高德地图)**: Primary map provider
- **Custom Info Windows**: Multiple styles (Lite, Warn, Yard, Popup)
- **Floor Plans**: Interactive SVG floor plans (`components/Floor/`)
- **Coordinate System**: Uses grid-based coordinates (see README.md for examples)
### Audio System
Dual-mode audio player managed in Pinia store:
- **Single Mode**: Background audio for individual locations
- **Playlist Mode**: Audio lists for tours
- Components: `audioBackground.vue`, `audioBackground1.vue`, `audioList.vue`
- State: `audio_entity`, `audio_status`, `audio_list_entity`, `audio_list_status`
### VR Panorama
- **Library**: `@photo-sphere-viewer/*` plugins
- **Component**: `components/VRViewer/index.vue`
- Features: Markers, gyroscope, gallery, stereo, virtual tour
### QR Code Scanning
- **Library**: `@zxing/library`
- **Views**: `scan.vue` in bieyuan/, by/, checkin/
### Check-in System
- **Views**: `checkin/index.vue`, `checkin/scan.vue`, `checkin/info_w.vue`
- **API**: `@/api/checkin.js`
## Common Patterns
### Creating New API Endpoints
```javascript
// src/api/feature.js
import { fn, fetch } from '@/api/fn';
const Api = {
FEATURE: '/srv/?a=feature',
};
export const featureAPI = (params) => fn(fetch.get(Api.FEATURE, params));
```
### Creating New Views
1. Create view file in `src/views/feature/`
2. Add route module in `src/router/routes/modules/feature/index.js`
3. Add to keep-alive cache if needed: `store.keepThisPage()`
### Using Map Data
```javascript
import { mapAPI } from '@/api/map.js';
const { data } = await mapAPI({ id: locationId });
// Process map data (coordinates, markers, etc.)
```
### WeChat Integration
- **Config**: `src/api/wx/config.js`
- **JS API List**: `src/api/wx/jsApiList.js`
- **Payment**: `src/api/wx/pay.js`
- Initialized in `App.vue` onMounted
## Code Style Notes
- **Vue Setup**: Uses `<script setup>` syntax
- **Component Names**: Uses `DefineOptions()` plugin to support `name` option in setup scripts
- **Less Preprocessor**: Global styles imported via `additionalData` in vite.config.js
- **Auto-imports**: Vue, VueRouter APIs auto-imported (see `src/auto-imports.d.ts`)
- **Legacy Support**: Uses `@vitejs/plugin-legacy` for older browser support (commented out in current config)
## Known Issues & Considerations
### Keep-Alive Cache Quirk
From `src/store/index.js:25`:
```javascript
keepPages: ['default'], // 很坑爹,空值全部都缓存
```
Empty array causes all pages to cache. Must include at least `'default'` as placeholder.
### Route Hash Mode
All routes include `#/index.html` prefix:
- Full URL example: `http://localhost:8006/index.html#/index.html/views/page`
- When generating routes or links, must include this prefix
### Dynamic Route Generation
Routes loaded asynchronously via mock data (`src/mock/routes.js`) and processed through `generateRoutes()` utility. 404 page acts as intermediate to avoid white screen on refresh.
### Multi-Page Architecture (commented out)
Project structure supports multiple entry points (`src/packages/mono1/`, `src/packages/mono2/`), but currently using single-page setup with `index.html` as only entry.
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Feb 9, 2026
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #3942 | 11:03 AM | ✅ | Created comprehensive project documentation | ~900 |
</claude-mem-context>
\ No newline at end of file
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Feb 9, 2026
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #3942 | 11:03 AM | ✅ | Created comprehensive project documentation | ~900 |
</claude-mem-context>
\ No newline at end of file
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Feb 9, 2026
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #3942 | 11:03 AM | ✅ | Created comprehensive project documentation | ~900 |
</claude-mem-context>
\ No newline at end of file
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Feb 9, 2026
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #3942 | 11:03 AM | ✅ | Created comprehensive project documentation | ~900 |
</claude-mem-context>
\ No newline at end of file