feat: 更新登录页面和项目文档
All checks were successful
Auto Deploy / build-and-deploy (push) Successful in 32s
All checks were successful
Auto Deploy / build-and-deploy (push) Successful in 32s
- 添加 CLAUDE.md 项目文档 - 添加自动部署脚本 - 修改登录页面"其他登录方式"文本 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
201
CLAUDE.md
Normal file
201
CLAUDE.md
Normal file
@@ -0,0 +1,201 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
This is a multi-tenant service management platform ("百业到家") built with Ant Design Pro, React 19, TypeScript, and UmiJS Max framework. The application uses dynamic routing loaded from a backend API and implements a comprehensive permission system.
|
||||
|
||||
## Development Commands
|
||||
|
||||
```bash
|
||||
# Start development server (with mocks)
|
||||
pnpm dev
|
||||
# or
|
||||
pnpm start
|
||||
|
||||
# Start development server (without mocks, connects to backend)
|
||||
pnpm start:dev
|
||||
|
||||
# Build for production
|
||||
pnpm build
|
||||
|
||||
# Lint (Biome + TypeScript check)
|
||||
pnpm lint
|
||||
|
||||
# Run tests
|
||||
pnpm test
|
||||
|
||||
# Run tests with coverage
|
||||
pnpm test:coverage
|
||||
|
||||
# Type check only
|
||||
pnpm tsc
|
||||
```
|
||||
|
||||
**Important**: This project uses **pnpm** as the package manager, not npm or yarn.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Dynamic Routing System
|
||||
|
||||
Routes are **not** statically defined in `config/routes.ts` (most routes are commented out). Instead, routes are dynamically loaded from the backend API:
|
||||
|
||||
1. On app initialization, `getInfo()` fetches user permissions and menu structure
|
||||
2. `patchClientRoutes()` in `src/app.tsx` transforms backend menu data into UmiJS routes
|
||||
3. `loopMenuItem()` in `src/utils/menuUtils.tsx` recursively converts menu items to route objects
|
||||
4. Routes are lazy-loaded using `React.lazy(() => import('@/pages/${component}'))`
|
||||
|
||||
**When adding new pages**: Create the page component in `src/pages/`, then configure the route in the backend system (not in code).
|
||||
|
||||
### Multi-Tenant Architecture
|
||||
|
||||
Every API request includes a `tenant-id` header. Tenant information is:
|
||||
- Stored in web-storage-cache with key `CACHE_KEY.TenantId`
|
||||
- Set during login via `setTenantId()`
|
||||
- Automatically added to all requests by the request interceptor in `src/app.tsx`
|
||||
|
||||
### Authentication Flow
|
||||
|
||||
1. User logs in with tenant name, username, and password (password is RSA encrypted via JSEncrypt)
|
||||
2. Backend returns `accessToken` and `refreshToken`
|
||||
3. Tokens stored in web-storage-cache (see `src/utils/auth.ts`)
|
||||
4. All requests include `Authorization: Bearer ${accessToken}` header
|
||||
5. On 401 response, automatically attempts token refresh using `refreshToken`
|
||||
6. If refresh fails, redirects to login page
|
||||
|
||||
**Token refresh logic** is in `src/requestErrorConfig.ts` with request queuing to prevent duplicate refresh attempts.
|
||||
|
||||
### Request Interceptors
|
||||
|
||||
All API requests are automatically modified (see `src/app.tsx`):
|
||||
- **API prefix**: `/admin-api` is prepended to all URLs (unless already present)
|
||||
- **Headers**: `Authorization`, `tenant-id`, and `Accept` headers are added
|
||||
- **Parameter serialization**: Arrays are serialized specially:
|
||||
- `createTime` arrays become `createTime[0]` and `createTime[1]`
|
||||
- Other arrays become `key[]` format
|
||||
|
||||
### Caching Strategy
|
||||
|
||||
Uses `web-storage-cache` library (see `src/hooks/web/useCache.ts`):
|
||||
- `CACHE_KEY.USER`: Current user info
|
||||
- `CACHE_KEY.ROLE_ROUTERS`: Dynamic menu/route data
|
||||
- `CACHE_KEY.ACCESS_TOKEN` / `CACHE_KEY.REFRESH_TOKEN`: Auth tokens
|
||||
- `CACHE_KEY.DICT_CACHE`: Dictionary/enum data loaded on app init
|
||||
- `CACHE_KEY.LoginForm`: Remember me functionality (password encrypted)
|
||||
|
||||
### State Management
|
||||
|
||||
- **UmiJS Model Plugin**: For global state (see `src/app.tsx` - `initialState`)
|
||||
- **Custom Hooks**: In `src/hooks/stores/` (e.g., `useDictStore` for dictionary management)
|
||||
- **Web Storage Cache**: For persistent data across sessions
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── pages/ # Feature pages organized by domain
|
||||
│ ├── ai/ # AI model and sample management
|
||||
│ ├── prod/ # Product and category management
|
||||
│ ├── system/ # System admin (users, roles, menus, tenants, logs, messages)
|
||||
│ ├── trade/ # Order and sales management
|
||||
│ └── user/ # Login page
|
||||
├── services/ # API service layer (mirrors page structure)
|
||||
├── components/ # Reusable components
|
||||
│ ├── Draggable/ # Drag-and-drop components using @dnd-kit
|
||||
│ ├── Upload/ # File/image/video upload components
|
||||
│ ├── GroupTag/ # Tag management components
|
||||
│ └── Tinymce/ # Rich text editor wrapper
|
||||
├── hooks/ # Custom React hooks
|
||||
│ ├── antd/ # Ant Design related hooks
|
||||
│ ├── stores/ # State management hooks
|
||||
│ └── web/ # Web utilities (cache, etc.)
|
||||
├── utils/ # Utility functions
|
||||
│ ├── auth.ts # Token and tenant management
|
||||
│ ├── menuUtils.tsx # Dynamic route conversion
|
||||
│ ├── dict.ts # Dictionary/enum utilities
|
||||
│ └── tree.ts # Tree data structure helpers
|
||||
├── constants/ # Shared constants and enums
|
||||
├── locales/ # i18n translations (zh-CN default)
|
||||
└── app.tsx # App initialization and runtime config
|
||||
```
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
Multiple environment files:
|
||||
- `.env.local` - Local overrides (gitignored)
|
||||
- `.env.dev` - Development environment
|
||||
- `.env.prod` - Production environment
|
||||
|
||||
**Proxy configuration** in `config/proxy.ts`:
|
||||
- `dev`: Points to local backend (currently `http://192.168.1.89:48080`)
|
||||
- `test`: Points to test environment
|
||||
- `pre`: Points to pre-production environment
|
||||
|
||||
Switch environments using `UMI_ENV`:
|
||||
```bash
|
||||
cross-env UMI_ENV=dev pnpm start # Development
|
||||
cross-env UMI_ENV=test pnpm start # Test
|
||||
cross-env UMI_ENV=pre pnpm start # Pre-production
|
||||
```
|
||||
|
||||
## Code Conventions
|
||||
|
||||
### Linting
|
||||
- Uses **Biome** (not ESLint) for linting and formatting
|
||||
- Configured in `biome.json`
|
||||
- Pre-commit hook runs Biome via lint-staged
|
||||
|
||||
### Commit Messages
|
||||
- Uses commitlint with conventional commits
|
||||
- Enforced via Husky pre-commit hook
|
||||
- Format: `type(scope): subject` (e.g., `feat: add user management`)
|
||||
|
||||
### Component Patterns
|
||||
- **ProTable**: Use `EnhancedProTable` wrapper for common table functionality
|
||||
- **Forms**: Use `DrawerForm` or `ModalForm` from `@ant-design/pro-components`
|
||||
- **File Uploads**: Use custom `UploadImages` or `UploadVideo` components in `src/components/Upload/`
|
||||
- **Rich Text**: Use `Tinymce` component wrapper (TinyMCE is in `public/tinymce/`)
|
||||
|
||||
### Service Layer
|
||||
- All API calls go through `src/services/`
|
||||
- Use UmiJS `request` from `@umijs/max` (configured in `src/app.tsx`)
|
||||
- Response format: `{ code: number, data: any, msg: string }`
|
||||
- Success when `code === 0`
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Adding a New Page
|
||||
|
||||
1. Create page component in `src/pages/{domain}/{feature}/index.tsx`
|
||||
2. Create corresponding service in `src/services/{domain}/{feature}/index.ts`
|
||||
3. Configure the menu/route in the backend system (not in code)
|
||||
4. The route will automatically appear after backend configuration
|
||||
|
||||
### Working with Dictionaries/Enums
|
||||
|
||||
Dictionaries are loaded on app init and cached:
|
||||
```typescript
|
||||
import { useDictStore } from '@/hooks/stores/dict';
|
||||
|
||||
const dictStore = useDictStore();
|
||||
const dictData = dictStore.getDictByType('dict_type_key');
|
||||
```
|
||||
|
||||
### File Uploads
|
||||
|
||||
Media files are uploaded via `src/services/infra/file/index.ts` or `src/services/infra/media/index.ts`. Use the Upload components which handle the API integration.
|
||||
|
||||
## Testing
|
||||
|
||||
- Jest configured with `jest.config.ts`
|
||||
- Test files should be colocated with components or in `__tests__` directories
|
||||
- Run single test: `pnpm test -- path/to/test.spec.ts`
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **Node version**: Requires Node.js >= 20.0.0 (see `package.json` engines)
|
||||
- **React 19**: Uses React 19 with `@ant-design/v5-patch-for-react-19` compatibility patch
|
||||
- **Mako bundler**: Uses UmiJS Mako for faster builds (configured in `config/config.ts`)
|
||||
- **Mock data**: Located in `mock/` directory, enabled by default in dev mode
|
||||
- **TinyMCE**: Static files in `public/tinymce/`, Chinese language pack included
|
||||
30
auto-deploy.ps1
Normal file
30
auto-deploy.ps1
Normal file
@@ -0,0 +1,30 @@
|
||||
# Auto Deploy Script for PowerShell
|
||||
$SERVER = "43.139.42.137"
|
||||
$USER = "root"
|
||||
$REMOTE_PATH = "/home/1panel/www/sites/admin.petshy.tashowz.com/index"
|
||||
|
||||
Write-Host "=== Auto Deploy ===" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# 1. Build project
|
||||
Write-Host "Building project..." -ForegroundColor Yellow
|
||||
pnpm build
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "Build failed" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host "Build complete" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# 2. Upload files
|
||||
Write-Host "Uploading files to server..." -ForegroundColor Yellow
|
||||
scp -r dist/* ${USER}@${SERVER}:${REMOTE_PATH}/
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host ""
|
||||
Write-Host "Deploy complete!" -ForegroundColor Green
|
||||
Write-Host "Visit: http://admin.petshy.tashowz.com" -ForegroundColor Cyan
|
||||
} else {
|
||||
Write-Host "Upload failed" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
@@ -143,7 +143,7 @@ const Page = () => {
|
||||
fontSize: 14,
|
||||
}}
|
||||
>
|
||||
其他登录方式
|
||||
其他登录方式111
|
||||
</span>
|
||||
</Divider>
|
||||
<Space align="center" size={24}>
|
||||
|
||||
Reference in New Issue
Block a user