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>
This commit is contained in:
Qiufeng
2026-06-15 19:19:15 +08:00
co-authored by Claude Opus 4.8
commit 5e51dc3f56
10584 changed files with 2501339 additions and 0 deletions
@@ -0,0 +1,17 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "oa-unified",
"runtimeExecutable": "java",
"runtimeArgs": ["-jar", "/Users/qiu/Desktop/ERP/oa-backend/build/libs/oa-backend-0.1.0.jar"],
"port": 8090
},
{
"name": "modern-ui-dev",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"port": 5175
}
]
}
@@ -0,0 +1,220 @@
# Design
## Source of Truth
- Status: Active
- Last refreshed: 2026-06-09
- Primary product surfaces: ERP 管理员工作台、领域管理页、实体查询页、表单录入页、记录详情抽屉、模块导航。
- Evidence reviewed:
- `src/components/erp/ErpAppShell.vue`
- `src/components/erp/ErpPageHeader.vue`
- `src/components/erp/ErpDomainAdminView.vue`
- `src/components/erp/ErpTabbedDataPanel.vue`
- `src/components/erp/ErpDataTable.vue`
- `src/components/erp/ErpSearchForm.vue`
- `src/components/erp/ErpEntityForm.vue`
- `src/components/erp/ErpStatusTag.vue`
- `src/components/erp/ErpActionBar.vue`
- `src/components/erp/ErpDrawer.vue`
- `src/components/erp/ErpUpload.vue`
- `src/styles/erp-ui.css`
- `src/styles/tokens.css`
- `src/styles/base.css`
- `src/styles/element-overrides.css`
- `src/styles/erp-patterns.css`
- `src/styles/modern.css`
- Companion handbook: `UI.md` is the component and pattern usage guide for page authors.
## Brand
- Personality: calm, operational, precise, trustworthy.
- Trust signals: compact density, visible filters, clear record counts, status labels, explicit disabled reasons, consistent detail entry points.
- Avoid: decorative-first layouts, oversized marketing treatment, one-off color palettes, nested card stacks, local CSS that duplicates wrapper behavior, copy that reads like an internal implementation report.
## Product Goals
- Goals:
- Make every business page feel like a usable ERP administrator workspace.
- Surface search, tabular records, state, actions, and detail paths within the first screen.
- Keep complex areas scan-friendly for repeated daily use.
- Let wrappers and shared patterns carry layout, density, tokens, and interaction states.
- Non-goals:
- Building separate visual systems per domain.
- Recreating Element Plus primitives directly in each page when an ERP wrapper exists.
- Adding decorative sections that do not help an administrator decide or act.
- Success signals:
- A page can be understood by title, breadcrumb, filters, table, status, and actions without reading code.
- Loading, empty, error, permission, and disabled states are visible and useful.
- New pages need little or no local CSS beyond page-specific grid placement.
## Personas and Jobs
- Primary personas:
- ERP administrator managing orders, products, parties, accounting, facilities, operations, content, and HR records.
- Domain operator who searches, filters, updates, and checks record status throughout the day.
- Implementation maintainer who adds pages while preserving a shared product experience.
- User jobs:
- Find records by identifier, name, state, date, or related entity.
- Compare records in dense tables and open one record for details.
- Understand whether an action can run, why it is disabled, and what result followed.
- Move from global navigation to a domain workspace, then to a specific record or action.
- Key contexts of use:
- Desktop administration with high information density.
- Narrow screens where navigation collapses and forms become single-column.
- Mixed data readiness where some records, actions, or permissions may be unavailable.
## Information Architecture
- Primary navigation:
- `ErpAppShell` owns the top-level shell, left menu, top actions, global search, and breadcrumb trail.
- Business pages should not create independent shell navigation.
- Core routes and screens:
- Domain landing views use `ErpDomainAdminView` or a domain-specific workspace wrapper.
- State-split record areas use `ErpTabbedDataPanel` when one kind of work is divided by queue, status, facility, ownership, or approval step.
- Entity record areas use `ErpDataTable` for listing and detail drawer entry.
- Search and edit flows use `ErpSearchForm` and `ErpEntityForm`.
- Content hierarchy:
- Page header: breadcrumb, domain title, short operational description, primary action.
- Work controls: search form, status filters, quick actions.
- Main work area: data table with pagination and row-level details.
- Support area: metrics, queue cards, execution state, or governance notes when they help the workflow.
## Design Principles
- Wrapper-first: every business page starts from `src/components/erp` wrappers before direct Element Plus composition.
- Data before decoration: tables, filters, status, and actions are the primary visual weight.
- One clear action area: primary actions sit in the header or action bar; secondary actions group in overflow or a side panel.
- Stable density: use the 4px spacing rhythm, 28/32/36px controls, compact table rows, and small radius tokens.
- Concrete wrapper choice: page authors choose wrappers by business job, not by appearance. Use tabbed panels for one record family split by state, data tables for scan-and-open lists, search forms for structured filters, status tags for business state, and action bars for executable commands with permission or running state.
- Explicit state: loading, empty, error, no-access, disabled, and success states must tell the administrator what happened and what can be done next.
- Tradeoffs:
- Prefer reusable wrapper behavior even when local markup could be shorter.
- Prefer compact panels and grids over editorial storytelling.
- Prefer neutral surfaces with state hues used only for state.
## Visual Language
- Color:
- Use tokens from `src/styles/tokens.css`.
- Primary blue is for navigation focus and primary actions.
- Success, warning, danger, and info hues are reserved for state labels, alerts, and risk lines.
- Work surfaces stay neutral: white, muted, quiet, raised, or sunken token surfaces.
- Typography:
- Use `--erp-font-family` and `--erp-font-size-*`.
- Page titles may use larger sizes; panels, cards, controls, and tables stay compact.
- Letter spacing stays `0`.
- Spacing and layout rhythm:
- Use `--erp-space-*`, `--erp-work-area-padding`, and `--erp-work-area-gap`.
- Search forms and table toolbars align on the same compact rhythm.
- Table density stays compact by default; row height should not grow to carry narrative text.
- Shape, border, and elevation:
- Default radius is `--erp-radius-xs` or `--erp-radius-sm`.
- Cards and panels use borders, not heavy shadow.
- Avoid cards inside cards.
- Motion:
- Keep motion functional: drawer opening, dropdowns, loading indicators, and focus states.
- Do not add decorative motion to administrator workflows.
- Imagery and iconography:
- Use Element Plus icons already available in the app for action affordances.
- Do not rely on decorative imagery to explain operational screens.
## Components
- Existing components to reuse:
- Shell and navigation: `ErpAppShell`, `ErpPageHeader`.
- Domain workspace: `ErpDomainAdminView` and domain-specific `Erp*Workspace.vue` wrappers.
- Data: `ErpTabbedDataPanel`, `ErpDataTable`, `ErpStatusTag`.
- Forms: `ErpSearchForm`, `ErpEntityForm`, `ErpLookup`, `ErpUpload`.
- Actions and details: `ErpActionBar`, `ErpDrawer`.
- Wrapper decision rules:
- `ErpPageHeader`: required for route-level admin pages. Breadcrumbs identify module and domain; the actions slot holds page-level commands such as create, refresh, export, or open global processing.
- `ErpTabbedDataPanel`: use for a single operational list split by order state, inventory facility, accounting close state, approval queue, assignment, or publish state. Do not use it for unrelated datasets or route navigation.
- `ErpDataTable`: use for record lists and entity rows that need scanning, pagination, status cells, source state, and a detail drawer. Keep visible columns focused; secondary facts belong in the drawer or support panel.
- `ErpSearchForm`: use when filters come from metadata or when the page has three or more structured fields. Use lookups for related entities and keep reset/submit visible.
- `ErpStatusTag`: use for business state in rows, queues, tabs, selected-record headers, and compact metrics. Pair state color with text and avoid local color mappings in pages.
- `ErpActionBar`: use for executable action groups where enabled count, disabled reason, running state, overflow, and result feedback matter. Header actions are for one page-level command; action bars handle multi-action workflows.
- New or changed components:
- Add a wrapper only when at least two business pages need the same behavior, state handling, or layout.
- Do not add wrappers solely for naming convenience.
- Variants and states:
- Tabbed panels include stable tab id, label, optional count, optional status, loading, disabled, panel actions, dense mode, and an empty state.
- Tables include loading, empty, unavailable, error, pagination, row details, and status cells.
- Forms include readonly, disabled, option loading, no-field, and submit feedback states.
- Actions include enabled count, disabled reason, running state, success, warning, and error messaging.
- Cards use density with intent: large for first-screen domain measures, medium for normal queue or record groups, small for side-panel rows and action candidates, mini for counters and KPI chips.
- Token and component ownership:
- `src/styles/tokens.css` owns product tokens.
- `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 to ERP tokens.
- `src/styles/erp-patterns.css` owns reusable ERP layout classes.
- `src/styles/modern.css` owns app shell and route-level layout patterns and is imported directly by `src/main.ts`.
- `src/styles/erp-ui.css` is the ERP style entry that imports Element Plus CSS, tokens, base defaults, Element Plus overrides, and ERP patterns.
## Accessibility
- Target standard: keyboard-operable admin workflows with readable contrast and visible focus.
- Keyboard and focus behavior:
- Use Element Plus controls through wrappers to preserve focus management.
- Drawers and dialogs must have clear titles and a predictable close path.
- Row detail entry must be reachable through buttons or clickable rows with clear affordance.
- Contrast and readability:
- State colors must use token pairs for text, background, and border.
- Compact typography must remain legible at table density.
- Screen-reader semantics:
- Keep native Element Plus form labels, table headers, breadcrumbs, alerts, and descriptions.
- Avoid replacing text labels with icon-only controls unless the control has a label.
- Reduced motion and sensory considerations:
- Keep animations short and functional.
- Do not communicate state by color alone; pair color with labels.
## Responsive Behavior
- Supported breakpoints and devices:
- Desktop and laptop are primary.
- Tablet and narrow browser widths must remain usable for search, table scanning, and record detail.
- Layout adaptations:
- Search forms collapse from four columns to fewer columns, then one column.
- Side support panels move below the main table when width is limited.
- Drawers remain the preferred detail surface on desktop; narrow widths should keep content single-column.
- Touch and hover differences:
- Hover may provide emphasis but cannot be required for core actions.
- Buttons and menu items must keep stable hit areas from Element Plus sizing tokens.
## Interaction States
- Loading:
- Use table loading, form option loading, action button loading, or skeleton patterns.
- Loading text should say what record area is loading.
- Empty:
- Empty states should mention the current filter or missing selection and offer a next action when available.
- Error:
- Errors should describe the affected area and keep the rest of the page usable.
- Success:
- Success feedback should be brief and tied to the completed action.
- Disabled:
- Disabled actions must expose a reason through `ErpActionBar` or button title/notice.
- Slow or unavailable data:
- Show state tags or alerts near the affected table, not only at page top.
## Content Voice
- Tone: direct, operational, administrator-facing.
- Terminology:
- Use "工作台", "管理", "记录", "状态", "筛选", "详情", "执行", "授权", "处理".
- Use domain nouns such as order, product, party, accounting, facility, operations when they match route context.
- Microcopy rules:
- Page titles describe the domain and task.
- Button labels use verbs.
- Empty and error copy should give a next step or explain current limits.
- Avoid implementation-layer wording in visible page copy.
## Implementation Constraints
- Framework and styling system:
- Vue pages use Element Plus through ERP wrappers and shared classes.
- Direct Element Plus use is allowed for simple controls only when no ERP wrapper exists.
- Design-token constraints:
- Use CSS custom properties from `src/styles/tokens.css`.
- Do not hard-code colors, spacing, radius, or table density in business pages unless extending a documented pattern.
- Performance constraints:
- Tables should display a focused set of columns, paginate records, and avoid rendering huge detail blocks inline.
- `ErpDataTable` should stay the default for scan-heavy record work; hand-built tables must preserve compact row density, status handling, pagination, and nearby search.
- Detail-heavy content belongs in drawers.
- Compatibility constraints:
- Preserve existing route behavior and navigation targets.
- Documentation changes do not alter runtime behavior.
- Test and screenshot expectations:
- For UI code changes, run the smallest targeted check plus the app build when practical.
- For documentation-only updates, run text checks for forbidden expressions and scope drift.
## Open Questions
- [ ] Which domain workspaces should graduate additional repeated local layouts into new ERP wrappers?
- [ ] Should narrow-screen drawer width become tokenized for all detail surfaces?
- [ ] Should action severity mapping be centralized for all domain-specific action rows?
+239
View File
@@ -0,0 +1,239 @@
# 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?
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>凯迪协同办公平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,53 @@
{
"name": "ofbiz-modern-ui",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --host 0.0.0.0",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview --host 0.0.0.0",
"verify:admin-site": "node scripts/verify-admin-site.mjs",
"verify:admin-product": "node scripts/verify-admin-product.mjs",
"verify:erp-renderer-copy": "node scripts/verify-erp-renderer-production-copy.mjs",
"verify:admin-runtime": "node scripts/verify-admin-runtime.mjs",
"verify:browser-runtime": "node scripts/verify-browser-runtime.mjs",
"verify:browser-runtime-policy": "node scripts/verify-browser-runtime-policy.mjs",
"verify:coverage": "node scripts/verify-coverage.mjs",
"verify:screenshots": "node scripts/capture-admin-screenshots.mjs",
"verify:order-workspace": "node scripts/verify-order-workspace.mjs",
"verify:finance-operations": "node scripts/verify-finance-operations-workspace.mjs",
"verify:business-page": "node scripts/verify-business-page-console.mjs",
"verify:modern-navigation": "node scripts/verify-modern-navigation.mjs",
"verify:preview": "node scripts/verify-preview.mjs",
"verify:admin-rendering": "npm run verify:admin-site && npm run verify:admin-product && npm run verify:erp-renderer-copy && npm run verify:browser-runtime-policy",
"verify:business-e2e:batch": "node scripts/verify-business-e2e-batch.mjs",
"verify:parity": "node scripts/verify-parity.mjs"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.2",
"@tiptap/extension-collaboration": "^3.26.1",
"@tiptap/extension-collaboration-caret": "^3.26.1",
"@tiptap/extension-image": "^3.26.1",
"@tiptap/extension-link": "^3.26.1",
"@tiptap/starter-kit": "^3.26.1",
"@tiptap/vue-3": "^3.26.1",
"element-plus": "^2.14.1",
"mammoth": "^1.12.0",
"pdfjs-dist": "^6.0.227",
"sortablejs": "^1.15.7",
"vue": "^3.5.24",
"vue-router": "^4.6.4",
"vuedraggable": "^4.1.0",
"xlsx": "^0.18.5",
"y-prosemirror": "^1.3.7",
"y-protocols": "^1.0.7",
"yjs": "^13.6.31"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.2",
"typescript": "^5.9.3",
"vite": "^7.2.7",
"vue-tsc": "^3.1.6"
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More