Files
ERP/element-plus-lab/UI.md
T
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

610 lines
18 KiB
Markdown

# OFBiz Element Plus UI Lab
This directory is the UI lab for rebuilding OFBiz screens with Vue 3 and Element Plus. It is not wired to the OFBiz backend yet; it is the place to define reusable UI rules, component wrappers, and visual behavior before replacing real pages.
## Run
```bash
pnpm install
pnpm dev --port 5174
pnpm build
node scripts/generate-element-plus-inventory.mjs
```
Local preview:
```text
http://localhost:5174/
```
Direct page preview:
```text
http://localhost:5174/#/page/navigation
http://localhost:5174/#/page/catalog?group=数据展示
http://localhost:5174/#/component/table
http://localhost:5174/#/component/table?view=code
```
## File Map
```text
src/main.js
Imports Element Plus, global CSS, and mounts the app.
src/App.vue
Thin app entry. It renders ElementPlusShowcase only.
src/components/ElementPlusShowcase.vue
Page shell for the lab: sidebar, topbar, active page state, and page composition.
src/components/docs/DemoBlock.vue
Shared documentation block. Every component example uses 展示 / 代码 tabs.
src/components/showcase/
One file per documentation page. Keep examples split by component family.
src/data/showcaseData.js
Page menu, Element Plus inventory, ERP priority levels, sample order rows, metric cards, and utility functions.
src/data/elementPlusInventory.js
Generated full Element Plus inventory. Contains every local component directory, public El* export, and directive.
src/data/erpComponentDocs.js
ERP documentation layer on top of the generated inventory. Adds wrapper names, local CSS classes,
preview types, original code, ERP code, local style snippets, and OFBiz usage notes for every component.
scripts/generate-element-plus-inventory.mjs
Regenerates the full inventory from node_modules/element-plus. Run after upgrading Element Plus.
src/styles/tokens.css
ERP design tokens: color, spacing, radius, typography, shadows.
src/styles/erp-ui.css
Global UI entry. Import this once before page-specific CSS in every modern OFBiz frontend.
src/styles/base.css
Global reset and page baseline.
src/styles/element-overrides.css
Element Plus CSS variable mapping and direct Element class overrides.
src/styles/erp-patterns.css
Reusable ERP-specific classes such as .erp-table, .erp-form, .risk-dot, .component-chip.
src/styles/app.css
Lab shell and demo-only layout styles. Do not put reusable product patterns here.
```
## Element Plus Inventory
The catalog in `src/data/showcaseData.js` is checked against the local package:
```text
element-plus: 2.14.1
node_modules/element-plus/es/components: 122 directories
public El* exports from element-plus: 123
node_modules/element-plus/es/directives: 4 directories
```
The showcase intentionally separates three things:
```text
Component directories
Concrete Element Plus component folders, including subcomponents such as Table Column,
Tab Pane, Option, Dropdown Item, Carousel Item, and internal foundations.
Public El* exports
Components plus public services/directives such as ElMessage, ElMessageBox,
ElNotification, ElLoadingService, and Popper subparts.
Directive directories
click-outside, mousewheel, repeat-click, trap-focus.
```
When Element Plus is upgraded, run:
```bash
node scripts/generate-element-plus-inventory.mjs
```
Do not hand-edit component counts. The generated facts stay in `src/data/elementPlusInventory.js`.
ERP-specific decisions stay in `src/data/erpComponentDocs.js`, so package upgrades do not wipe local design decisions.
## Local Component Docs
Every Element Plus component directory gets a local ERP doc record:
```js
{
slug: 'table',
tag: 'el-table',
exportName: 'ElTable',
group: '数据展示',
priority: '高',
wrapperName: 'ErpTable',
localClass: 'erp-table',
originalCode: '<el-table ... />',
erpCode: '<el-table class="erp-table" ... />',
styleCode: '/* src/styles/erp-patterns.css */ ...',
detailRoute: '#/component/table'
}
```
The catalog page reads `erpComponentDocs`, not the raw inventory directly. That is the split:
```text
elementPlusInventory.js = package truth
erpComponentDocs.js = OFBiz local usage and style truth
```
High-frequency ERP components already have concrete preview and ERP code patterns:
```text
Table / Table V2 / Pagination
Menu / Sub Menu / Menu Item
Breadcrumb / Breadcrumb Item / Page Header
Form / Form Item / Input / Select / Select V2 / Date Picker
Button / Button Group / Dropdown
Dialog / Drawer / Popconfirm / Tooltip
Tag / Alert / Message / MessageBox / Notification
Tree / Tree V2 / Tree Select / Upload / Descriptions
Empty / Progress / Result / Skeleton
Timeline / Steps / Collapse / Tabs / Segmented
Calendar / Image / Carousel / Statistic
Switch / Slider / Rate / Color Picker / Transfer
Space / Text / Link / Divider
```
Subcomponents such as `Table Column`, `Breadcrumb Item`, `Menu Item`, `Dropdown Item`, `Option`, and `Tab Pane`
are retained as independent detail pages, but their wrapper guidance points back to the parent component.
## CSS Order
Use the single global entry in future OFBiz frontend pages:
```js
import './styles/erp-ui.css'
import './styles/app.css'
```
`erp-ui.css` keeps this internal order:
1. Element Plus official CSS.
2. ERP tokens.
3. Global baseline.
4. Element Plus overrides.
5. Reusable ERP patterns.
Page-specific styles come after `erp-ui.css`. Do not import Element Plus CSS directly in feature pages.
## Component Rules
Use Element Plus as the raw component layer. Do not use raw Element Plus directly in OFBiz feature pages once a reusable ERP wrapper exists.
Preferred path:
```text
Element Plus primitive -> ERP wrapper/pattern -> OFBiz feature page
```
Example:
```vue
<el-table :data="rows" class="erp-table" stripe>
<el-table-column prop="orderId" label="单据号" width="126" />
<el-table-column prop="amount" label="金额" align="right" />
</el-table>
```
Later wrapper target:
```vue
<ErpTable :rows="rows" :columns="columns" row-key="orderId" />
```
## Component Decision Rules
Pick components by business task first, not by visual taste.
```text
Page skeleton
Container / Aside / Main / Card / Collapse / Splitter
Use for module frame, page sections, details summary, and collapsible advanced content.
Navigation location
Menu / Breadcrumb / Page Header / Tabs / Steps / Timeline
Use for module switching, current path, local views, process position, and audit history.
Query and input
Form / Input / Select / Date Picker / Tree Select / Autocomplete / Upload
Use for search bars, editing forms, entity lookup, legal values, dates, and attachments.
Data scanning
Table / Table V2 / Pagination / Descriptions / Tree / Statistic / Tag
Use for dense business objects, read-only summaries, hierarchy, metrics, and statuses.
Actions and feedback
Button / Dropdown / Popconfirm / Dialog / Drawer / Message / Alert / Result
Use for primary actions, secondary action menus, confirmations, details, and completion states.
State and loading
Empty / Skeleton / Progress / Badge / Calendar / Image / Transfer
Use for no-data states, loading, measurable progress, counters, schedules, media, and assignment.
```
Important component choices:
- Use `Table` for auditable ERP records; use `Table V2` only when row count and scroll performance are the actual problem.
- Use `Descriptions` for read-only details; do not make read-only content look like disabled forms.
- Use `Tabs` for views inside the same business object; use `Menu` for module-level navigation.
- Use `Steps` for current process position; use `Timeline` for history and audit records.
- Use `Drawer` for side details and audit context; use `Dialog` for short blocking confirmation or editing.
- Use `Message` for short save feedback; use `Alert` for persistent warnings; use `Result` only at a flow endpoint.
- Use `Autocomplete`, `Tree Select`, or `Cascader` for entity lookup; do not overload plain `Input` with hidden lookup logic.
- Use `Dropdown` for secondary or low-frequency actions; never hide the main workflow action inside it.
## Page Layout Playbook
Use these four page skeletons before selecting individual controls.
```text
List page
Breadcrumb / Page Header
Query Form
Toolbar with one primary action
Table
Pagination
Drawer for row details or audit context
Detail page
Breadcrumb / object title / status tags
Descriptions summary
Tabs for lines, audit, attachments
Table for line items
Drawer for side context
Entry page
Two-column Form
Entity pickers for customer, supplier, org, warehouse
Upload only near attachment fields
Footer actions with one primary submit
Popconfirm for destructive or irreversible actions
Process page
Steps for current progress
Alert for blocking warning
Progress for measurable work
Skeleton while content loads
Result only when the process has ended
```
Layout defaults:
- Query forms use 4 columns on desktop. Editing forms use 2 columns. Detail summaries use 2-3 columns.
- List pages follow this order: page context, filters, toolbar, table, pagination, detail drawer.
- The visible work area gets one `primary` button. Secondary actions are normal buttons, links, or dropdown items.
- Numbers and money align right. Status is near the business object it describes.
- Dense table pages should keep vertical rhythm tight; dialogs and destructive confirmations should keep more reading space.
## Catalog Layout Contract
The full component catalog is intentionally split into four layers:
```text
Catalog summary
Count and completeness signals for the local Element Plus inventory.
Page playbook
OFBiz page templates that map common page types to component sets.
Usage map
Business scenarios that link directly to the components used in that scenario.
Grouped component library
All 122 Element Plus component directories, grouped by component family.
```
Every component card includes:
```text
Component name
Element Plus tag and export
ERP priority
One-line usage rule
Independent 展示 / 代码 tabs
Direct detail link
Direct component code page link
```
Every component detail page includes:
```text
展示
原始代码
ERP代码
本地样式
什么时候用
什么时候不用
排版规则
落地 CSS 文件
同组组件跳转
```
## Page Split Contract
The lab is a multi-page component document. The left menu switches pages instead of scrolling to anchors.
Routes are hash based so every page and component can be linked directly:
```text
#/page/catalog
#/page/catalog?group=数据展示
#/component/table
#/component/menu
#/component/breadcrumb
```
The left menu calls `navigateTo('page/<id>')`, so page changes are real URL changes. The full catalog card titles
and detail buttons call `navigateTo('component/<slug>')`, so every component has a direct page.
Pages are registered in `docPages` inside `src/data/showcaseData.js`. Each page carries:
```text
id
label
icon
title
description
```
Each file under `src/components/showcase/` owns one documentation page:
```text
FoundationShowcase.vue Tokens and product tone
MetricsShowcase.vue Statistic cards and dashboard summaries
ComponentCatalogShowcase.vue Full Element Plus inventory
ButtonShowcase.vue Buttons, groups, dropdown actions
FormShowcase.vue Form, input, select, picker, switches
TableShowcase.vue Table, columns, pagination, cells
StatusShowcase.vue Tag, alert, progress, badge, timeline
NavigationShowcase.vue Side menu, top menu, breadcrumb, page header
TokenRail.vue Token notes and next component queue
DocumentDrawer.vue Drawer detail preview
```
When adding a new component family, create a new `*Showcase.vue` file, register it in `docPages`, and render it from `ElementPlusShowcase.vue`. Put sample data in `src/data/showcaseData.js` unless it is purely local demo state.
## Demo / Code Tabs
Every component page should use `DemoBlock.vue` so examples always include both the rendered component and the corresponding code.
```vue
<DemoBlock
:code="tableCode"
description="ERP 表格优先保证扫描效率、状态清晰、数字右对齐和固定操作列。"
eyebrow="Data Table"
title="订单工作台表格"
>
<el-table :data="orderRows" class="erp-table" stripe />
</DemoBlock>
```
Code snippets live near the component demo as string constants. Keep snippets short and focused; do not paste an entire page when the user only needs the component call pattern.
The full catalog has its own tab contract:
```text
Catalog card tabs:
展示
代码
Single component detail tabs:
展示
原始代码
ERP代码
本地样式
```
Catalog card tab state is per component slug, so switching `Table` to `代码` does not switch `Button` or other cards.
Use direct links when reviewing:
```text
http://localhost:5174/#/page/catalog
http://localhost:5174/#/page/catalog?group=数据展示
http://localhost:5174/#/component/table
http://localhost:5174/#/component/table?view=code
http://localhost:5174/#/component/menu
http://localhost:5174/#/component/breadcrumb
```
## Local Style Ownership
Reusable product CSS lives here:
```text
src/styles/tokens.css
Color, radius, spacing, typography, surface, state tokens.
src/styles/element-overrides.css
Element Plus CSS variables and global Element class overrides.
src/styles/erp-patterns.css
OFBiz reusable patterns: .erp-table, .erp-side-menu, .erp-breadcrumb,
.erp-field-control, .erp-dense-pagination, .erp-tabs, .erp-status-tag,
.erp-detail-descriptions, .erp-entity-card, .erp-upload.
```
The lab-only page layout stays in `src/styles/app.css`. Do not move product wrapper styles there.
## Calling Pattern
State lives in the composition shell while each showcase section receives explicit props and emits updates:
```vue
<FormShowcase
v-model:check-values="checkValues"
v-model:date-range="dateRange"
v-model:order-status="orderStatus"
/>
```
Inside the section, keep Element Plus calls direct and obvious:
```vue
<el-select :model-value="orderStatus" @update:model-value="$emit('update:orderStatus', $event)">
<el-option label="已审批" value="approved" />
</el-select>
```
This is the migration pattern for OFBiz pages too: page state stays near the business workflow; reusable display or input behavior moves into an ERP wrapper only after it repeats.
## Reusable CSS
Use these files first:
```text
src/styles/tokens.css
src/styles/element-overrides.css
src/styles/erp-patterns.css
```
Current reusable classes:
```text
.erp-form
.erp-metric-card
.erp-metric-card--large
.erp-metric-card--small
.erp-metric-card--mini
.erp-table
.form-grid
.table-search
.icon-cell
.risk-dot
.component-chip
```
Component usage data lives in:
```text
src/data/erpComponentDocs.js
groupContracts
groupGuidance
previewGuidance
componentDocOverrides
erpComponentUsageMap
erpLayoutPlaybook
```
Catalog UI and per-component detail layout live in:
```text
src/components/showcase/ComponentCatalogShowcase.vue
```
Only product-reusable styling belongs in:
```text
src/styles/erp-patterns.css
src/styles/element-overrides.css
src/styles/tokens.css
```
Catalog-only grouping, playbook cards, mini previews, and documentation layout belong in:
```text
src/styles/app.css
```
Rule of thumb:
- If a style should apply across OFBiz modules, put it in `erp-patterns.css`.
- If it changes Element Plus global behavior, put it in `element-overrides.css`.
- If it is only for the lab page layout, put it in `app.css`.
- If it is a primitive value such as color, spacing, radius, font, or shadow, put it in `tokens.css`.
## Metric Cards
Do not use the old left-color-bar card for OFBiz dashboards. It is too decorative and does not read like a durable ERP control.
Use one KPI component with three size levels:
```vue
<div class="erp-metric-card erp-metric-card--large is-primary">...</div>
<div class="erp-metric-card erp-metric-card--small is-warning">...</div>
<div class="erp-metric-card erp-metric-card--mini is-danger">...</div>
```
Default dashboard size: `erp-metric-card--large`.
Use `--large` for dashboard summary rows and landing workspaces. Use `--small` above dense tables or within secondary panels. Use `--mini` inside narrow sidebars, table toolbars, or pages with many metrics.
## Design Intent
This UI system should feel quiet, durable, and operational. OFBiz users need to scan dense business data, make safe changes, and repeat workflows all day.
Keep these defaults:
- Typography: 12/13/14/18/24.
- Main radius: 6px for controls, 8px for panels.
- Tables: compact row height, sticky action column when needed, numbers right-aligned.
- Colors: low-saturation status colors, strong enough for scanning.
- Buttons: one primary action per visible work area.
- Forms: grouped fields, predictable labels, clear validation states.
- Avoid marketing layouts, oversized heroes, decorative cards, and one-hue themes.
## Priority For OFBiz
High-priority components to turn into ERP wrappers first:
```text
Table / Table V2
Form
Input / Select / Date Picker / Tree Select
Button / Dropdown
Tag / Alert / Message / Popconfirm
Tabs / Menu / Breadcrumb / Steps
Drawer / Dialog
Upload
Descriptions
Tree / Tree V2
Pagination
```
Lower-priority components can stay as direct Element Plus usage until real OFBiz screens need them.
## Adding A Wrapper
Create wrappers under a future `src/components/erp/` directory. Keep wrappers narrow and composable.
Example target structure:
```text
src/components/erp/ErpTable.vue
src/components/erp/ErpSearchBar.vue
src/components/erp/ErpStatusTag.vue
src/components/erp/ErpMoneyCell.vue
src/components/erp/ErpEntityPicker.vue
src/components/erp/ErpAuditTimeline.vue
```
Wrapper acceptance criteria:
- Has a simple prop API.
- Uses Element Plus internally.
- Uses tokens and ERP classes rather than hardcoded one-off styles.
- Handles empty, loading, disabled, error, and long-content states.
- Is demonstrated in a showcase section before being used in OFBiz pages.
## Backend Integration Direction
Keep OFBiz backend unchanged at first. Build the modern frontend page by page:
1. Recreate the target page in the lab with sample data.
2. Extract reusable wrappers.
3. Connect the page to OFBiz services/API.
4. Preserve permissions, auditability, and business workflow semantics.
5. Replace the legacy page only after visual and workflow checks pass.