Erupt部署
创建一个SpringBoot项目(此处为2.7.10)
目录结构
demo -- 项目名称
├── src
└── main
├── java -- 代码文件目录
└── com.example.demo -- 包名
└── DemoApplication -- 入口类
└── resources -- 资源文件目录
└── application.properties -- 配置文件
├── ......
└── pom.xml -- Maven依赖配置
创建数据库
数据库随便创一个本项目创建了一个名为erupt的数据库
导入依赖
<!--后端权限逻辑-->
<dependency>
<groupId>xyz.erupt</groupId>
<artifactId>erupt-admin</artifactId>
<version>1.12.0</version>
</dependency>
<!--后台WEB界面-->
<dependency>
<groupId>xyz.erupt</groupId>
<artifactId>erupt-web</artifactId>
<version>1.12.0</version>
</dependency>
这里需要注意,他的官方文档说是要去看一下版本号
这里有一个坑就是你去到官网提供的应该导入的是1.11.7
但是多次Maven导不进去说是不存在资源,于是去Erupt-Admin的Maven仓库发现这个支持只有1.12.0所以本项目需要导入的是1.12.0
配置application.yaml文件
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/erupt?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
jpa:
show-sql: true
generate-ddl: true
database: mysql
依赖
依赖需要包含web ,mysql driver 和官网提到的那两个依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.10</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>erupt-study</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>erupt-study</name>
<description>erupt-study</description>
<properties>
<java.version>1.8</java.version>
<erupt.version>1.11.7</erupt.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<!--后端权限逻辑-->
<dependency>
<groupId>xyz.erupt</groupId>
<artifactId>erupt-admin</artifactId>
<version>1.12.0</version>
</dependency>
<!--后台WEB界面-->
<dependency>
<groupId>xyz.erupt</groupId>
<artifactId>erupt-web</artifactId>
<version>1.12.0</version>
</dependency>
</dependencies>
</project>
给启动类注入标签
@EntityScan
和@EruptScan
package com.example.eruptstudy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import xyz.erupt.core.annotation.EruptScan;
@SpringBootApplication
@EntityScan
@EruptScan
public class EruptStudyApplication {
public static void main(String[] args) {
SpringApplication.run(EruptStudyApplication.class, args);
}
}
启动服务
直接运行启动类,会看到一堆Hibernate的东西,不得不说还是老架构NB
访问服务页面
由于没有配置serve.port所以默认8080
进入8080端口
默认账号密码均为erupt
进入到管理页面
入门示例
我们需要创建一个model的文件夹存放我们需要添加进来的页面类
这里用创建的一个user表来做测试
创建页面类
package com.example.eruptstudy.model;
import org.hibernate.annotations.GenericGenerator;
import xyz.erupt.annotation.Erupt;
import xyz.erupt.annotation.EruptField;
import xyz.erupt.annotation.sub_field.Edit;
import xyz.erupt.annotation.sub_field.View;
import javax.persistence.*;
import java.util.Date;
/*
* @Erupt注解修饰在类上,@EruptField注解修饰在字段上
* 其他注解均为Jpa注解
*/
@Erupt(name = "简单的例子")
@Table(name = "user")
@Entity
public class DemoSimple {
//主键
@Id
@GeneratedValue(generator = "generator")
@GenericGenerator(name = "generator", strategy = "native")
@Column(name = "id")
@EruptField
private Long id; //如果继承BaseModel不能再重复声明id
//文本输入
@EruptField(
views = @View(title = "文本"),
edit = @Edit(title = "文本")
)
private String input;
//数值输入
@EruptField(
views = @View(title = "名称"),
edit = @Edit(title = "名称")
)
@Column(name = "name")
private String name;
//布尔选择
@EruptField(
views = @View(title = "密码"),
edit = @Edit(title = "密码")
)
@Column(name = "password")
private String password;
//时间选择
@EruptField(
views = @View(title = "时间"),
edit = @Edit(title = "时间")
)
private Date date;
}
这里需要注意,文本和时间这两个字段没删所以前端显示是空的
重启回到菜单管理页面进行修改
刷新一下重新打开页面就可以看到成功了
@Erupt注解
属性:
public @interface Erupt {
String primaryKeyCol() default "id"; //主键列名称,默认值为id
String name(); //功能名称
String desc() default ""; //功能描述
boolean authVerify() default true; //访问是否需要授权校验
Power power() default @Power; //控制增删改查导入导出功能
RowOperation[] rowOperation() default {}; //自定义操作按钮
Drill[] drills() default {}; //自定义下钻关联视图
Filter[] filter() default {}; //数据过滤
String orderBy() default ""; //排序
Class<? extends DataProxy>[] dataProxy() default {}; //代理回调接口方法集
Tree tree() default @Tree; //树节点配置
LinkTree linkTree() default @LinkTree(field = ""); //左树右表配置
KV[] param() default {}; //自定义参数
}
一般常用
@Erupt(
name = "Erupt", //功能名称
desc = "Erupt Framework", //描述
orderBy = "id desc", //排序表达式
.....
)
public class EruptTest extends BaseModel {
//TODO
}
属性表
https://www.yuque.com/erupts/erupt/mzi9ry?inner=DtN58
布局属性@Layout
public @interface Layout {
//表单大小
FormSize formSize() default FormSize.DEFAULT;
//表格左侧列固定数量
int tableLeftFixed() default 0;
//表格右侧列固定数量
int tableRightFixed() default 0;
enum FormSize {
DEFAULT, //默认布局,每行显示三个表单组件
FULL_LINE //整行布局,每行显示一个表单组件
}
}
@Power注解
用于权限控制
@Erupt(
name = "Erupt",
power = @Power(add = true, delete = true,
edit = true, query = true,
importable = false, export = false)
)
public class EruptTest extends BaseModel {
}
属性
public @interface Power {
boolean add() default true; //数据新增功能
boolean delete() default true; //数据删除功能
boolean edit() default true; //数据修改功能
boolean query() default true; //输入查询功能
boolean viewDetails() default true; //数据查看功能
boolean export() default false; //数据导出功能
boolean importable() default false; //数据导入功能
//实现此接口动态控制权限
Class<? extends PowerHandler> powerHandler() default PowerHandler.class;
}
对于权限的管理,若需要动态控制权限这里主要是去实现 PowerHandler
,这里传入一个PowerHandler
类即可,但是如何区分角色权限又是另一回事这里需要研究
@Filter注解
数据过滤
@Erupt(
name = "Test",
filter = @Filter("EruptTest.name = '张三'"),
)
public class EruptTest extends BaseModel {
@EruptField(
views = @View(title = "名称"),
edit = @Edit(title = "名称")
)
private String name;
}
属性
public @interface Filter {
String value() default ""; //条件表达式
String[] params() default {}; //回调参数
//动态控制过滤条件
Class<? extends FilterHandler> conditionHandler() default FilterHandler.class;
}
@EruptField注解
字段注解
@EruptField(
sort = 10,
views = @View(title = "名称"),
edit = @Edit(title = "名称")
)
private String name;
属性名 | 描述 |
---|---|
views | 表格项配置(允许不配置,则不展示在表格内,也不会参与查询) |
edit | 编辑项配置(允许不配置,则不展示组件,新增和编辑不信任任何前端值) |
sort | 前端展示顺序,默认按照字段排列顺序进行排序,数字越小越靠前 |
params | 自定义参数 |
@View
属性名 | 描述 |
---|---|
title | 表格列名称 |
desc | 表格列描述 |
type | 数据展示形式,详见 type参照 |
show | 是否显示 |
sortable | 是否支持排序前端通过表格列进行排序操作 |
export | 是否支持Excel导出 |
className | 表格样式类名(可在app.css中定义类样式) |
width | 列宽度(1.6.8及以上版本支持) |
column | 如果修饰字段为对象类型,需要使用此属性指定,要展示哪一个字段在@ManyToOne时使用此配置 |
template | 字符串转换模板 该参数在前端使用eval方法解析支持变量:1、item(整行数据)2、item.xxx(数据中的某一列)3、value (当前数据)配置为 → template = "‘姓名:’ + value"展示效果 → 姓名xxxx |
@View → type参照
属性名 | 描述 |
---|---|
AUTO | 根据@Edit → EditType或字段类型自动识别EditType.ATTACHMENT → ATTACHMENTEditType.ATTACHMENT.IMAGE → IMAGEEditType.HTML_EDITOR → HTMLEditType.CODE_EDITOR → CODEEditType.MAP → MAPBoolean → BOOLEANDate → DATEInteger → NUMBERFloat → NUMBERDouble → NUMBER其他 → TEXT |
TEXT | 普通文本 |
IMAGE | 图片 |
IMAGE_BASE64 | base64格式图片 |
SWF | flash动画 |
HTML | 渲染HTML代码段 |
MOBILE_HTML | 手机屏幕尺寸渲染HTML代码段 |
QR_CODE | 二维码 |
LINK | 新窗口方式打开链接 |
LINK_DIALOG | 对话框方式打开链接 |
DOWNLOAD | 直接下载 |
ATTACHMENT | 新窗口方式代开附件 |
ATTACHMENT_DIALOG | 对话框方式打开附件 |
DATE | 日期 |
BOOLEAN | 布尔 |
NUMBER | 数值 |
MAP | 地图 |
CODE | 代码 |
@Edit
属性名 | 描述 |
---|---|
title | 编辑框名称 |
desc | 描述 |
notNull | 是否为必填项 |
show | 是否显示 |
readonly | 是否只读 @Readonly |
showBy | 组件在何种情况下显示,具体使用方法如下:showBy = @ShowBy(dependField = “number”, expr = “value == 1”)**dependField:展示此组件需要依赖的组件expr**:表达式返回true则本组件显示表达式说明:value表示依赖字段number的值,语法为JavaScript,如果number的输入值为1则显示本组件。 |
placeHolder | 描述输入字段预期值的提示信息 |
search | 是否支持搜索search = @Search*(vague = true)* vague 为 true 时各组件会有相应的 高级查询 查询策略 |
orderBy | 排序规则,参照hql语句 order by 语法当字段类型为@Erupt修饰的复杂对象时可用 |
filter | 过滤规则,参照hql语句where语法当字段类型为@Erupt修饰的复杂对象时可用 |
type | 编辑类型,详见 type参照 |
@Edit → type参照
类型 | 描述 | 搜索 | 高级搜索 | 使用方法 |
---|---|---|---|---|
AUTO | 默认类型,可通过字段类型等特征进行推断 | # | ||
INPUT | 文本输入框 | ✅ | ✅ | # |
NUMBER | 数值输入框 | ✅ | ✅ | # |
SLIDER | 滑动输入条 | ✅ | ✅ | # |
DATE | 时间选择器 | ✅ | ✅ | # |
BOOLEAN | 开关 | ✅ | ❌ | # |
CHOICE | 单选框 | ✅ | ✅ | # |
TAGS | 标签选择器 | ✅ | ❌ | # |
AUTO_COMPLETE | 自动完成 | ✅ | ❌ | # |
TEXTAREA | 多行文本输入框 | ✅ | ✅ | # |
HTML_EDITOR | 富文本编辑器 | ✅ | ✅ | # |
CODE_EDITOR | 代码编辑器 | ✅ | ✅ | # |
ATTACHMENT | 附件,图片 | ❌ | ❌ | # |
MAP | 地图 | ❌ | ❌ | # |
DIVIDE | 分割线 | ❌ | ❌ | # |
TPL | 自定义HTML模板 | ❌ | ❌ | |
COMBINE | 表单联合 | ❌ | ❌ | |
HIDDEN | 隐藏 | ❌ | ❌ | # |
EMPTY | 空(仍占据组件位置) | ❌ | ❌ | # |
👇 如下组件使用较为复杂,建议充分了解JPA后使用 | ||||
REFERENCE_TREE | 树引用 | ✅ | ❌ | # |
REFERENCE_TABLE | 表格引用 | ✅ | ❌ | # |
CHECKBOX | 复选框 | ❌ | ❌ | # |
TAB_TREE | 多选树 | ❌ | ❌ | # |
TAB_TABLE_REFER | 多选表格 | ❌ | ❌ | # |
TAB_TABLE_ADD | 一对多新增 | ❌ | ❌ | # |
一对一案例
首先创建两张表
Teacher表
_user表
从数据库上我们可以初步分析我们需要通过用户的teacher_id访问到Teacher表的id
代码
package com.example.eruptstudy.model;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.formula.functions.T;
import org.hibernate.annotations.GenericGenerator;
import xyz.erupt.annotation.Erupt;
import xyz.erupt.annotation.EruptField;
import xyz.erupt.annotation.sub_erupt.Filter;
import xyz.erupt.annotation.sub_erupt.Layout;
import xyz.erupt.annotation.sub_erupt.Power;
import xyz.erupt.annotation.sub_field.Edit;
import xyz.erupt.annotation.sub_field.EditType;
import xyz.erupt.annotation.sub_field.View;
import xyz.erupt.annotation.sub_field.sub_edit.Search;
import javax.persistence.*;
import java.util.Date;
import java.util.Set;
/*
* @Erupt注解修饰在类上,@EruptField注解修饰在字段上
* 其他注解均为Jpa注解
*/
@Getter
@Setter
@Erupt(
name = "简单的例子",
layout = @Layout
)
@Table(name = "_user")
@Entity
public class DemoSimple {
//主键
@Id
@GeneratedValue(generator = "generator")
@GenericGenerator(name = "generator", strategy = "native")
@Column(name = "id")
@EruptField
private Integer id; //如果继承BaseModel不能再重复声明id
//数值输入
@EruptField(
views = @View(title = "名称"),
edit = @Edit(title = "名称", search = @Search)
)
@Column(name = "name")
private String name;
//布尔选择
@EruptField(
views = @View(title = "密码"),
edit = @Edit(title = "密码")
)
@Column(name = "password")
private String password;
@OneToOne(
cascade = CascadeType.ALL
)
@EruptField(
// views = @View(title = "扩展表姓名", column = "id"),
edit = @Edit(title = "扩展表定义", type = EditType.COMBINE)
)
private Teacher teacher;
}
package com.example.eruptstudy.model;/*
* Copyright © 2020-2035 erupt.xyz All rights reserved.
* Author: YuePeng (erupts@126.com)
*/
import javax.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import xyz.erupt.annotation.*;
import xyz.erupt.annotation.sub_erupt.*;
import xyz.erupt.annotation.sub_field.*;
import xyz.erupt.annotation.sub_field.sub_edit.*;
import xyz.erupt.upms.model.base.HyperModel;
import xyz.erupt.jpa.model.BaseModel;
import java.util.Set;
import java.util.Date;
@Getter
@Setter
@Erupt(name = "教师")
@Table(name = "teacher")
@Entity
public class Teacher extends BaseModel {
@EruptField(
views = @View(title = "Id"),
edit = @Edit(title = "Id", notNull = true)
)
private Long tid;
@EruptField(
views = @View(title = "名称"),
edit = @Edit(title = "名称")
)
private String tname;
}
效果
可删改查,增放到多对多
一对多案例
创建数据库
我们创建一个teacher2的数据库,字段:
然后再最开始的_user表中添加字段teacher_id2
创建Teacher2类
package com.example.eruptstudy.model;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import xyz.erupt.annotation.Erupt;
import xyz.erupt.annotation.EruptField;
import xyz.erupt.annotation.sub_field.Edit;
import xyz.erupt.annotation.sub_field.View;
import xyz.erupt.jpa.model.BaseModel;
import javax.persistence.*;
import java.util.Collection;
@Getter
@Setter
@Entity
@Erupt(name = "测试教师2")
@Table(name = "teacher2")
public class Teacher2 {
@Id
@GeneratedValue(generator = "generator")
@GenericGenerator(name = "generator", strategy = "native")
@EruptField
@Column(name = "tid")
private Long id;
@EruptField(
views = @View(title = "名称"),
edit = @Edit(title = "名称")
)
@Column(name = "tname")
private String tname;
}
在一开始的DemoSimple类中加入
@EruptField(
edit = @Edit(
title = "多对多,关联多条数据",
type = EditType.TAB_TABLE_REFER
)
)
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinTable(name = "user_teacher2",
joinColumns = @JoinColumn(name = "teacher_id2", referencedColumnName = "teacher_id2"),
inverseJoinColumns = @JoinColumn(name = "tid", referencedColumnName = "tid")
)
// @JoinColumn(name = "use_id")
private Set<Teacher2> teacher2;
这里解释一下
-
@JoinTable
是创建一个表name
是这个表的名称
-
joinColumns
是加入的当前表的字段-
JoinColumn
这个是映射字段,这里添加关联从而连接起来 name是映射出来创建出来表的字段的字段,来自的外键是来自这张表的referencedColumnName
的teacher_id2
字段就比如说我想要在
user
表中的teacher_id2字段映射为wuhu
那么语句就是这样写joinColumns = @JoinColumn(name = "wuhu", referencedColumnName = "teacher_id2")
-
inverseJoinColumns
这个是映射其他表的字段的这里做的事情和上面那个解释一样,也就是说这里是把teacher2的tid映射了
-
-
JoinColumn
这个是用于增加的后面讲
一些注解坑
@Id与BaseModel
官网文档的后面都是用继承BaseModel
来写,但是如果你的主键不是名字叫id的话他会给你自主生成id这个字段到数据库里面,如果是数据库的主键名为其他
的那么在其字段加上@Id
就不会在类上爆红了
一对一
我们需要清楚的是,我们原本的数据库的字段是需要全部搞到的,所以实体类的概念还是存在,只是多出来的属性需要自行添加加入,所以最开始的误区就是实体类的字段与之对应的数据库属性
没有写全,这里需要注意
Caused by: org.hibernate.MappingException: Unable to find column with logical name…supertables and
这个是由于你在实体类中属性没有写全,缺少了这个属性,需要加上这个属性并且使用@Column注解
无法解决的BUG
一对多非官方设置的
主要的
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinColumn(name="use_id")
@EruptField(
edit = @Edit(
title = "多对多,关联多条数据",
type = EditType.TAB_TABLE_REFER
)
)
调用其他表的
public class Teacher2 {
@Id
@GeneratedValue(generator = "generator")
@GenericGenerator(name = "generator", strategy = "native")
@EruptField
@Column(name = "tid")
private Long id;
@EruptField(
views = @View(title = "名称"),
edit = @Edit(title = "名称")
)
@Column(name = "tname")
private String tname;
@EruptField(
edit = @Edit(title = "学生学号")
)
@Column(name = "use_id")
private Long use_id;
}
这样在页面上会显示了,对其删除会发生诡异的事情
我的数据库的数据:
页面显示
删除123后点击修改保存,再次打开诡异的事情就发生了
数据库数据:
一对多官方配置方法(暂时没法解决的
把上面的改成这个
@OneToMany //多对多
@JoinColumn(name = "teacher_id2")
@JoinTable(name = "teacher2_demo_simple", // Define a new join table name
joinColumns = @JoinColumn(name = "demo_simple_id", referencedColumnName = "teacher_id2"), // Match the columns
inverseJoinColumns = @JoinColumn(name = "use_id", referencedColumnName = "use_id")) // Match the columns
@EruptField(
edit = @Edit(
title = "多对多,关联多条数据",
type = EditType.TAB_TABLE_REFER
)
)
private Set<Teacher2> teacher2;
查不到数据,非常的蹊跷