Files
fad_oa/CLAUDE.md

96 lines
4.5 KiB
Markdown
Raw Normal View History

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
福安德综合办公系统 (FAD OA) — 基于 RuoYi-Flowable-Plus 二次开发,面向工程项目的投标管理、进度控制、成本核算及日常 OA 办公。
**Tech Stack**: Spring Boot 2.7 + MyBatis-Plus 3.5 + Flowable 6.8 + Vue 2 + Element UI + MySQL 8.0 + Redis
## Build & Run
```bash
# Backend build (dev profile, skip tests)
mvn clean package -D maven.test.skip=true -P dev
# Backend build (prod)
mvn clean package -D maven.test.skip=true -P prod
# Frontend dev server (port 80)
cd ruoyi-ui && npm run dev
# Frontend lint
cd ruoyi-ui && npm run lint
# Frontend prod build
cd ruoyi-ui && npm run build:prod
```
Active Maven profile defaults to `dev` (`pom.xml` line 72). Backend entry point: `ruoyi-admin/`.
## Database
Init script: `script/sql/mysql/ry-vue-flowable-xg.sql`. Module-specific migrations live in `sql/` (e.g. `oa_approval.sql`, `warehouse_*.sql`, `hrm_*.sql`).
Dev DB: `fad_oa_dev` @ 49.232.154.205:13306
Prod DB: `fad_oa` @ 49.232.154.205:13306
Redis: 49.232.154.205:6379 (password: WANGyu11!)
**Menu SQL pattern**: When adding menus to `sys_menu`, use fixed snowflake IDs (not RAND()). Reference `sql/warehouse_phase0_menu.sql` for the correct pattern. Menu changes require COMMIT + restart backend to flush Redis cache — clearing Redis is not enough on its own.
## Module Architecture
| Module | Purpose |
|--------|---------|
| `ruoyi-admin/` | Spring Boot entry point, YAML configs |
| `ruoyi-framework/` | Security (Sa-Token), interceptors, global config |
| `ruoyi-system/` | Users, roles, menus, depts, dicts, posts |
| `ruoyi-flowable/` | Flowable workflow engine integration |
| `ruoyi-oa/` | Core OA: projects, contracts, bidding, finance, warehouse, approval |
| `ruoyi-ui/` | Vue 2 frontend (Element UI) |
| `fad-hrm/` | HRM: employees, attendance, leave, travel, seal, payroll, flow tasks |
| `fad-app/` | Mobile app API endpoints |
| `fad-export/` | Foreign trade public web pages |
| `fad-rolling-mill/` | Rolling mill business module |
| `klp-wms/` | Warehouse management module |
## Dynamic Menu System (Critical)
Menus are **not hardcoded in Vue Router**. They are stored in `sys_menu` DB table and delivered by `GET /getRouters`. The frontend flow:
1. `ruoyi-ui/src/store/modules/permission.js``GenerateRoutes` action
2. Calls `getRouters()``@/api/menu.js``GET /getRouters`
3. Backend returns JSON with `component` paths (e.g. `"hrm/employee/index"`)
4. `filterAsyncRouter()` resolves strings to actual Vue components via dynamic `import()`
5. Routes are added at runtime via `router.addRoutes()`
**Implication**: Adding a new page requires both a `sys_menu` INSERT (with correct `component` path) AND the actual `.vue` file at `ruoyi-ui/src/views/<component>`. No changes to `router/index.js` are needed for C-type page menus — only hidden/detail routes go there.
F-type menus (buttons) use `perms` field for permission checks (e.g. `system:user:add`). M-type menus are directory containers with no component.
## HRM Module Structure
The HRM module (`fad-hrm/` backend, `ruoyi-ui/src/views/hrm/` frontend) is a self-contained HR system built on a custom flow engine (NOT Flowable — uses its own `hrm_flow_*` tables).
**Two separate approval systems exist**:
- **HRM flow engine**: `hrm_flow_task`, `hrm_flow_instance` etc. — handles leave/travel/seal/reimburse/appropriation workflows. Pages: `hrm/requests/`
- **OA approval center**: `oa_approval_instance` table — lightweight generic approval for purchase/contract. Pages: `oa/approval/`
Both have items named "我的审批" in the menu. They serve different data sources and must NOT be conflated.
## Key Auth Patterns
- Uses **Sa-Token** (not Spring Security), configured in `application.yml`
- `@SaCheckPermission` for API-level permission checks
- Frontend permission checks: `v-hasPermi` directive and `auth.hasPermiOr()` in `@/plugins/auth`
- Menu visibility is controlled by `sys_role_menu` table — role-to-menu many-to-many
## API Response Conventions
The backend uses two response wrappers:
- `TableDataInfo<T>`: `{ total, rows, code, msg }` — paginated lists → frontend accesses `res.rows`
- `R<T>`: `{ data, code, msg }` — single entities → frontend accesses `res.data`
Frontend API modules are in `ruoyi-ui/src/api/`. The axios interceptor in `@/utils/request` unwraps the HTTP response, so `.then(res => ...)` receives the JSON body directly (not the full axios response).