Files
yidaima/RuoYi-Vue/docs/superpowers/specs/2026-05-27-frontend-page-designer-design.md
2026-05-27 14:32:39 +08:00

9.7 KiB

Frontend Page Designer Design

Goal

Build a user-facing frontend page designer inside the EasyCode generation workbench. The designer lets a user configure generated portal pages visually, then stores the result in an independent front_project_page_design table so project generation can produce Vue frontend pages from the saved layout.

Scope

The first phase covers generated user-facing frontend pages only.

Included:

  • Initialize page design records from confirmed appBlueprint.frontendPages.
  • Show a menu/page tree for frontend pages.
  • Edit page metadata, bound table, route path, page type, layout regions, displayed fields, query fields, form fields, table row actions, and toolbar actions.
  • Save page design records independently from appBlueprint.
  • Use saved page designs during generated project preview and download.
  • Keep existing generation behavior as a fallback when no page design exists.

Excluded from phase one:

  • RuoYi admin page visual design.
  • Free-form nested low-code containers.
  • Runtime page rendering inside EasyCode beyond lightweight preview/wireframe.
  • Page design version history beyond a simple version field for optimistic locking.
  • Multi-user collaborative editing.

Current Context

The project already has these concepts:

  • AppBlueprintDesign contains roles, frontendMenus, adminMenus, and frontendPages.
  • AppPageDesign names generated frontend pages with code, menuCode, path, pageType, and tableName.
  • BusinessActionDesign.uiBindings can attach generated business actions to frontend page slots.
  • GenerateView.vue already orchestrates app blueprint generation, database design, business blueprint generation, and preview generation.
  • Qing templates already generate a Vue frontend shell and table-oriented frontend pages.

The new designer should sit between app blueprint/database design and project preview generation.

Architecture

Add a persistent page design layer:

appBlueprint.frontendPages
        |
        v
front_project_page_design
        |
        v
FrontendPageDesigner.vue
        |
        v
FrontProjectConverter / GenProject
        |
        v
Velocity templates

appBlueprint remains the source for application structure: menus, route entry points, and page codes. front_project_page_design becomes the source for how each generated frontend page is composed.

The generator reads page designs by project ID and exposes them to Velocity alongside tables, frontend pages, and business actions. If a page has no saved design, the generator builds a default design from the table columns and existing table CRUD flags.

Database

Create front_project_page_design.

Columns:

  • design_id bigint primary key.
  • project_id bigint, required.
  • user_id bigint, required.
  • page_code varchar(100), required. Matches AppPageDesign.code.
  • menu_code varchar(100), optional. Matches AppMenuDesign.code.
  • page_name varchar(100), required.
  • route_path varchar(255), required.
  • page_type varchar(50), required. Supported values: list, detail, form, current_user_list.
  • table_name varchar(100), required for table-backed pages.
  • layout_json longtext, required.
  • action_json longtext, optional.
  • status char(1), default 0.
  • version int, default 1.
  • RuoYi audit columns: create_by, create_time, update_by, update_time, remark.

Indexes:

  • Unique key on (project_id, page_code).
  • Normal index on (project_id, menu_code).
  • Normal index on (project_id, table_name).

Deletion behavior:

  • Deleting a project deletes its page designs.
  • Regenerating app blueprint does not automatically delete existing designs. The user can run initialization again to add missing designs and mark orphaned designs as detached.

Page Design DSL

layout_json stores layout composition:

{
  "canvas": "frontend-list-v1",
  "regions": [
    {
      "id": "query",
      "type": "query",
      "fields": ["title", "category", "status"]
    },
    {
      "id": "toolbar",
      "type": "toolbar",
      "actions": ["create", "export", "batchDelete"]
    },
    {
      "id": "table",
      "type": "table",
      "fields": ["cover", "title", "author", "stock", "status"],
      "rowActions": ["view", "edit", "delete"]
    },
    {
      "id": "form",
      "type": "dialogForm",
      "fields": ["title", "author", "category", "price"]
    }
  ]
}

action_json stores button/action configuration that is local to the page:

{
  "toolbarActions": [
    { "code": "create", "label": "Create", "type": "primary", "builtin": true },
    { "code": "export", "label": "Export", "type": "default", "builtin": true }
  ],
  "rowActions": [
    { "code": "view", "label": "View", "builtin": true },
    { "code": "borrow", "label": "Borrow", "businessActionCode": "borrow_book" }
  ]
}

Field names in layout_json reference DatabaseColumnDesign.javaField. The backend accepts database column names too, normalizes them to Java field names, and rejects unknown fields.

Backend API

Add routes under FrontProjectController:

  • GET /front/project/{projectId}/page-designs Returns all active page designs for the project, sorted by menu/page order.

  • POST /front/project/{projectId}/page-designs/init Creates missing page design records from appBlueprint.frontendPages. Existing records are preserved. Detached records are returned so the UI can show them separately.

  • GET /front/project/{projectId}/page-designs/{designId} Returns one page design with normalized layout and field metadata.

  • PUT /front/project/{projectId}/page-designs/{designId} Validates and saves metadata, layout_json, action_json, and version.

Validation rules:

  • The project must belong to the current frontend user.
  • page_code must be unique per project.
  • page_type must be one of the supported values.
  • table_name must exist in the saved database design when the page type is table-backed.
  • Region IDs must be unique inside a page.
  • Region types must be supported by the selected page type.
  • Fields must exist in the bound table.
  • Built-in actions must be allowed by table operation flags.
  • businessActionCode must exist in saved business blueprint when present.
  • Save rejects stale version values.

Frontend UI

Add FrontendPageDesigner.vue and integrate it into GenerateView.vue after database design and before business blueprint/preview.

Layout:

  • Left panel: frontend menu/page tree from page designs, grouped by menu and child pages.
  • Center panel: canvas with fixed first-phase regions based on page type.
  • Right panel: property editor for page metadata, bound table, fields, and actions.
  • Bottom toolbar: initialize from blueprint, save, reset to default, and show JSON.

First-phase interactions:

  • Select a page.
  • Add missing page designs from blueprint.
  • Reorder fields inside query/table/form regions.
  • Toggle fields visible/hidden.
  • Configure action labels and placement.
  • Bind business actions already present in businessActions.uiBindings.
  • View JSON for debugging and advanced edits.

Drag-and-drop is scoped to field/action ordering in phase one. The region list itself is fixed by page type to keep templates deterministic.

Generation

Extend project conversion/generation so GenProject includes page designs.

Generation behavior:

  • FrontProjectConverter loads saved page designs for the project.
  • GenProjectServiceImpl exposes page designs to Velocity context.
  • Qing frontend templates resolve the current table page design by page code or table name.
  • If a page design exists, templates render query fields, table columns, form fields, toolbar actions, and row actions from layout_json and action_json.
  • If no page design exists, templates use current behavior based on table columns and operation flags.

This keeps old projects compatible and lets users opt into page design gradually.

Error Handling

UI behavior:

  • If initialization cannot find frontendPages, show a warning asking the user to generate or apply the system module blueprint first.
  • If no database tables exist, allow menu/page metadata editing but disable table field regions.
  • If a bound table was deleted, mark the page as needing repair and block preview generation until fixed.
  • If save returns a stale version error, ask the user to reload the page design before saving again.

Backend behavior:

  • Return clear ServiceException messages for invalid field, table, page type, action, or stale version errors.
  • Do not mutate existing page designs when initialization fails midway.

Tests

Backend tests:

  • SQL schema script includes front_project_page_design.
  • Mapper inserts, updates, lists, and deletes project page designs.
  • Initialization creates designs from frontendPages and preserves existing records.
  • Validation rejects unknown fields, unknown tables, invalid page types, and stale versions.
  • Project deletion removes page designs.
  • Generator uses saved page design when present and falls back when absent.

Frontend tests:

  • Designer initializes and renders page tree from API data.
  • Field visibility and ordering update layout_json.
  • Saving sends normalized payload with version.
  • Generate page disables preview when page design validation reports repair-required state.

Template tests:

  • Qing index.vue.vm renders query fields, table columns, form fields, toolbar actions, and row actions from page design.
  • Existing template output remains valid when no page design exists.

Rollout

  1. Add database script and backend domain/mapper/service/API.
  2. Add frontend API functions and FrontendPageDesigner.vue.
  3. Integrate the designer into GenerateView.vue.
  4. Extend conversion and template generation.
  5. Add tests around validation and template output.
  6. Keep existing JSON editor paths available for app and business blueprints.