Files
QiufengandClaude Opus 4.8 5e51dc3f56 SNAPSHOT W7 已部署稳定态 — 凯迪ERP+OA一体化平台 (MET 73.3%)
恢复点(restore point)。别人改崩后可 git reset --hard 回到此提交。

== 此快照内容 ==
- 后端 oa-backend: 734 控制器 / 711 实体 (Spring Boot 3.2.5 + SQLite, 端口8091)
- 前端 modern-ui/app: Vue3+Vite, 约700页 (构建产物已在 oa-backend/src/main/resources/static)
- 数据库 oa-backend/data/oa.db: 含全部演示数据 (强制入库, 6.6MB)
- 交接文档 go.md + go-code-reference/endpoints/entities/database.md
- 多代理建设脚本 .claude/wf-*.js

== 状态 ==
- 对 凯迪科技ERP_20260507.xlsx 合规 MET ~73.3% (PARTIAL 75: 34可建+6种子/bug+35外部硬天花板)
- 安全: 5轮红队+5轮复检, default-deny分级鉴权, 连续零可利用
- W3~W7 累计补完436缺口; W8末轮(40缺口)为半成品(源码树可编译但未集成)
- 运行: cd oa-backend; java -jar build/libs/oa-backend-0.1.0.jar --server.port=8091; admin/123456

== 排除(gitignore, 可再生) ==
node_modules / oa-backend/build / .jdks / *.log / Backup-ERP-* / 弃用的OFBiz核心(只保留modern-ui)
完整文件夹备份见同目录 Backup-ERP-20260615-191517/ (含上述全部, 仅缺 node_modules)

时间戳: 20260615-191517

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 19:19:15 +08:00

18 KiB

UI Handbook

This handbook defines how business pages in the modern ERP app should use Element Plus through the local ERP wrapper layer. It is the practical companion to DESIGN.md.

Wrapper-First Rule

  • Start with src/components/erp before composing raw Element Plus controls.
  • Use wrappers for shared behavior, state handling, density, labels, and administrator-facing copy.
  • Use local page CSS only for page-specific grid placement or one-off domain composition.
  • Do not scatter colors, spacing, radius, table density, or state styles across business pages.
  • When two pages need the same arrangement, promote it into an ERP wrapper or a class in src/styles/erp-patterns.css.

Style and Token Ownership

  • src/styles/erp-ui.css is the style entry and imports the ERP design system files.
  • src/styles/tokens.css owns color, spacing, radius, typography, control height, table height, card density, and shadows.
  • src/styles/base.css owns global element defaults such as box sizing, body typography, and base surface color.
  • src/styles/element-overrides.css maps Element Plus variables and base component styling to ERP tokens.
  • src/styles/erp-patterns.css owns reusable ERP classes such as forms, panels, cards, metrics, tables, status lines, menus, breadcrumbs, drawers, upload, empty, skeleton, and detail descriptions.
  • src/styles/modern.css owns the application shell, top menu, left menu, route layout, and existing domain-specific layout patterns, and is imported directly by src/main.ts.

Use tokens such as --erp-space-3, --erp-control-height, --erp-table-row-height, --erp-radius-xs, --erp-color-border-soft, and --erp-color-surface-quiet instead of hard-coded values.

Page Structure

Use this order for business pages:

  1. ErpPageHeader for module position, domain title, short operational description, and the one primary command for the page.
  2. Search or filter area with ErpSearchForm when fields come from metadata, or wrapper-owned compact controls when the page only has one or two fixed filters.
  3. State summary using metric cards, queue rows, alerts, or ErpStatusTag when the state changes what the administrator should inspect next.
  4. Main data area with ErpDataTable for record lists, remote entity rows, or route-owned rows.
  5. Detail entry through the table drawer or ErpDrawer; keep long record facts out of inline expanded rows.
  6. Secondary executable actions through ErpActionBar; use a right-side panel only when actions need supporting context.

For common domain pages, prefer ErpDomainAdminView because it already combines header, search, metrics, queue, table, side panel, and detail drawers.

Component Choice Matrix

Need Use Notes
Application shell, left menu, top menu ErpAppShell Do not duplicate global navigation inside pages.
Page title and breadcrumbs ErpPageHeader Use crumbs and the actions slot for page-level commands.
Domain management page ErpDomainAdminView Best default for order, product, party, accounting, facility, operations, content, marketing, HR, and similar workspaces.
Data listing ErpDataTable Includes loading, empty, unavailable, error, pagination, sorting, status cells, and detail drawer.
Search filters ErpSearchForm Metadata-driven fields, lookup, option loading, reset and submit.
Entity create or edit form ErpEntityForm Use for submit-oriented fields and disabled state handling.
Status label ErpStatusTag Use for row status, queue state, and record detail status.
Action group ErpActionBar Use for executable actions, disabled reasons, running state, and overflow.
Status-grouped data panel ErpTabbedDataPanel Use when one data panel needs stable tabs, header actions, and table or queue content.
Record detail ErpDrawer or table drawer Prefer drawer over expanding large inline detail blocks.
File selection ErpUpload or upload field in ErpEntityForm Keep upload copy and permission behavior consistent.
Lookup field ErpLookup through form wrappers Use for party, product, order, and related entity selection.

Tabbed Data Panels

  • Use ErpTabbedDataPanel when one work area contains the same kind of records split by operational state, queue, or ownership.
  • Good fits: sales orders by fulfillment state, procurement requirements by approval state, inventory exceptions by facility, accounting documents by close state, content items by publish state, and work requests by assignment state.
  • Keep tabs stable across refreshes. Do not create tabs from every transient filter value; use filters inside the active tab for dates, owner, keyword, and related entity.
  • Put ErpDataTable, a compact queue list, or a focused review panel in the default slot. Search, pagination, and row details stay owned by that inner content.
  • Use count when each tab represents a queue size; use status when the tab needs a short state label such as Ready, Review, or Processing.
  • Use dense for secondary panels inside a wider workspace. Leave normal density for the main record panel.
  • Use the actions slot for panel-level refresh, assignment, export, create, or batch commands that apply to the active tab. If the action applies to a selected row, keep it in the table row or detail drawer instead.
  • Do not use it for whole-page route navigation, decorative tab stacks, or unrelated datasets that do not share columns or workflow.

Tables

  • Use ErpDataTable for business records: orders, invoices, payments, requirements, shipments, inventory items, parties, work efforts, requests, content records, system jobs, and entity-backed rows.
  • Use the rows prop when the page already owns a filtered list. Use dataSource when the table should load an entity list and keep the source tag, search, refresh, pagination, and unavailable state together.
  • The wrapper displays up to 12 visible data columns and then the fixed action column. If a workflow needs more facts, move secondary facts into the drawer or a support panel instead of widening the table.
  • Put status fields through ErpStatusTag; ErpDataTable already detects status-like column names for standard cells.
  • Keep row details in the table drawer unless the page has a domain-specific drawer with stronger record context.
  • Use pagination for remote, large, or repeatedly refreshed record sets. Default scan size is 20 rows; 10 is suitable for narrow panels, 50 or 100 for audit-heavy pages.
  • Keep table search in the source toolbar for broad keyword search. Use ErpSearchForm above the table for structured filters such as party, product, facility, status, date range, and owner.
  • Preserve built-in loading, empty, unavailable, and error states. Do not replace the whole page when only one table source fails.
  • Use .erp-table and .erp-dense-pagination only when a wrapper cannot be used, such as a route renderer that supplies specialized table slots.

Table layout rules:

  • Primary identifier or name comes first.
  • Status and date columns stay visible when possible.
  • Amount columns align right.
  • Action columns stay narrow and predictable.
  • Long secondary values use muted subtext and ellipsis.

Table density rules:

  • Main work tables use compact small rows from ErpDataTable; this is the default ERP density.
  • Dense side tables should show 5-8 rows and avoid multi-line cells.
  • Audit or exception tables may show 20-50 rows, but must keep identifier, state, timestamp, owner, and action columns visible.
  • Do not increase row height to carry descriptions. Put descriptions in the drawer, a tooltip, or muted subtext under the primary value.
  • Keep toolbar, total count, and pagination visible near the table so operators can tell whether they are seeing a filtered subset.

Search Forms

  • Use ErpSearchForm when query fields come from screen metadata, entity definitions, adapter blocks, or an action contract.
  • Use direct compact controls only for one or two page-local switches such as status, facility, or active tab. Once the page has three or more structured fields, use ErpSearchForm.
  • Place search forms above the table or inside the domain wrapper's control area. Do not place a full search form inside a table body.
  • The wrapper shows up to 16 visible fields. Put the most operational fields first: identifier, status, related party/product/facility, date range, owner, and free text.
  • Use ErpLookup for related records rather than free text when the domain has a known entity.
  • Keep top labels and compact controls. Avoid placeholder-only forms; labels must remain visible.
  • Preserve reset and submit behavior. The action row also carries form status such as queryable, submittable, login required, readonly, or processing.
  • Put rarely used filters behind a drawer or collapsible panel, but keep the current filter state visible near the table after applying it.

Search form layout:

  • Desktop: four compact columns when space allows.
  • Medium width: two columns.
  • Narrow width and drawers: one column.
  • Actions align to the end using .erp-form-actions.

Entity Forms

  • Use ErpEntityForm for create, edit, and submit-oriented flows.
  • Use one column inside drawers and dialogs.
  • Use two columns in wider page panels only when fields are short and related.
  • Show readonly values with wrapper readonly display, not disabled inputs unless the value belongs in a form control.
  • Show disabled reasons near the form or action area.
  • Keep submit actions in a stable bottom action row.

Navigation

  • ErpAppShell owns top-level navigation and the left menu.
  • Business pages should receive navigation context rather than rebuilding it.
  • Use ErpPageHeader breadcrumbs for page-level location.
  • Use ErpPageHeader on every route-level admin page, including domain workspaces, entity search pages, and operational consoles.
  • Header actions are for page-level commands such as create, refresh, export, or open a global action. Row-specific commands stay in ErpDataTable, the drawer, or ErpActionBar.
  • Keep the page description to one sentence that states the operator's job: which records are managed, which queue is handled, or which state is monitored.
  • Use .erp-side-menu only for page-local secondary navigation.
  • Use .erp-horizontal-menu for top-level tabs or route groups inside the shell.
  • Top menu items should be short domain labels.
  • Left menu groups should be stable and scan-friendly.

Breadcrumb rules:

  • First item is the admin workspace or module root.
  • Middle items are domain or sub-area.
  • Last item is the current page or record label.
  • Breadcrumb text should be business-facing and concise.

Cards, Panels, and Metrics

  • Use .erp-panel or .erp-work-area for framed work sections.
  • Use .erp-card only for individual repeated items, not for whole page sections.
  • Use .erp-metric-card for numeric summaries.
  • Use density variants deliberately:
    • Large: first-screen domain summaries with a number, short label, and one operational hint, such as open orders, exceptions, value at risk, or jobs running.
    • Medium: normal panel item, queue card, or record group that carries a title, one secondary line, and one status or action.
    • Small: row summary, action candidate, handoff, warning, or compact queue item in a side panel.
    • Mini: numeric counters and short KPI chips inside a header or compact workspace.
  • Avoid nested cards.
  • Use neutral surfaces; state color belongs on a side border, tag, alert, or icon.
  • A card must help an operator compare, choose, or act. If it only wraps text, use a heading, list row, or panel section instead.
  • Large cards should be rare on record-heavy pages; use them for the top 3-4 domain measures, then return to tables.
  • Medium and small cards may repeat in grids or side panels. Keep their internal text short enough that the grid height remains stable.
  • Do not use cards as section containers around ErpDataTable, ErpSearchForm, or ErpTabbedDataPanel; those wrappers already provide the working surface.

Status, Alerts, and Feedback

  • Use ErpStatusTag for record, queue, tab, and drawer labels when the value is a business state such as Approved, Review, Created, Processing, Error, Cancelled, Ready, Packed, or equivalent domain wording.
  • Use status tags in table cells, queue rows, selected record headers, and compact metric cards. Avoid placing multiple status tags in the page header unless they describe the whole page.
  • Keep the source status from the data, then map display labels through the wrapper. Do not invent local color classes for every domain state.
  • Use .erp-state-line for state rows that need short text plus a state color.
  • Use Element Plus alerts with .erp-status-alert for warnings or errors that affect a whole panel.
  • Pair every color with text.
  • Place state messages near the affected control or table.

State expectations:

  • Loading: indicate what is loading.
  • Empty: explain the current filter or missing selection.
  • Error: name the affected area and keep other controls usable.
  • Disabled: explain why the action cannot run.
  • Success: keep feedback brief and tied to the completed action.

Dialogs and Drawers

  • Use drawers for record details, edit forms, action setup, and side-by-side review.
  • Use dialogs for short confirmations or focused blocking decisions.
  • Drawer titles must identify the record or action.
  • Drawer content should use one-column forms, descriptions, timelines, or action lists.
  • Long detail content should be grouped with headings and descriptions.
  • Keep primary and secondary actions at the bottom or in a stable action row.
  • Use .erp-drawer, .erp-dialog, and .erp-detail-descriptions classes where applicable.

Upload

  • Use ErpUpload or the upload field support inside ErpEntityForm.
  • Keep upload areas compact and connected to the form they affect.
  • Show file selection state and any permission note close to the upload control.
  • Do not create custom drag areas with local CSS when the shared upload wrapper is enough.
  • Use .erp-upload for shared upload styling when direct Element Plus upload is unavoidable.

Actions

  • Use ErpActionBar for executable business actions returned by a route, adapter block, service contract, or selected record context.
  • Use the page header for one page-level primary command. Use ErpActionBar when there are multiple executable choices, permission-dependent actions, batch commands, or a need to show why an action cannot run.
  • Primary action appears first and uses primary styling. Destructive actions use danger styling and clear labels.
  • Normal mode shows up to four primary buttons before overflow. Compact mode shows up to two; use compact mode in side panels, drawers, and secondary consoles.
  • The wrapper shows enabled count, disabled reason, running state, success, warning, and error feedback. Do not duplicate that feedback with page-local banners unless the whole panel is affected.
  • Disabled actions must expose a reason through the action definition. A disabled button without a reason is not acceptable for administrator workflows.
  • Running actions show button loading and should not shift layout.
  • Use .erp-action-stack and .erp-action-button for custom action groups that cannot use ErpActionBar.

Top Menu and Left Menu

  • Top menu:
    • Use shell-owned top navigation.
    • Keep labels short and domain-oriented.
    • Active state uses the ERP primary token and a restrained underline.
  • Left menu:
    • Use shell-owned left navigation for modules and durable route groups.
    • Use .erp-side-menu only for local subnavigation.
    • Keep item height aligned with the 38px menu rhythm.
    • Active state uses primary color and a left border, not a filled pill.

Empty, Loading, and Error States

  • Empty states use Element Plus empty components or .erp-empty-state.
  • Loading states use wrapper loading behavior, Element Plus loading, or .erp-skeleton.
  • Error states should not replace the whole page unless the whole page is unusable.
  • For tables, keep the toolbar and search visible during failures.
  • For forms, preserve entered values when an option load or submit action fails.

Responsive Layout

  • Use CSS grid and wrappers that can collapse cleanly.
  • Search forms should move from four columns to two and then one.
  • Metrics should wrap instead of shrinking text below readable size.
  • Side panels move below the main table on narrow widths.
  • Drawers keep one-column content and readable labels.
  • Do not scale font size with viewport width.

Accessibility and Interaction

  • Keep visible focus behavior from Element Plus and token overrides.
  • Do not remove native labels from forms or headers from tables.
  • Icon-only buttons require accessible labels or tooltips.
  • Use buttons for actions and links for navigation.
  • Keep hover states helpful but nonessential.
  • Do not communicate status by color alone.

Content Rules

  • Write for administrators: short, operational, and specific.
  • Use verbs for buttons: search, reset, refresh, create, save, assign, approve, cancel.
  • Use nouns for sections: filters, records, details, actions, queue, status.
  • Avoid visible implementation wording.
  • Avoid promising behavior that the page cannot currently perform.

Local CSS Rules

  • Business pages may add local classes for layout only when no wrapper or pattern exists.
  • Local CSS should reference ERP tokens and stay narrowly scoped.
  • Do not redefine Element Plus button, input, table, tag, menu, or card styles inside a page.
  • Do not add hard-coded state colors in pages.
  • If a layout pattern appears in multiple pages, move it into src/styles/erp-patterns.css or an ERP wrapper.

Review Checklist

  • Does the page use the right ERP wrapper for shell, header, table, form, status, actions, detail, and upload?
  • Are tokens used instead of hard-coded color, spacing, radius, and table density?
  • Are search, data table, state labels, action area, detail entry, empty, loading, and error states visible?
  • Does the page avoid decorative card stacks and local style drift?
  • Is copy business-facing and useful to an administrator?
  • Does the page work at desktop, medium, and narrow widths?