Files
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

18 KiB

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

pnpm install
pnpm dev --port 5174
pnpm build
node scripts/generate-element-plus-inventory.mjs

Local preview:

http://localhost:5174/

Direct page preview:

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

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:

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:

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:

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:

{
  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:

elementPlusInventory.js  = package truth
erpComponentDocs.js      = OFBiz local usage and style truth

High-frequency ERP components already have concrete preview and ERP code patterns:

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:

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:

Element Plus primitive -> ERP wrapper/pattern -> OFBiz feature page

Example:

<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:

<ErpTable :rows="rows" :columns="columns" row-key="orderId" />

Component Decision Rules

Pick components by business task first, not by visual taste.

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.

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:

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:

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:

展示
原始代码
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:

#/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:

id
label
icon
title
description

Each file under src/components/showcase/ owns one documentation page:

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.

<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:

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:

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:

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:

<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:

<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:

src/styles/tokens.css
src/styles/element-overrides.css
src/styles/erp-patterns.css

Current reusable classes:

.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:

src/data/erpComponentDocs.js
  groupContracts
  groupGuidance
  previewGuidance
  componentDocOverrides
  erpComponentUsageMap
  erpLayoutPlaybook

Catalog UI and per-component detail layout live in:

src/components/showcase/ComponentCatalogShowcase.vue

Only product-reusable styling belongs in:

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:

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:

<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:

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:

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.