245 lines
11 KiB
Markdown
245 lines
11 KiB
Markdown
# Agent Instructions for Trace Frontend
|
|
|
|
## Build & Development Commands
|
|
|
|
### Development
|
|
```bash
|
|
pnpm dev # Start dev server at http://localhost:5173
|
|
```
|
|
|
|
### Build
|
|
```bash
|
|
pnpm build # Build for production (outputs to dist/)
|
|
pnpm preview # Preview production build
|
|
```
|
|
|
|
### Testing & Linting
|
|
No test or lint commands are currently configured. When adding tests, use Vitest or Jest.
|
|
|
|
## Project Overview
|
|
|
|
This is a React 19 + TypeScript frontend for the Zhejiang Beifan Trace Coding Platform (溯源赋码平台). It provides:
|
|
- Public query interface for employee permission-code verification
|
|
- Admin dashboard for work-order statistics
|
|
- Permission issuance with automatic employee serial generation
|
|
- Product traceability management and public scan pages
|
|
- Project work-order management for on-site implementation records
|
|
- Aftersales work-order management for admins and assigned work-order roles
|
|
- User authentication and profile management
|
|
|
|
**Tech Stack**: React 19, TypeScript, Vite 7, Ant Design 6, React Router v7, Axios
|
|
|
|
## Code Style Guidelines
|
|
|
|
### File Organization
|
|
```
|
|
src/
|
|
├── components/ # Reusable UI components (AdminLayout, etc.)
|
|
├── pages/ # Page components (Login, Dashboard, etc.)
|
|
├── services/ # API service layer (api.ts with domain-specific APIs)
|
|
├── types/ # TypeScript type definitions (index.ts)
|
|
├── hooks/ # Custom React hooks
|
|
├── utils/ # Utility functions
|
|
├── styles/ # Global CSS files
|
|
├── assets/ # Static assets (images, etc.)
|
|
├── App.tsx # Main app with routes
|
|
└── main.tsx # Application entry point
|
|
```
|
|
|
|
### Imports
|
|
- Use `@/` alias for src directory (configured in vite.config.ts and tsconfig.json)
|
|
- Group imports: React/hooks first, then third-party libraries, then internal imports
|
|
- Example:
|
|
```tsx
|
|
import { useState } from 'react';
|
|
import { Form, Input, Button } from 'antd';
|
|
import { UserOutlined } from '@ant-design/icons';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { authApi } from '@/services/api';
|
|
import type { User } from '@/types';
|
|
```
|
|
|
|
### Naming Conventions
|
|
- **Components**: PascalCase (e.g., `LoginPage`, `AdminLayout`)
|
|
- **Functions/Methods**: camelCase (e.g., `handleLogin`, `loadStats`)
|
|
- **Constants**: UPPER_SNAKE_CASE (e.g., `API_BASE_URL`)
|
|
- **Types/Interfaces**: PascalCase (e.g., `User`, `ProductTrace`, `ApiResponse<T>`)
|
|
- **Files**: PascalCase for components/pages, lowercase for services/utils
|
|
|
|
### TypeScript
|
|
- All new code must be TypeScript
|
|
- Use `interface` for object shapes, `type` for unions/aliases
|
|
- Explicit return types for API functions and handlers
|
|
- Use `any` only as last resort - prefer `unknown` with type guards
|
|
- Strict mode enabled: no unused locals, no unused parameters
|
|
|
|
### Component Patterns
|
|
- Use functional components with hooks
|
|
- For pages: use `function PageName()` (not arrow functions)
|
|
- For layout/reusable components: use `function ComponentName()`
|
|
- Export with `export default ComponentName;`
|
|
- Use Ant Design components via destructuring: `const { Button, Form } = antd;`
|
|
|
|
### Error Handling
|
|
- Use try-catch blocks for async operations
|
|
- Display errors with Ant Design `message.error()`
|
|
- API services throw errors with descriptive messages
|
|
- Global axios interceptor handles 401 (auth) and 404 (not found) automatically
|
|
|
|
### API Services
|
|
- API calls organized by domain in `src/services/api.ts`:
|
|
- `authApi` - Authentication (login, logout, profile)
|
|
- `dashboardApi` - Dashboard statistics
|
|
- `employeeSerialApi` - Employee permission-code management
|
|
- `productTracesApi` - Product traceability
|
|
- `aftersalesApi` - Aftersales work orders (admin + public)
|
|
- `projectOrdersApi` - Project work orders (admin + public)
|
|
- `employeesApi` - Employee management (admin only): create/list/update/delete/reset password
|
|
- `usersApi` - Assignable work-order user picker via `assignable`
|
|
- Auth token automatically added via axios interceptor
|
|
- All API calls return typed responses based on `src/types/index.ts`
|
|
|
|
### Routing
|
|
- Use React Router v7 with `<Routes>` and `<Route>` components
|
|
- Protected routes wrapped with `<PrivateRoute>` component
|
|
- Admin pages wrapped with `<AdminRoutes>` layout component
|
|
- Use `useNavigate()` for programmatic navigation
|
|
- Use `useLocation()` to get current path
|
|
- Public routes (no auth): `/login`, `/query`, `/aftersales/:serialNumber`, `/project-orders/:serialNumber`, `/product-traces/:serialNumber`
|
|
- `PublicQuery` auto-redirects scanned `zjbf-sh-*` serials to `/aftersales/:serialNumber`.
|
|
- `PublicQuery` auto-redirects scanned `zjbf-xm-*` serials to `/project-orders/:serialNumber`.
|
|
- Product trace QR codes use `/product-traces/:serialNumber` directly.
|
|
- Shared public-page chrome (logo + 备案 footer) lives in `components/PublicLayout.tsx`
|
|
- `/admin/employee-serials` is the 权限管理 page despite the legacy route name.
|
|
- Work-order roles should only see/use the aftersales and project work-order modules; admins see all admin menu items.
|
|
|
|
### Roles and Permission Issuance
|
|
- `UserRole` includes system roles `admin`, legacy `technician`, legacy `employee`, and managed work-order roles `software_engineer`, `hardware_engineer`, `business_manager`, `project_manager`.
|
|
- `admin`: full backend access.
|
|
- Managed work-order roles: login access only for assigned aftersales/project work orders.
|
|
- `technician` is legacy-compatible and should not be offered as a new role.
|
|
- `employee` is legacy/no backend login access and should not be offered as a new role.
|
|
- Employee creation fields are name, phone, employee number, position, and role.
|
|
- Permission management creation/edit role choices must be exactly: 软件工程师、硬件工程师、商务经理、项目经理.
|
|
- Password field is required for all four managed work-order roles.
|
|
- Employee creation uses `employeesApi.create`, and the backend automatically creates the employee permission code; do not implement a separate "create then assign code" primary flow.
|
|
- Employee rows should display generated `employeeSerials` from the employee list response.
|
|
- Employee rows should provide a QR-code view for the active employee serial, using `/query?serial=...` as the scan target.
|
|
- Public employee serial queries should show employee name, phone, employee number, and position.
|
|
- Do not reintroduce enterprise/company-code management APIs or UI. The old `companyApi`, `serialApi`, `/admin/manage`, `/api/companies`, and `/api/serials` surfaces were removed.
|
|
|
|
### Aftersales Conventions
|
|
- Aftersales serial format is `zjbf-sh-YYMMDDNN` (daily sequence), e.g. `zjbf-sh-26052801`.
|
|
- Service type values must use `software` / `hardware` / `maintenance`:
|
|
- `software`: 软件故障
|
|
- `hardware`: 硬件故障
|
|
- `maintenance`: 售后维保
|
|
- Aftersales `companyName` is a customer-company text field only. Do not call or recreate company-management APIs from aftersales create/update flows.
|
|
- Use label text `现场情况说明` for `issueDescription` in create/detail/public-confirm views.
|
|
- In admin detail page, use `工单分配` as the UI label for reassign action.
|
|
- Signature display text should be `客户确认签名`.
|
|
- Only admins may create aftersales work orders. Managed work-order roles may only list/view/update/submit work orders assigned to themselves.
|
|
|
|
### Product Traceability
|
|
- Admin route: `/admin/product-traces`.
|
|
- Public route: `/product-traces/:serialNumber`.
|
|
- Manual product serial numbers are required.
|
|
- Form field order must remain: 企业名称、地址、电话、设备信息、质保期、出厂日期、产品序列号、官网链接(可选)、公众号二维码(可选).
|
|
- Official-account QR code images are uploaded to OSS and stored as backend-managed URLs/keys, not inline base64 in regular form payloads.
|
|
|
|
### Project Work Orders
|
|
- Project order serial format is `zjbf-xm-YYMMDDNN`.
|
|
- Project orders are for on-site investigation/implementation records.
|
|
- Only admins may create project work orders. Managed work-order roles may only list/view/update/submit project orders assigned to themselves.
|
|
- Completion requires site images and engineer signature, without customer signature.
|
|
- Site image limit is 18.
|
|
- Completed project orders use status text `已完成`.
|
|
|
|
### State Management
|
|
- Use React hooks (`useState`, `useEffect`) for local component state
|
|
- Authentication state persisted in localStorage via authApi
|
|
- No global state management library currently used
|
|
|
|
### Styling
|
|
- Global styles in `src/styles/global.css`
|
|
- Component-specific CSS in co-located styles directory (e.g., `pages/styles/Login.css`)
|
|
- Import component styles with relative path: `import './styles/PageName.css';`
|
|
- Use Ant Design components for primary UI, custom CSS for layout specifics
|
|
|
|
### Locale & Internationalization
|
|
- Chinese (zh_CN) locale configured globally via `ConfigProvider` in main.tsx
|
|
- All UI text should be in Chinese
|
|
- Ant Design components automatically use Chinese locale
|
|
|
|
## Key Patterns & Conventions
|
|
|
|
### Page Component Structure
|
|
```tsx
|
|
function PageName() {
|
|
const [loading, setLoading] = useState(false);
|
|
const [data, setData] = useState<DataType | null>(null);
|
|
|
|
useEffect(() => {
|
|
loadData();
|
|
}, []);
|
|
|
|
const loadData = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const result = await apiMethod();
|
|
setData(result);
|
|
} catch (error: any) {
|
|
message.error(error.message || '加载数据失败');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (loading) {
|
|
return <Spin size="large" />;
|
|
}
|
|
|
|
return <div>{/* JSX content */}</div>;
|
|
}
|
|
|
|
export default PageName;
|
|
```
|
|
|
|
### Route Guards
|
|
- `<PrivateRoute />` - Redirects to /login if not authenticated
|
|
- `<PublicRoute children={...} />` - Redirects to /admin/dashboard if authenticated
|
|
- Use `<Outlet />` for nested routes
|
|
|
|
### Environment Variables
|
|
- Use Vite's `import.meta.env.VITE_*` pattern
|
|
- Example: `const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api';`
|
|
- Define in `.env` file (not committed to git)
|
|
|
|
## Notes for Agents
|
|
|
|
1. **No tests configured**: When adding test frameworks, update AGENTS.md accordingly
|
|
2. **No linter configured**: Consider adding ESLint and Prettier
|
|
3. **Authentication flow**: Tokens stored in localStorage, added to requests via interceptor
|
|
4. **API proxy**: /api requests proxied to http://localhost:3000 during dev (see vite.config.ts)
|
|
5. **QR Code generation**: Uses `qrcode` library for generating QR codes for serial numbers
|
|
6. **Admin Layout**: Uses Ant Design Layout with Sider navigation and Header
|
|
7. **Type safety**: Always add types for new props, state, and API responses
|
|
|
|
## Common Tasks
|
|
|
|
### Add a new API endpoint
|
|
1. Add interface to `src/types/index.ts`
|
|
2. Add method to appropriate API object in `src/services/api.ts`
|
|
3. Handle errors appropriately with descriptive messages
|
|
|
|
### Add a new page
|
|
1. Create component in `src/pages/PageName.tsx`
|
|
2. Add CSS file in `src/pages/styles/PageName.css`
|
|
3. Add route in `src/App.tsx`
|
|
4. If admin page, wrap in `<AdminRoutes />` and add menu item in `AdminLayout.tsx`
|
|
|
|
### Add a new component
|
|
1. Create in `src/components/ComponentName.tsx`
|
|
2. Add styles in `src/components/styles/ComponentName.css` if needed
|
|
3. Import using `@/components/ComponentName`
|