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
versionfield for optimistic locking. - Multi-user collaborative editing.
Current Context
The project already has these concepts:
AppBlueprintDesigncontains roles,frontendMenus,adminMenus, andfrontendPages.AppPageDesignnames generated frontend pages withcode,menuCode,path,pageType, andtableName.BusinessActionDesign.uiBindingscan attach generated business actions to frontend page slots.GenerateView.vuealready 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_idbigint primary key.project_idbigint, required.user_idbigint, required.page_codevarchar(100), required. MatchesAppPageDesign.code.menu_codevarchar(100), optional. MatchesAppMenuDesign.code.page_namevarchar(100), required.route_pathvarchar(255), required.page_typevarchar(50), required. Supported values:list,detail,form,current_user_list.table_namevarchar(100), required for table-backed pages.layout_jsonlongtext, required.action_jsonlongtext, optional.statuschar(1), default0.versionint, default1.- 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-designsReturns all active page designs for the project, sorted by menu/page order. -
POST /front/project/{projectId}/page-designs/initCreates missing page design records fromappBlueprint.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, andversion.
Validation rules:
- The project must belong to the current frontend user.
page_codemust be unique per project.page_typemust be one of the supported values.table_namemust 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.
businessActionCodemust exist in saved business blueprint when present.- Save rejects stale
versionvalues.
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:
FrontProjectConverterloads saved page designs for the project.GenProjectServiceImplexposes 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_jsonandaction_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
ServiceExceptionmessages 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
frontendPagesand 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.vmrenders 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
- Add database script and backend domain/mapper/service/API.
- Add frontend API functions and
FrontendPageDesigner.vue. - Integrate the designer into
GenerateView.vue. - Extend conversion and template generation.
- Add tests around validation and template output.
- Keep existing JSON editor paths available for app and business blueprints.