前后端 | 低代码平台之 Erupt

news2025/1/11 19:12:53

前文提要

最近大家是不是都有那种危机感,项目变多了,工时压紧了,老板说,我不管你加不加班,我只看结果,项目经理说,我不管你用什么技术栈,我只要没BUG,测试说,交互不管好不好,我们只要搞光速推塔。你心说?那我走?

大家也发现了,以前要很多行代码才能实现的功能,现在变得格外简单,原因很多大佬开源了很多项目,很多大厂平台供我们选择,从此,无止尽的C+V操作变成了拼技术选型,拼方向,别人一行代码搞定的事情,一个类生成CRUD,你要不停的拷拷拷,BUG多数全凭心情,那为什么不选择一款开箱既用的产品呢?

功能概述

使用 Apache License 2.0 协议,源代码完全开源,无商业限制

代码生成器VSErupt
前端 + 后端 7 ~ 10 个文件文件数量仅需一个类文件
重新生成代码或修改已生成代码修改字段添加字段注解
需要手动执行建表 SQL建表语句自动建表
需要整个工程,模块众多不好管理初次部署仅需引入 Jar 依赖即可,基础数据自动生成
需要熟悉代码生成器所提供的前端 API,有一定学习成本前端代码零前端代码
传统分层调用的方式开发开发方式全注解式开发
仅支持基本的数据组件复杂的组件需自定义组件支持支持23类表单组件,且支持一对多,多对多等复杂关系组件
一般只支持 MySQL数据库支持 MySQL、Oracle、PostgreSQL、H2 等所有主流数据库
需要生成大量代码复制到项目中,功能越多维护成本越高开发时间仅需一个后端工程师,短时间就可以完成高质量后台管理系统
Java 代码逻辑扩展按需 @DataProxy 实现
表数量越多启动越慢启动速度百张表映射毫秒级初始化

 

 import: 支持多数据源

并且:项目内置了很多功能无需开发,开箱即用

 简单实力

简单CRUD

@Erupt(
       name = "简单的例子",
       power = @Power(importable = true, export = true)
)
@Table(name = "t_simple")   //数据库表名
@Entity
public class Simple extends BaseModel {

    @EruptField(
            views = @View(title = "文本"),
            edit = @Edit(title = "文本", notNull = true, search = @Search)
    )
    private String input;

    @EruptField(
            views = @View(title = "数值", sortable = true),
            edit = @Edit(title = "数值", search = @Search)
    )
    private Float number;

    @EruptField(
            views = @View(title = "布尔"),
            edit = @Edit(title = "布尔", search = @Search)
    )
    private Boolean bool;


    @EruptField(
            views = @View(title = "时间"),
            edit = @Edit(title = "时间", search = @Search(vague = true))
    )
    private Date date;

    @EruptField(
            views = @View(title = "滑动条"),
            edit = @Edit(title = "滑动条", type = EditType.SLIDER, search = @Search,
                    sliderType = @SliderType(max = 90, markPoints = {0, 30, 60, 90}, dots = true))
    )
    private Integer slide;

    @EruptField(
            views = @View(title = "下拉选择"),
            edit = @Edit(
                    search = @Search,
                    title = "下拉选择", type = EditType.CHOICE,
                    choiceType = @ChoiceType(fetchHandler = SqlChoiceFetchHandler.class,
                            fetchHandlerParams = "select id,name from e_upms_menu"
                    )
            )
    )
    private Long choice;

}

像这种带有CRUD功能的表单,只需要这样几行代码,一个文件就可以了

 那你选择写Controller、Service、Dao、View + HTML语法,还是写这几行代码呢?

简单上传附件

@Column(length = 120)
    @EruptField(
            views = @View(title = "附件",
                    type = ViewType.ATTACHMENT),
            edit = @Edit(title = "附件", type = EditType.ATTACHMENT,
                    attachmentType = @AttachmentType(fileTypes = {"PDF","PNG","JPEG","ZIP"}, maxLimit = 1))
    )
    private String fileUrl;

这是给你封装好的上传附件组件,无需其他代码,非常好用

一对多级联

@ManyToMany
    @JoinTable(
            name = "COMMON_ZY_SZHJXZY",
            joinColumns = {@JoinColumn(
                    name = "zbid",
                    referencedColumnName = "id"
            )},
            inverseJoinColumns = {@JoinColumn(
                    name = "ywid",
                    referencedColumnName = "id"
            )}
    )
    @EruptField(
            edit = @Edit(
                    title = "仿真实习实训软件面向专业",
                    type = EditType.TAB_TABLE_REFER,
                    notNull = true,
                    search = @Search(vague = true)
            ),
            sort = 45
    )
    private Set<ZyjsZyszView> zyjsZyszs;

高级用法

如果你的数据源不是项目链接的单标,是从接口或者其他库获得的,我们可以采用多数据源

代码实力

//注入启动类
@Bean
    public ApplicationRunner appRunner() {
        return new ApplicationRunner() {
            @Override
            public void run(ApplicationArguments args) throws Exception {
                DataProcessorManager.register("BndhdDataSource", BndhdDataService.class);
            }
        };
    }

实体类 

@Erupt(
        name = "SCHOOL_ACTIVITY_ZYJY",
        desc = "本年度活动表"
)
@EruptDataProcessor("BndhdDataSource")
@Entity
@Getter
@Setter
@DynamicInsert
@DynamicUpdate
@Power(delete = false)
public class Bndhd{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(generator = "sys_uuid")
    @GenericGenerator(name = "sys_uuid", strategy = "uuid")
    @Column(name = "id", length = 64)
    @EruptField
    private String id;


    @Column(length = 400)
    @EruptField(
            views = @View(
                    title = "学校名称",
                    desc = "学校名称",
                    width = "120"
            ),
            edit = @Edit(
                    title = "学校名称",
                    desc = "学校名称",
                    search = @Search(vague = true)
            )
    )
    private String XXMC;

    @Column(length = 400)
    @EruptField(
            views = @View(
                    title = "活动名称",
                    desc = "活动名称",
                    width = "120"
            )
    )
    private String HDMC;

    @Column(length = 400)
    @EruptField(
            views = @View(
                    title = "活动类型",
                    desc = "活动类型",
                    width = "120"
            ),
            edit = @Edit(
                    title = "活动类型",
                    desc = "活动类型",
                    search = @Search
            )
    )
    private String HDLX;

    @Column(length = 400)
    @EruptField(
            views = @View(
                    title = "活动开始时间",
                    desc = "活动开始时间",
                    width = "120"
            )
    )
    private String HDKSRQ;

    @Column(length = 400)
    @EruptField(
            views = @View(
                    title = "活动结束时间",
                    desc = "活动结束时间",
                    width = "120"
            )
    )
    private String HDJSRQ;

    @Column(length = 400)
    @EruptField(
            views = @View(
                    title = "目前状态",
                    desc = "目前状态",
                    width = "120"
            )
    )
    private String MQZT;
}

重写数据源方法 

@Service
public class BndhdDataService implements IEruptDataService {

    @Autowired
    private JdbcTemplateService jdbcTemplateService;

    @Override
    public PowerObject power(){
        PowerObject powerObject = new PowerObject();
        powerObject.setDelete(false);
        powerObject.setAdd(false);
        powerObject.setEdit(false);
        powerObject.setViewDetails(false);
        return powerObject;
    }

    @Override
    public Object findDataById(EruptModel eruptModel, Object id) {
        return null;
    }

    @Override
    public Page queryList(EruptModel eruptModel, Page page, EruptQuery eruptQuery) {
        Page pageResult = new Page();
        pageResult.setPageSize(page.getPageSize());
        String queryParam = "";
        // 职业教育活动周
        String zyhdzSql = "SELECT XXDM XXDM,HDMC,'职业教育活动周' HDLX,HDKSRQ HDKSRQ,HDJSRQ HDJSRQ FROM SCHOOL_ACTIVITY_ZYJY WHERE IS_DELETE = '0' ";
        // 文明风采
        String wmfcSql = "SELECT XXDM XXDM,HDMC,'文明风采' HDLX,HDKSRQ HDKSRQ,HDJSRQ HDJSRQ FROM SCHOOL_ACTIVITY_WMFC WHERE IS_DELETE = '0' ";
        // 其他
        String qtSql = "SELECT XXDM XXDM,HDMC,'其他' HDLX,HDKSRQ HDKSRQ,HDJSRQ HDJSRQ FROM SCHOOL_ACTIVITY_QT WHERE IS_DELETE = '0' ";
        // 大国工匠
        String dggjSql = "SELECT XXDM XXDM,HDMC,'大国工匠' HDLX,HDKSRQ HDKSRQ,HDJSRQ HDJSRQ FROM SCHOOL_ACTIVITY_DGGJ WHERE IS_DELETE = '0'";
        String queryMainSql = "";
        List<Condition> conditions = eruptQuery.getConditions();
        Map<String, String> keyToQueryMainSql = new HashMap<>();
        keyToQueryMainSql.put("职业教育活动周", zyhdzSql);
        keyToQueryMainSql.put("文明风采", wmfcSql);
        keyToQueryMainSql.put("其他", qtSql);
        keyToQueryMainSql.put("大国工匠", dggjSql);
        Boolean isDggj = true;
        for (Condition condition : conditions) {
            String key = condition.getKey();
            if (ObjUtil.isNotEmpty(condition.getValue())) {
                String value = condition.getValue().toString();
                if (key.equals("XXMC")) {
                    queryParam = " AND T.XXMC = '" + value + "'";
                } else if (key.equals("HDLX") && keyToQueryMainSql.containsKey(value)) {
                    queryMainSql = keyToQueryMainSql.get(value);
                    isDggj = false;
                } else if(key.equals("HDLX") && !keyToQueryMainSql.containsKey(value)){
                    queryParam = " AND T.XXMC = '」@「'";
                }
            }
        }
        if (isDggj) {
            StringBuilder sb = new StringBuilder();
            keyToQueryMainSql.forEach((k, v) -> {
                sb.append(v).append(" UNION ALL ");
            });
            queryMainSql = sb.substring(0, sb.length() - " UNION ALL ".length());
        }
        String dySql = "SELECT T.XXDM,T.XXMC,T.XXXZQHM AS REGIONID,REGION.NAME REGIONNAME,T.HDLX,T.HDMC,T.HDKSRQ,T.HDJSRQ, " +
                "case when to_date(T.HDJSRQ,'') > sysdate then '未结束' else '结束' end as mqzt " +
                "FROM ( " +
                "SELECT T.XXDM,T.HDMC,T.HDLX,T.HDKSRQ,T.HDJSRQ,SCHOOL_INFO.XXXZQHM,SCHOOL_INFO.XXMC " +
                "FROM " +
                "( " + queryMainSql + ") T " +
                "INNER JOIN SCHOOL_INFO ON ( T.XXDM = SCHOOL_INFO.XXDM) ) T " +
                "INNER JOIN REGION ON T.XXXZQHM = REGION.ID " + queryParam;
        String countSql = "SELECT COUNT(*) FROM (" + dySql + ") T";
        Integer count = jdbcTemplateService.getValue(countSql);
        long longValue = count.longValue();
        pageResult.setTotal(longValue);
        List<Map<String, Object>> bndhdList = new ArrayList<>();
        bndhdList = jdbcTemplateService.getListMap(dySql);
        pageResult.setList(bndhdList);
        return pageResult;
    }

    @Override
    public Collection<Map<String, Object>> queryColumn(EruptModel eruptModel, List<Column> columns, EruptQuery eruptQuery) {
        return null;
    }

    @Override
    public void addData(EruptModel eruptModel, Object object) {

    }

    @Override
    public void editData(EruptModel eruptModel, Object object) {

    }

    @Override
    public void deleteData(EruptModel eruptModel, Object object) {

    }
}

怎么样?喜欢玩攻速流的程序员们心动了吗?现在Enjoy your time!

erupt开源低代码框架,零前端代码,纯注解开发管理后台!icon-default.png?t=N7T8https://www.erupt.xyz/#!/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1691674.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法】分治 - 快速排序

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、颜色分类二、排序数组三、数组中的第k个数四、最小的k个数总结 引言 本节主要介绍快速排序&#xf…

类图的六大关系

类图中的六大关系包括&#xff1a;继承关系、实现关系、关联关系、聚合关系、组合关系和依赖关系。 1. 继承关系 继承是一种类与类之间的关系&#xff0c;表示一种泛化和特化的关系。子类继承父类的特性和行为。 class Animal {void eat() {System.out.println("This an…

足球走地全自动化操作软件实现过程

本次采用selenium实现自动化操作的流程 打开浏览器录入账号密码等待数据请求&#xff08;监听&#xff09;有新数据&#xff0c;进行自动化操作通过homeName搜索&#xff0c;找到对应数据找到对应的类型&#xff08;让、大小…&#xff09;找到对应的盘口输入数量提交 附登录…

系统资源监控器工具glances的使用详解

目录 1、glances工具介绍 2、安装方式 3、glances的工具界面说明 4、常用的参数选项 5、常用快捷键说明 1、glances工具介绍 glances可以分析系统的 CPU使用率、内存使用率、内核统计信息和运行队列信息磁盘I/O速度、传输和读/写比率、磁盘适配器网络I/O速度、传输和读/写…

华为编程题目(实时更新)

1.大小端整数 计算机中对整型数据的表示有两种方式&#xff1a;大端序和小端序&#xff0c;大端序的高位字节在低地址&#xff0c;小端序的高位字节在高地址。例如&#xff1a;对数字 65538&#xff0c;其4字节表示的大端序内容为00 01 00 02&#xff0c;小端序内容为02 00 01…

电脑远程控制另一台电脑怎么弄?

可以远程控制另一台电脑吗&#xff1f; “你好&#xff0c;我对远程访问技术不太了解。现在&#xff0c;我希望我的朋友可以远程控制我的Windows 10电脑&#xff0c;以便她能帮我解决一些问题。请问&#xff0c;有没有免费的方法可以实现这种远程控制&#xff1f;我该如何操作…

如何选择一个最强大模型-看最硬核排名了!

Chatbot Arena由伯克利大学主导团队 LMSYS Org 发布了一个针对大语言模型的基准平台 Chatbot Arena。该平台采用匿名、随机的方式让不同的大模型产品进行对抗评测&#xff0c;基于国际象棋等竞技游戏中广泛使用的埃洛等级分系统&#xff0c;通过用户投票产生&#xff0c;系统每…

基于SpringBoot的网盘系统设计与实现

第1章 绪论... 1 1.1 研究背景与意义... 1 1.1.1 研究背景... 1 1.1.1 研究意义... 1 1.2 国内外研究现状... 2 1.2.1 国内研究现状... 2 1.2.2 国外研究现状... 3 1.3 论文组织架构... 4 第2章 关键技术介绍... 5 2.1 SpringBoot. 5 2.2 MySQL数据库... 5 2.3 MVC架…

区块链论文总结速读--CCF A会议 USENIX Security 2024 共7篇 附pdf下载

Conference&#xff1a;33rd USENIX Security Symposium CCF level&#xff1a;CCF A Categories&#xff1a;网络与信息安全 Year&#xff1a;2024 Num&#xff1a;7 1 Title: Practical Security Analysis of Zero-Knowledge Proof Circuits 零知识证明电路的实用安全…

对AI 感兴趣的小伙伴

如图&#xff0c;欢迎来玩儿&#xff01; 欢迎来玩儿

备考AMC8和AMC10竞赛,吃透2000-2024年1850道真题和解析(持续)

多做真题&#xff0c;吃透真题和背后的知识点是备考AMC8、AMC10有效的方法之一&#xff0c;通过做真题&#xff0c;可以帮助孩子找到真实竞赛的感觉&#xff0c;而且更加贴近比赛的内容&#xff0c;可以通过真题查漏补缺&#xff0c;更有针对性的补齐知识的短板。 今天我们继续…

嵌入式学习——3——UDP TFTP简易文件传输

tftp协议概述 简单文件传输协议&#xff0c;适用于在网络上进行文件传输的一套标准协议&#xff0c;使用UDP传输 特点&#xff1a; 是应用层协议 基于UDP协议实现 数据传输模式 octet&#xff1a;二进制模式&#xff08;常用&#xff09; mail&#xff1a;已经不再支持 TFTP通信…

ping 探测网段哪些地址被用

#!/bin/bash# 遍历192.168.3.1到192.168.3.254 for i in {1..254} doip"192.168.3.$i"# 对每个IP地址进行三次ping操作if ping -c 3 -W 1 $ip > /dev/null 2>&1thenecho "$ip: yes"fi done$ sh test.sh 192.168.3.1: yes 192.168.3.95: yes 192.…

Terminal Web终端基础(Web IDE 技术探索 二)

Terminal是web终端技术&#xff0c;类似cmd命令窗口&#xff0c;Webcontainer 中推荐使用的是Xterm.js&#xff0c;这里就不细说Xterm.js 的使用了&#xff0c;我们使用第三方库来实现&#xff08;原生确实有点难用&#xff09;。 vue-web-terminal 一个由 Vue 构建的支持多内容…

基础5 探索JAVA图形编程桌面:字符操作组件详解

在繁华都市的一个角落&#xff0c;卧龙和凤雏相聚在他们常去的台球厅。灯光洒在绿色的台球桌上&#xff0c;彩色的台球整齐地排列着&#xff0c;仿佛在等待着一场激烈的角逐。 卧龙轻轻地拿起球杆&#xff0c;微微瞄准&#xff0c;然后用力一击&#xff0c;白球带着一股强大的力…

MySQL 高阶语句(二)

一、子查询 子查询也被称作内查询或者嵌套查询&#xff0c;是指在一个查询语句里面还嵌套着另一个查询语句。子查询语句是先于主查询语句被执行的&#xff0c;其结果作为外层的条件返回给主查询进行下一 步的查询过滤。PS: 子语句可以与主语句所查询的表相同&#xff0c;也可以…

Python异常处理:打造你的代码防弹衣!

Hi&#xff0c;我是阿佑&#xff0c;上文咱们讲到——揭秘Python的魔法&#xff1a;装饰器的超能力大揭秘 ‍♂️✨&#xff0c;阿佑将带领大家通过精准捕获异常、使用with语句和上下文管理器、以及异常链等高级技巧来增强代码的健壮性。就像为代码穿上防弹衣&#xff0c;保护它…

微调Llama3实现在线搜索引擎和RAG检索增强生成功能

视频中所出现的代码 Tavily SearchRAG 微调Llama3实现在线搜索引擎和RAG检索增强生成功能&#xff01;打造自己的perplexity和GPTs&#xff01;用PDF实现本地知识库_哔哩哔哩_bilibili 一.准备工作 1.安装环境 conda create --name unsloth_env python3.10 conda activate …

5.17 作业+思维导图+模拟面试

// tcp_ser.c #include <myheader.h>#define SER_PORT 8888 #define SER_IP "192.168.125.109"int newfd, sfd;int main(int argc, const char *argv[]) {//1、为通信创建一个端点sfd socket(AF_INET, SOCK_STREAM, 0);//参数1&#xff1a;说明使用的是ipv4通…