业务场景:让数据价值触手可及
在现代企业数字化转型进程中,数据不仅是资产,更是决策的核心驱动力。以“经费申请”系统为例,用户不仅需要查看列表数据,更希望在操作界面中实时掌握关键业务指标——如“年度申请总额”、“当前选中记录的金额汇总”等。 传统开发模式下,这类统计功能需前后端协同开发,涉及接口设计、数据聚合、UI 布局调整等多个环节,开发周期长、维护成本高。而在 Oinone 低代码平台 中,我们通过高度可扩展的组件化架构与灵活的布局引擎,仅需数个文件即可实现完整的统计功能集成,真正做到了“零侵入、高复用、快交付”。
实现步骤:优雅实现表格统计功能
Oinone 平台凭借其模块化设计哲学与声明式布局能力,允许开发者以极简方式扩展系统功能。以下以“经费申请”模块为例,展示如何在表格工具栏中动态集成统计数据组件。
1. 创建模块目录结构
在 layout 目录下新建 TrainingFee 模块文件夹,用于组织相关组件。
2. 构建四大核心文件
TrainingFeeStatistics.vue:UI 层组件,负责呈现统计信息TrainingFeeStatisticsWidget.ts:逻辑层组件,封装数据获取与状态管理index.ts:模块导出入口Register.ts:布局注册器,实现组件动态注入
TrainingFeeStatistics.vue —— 精致 UI,极致体验
<template>
<div class="action-bar-container">
<slot name="tableAction"></slot>
<div class="statistic">
申请总额:{{ yearTotalAmount }}元
<span style="margin-left: 5px" v-if="activeRecords.length !== 0">
已选择申请总额:{{ totalAmount }}元
</span>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, defineProps } from 'vue';
const props = defineProps({
activeRecords: {
type: Object,
default: () => []
},
yearTotalAmount: {
type: Number,
default: 0.0
}
});
const totalAmount = computed(() => {
let sum = 0.0;
for (let i = 0; i < props.activeRecords.length; i++) {
sum += parseFloat(props.activeRecords[i].approvalAmount);
}
return sum.toFixed(2);
});
</script>
<style scoped>
.action-bar-container {
display: flex;
}
.statistic {
display: inline;
margin-left: 10px;
vertical-align: middle;
line-height: var(--oio-height);
}
:deep(.action-bar) {
width: auto;
}
</style>
亮点说明:
通过slot机制实现与原生操作栏无缝融合,利用computed实现响应式数据计算,结合 CSS 变量确保 UI 高度适配平台主题,体现 Oinone 对用户体验一致性的极致追求。
TrainingFeeStatisticsWidget.ts —— 智能逻辑,高效聚合
import { BaseElementWidget, BaseElementWidgetProps, SPI, Widget, http } from '@kunlun/dependencies';
import TrainingFeeStatistics from './TrainingFeeStatistics.vue';
@SPI.ClassFactory(BaseElementWidget.Token({ widget: 'TrainingFeeStatisticsWidget' }))
export class TrainingFeeStatisticsWidget extends BaseElementWidget {
public initialize(props: BaseElementWidgetProps) {
if (!props.slotNames) {
props.slotNames = ['tableAction'];
}
super.initialize(props);
this.setComponent(TrainingFeeStatistics);
return this;
}
@Widget.Reactive()
private yearTotalAmount: number = 0.0;
public async $$mounted() {
super.$$mounted();
await this.statisticsCurrent();
}
private async statisticsCurrent() {
const result = await http.query(
'Expense',
`{
trainingFeeQuery {
statisticTotalAmount(data: {}) {
approvalAmount
}
}
}`
);
const res = result.data.trainingFeeQuery.statisticYearTotalAmount as any;
this.yearTotalAmount = res.approvalAmount;
}
}
架构优势:
采用 SPI(Service Provider Interface)机制实现组件热插拔,通过@Widget.Reactive()实现响应式状态管理,结合 GraphQL 高效查询,充分体现了 Oinone 前后端一体化、响应式编程、微内核架构的设计理念。
index.ts —— 模块化入口,清晰易维护
import './Register';
export * from './TrainingFeeStatisticsWidget';
简洁的模块导出机制,支持按需加载与依赖注入,便于团队协作与版本管理。
Register.ts —— 声明式布局,动态注入
import { ViewType, LayoutManager } from '@kunlun/dependencies';
LayoutManager.register(
{
viewType: ViewType.Table,
moduleName: 'ZsIcBiz',
model: 'app.expense.TrainingFee'
},
`<view type="TABLE">
<pack widget="group">
<view type="SEARCH">
<element widget="search" slot="search" slotSupport="field" />
</view>
</pack>
<pack widget="group" slot="tableGroup">
<element widget="TrainingFeeStatisticsWidget">
<template slot="tableAction">
<element widget="actionBar" slot="actionBar" slotSupport="action">
<xslot name="actions" slotSupport="action" />
</element>
</template>
</element>
<element widget="table" slot="table" slotSupport="field">
<element widget="expandColumn" slot="expandRow" />
<xslot name="fields" slotSupport="field" />
<element widget="rowActions" slot="rowActions" slotSupport="action" />
</element>
</pack>
</view>`
);
革命性优势:
通过LayoutManager.register实现运行时布局动态注册,无需修改原始代码即可扩展功能,真正实现“配置即代码,扩展无侵入”。
对比主流平台:Oinone 的技术领先性
为了更清晰地展现 Oinone 的优势,我们将其与当前主流低代码平台在实现相同“表格统计”功能时的表现进行横向对比:
| 功能能力 | Oinone | 若依(RuoYi) | JeecgBoot | 宜搭(YiDa) |
|---|---|---|---|---|
| 是否支持自定义组件注入 | ✅ 完全支持,通过 SPI 机制动态注册 | ❌ 仅支持前端代码扩展,需手动修改页面 | ⚠️ 支持部分自定义组件,但需遵循固定模板 | ✅ 支持,但局限于可视化拖拽,无法深度编程 |
| 是否支持运行时布局修改 | ✅ 支持 LayoutManager 动态注册,无需重启 | ❌ 需修改前端 Vue 文件,重新构建部署 | ⚠️ 需通过代码生成器重新生成代码 | ✅ 支持,但仅限于基础控件,不支持逻辑层扩展 |
| 是否支持响应式状态管理 | ✅ 原生支持 @Widget.Reactive() 响应式编程 | ❌ 依赖 Vue 原生响应式,需手动维护 | ⚠️ 支持 Vue/React 状态管理,但需开发者自行实现 | ⚠️ 支持简单数据绑定,复杂逻辑需 JS 脚本 |
| 是否支持 GraphQL 数据查询 | ✅ 原生集成,高效精准获取数据 | ❌ 仅支持 REST API,需多次请求 | ⚠️ 支持 REST,GraphQL 需额外集成 | ✅ 支持,但语法受限,调试困难 |
| 扩展开发效率 | ⭐⭐⭐⭐⭐(4 文件,<100 行代码) | ⭐⭐(需修改源码,易出错) | ⭐⭐⭐(需生成代码,灵活性差) | ⭐⭐⭐⭐(可视化操作快,但逻辑受限) |
| 维护成本 | 极低(无侵入,独立模块) | 高(代码耦合,升级易冲突) | 中(依赖代码生成器) | 中(依赖平台规则) |
结论:
Oinone 凭借其微内核 + 插件化 + 声明式布局的先进架构,在实现复杂业务扩展时展现出无与伦比的灵活性与可维护性,远超传统低代码平台。
为什么选择 Oinone?
- 极致可扩展性:基于 SPI 与组件化架构,支持任意层级的功能扩展。
- 零侵入式开发:无需修改原始代码,通过注册机制动态注入,保障系统稳定性。
- 高可定制性:从 UI 到逻辑层全面开放,满足企业级复杂业务需求。
- 开发效率倍增:标准化开发模式,新人也能快速上手,交付周期缩短 60%+。
- 面向未来架构:支持 GraphQL、响应式编程、微前端等现代技术栈。
结语
在数字化浪潮中,低代码平台不再是“表单工具”,而是企业业务创新的加速器。Oinone 以工程化思维重构低代码开发范式,让开发者既能享受“低代码”的高效,又能保有“高代码”的自由与掌控力。
Oinone —— 不止于低代码,更懂企业级扩展。
添加微信(微信号:coder1908),立即体验 Oinone,开启您的智能开发之旅!
Gitee开源地址