不手写 Vue 页面的前端开发:高代码模式与 14 种页面模式

这套做法里,业务开发者只写 TypeScript 子类,页面由固定的解析页面渲染。14 种页面模式覆盖列表、树表、向导、大屏等常见场景。

面向模式的高代码开发

摘要 :本文阐述驰骋 BPM/CCFlow 体系中「面向模式的编程」(Pattern-Oriented Development)方法论。该方法将前端页面抽象为若干可复用的页面模式 ,每种模式由基类 定义规则、由子类 实现业务、由解析页面 (Vue 组件)统一渲染,形成「定义---实现---解析」的铁三角架构。与将业务规则存入数据库、由运行时解析的低代码模式相对,高代码模式以 TypeScript 类文件作为业务载体,借助 ORM 思想实现规则的定义与持久化。本文结合 Vue3/src 真实代码,逐一说明 14 种页面模式的作用范围、应用场景与实现要点。


第一章 高代码与低代码

1.1 低代码开发模式

低代码模式指通过拖拉拽设计器生成应用行为的方式。在驰骋平台中,典型入口包括:实体设计、大屏设计、视图设计、表单设计器等。

核心特征:

维度 说明
规则载体 数据库表(如 Sys_MapAttr、Sys_MapData、菜单配置表等)
实现路径 梳理规则 → 定义规则 → 存储规则 → 解析规则
页面生成 设计器将元数据写入库表,前端通用解析器读取元数据动态渲染
数据库依赖 高度依赖------字段、布局、查询条件、权限等均落库

低代码适合标准化、配置驱动的场景:快速搭建 CRUD、调整字段可见性、切换列表样式等,无需重新编译前端。

1.2 高代码开发模式

高代码模式指通过 TypeScript 类文件 描述页面操作行为与展现效果的工作方式。业务规则的载体是代码文件;规则的「定义」与「解析」通过面向对象的 ORM 体系完成------实体类 EnMap 描述数据结构,页面基类描述交互行为,解析页面读取基类/子类状态后渲染 UI。

核心特征:

维度 说明
规则载体 .ts 源文件(持久化在代码仓库 / 编译产物中)
实现路径 梳理规则 → 定义规则 → 解析规则(无独立的「存储到库表」环节)
页面生成 子类继承基类,重写 Init() 等方法;解析页面反射加载子类并绑定 UI
灵活性 可编写任意业务逻辑、复杂算法、外部 API 集成

1.3 两种模式的对比

scss 复制代码
低代码:  业务元数据 ──写入──▶ 数据库 ──读取──▶ 通用解析器 ──▶ 页面
高代码:  子类 .ts 文件 ──继承──▶ 基类 ──加载──▶ 解析页面(.vue) ──▶ 页面

二者并非对立,而是在同一平台内互补:低代码负责「可配置的标准能力」,高代码负责「不可配置或高度定制的能力」。驰骋 BPM 的主体功能(流程、表单、组织、单据)大量采用高代码模式实现,低代码设计器则用于元数据维护与快速原型。


第二章 基本理念

2.1 定义

面向模式的编程 (亦称高代码开发 )是:利用代码描述页面操作行为与展现效果的工作方式。开发者不直接编写 .vue 页面,而是编写继承自模式基类的 TypeScript 子类;由少量固定的解析页面读取子类配置,完成 UI 渲染与事件分发。

2.2 抽象:13+1 种页面模式

系统将常见应用场景抽象为 14 种页面模式(用户材料中列举 13 种核心模式 + Panel 等扩展)。每种模式对应:

  • 1 个基类 (PageBase* / Entity / DataVBase / TabsBase)
  • N 个子类 (GL_*、GPN_*、TreeEns_*、GPE_*、PG_* 及实体类等)
  • 1 个(或少数几个)解析页面 (GenerList.vue、En.vue、Search.vue 等)
序号 模式标识 中文名称 基类 解析页面 子类命名惯例
1 GenerList 通用列表 PageBaseGenerList GenerList.vue GL_*
2 TreeEns 左树右表 PageBaseTreeEns TreeEns.vue TreeEns_*
3 GPN 新建(分步/分组) PageBaseGroupNew GroupPageNew.vue GPN_*
4 GPE 枚举/分组编辑 PageBaseGroupEdit GroupPageEdit.vue GPE_*
5 Entity 实体编辑 Entity En.vue / EnOnly MapAttr*、Student 等
6 Search 查询 Entity + EnCfg Search.vue 同实体类
7 Ens 批量编辑 Entities Ens.vue 同实体类
8 Group 分组分析 Entity + 分组配置 SearchGroup 组件 同实体类
9 DtlSearch 从表查询 Entity(从表) DtlSearch.vue 同实体类
10 DtlBatch 从表批量编辑 Entity(从表) DtlBatch.vue 同实体类
11 Tabs 标签页容器 TabsBase Tabs.vue Tabs_*
12 DataV 大屏 DataVBase views/data_visualization DataV_*
13 Panel Icon 列表 GenerList(BigIcon 等) GenerList.vue 低代码列表入口
14 PanelGroup 分组编辑面板 PageBasePanelGroup PanelGroup.vue PG_*

说明 :Search、Ens、Group、DtlSearch、DtlBatch 与 Entity 共用同一实体类 ;差异体现在 EnCfg 组件展现配置及打开的解析页面不同。这是 ORM 思想在前端的典型体现------一份实体定义,多种视图模式。

2.3 设计思路

把后端面向对象的编程思想搬到前端:

  • 基类 :封装页面骨架、公共属性、抽象方法(如 Init()、BtnClick())
  • 子类:只写与本业务相关的列定义、数据源、按钮响应
  • 继承与封装:子类不可绕过基类契约,保证「千人一面」
  • 多态 :解析页面通过 ClassID 工厂加载不同子类,同一解析器呈现不同业务

2.4 技术储备

学习该模式之前,需要深刻理解:

  • 面向对象:基类、子类、继承、封装、多态
  • TypeScript 类与抽象类
  • 驰骋 ORM:Entity、Map、Entities、EnMap 属性定义
  • 异步数据:Retrieve、Insert、Update、HttpHandler

2.5 页面模式的定义

页面模式 :具有相同布局 与相同操作行为的页面,归为一种模式。

例如:待办列表与已办列表布局一致(工具栏 + 表格 + 行按钮),仅数据源不同 → 同属 GenerList 模式;流程属性编辑与节点属性编辑都是「左侧分组 + 右侧表单项」→ 同属 GPE 或 Entity 模式。


第三章 设计图:铁三角

面向模式开发的核心架构是 基类 --- 子类 --- 解析页面 构成的铁三角:

各环节职责与流向对照:

流向 内容
子类 → 基类 继承模式契约(Init、BtnClick 等抽象方法)
子类 → 解析页面 ClassFactory 按 ClassID 动态加载子类实例
基类 → 解析页面 属性契约:Columns / Data / SubPages
解析页面 → 界面 读取 Init 结果渲染统一风格 UI
界面 → 子类 用户操作回调 BtnClick / LinkFieldClick

三者职责:

角色 职责 是否随业务增长
基类 定义模式契约、公共属性、抽象方法 极少变动
子类 业务规则:列、数据、按钮、校验 每个功能一个文件
解析页面 布局、组件库、路由、弹窗框架 极少变动;技术升级主要改这里

铁三角的价值:业务逻辑(子类)与展现技术(解析页面)分离。升级 Vue 版本、替换 UI 组件库时,只需改造解析层,数千个子类文件无需重写。

代码锚点------工厂加载子类(以通用列表为例):

typescript 复制代码
// WF/GenerList/ClassFactoryOfGenerList.ts(概念示意)
export class ClassFactoryOfGenerList {
  public static GetEn(classID: string): PageBaseGenerList {
    // 根据 classID 动态 import 对应 GL_* 子类
  }
}

解析页面 GenerList.vue 在 InitPage 时调用工厂,获得子类实例,再读取其 Columns、Data、PageTitle 等属性绑定到表格。


第四章 驰骋低代码平台模式数据

驰骋 BPM / CCFlow 前端 Vue3/src 中,各模式子类文件数量(统计口径:仓库内 *_*.ts 文件,含 Demo/App 扩展):

# 模式 名称 基类 子类数量(约) 典型应用
1 GenerList 通用列表 PageBaseGenerList 122 发起、待办、在途、抄送、已完成、近期
2 TreeEns 左树右表 PageBaseTreeEns 21 组织结构、流程树、表单树、数据源管理
3 GPN 新建 PageBaseGroupNew 161 新建流程、表单、人员、菜单、条件
4 GPE 枚举/分组编辑 PageBaseGroupEdit 121 接收人规则、发起规则、考核规则、超时规则
5 Entity 实体 Entity 500+ 流程属性、节点属性、字段属性、业务实体
6 Search 查询 同 Entity 同实体 流程查询、待办查询、单据查询
7 Ens 批量编辑 同 Entity 同实体 批量修改、导入前编辑
8 Group 分组分析 同 Entity 同实体 按维度汇总、分组报表
9 DtlSearch 从表查询 同 Entity 同实体 从表数据浏览
10 DtlBatch 从表批量编辑 同 Entity 同实体 从表行内编辑、批量维护
11 Tabs 标签页 TabsBase 2 人员/岗位/岗位类型维护
12 DataV 大屏 DataVBase 8 管理员主页、人员主页、单流程统计
13 Panel Icon 列表 GenerList 展示模式 1 低代码实体列表(BigIcon)
14 PanelGroup 分组编辑 PageBasePanelGroup 6 菜单模块、表单分类、流程分类

数据说明:GPN/GL/GPE 数量为文件名匹配统计;Entity 为 extends Entity 的类文件,涵盖流程、表单、单据、Demo 等全域实体。数字随版本迭代变化,量级可说明「模式化开发已规模化落地」。


第五章 各模式详解

本章按模式逐一说明:模式描述 、作用范围 、应用场景 、基类与解析页面 、代码示例。


5.1 模式一:GenerList(通用列表)

模式描述

GenerList 是驰骋平台使用最广泛的列表模式。子类在 Init() 中定义列(Columns)、加载数据(Data)、配置工具栏与行按钮;解析页面 GenerList.vue 负责表格/分组/窗口/图表等多种展示形态。

作用范围
  • 不需要左侧树的纯列表页
  • 支持表格、大图标、分组图标、窗口卡片、饼图/柱图/折线图等展示
  • 支持关键字、日期范围、外键条件下拉、列头筛选
应用场景
场景 子类示例
待办工作 GL_Todolist
在途流程 GL_Runing
抄送 GL_CC
已完成 GL_Complete
近期发起 GL_Start / GL_RecentStart
单据待办 GL_BillTodolist
基类关键 API
typescript 复制代码
// bp/UIEntity/PageBaseGenerList.ts
export abstract class PageBaseGenerList {
  public PageTitle: string | null = '待办';
  public Columns: Array<Record<string, any>> = [];
  public Data: Array<Record<string, any>> = [];
  public HisGLShowModel = GenerListPageShowModel.Table; // 展示模式
  public LinkField = 'Title';                          // 链接列
  public BtnOfToolbar = '';                            // 工具栏按钮
  public BtnsOfRow = '';                               // 行按钮

  abstract Init();
  abstract LinkFieldClick(object: Record<string, any>, linkField?: string);
  abstract BtnClick(btnName: string, record: Record<string, any>, ids?: string);
}
子类示例:待办列表
typescript 复制代码
// WF/GenerList/GL_Todolist.ts
export class GL_Todolist extends PageBaseGenerList {
  constructor() {
    super('GL_Todolist');
    this.PageTitle = '待办';
  }

  async Init() {
    this.DTFieldOfSearch = 'RDT';
    this.LinkField = 'Title';
    this.GroupFields = 'NodeName,FlowName,StarterName';
    this.PageSize = 15;
    this.HisGLShowModel = GenerListPageShowModel.Table;

    this.Columns = [
      { Key: 'Title', Name: '标题', IsShow: true, width: 350 },
      { Key: 'StarterName', Name: '发起人', IsShow: true, width: 100 },
      { Key: 'RDT', Name: '发起日期', IsShow: true, DataType: DataType.AppDateTime },
      { Key: 'NodeName', Name: '停留节点', IsShow: true, enableSearch: true },
      // ...
    ];

    const handler = new HttpHandler('BP.WF.HttpHandler.WF');
    handler.AddUrlData();
    const data = await handler.DoMethodReturnJson('Todolist_Init');
    this.Data = data;
  }

  LinkFieldClick(record) {
  // 打开 MyFlow 处理页
  }

  BtnClick(btnName, record, ids) {
  // 批处理、删除等
  }
}
解析页面

WF/views/GenerList.vue:读取子类 Columns/Data,渲染 Ant Design Vue / Naive UI 表格,处理分页、导出、打印、密度切换。


5.2 模式二:TreeEns(左树右表)

模式描述

左侧树形导航 + 右侧明细列表的经典布局。树节点与明细通过 RefKey 关联;支持懒加载、拖拽排序、右键菜单、节点增删改。

作用范围
  • 层级结构 + 明细数据联动
  • 组织、分类、目录类业务
  • 右侧可为表格、Search、GenerList 或纯实体列表
应用场景
场景 子类示例
组织人员 TreeEns_Dept2Emp
流程分类 TreeEns_FlowSort2Flow
表单分类 TreeEns_FrmSort2Frm
数据源 TreeEns_DBSrc
网盘目录 TreeEns_DirectoryTree2FileDtl
基类关键 API
typescript 复制代码
// bp/UIEntity/PageBaseTreeEns.ts
export abstract class PageBaseTreeEns {
  public TreeEns?: EntitiesNoName;  // 树实体集合
  public DtlEns?: EntitiesNoName;   // 右侧明细集合
  public RefKey: string | null = 'FK_Dept';
  public RootNo = '0';
  public IsLazy = false;
  public Columns: Array<Record<string, any>> = [];

  abstract BtnClick(btnLab, treeNodeID, itemIDs, treeNodeOrgNo, record);
  async GetDataByTreeNodeID(treeNodeID: string) { /* 按树节点过滤明细 */ }
}
子类示例:组织结构
typescript 复制代码
// WF/Admin/Organization/TreeEns_Dept2Emp.ts
export class TreeEns_Dept2Emp extends PageBaseTreeEns {
  constructor() {
    super('TreeEns_Dept2Emp');
    this.PageTitle = '组织结构';
  }

  override async Init(rootNo = '0') {
    this.IsLazy = true;
    const trees = new Depts();
    await trees.Retrieve('ParentNo', rootNo, 'Idx');
    this.TreeEns = trees;

    this.DtlEns = new Emps();
    this.RefKey = 'FK_Dept';

    this.Columns = [
      { id: 'Name', name: '名称', IsShow: true, Width: 300 },
      { id: 'StationName', name: '岗位名称', IsShow: true },
      // ...
    ];
  }

  BtnClick(btnLab, treeNodeID, itemIDs, treeNodeOrgNo, record) {
    // 新建人员、批量删除、角色维护等
  }
}

5.3 模式三:GPN(Group Page New,新建)

模式描述

GPN 用于分步新建 、分组向导 场景。开发者在 Init() 中调用 AddGroup、TextBox1_Name、SelectItemsByList、FileUpload 等声明式 API 描述表单项;解析页面 GroupPageNew.vue 渲染分步表单并收集参数,最终调用子类 Save() 完成持久化。

作用范围
  • 新建实体前的信息采集(一步或多步)
  • 需要分组展示、图标、帮助文档的创建向导
  • 支持返回 GPNReturnObj 打开抽屉、跳转 URL、关闭弹窗等
应用场景
场景 子类示例
新建流程 GPN_NewFlow
新建表单 GPN_NewFrm
新建人员 GPN_Emp
新建菜单 GPN_Menu
新建条件 GPN_Cond
基类关键 API
typescript 复制代码
// bp/UIEntity/PageBaseGroupNew.ts
export abstract class PageBaseGroupNew {
  public SubPages: Pages;
  public Groups: Groups;

  abstract Init();
  abstract Save(pageID, sortNo, ...tbValues): Promise<GPNReturnObj>;

  public AddGroup(no: string, name: string) { /* 增加分组 */ }
  public TextBox1_Name(pageNo, name, help, label, defaultVal) { /* 单文本框 */ }
  public SelectItemsByGroupList(pageNo, name, help, multi, groupSrc, itemSrc) { /* 分组列表选择 */ }
}
子类示例:新建流程
typescript 复制代码
// WF/Admin/FlowLogic/GPN_NewFlow.ts
export class GPN_NewFlow extends PageBaseGroupNew {
  constructor() {
    super('GPN_NewFlow');
    this.PageTitle = '新建流程';
  }

  public async Init() {
    this.AddGroup('A', '内置表单模式');
    this.TextBox1_Name('JiJian', '极简模式', GPN_NewFlow.JiJian, '流程名称', '我的极简流程');
    this.AddIcon('icon-paper-plane', 'JiJian');

    this.AddGroup('B', '绑定表单模式');
    this.TextBox1_Name('RefOneFrmTree', '绑定单表单', GPN_NewFlow.RefFrm, '流程名称', '我的单表单流程');
    this.SelectItemsByGroupList('RefOneFrmTree.SelectOneFrm', '选择表单', ...);

    this.AddGroup('D', '使用高代码');
    this.TextBox1_Name('EntityTS', '绑定高代码', this.EntityTS, '流程名称', '我的高代码流程');
  }

  // Save() 中根据 pageID 创建不同模式的流程
}

5.4 模式四:GPE(Group Page Edit,枚举/分组编辑)

模式描述

GPE 用于编辑某一实体上的枚举字段 或一组相关配置项 。左侧分组导航 + 右侧单选/下拉/表格/自定义组件;每次修改往往直接写回实体字段(如节点的 DeliveryWay)。

作用范围
  • 一个字段多种取值,且每种取值对应不同子配置页
  • 流程节点规则、表单扩展、字段行为配置
  • 支持 SingleEnumRadioButon、SingleEnumDDL、SelfComponent 等编辑模型
应用场景
场景 子类示例
接收人规则 GPE_AccepterRole
超时处理 GPE_OvertimeRole
抄送规则 GPE_CCRole
字段弹窗 GPE_Pop
发起限制 各 GPE_* 节点/流程规则类
子类示例:接收人规则
typescript 复制代码
// WF/Admin/AttrNode/AccepterRole/GPE_AccepterRole.ts
export class GPE_AccepterRole extends PageBaseGroupEdit {
  constructor() {
    super('GPE_AccepterRole');
    this.PageTitle = '接收人规则';
  }

  async Init() {
    this.entity = new Node();
    this.KeyOfEn = NodeAttr.DeliveryWay; // 绑定枚举字段

    this.AddGroup('A', '按组织结构绑定');
    this.SingleEnumRadioButon('ByStation', '按角色智能计算', 'DeliveryWay', help, 'DeliveryWay', '@0=...');
    // 每种规则对应不同子页面与保存逻辑
  }
}

5.5 模式五:Entity(实体编辑)

模式描述

Entity 是 ORM 的核心。每个业务对象对应一个实体类,在 EnMap 中声明表名、字段、分组、外键、附件、从表等;解析页面 En.vue 根据 EnMap 自动生成表单,并挂载「相关功能」菜单(Search、GPN、GPE、GL 等)。

作用范围
  • 单条记录的增删改查
  • 属性页、配置页、主数据维护
  • 实体可嵌套从表、附件、关联查询
应用场景
场景 子类示例
文本字段属性 MapAttrString
数值字段属性 MapAttrNum
流程定义 FlowExt
节点定义 NodeExt
业务主数据 Student、Emp
子类示例:学生实体
typescript 复制代码
// App/Demo/Student.ts
export class Student extends EntityNoName {
  constructor(pkval?: string) {
    super('TS.Demo.Student');
    if (!!pkval) this.setPKVal(pkval);
  }

  public override get EnMap() {
    const map = new Map('Demo_Student', '学生');
    map.AddGroupAttr('基本字段');
    map.AddTBStringPK('No', null, '编号', true, true, 4, 4, 80);
    map.AddTBString('Name', null, '名称', true, false, 0, 200, 80);
    map.AddDDLSysEnum('ZZMM', 0, '政治面貌', true, true, 'ZZMM', '@0=少先队员@1=团员@2=党员');
    map.AddDDLEntities('BanJiNo', null, '班级', new BanJi(), true);
    // 相关功能:查询、新建、报表等通过 RefMethod 挂载
    return map;
  }
}
解析页面

WF/Comm/En.vue:加载实体 → 渲染 EnOnly 表单 → 左侧「相关功能」树 → 内嵌打开 GPE/GPN/GL/Search 等子页面。


5.6 模式六:Search(查询)

模式描述

Search 与 Entity 共用实体类 ,通过 EnCfg(组件展现设置)配置查询列、条件、焦点字段、工具栏按钮等。解析页面 Search.vue 读取实体 EnMap + EnCfg,渲染查询工具栏与结果表格。

作用范围
  • 主数据列表查询
  • 多条件组合、日期段、数值区间、Pop 弹窗选值
  • 点击焦点字段打开 En.vue 详情
应用场景

流程查询、学生查询、单据查询、历史数据检索等------凡是以「条件筛选 + 列表展示」为主的页面。

实现要点
typescript 复制代码
// bp/sys/EnCfg.ts --- 组件展现设置(节选)
export class EnCfg extends EntityNoName {
  public override get EnMap() {
    const map = new Map('Sys_EnCfg', '组件展现设置');
    map.AddTBStringPK('No', null, '实体名称', true, true, 1, 100, 60);
    map.AddBoolean('IsEnableFocusField', false, '是否启用焦点字段?', true, true);
    map.AddTBString('FocusField', null, '焦点字段', true, false, 0, 30, 60);
    // 查询列、排序、按钮等配置...
    return map;
  }
}

访问方式:GloComm.UrlSearch(enName, paras) → Search.vue?EnName=TS.Demo.Student&...


5.7 模式七:Ens(批量编辑)

模式描述

对实体集合进行表格内批量编辑 :可编辑列、拖拽排序、批量保存、导入导出。共用实体类,解析页面为 Ens.vue。

作用范围
  • 需要同时修改多行字段
  • 维护类从表、排序类数据
  • 与 Search 互补:Search 偏浏览,Ens 偏编辑
应用场景

批量修改状态、批量调整序号、简易数据维护屏。


5.8 模式八:Group(分组分析)

模式描述

在 Search 基础上按指定维度分组汇总 展示,解析组件为 SearchGroup(嵌入 SearchBill.vue 或 Search.vue 的 displayMode === 'group')。

作用范围
  • 分组统计、分类汇总
  • 按部门/类型/状态聚合列表
应用场景

单据按状态分组、学生按班级分组、报表式分组浏览。


5.9 模式九:DtlSearch(从表查询)

模式描述

专用于从表 (明细表)的查询浏览,解析页面 WF/Comm/Dtl/DtlSearch.vue。从表实体同样在 EnMap 中定义,通过主表 PK 过滤。

作用范围
  • 主从结构中的「从」侧只读或轻量浏览
  • 从表字段较多、需独立开窗查询
应用场景

订单明细、简历明细、流程子表数据查询。


5.10 模式十:DtlBatch(从表批量编辑)

模式描述

从表的行内编辑 与批量维护,解析页面 WF/Comm/Dtl/DtlBatch.vue。支持可编辑列定义、拖拽排序、批量删除。

作用范围
  • 从表需要频繁增删改
  • 明细行数多、表单内嵌展示空间不足
应用场景

学生成绩明细、费用明细、从表批量录入。


5.11 模式十一:Tabs(标签页)

模式描述

TabsBase 子类在 Init() 中通过 AddSearch、AddGL、AddSelfUrl 注册多个标签;解析页面统一渲染 Tab 栏,每个 Tab 内嵌已有模式页面。

作用范围
  • 同一业务对象多种视图并列
  • 减少菜单项、聚合相关功能
应用场景
typescript 复制代码
// WF/Admin/Tabs_FlowApp.ts
export class Tabs_FlowApp extends TabsBase {
  constructor() {
    super('Tabs_FlowApp');
    this.PageTitle = '流程应用';
  }

  override Init() {
    this.AddSearch('学生女', 'icon-drop', 'TS.Demo.Student', '&XB=0');
    this.AddSearch('学生男', 'icon-drop', 'TS.Demo.Student', '&XB=1');
    this.AddGL('待办', 'icon-drop', 'GL_Todolist', '&FlowNo=001');
  }
}

人员/岗位/岗位类型维护等综合管理页。


5.12 模式十二:DataV(大屏)

模式描述

DataVBase 子类在 Init() 中通过 AddChartPie、AddChartZZT、AddHtmlDtls、Self_TodolistAdmin 等方法组装大屏区块;解析页面 views/data_visualization/index.vue 按网格布局渲染图表与自定义组件。

作用范围
  • 管理驾驶舱、个人主页
  • 统计图表、指标卡片、流程动态
应用场景
typescript 复制代码
// WF/Admin/DataV_HomeAdmin.ts
export class DataV_HomeAdmin extends DataVBase {
  constructor() {
    super('DataV_HomeAdmin');
    this.PageTitle = 'Admin统计';
  }

  override async Init() {
    this.Self_Know();
    this.Self_MovementFlowAdmin();
    this.Self_TodolistAdmin();
    this.Self_RuningAdmin();
    this.AddHtmlDtls({
      title: '平台数据',
      icon: 'icon-settings',
      colSpan: 4,
      children: [
        { icon: 'icon-organization', title: '支持组织结构', docs: '单组织、集团、SAAS' },
        // ...
      ],
    });
  }
}

管理员主页、人员主页、单流程数据统计(DataV_OneFlowAdmin / DataV_OneFlowEmp)。


5.13 模式十三:Panel(Icon 列表)

模式描述

Panel 并非独立基类,而是 GenerList 的 Icon 展示模式 (GenerListPageShowModel.BigIcon / GroupBigIcon),或低代码实体在设计器中配置的「列表入口」。系统列表、应用入口等以大图标卡片呈现。

作用范围
  • 应用门户、功能导航
  • 低代码配置的实体列表面板
应用场景

低代码实体列表、「我的系统」类大图标入口(HisGLShowModel = GenerListPageShowModel.BigIcon)。


5.14 模式十四:PanelGroup(分组编辑面板)

模式描述

分组 + 明细分组面板 编辑模式。左侧(或顶部)为分组列表,组内为明细项;支持分组/明细拖拽排序、组内新建、Icon 点击事件。基类 PageBasePanelGroup,解析页面 PanelGroup.vue。

作用范围
  • 两级结构:分类 + 项
  • 菜单模块、方法分组等「先选组、再管项」场景
  • 支持 Table 与 Icon 两种列表模式(ListModel)
应用场景
typescript 复制代码
// CCFast/GPM/PG_Module2Menu.ts
export class PG_Module2Menu extends PageBasePanelGroup {
  constructor() {
    super('PG_Module2Menu');
    this.PageTitle = '模块/菜单';
    this.HisListModel = ListModel.Table;
  }

  public async Init() {
    this.BtnsTop = '新建模块';
    this.BtnsEnGroup = '新建模块,新建菜单,权限';
    this.GroupsEns = await new Modules().Retrieve('SystemNo', this.PKVal, 'Idx');
    this.DtlEns = await new Menus().Retrieve('SystemNo', this.PKVal, 'Idx');
    this.RefKey = MenuAttr.ModuleNo;
    this.IsGroupMove = true;
    this.IsEnMove = true;
  }
}

菜单/模块管理(PG_Module2Menu)、流程分类(PG_FlowSort2Flow)、表单分类(PG_FrmSort2Frm)。


第六章 模式协作与实体相关功能

实体 EnMap 可通过 RefMethod 挂载其他模式,形成以实体为中心的功能网络:

typescript 复制代码
// bp/en/Map/RefMethod.ts(概念)
// 实体属性页可挂载:
// - RefMethodType.GroupPageNew  → GPN
// - RefMethodType.GroupPageEdit → GPE
// - RefMethodType.GenerList     → GL
// - RefMethodType.PanelGroup    → PG
// - Search / Ens / Tabs / DataV ...

En.vue 根据 RefMethodType 分发到对应解析组件------这是铁三角在组合维度的延伸:实体是 hub,各模式是 spoke。

URL 统一入口 (WF/Comm/GloComm.ts):

typescript 复制代码
GloComm.UrlGenerList(classID, paras);   // 通用列表
GloComm.UrlGPN(classID, pkval, paras);  // 新建
GloComm.UrlSearch(enName, paras);       // 查询
// 以及 En、TreeEns、DataV 等

第七章 实施的成功标准

驰骋团队在实践中将以下三条作为高代码模式落地的验收标准:

标准一:基本全栈模式化开发

业务功能优先通过 14 种模式子类实现,而非从零编写页面。前端、后端均遵循 Entity/Handler 体系,形成可复制的开发流水线。

标准二:一般不开发 .vue 页面

新业务默认只写 TypeScript 子类 (GL_*、GPN_*、实体类等)。.vue 文件限定在「解析层」与极少数特殊交互;避免业务逻辑散落在 Vue 单文件组件中。

标准三:不需要美工、测试人力显著下降

  • 不需要美工:解析页面统一视觉与交互,子类不涉及 CSS 布局
  • 测试人员减少约 70%:同一模式行为一致,回归测试可针对解析层;子类主要验证业务数据与按钮逻辑

第八章 优点

8.1 风格统一

所有 GenerList 待办、已办、在途页面共用 GenerList.vue,工具栏位置、表格密度、导出打印交互完全一致。统一解析 → 统一风格 → 统一操作习惯 → 培训成本极低。

8.2 代码规范

基类对子类形成强制性约束:

  • 必须实现 Init()、BtnClick() 等抽象方法
  • 列定义必须遵循 Columns 结构
  • 工厂按 ClassID 注册,避免「野生页面」

实施人员、二开人员代码结构一致,实现千人一面。

8.3 容易升级

前端技术演进时:

vbnet 复制代码
升级前:GenerList.vue + 122 个 GL_*.ts
升级后:GenerList.vue'(新组件库)+ 122 个 GL_*.ts(无需修改)

业务逻辑与展现技术解耦,使平台可跟进 Vue、UI 库、构建工具的版本更新,而不牵一发而动全身。

8.4 可度量、可治理

模式文件数量可统计(见第四章),代码评审可针对「是否选错模式」「是否在子类写 UI」等明确规则,利于大型团队治理。


第九章 开发实践建议

9.1 如何选择模式

需求特征 推荐模式
纯列表、工作台 GenerList
树 + 列表联动 TreeEns
向导式新建 GPN
枚举/规则配置 GPE
单条表单编辑 Entity
条件查询 + 列表 Search
批量改多行 Ens
分组汇总 Group
从表明细 DtlSearch / DtlBatch
多 Tab 聚合 Tabs
驾驶舱 DataV
分类 + 项维护 PanelGroup

9.2 子类开发最小步骤(以 GenerList 为例)

  1. 在 WF/GenerList/ 或业务目录新建 GL_MyFeature.ts
  2. extends PageBaseGenerList,super('GL_MyFeature')
  3. 实现 Init():配置 Columns、请求数据填充 Data
  4. 实现 LinkFieldClick、BtnClick
  5. 在 ClassFactoryOfGenerList 注册类名
  6. 菜单或 RefMethod 配置 URL:GenerList.vue?EnName=GL_MyFeature

9.3 与低代码的配合

  • 实体字段、表单布局:低代码设计器维护 EnMap 元数据
  • 复杂列表、特殊新建流程:高代码 GL_* / GPN_* 扩展
  • EnCfg 桥接两者:低代码配置 Search 列,高代码实体提供数据源

第十章 结论

面向模式的高代码开发,本质是将前端页面开发从「手工 UI 编程」转变为「选模式 → 写子类 → 由解析器呈现」的工业化流程。铁三角(基类、子类、解析页面)保证了:

  1. 业务可表达:TypeScript 全能力,无低代码表达力天花板
  2. 体验可统一:解析层集中管控 UI/UX
  3. 演进可持续:技术升级与业务扩展解耦

驰骋 BPM 在 Vue3/src 中以 500+ 实体、120+ GL、160+ GPN、120+ GPE 的规模验证了该方法论。对于企业级 BPM、单据、组织权限等复杂系统,面向模式的高代码开发是一条可复制、可治理、可度量的工程化路径。


附录 A:基类与解析页面路径速查

模式 基类路径 解析页面路径
GenerList bp/UIEntity/PageBaseGenerList.ts WF/views/GenerList.vue
TreeEns bp/UIEntity/PageBaseTreeEns.ts WF/Comm/TreeEns.vue
GPN bp/UIEntity/PageBaseGroupNew.ts WF/Comm/UIEntity/GroupPageNew.vue
GPE bp/UIEntity/PageBaseGroupEdit.ts WF/Comm/UIEntity/GroupPageEdit.vue
Entity bp/en/Entity.ts WF/Comm/En.vue
Search Entity + bp/sys/EnCfg.ts WF/Comm/Search.vue
Ens bp/en/Entities.ts WF/Comm/Ens.vue
DtlSearch Entity WF/Comm/Dtl/DtlSearch.vue
DtlBatch Entity WF/Comm/Dtl/DtlBatch.vue
Tabs bp/UIEntity/TabsBase.ts WF/Comm/Tabs.vue
DataV bp/UIEntity/DataVBase.ts views/data_visualization/index.vue
PanelGroup bp/UIEntity/PageBasePanelGroup.ts WF/Comm/PanelGroup.vue

附录 B:子类文件命名规范

前缀 模式 示例
GL_ GenerList GL_Todolist
TreeEns_ 左树右表 TreeEns_Dept2Emp
GPN_ 新建 GPN_NewFlow
GPE_ 分组编辑 GPE_AccepterRole
PG_ PanelGroup PG_Module2Menu
DataV_ 大屏 DataV_HomeAdmin
Tabs_ 标签页 Tabs_FlowApp
TS.* / 业务名 Entity TS.Demo.Student

相关推荐
开源驰骋低代码_工作流1 天前
从评估维度到场景匹配:工作流引擎选型实践对照
bpmn-js
开源驰骋低代码_工作流4 天前
只做加法不重构:流程引擎的长期演进是怎么做到的
bpmn-js
开源驰骋低代码_工作流4 天前
前后端分离下的流程集成:一份 Toolkit 落地清单
bpmn-js
开源驰骋低代码_工作流11 天前
交互层是产品还是框架:四大菜单与三大处理器的对比视角
bpmn-js
开源驰骋低代码_工作流18 天前
不做甘特图控件:流程引擎之上的工程运行时怎么设计
bpmn-js
开源驰骋低代码_工作流18 天前
三类任务、一个工作台:把项目执行收进流程平台的产品设计
bpmn-js
开源驰骋低代码_工作流19 天前
同一道请假审批,六款 Java 工作流引擎的实现路径与成本对比
bpmn-js
开源驰骋低代码_工作流19 天前
把请假审批交给六款 .NET 引擎:实现路径、场景适配与相对打分
bpmn-js
开源驰骋低代码_工作流24 天前
不走寻常路的 ORM:Map/Attr 元数据体系如何同时驱动持久化与表单渲染
bpmn-js