# XinAdmin XinAdmin is a full-stack development framework: PHP8.2 + Laravel12 + React19 + TypeScript + Ant Design6 + Zustand + Tailwind CSS4. Licensed under MIT, free for commercial use without authorization. ## Built-in Features - Dashboard: Echarts-based dashboards with demo pages - Administrators: Backend user management with groups, permissions, and settings - Role & Department Management: Role-based menu permission control, enterprise org structure - System Settings: Visual form-based server variable configuration - File Management: Backend file manager with folders, multi-select, grouping - Dictionary Management: Maintenance of frequently used static data - Mail & Storage Configuration: Visual config and testing for Laravel mail/filesystem - AI Configuration: Visual config and testing for Laravel AI SDK - Frontend Members: Permission, grouping, lists, balance records # AnnoRoute AnnoRoute is a PHP 8 Attribute-based route registration module. Routes are declared via controller annotations — no manual route files needed. Sanctum auth and permission verification are auto-integrated. ## Usage - `#[GetRoute]` / `#[PostRoute]` / `#[PutRoute]` / `#[DeleteRoute]` on methods declare HTTP routes - The `authorize` parameter controls access: `'query'` becomes ability `prefix.query`, `false` makes a route public - `#[RequestAttribute]` params: `routePrefix`, `abilitiesPrefix`, `middleware` (string|array), `authGuard` (?string) - Method attributes share: `route` (path appended to prefix), `authorize` (string|bool), `middleware`, `where` (regex array) - Final route = `routePrefix + route`; final ability = `abilitiesPrefix + '.' + authorize` - When `authorize` is not falsy, `auth:sanctum` + `authGuard` + `abilities:` middleware are auto-assembled - Extend `Modules\Common\Http\Controllers\BaseController` for `success()` / `error()` response helpers # Frontend Source lives in `web/`. Bundled with Vite, outputting to `public/`. Package manager: pnpm. ## Directory Structure | Directory | Purpose | |-----------|---------| | `web/api/` | Typed Axios wrappers per backend module | | `web/components/` | Reusable UI: `AuthButton`, `DictTag`, `IconFont`, `XinForm`, `XinTable` | | `web/domain/` | TypeScript interfaces for API models | | `web/hooks/` | `useAuth`, `useLanguage`, `useMobile`, `useRequest` | | `web/layout/` | Layout engine (4 modes), menu, header, breadcrumbs, theme | | `web/locales/` | i18n (i18next), zh_CN + en_US | | `web/pages/` | Auto-discovered page components (file-system routing) | | `web/router/` | React Router v7 `createBrowserRouter` | | `web/stores/` | Zustand: `global` (app/theme), `user` (auth/perms), `dict` (cache) | | `web/utils/` | Axios instance with dedup, auth headers, error handling | ## Key Conventions - Path alias `@/` → `web/` - Zustand stores: `State` + `Actions` → `persist` + `devtools` → localStorage - Access stores via selector: `useXxxStore(state => state.field)` - All user-facing text via `useTranslation()` (react-i18next) - Locale files mirror page paths: `pages/system/user.tsx` → `locales/zh_CN/system/user.ts`, key prefix `system.user` - All keys dot-separated, double quotes, 2-space indent. See `@skill:xinadmin-development` for details - Permission checks: `` or `useAuth().auth('permission')` - HTTP client auto-attaches `Authorization: Bearer`, `User-Language`, handles 401 auto-logout - Pages in `web/pages/` are auto-routed; `index.tsx` maps to parent directory; root `/` → `/dashboard/analysis` - Pages outside layout: add to `excludePaths` array in router config # Antd Ant Design 6 is the UI component library. Components are imported from `antd` and themed via `` with tokens from `web/layout/theme.ts`. ## Key Conventions - Use `antd` MCP tools (`antd_info`, `antd_doc`, `antd_demo`) to verify component APIs before writing code - Never use deprecated props or components — check with `antd_changelog` when upgrading or referencing older examples - Theme tokens flow: `web/layout/theme.ts` → `` → Ant Design components - Common components: `Table`, `Form`, `Modal`, `Drawer`, `Button`, `Input`, `Select`, `DatePicker`, `Switch`, `Tag`, `Card`, `App` ... # Layout Wraps authenticated pages. Supports 4 modes set via global store: `side` (default), `top`, `mix`, `columns`. Menus are fetched from `/system/menu` and stored in `LayoutContext` (React Context). Menu type: `'menu'` (folder), `'route'` (page), `'rule'` (perm-only). Server filters by user role — no client-side filtering needed. Labels support i18n via `node.local`. Theme tokens (20+ properties) are managed in `web/layout/theme.ts`, applied via Ant Design ``, persisted to localStorage under `global-storage`. # XinForm And XinTable Two declarative JSON-driven CRUD components. Define columns once with metadata — the same definition drives table display, search form, and create/edit forms. ## XinForm Use for settings/config pages or standalone forms. Supports 3 layout modes: `'Form'` (inline), `'ModalForm'`, `'DrawerForm'`. ```tsx New} modalProps={{ title: 'Create User', width: 600 }} onFinish={async (values) => { await save(values); return true; }} /> ``` Key `FormColumn` fields: `dataIndex` (supports nested paths `['a','b']`), `valueType` (26 types: `text`, `password`, `select`, `date`, `switch`, etc.), `fieldProps`, `fieldRender` (custom render), `dependency` (field linkage: `{ dependencies, visible?, disabled?, fieldProps? }`), `hideIn*` visibility flags. `formRef` exposes `open()`, `close()`, `isOpen()`, `setLoading()` plus all Ant Design `FormInstance` methods. ## XinTable Use for standard CRUD pages (list + create + update + delete). Auto-handles API calls, permissions, search, and toolbar. ```tsx api="/system/user" columns={[ { title: 'ID', dataIndex: 'id', hideInForm: true, width: 80 }, { title: 'Username', dataIndex: 'username', valueType: 'text', rules: [{ required: true }] }, { title: 'Status', dataIndex: 'status', valueType: 'radio', render: (v) => {v === 1 ? 'Active' : 'Inactive'} }, ]} rowKey="id" accessName="system.user" formProps={{ grid: true, colProps: { span: 12 }, layout: 'vertical' }} modalProps={{ width: 800 }} /> ``` Required props: `api` (REST endpoint), `accessName` (permission prefix), `rowKey` (PK field), `columns`. Default REST behavior — `GET {api}` for list, `POST {api}` for create, `PUT {api}/{id}` for update, `DELETE {api}/{id}` for delete. Add/edit/delete buttons auto-wrapped in ``. Customize with: `handleRequest` (full custom fetch), `requestParams` (transform before send), `handleFinish` (custom submit), `actionBarRender` / `toolBarRender` / `operateRender` (slot overrides). ## Choosing Between Them - **XinTable**: Full CRUD pages (users, roles, dicts, files) - **XinForm** (inline/ModalForm): Settings pages with a single form (mail, storage, AI config) - **XinForm** (ModalForm + trigger): Add/edit without a table (dept management) - Use `hideInForm` / `hideInTable` / `hideInSearch` to control per-context visibility # Development Workflow When building a new CRUD feature, follow this four-phase workflow. See `@skill:xinadmin-development` for complete details. 1. **Database Migration** — create table structure, indexes, foreign keys 2. **Backend** — Controller (AnnoRoute attributes), Model, FormRequest 3. **Frontend** — Page (file-system routing), Domain types, API wrappers, i18n 4. **Menu & Permissions** — seeder menu entry + rules, menu translation keys