人员信息表
数据库设计
表名:t_user
字段名 | 描述 | 字段类型 | java 字段 | UI 控件 |
---|---|---|---|---|
name | 姓名 | varchar(32) | String | input[text] |
gender | 性别 | varchar(32) | Enum(by code) | radio |
age | 年龄 | int | Integer | input[number] |
birthday | 出生时间 | datetime | LocalDate | input[date] |
mobile | 手机号码 | varchar | String | text |
邮箱 | varchar | String | input[email] | |
native_place | 籍贯 | varchar(32) | String | select |
hobby | 兴趣爱好 | varchar(32) | Enum(by name) | checkbox |
marriage | 婚否 | bit | String | checkbox |
introduce | 自我介绍 | text | String | textarea |
attachment | 附件 | text | List | file |
school_experience | 学习经历 | text | List | table |
status | 用户状态 | varchar(32) | Enum(by order) | select |
常规代码
User.java
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@Table(value = "t_user", comment = "人员信息表")
public class User extends BaseEntity {
@Column(comment = "姓名", nullable = false)
private String name;
@Column(comment = "性别", nullable = false)
private GenderEnum gender;
@Column(comment = "年龄", nullable = false)
private Integer age;
@Column(comment = "出生时间")
private LocalDate birthday;
@Column(comment = "手机号码", nullable = false)
private String mobile;
@Column(comment = "邮箱")
private String email;
@Column(comment = "籍贯", nullable = false)
private String nativePlace;
@Column(comment = "兴趣爱好", value = "hobby", nullable = false)
private List<HobbyEnum> hobbyList;
@Column(comment = "婚否", nullable = false)
private Boolean marriage;
@Column(comment = "自我介绍", columnDefinition = "text", nullable = false)
private String introduce;
@Column(comment = "附件", columnDefinition = "text", value = "attachment", nullable = false)
private List<Map<String, Object>> attachmentList;
@Column(comment = "学习经历", columnDefinition = "text", value = "school_experience")
private List<List<String>> schoolExperienceList;
@Column(comment = "用户状态")
private StatusEnum status;
@AllArgsConstructor
@Getter
public enum GenderEnum {
UNKNOWN(0, "Unknown"),
MALE(1, "Male"),
FEMALE(2, "Female");
private static final Map<Integer, GenderEnum> codeMap = new HashMap<>();
static {
for (GenderEnum e : values()) {
codeMap.put(e.code, e);
}
}
private final int code;
private final String label;
@JsonValue
public int getCode() {
return this.code;
}
public static GenderEnum valueOfCode(int code) {
return codeMap.get(code);
}
}
@Getter
public enum StatusEnum {
LOCKED, NORMAL
}
@AllArgsConstructor
@Getter
public enum HobbyEnum {
BASKETBALL("篮球"),
FOOTBALL("羽毛球"),
BADMINTON("羽毛球"),
VOLLEYBALL("排球");
@JsonValue
public String getCode() {
return this.name();
}
private final String label;
public static HobbyEnum valueOfCode(String code) {
return valueOf(code);
}
}
}
执行 tableGenerator.createTable(User.class)
生成表。
create table t_user
(
id bigint not null comment '主键'
primary key,
name varchar(32) not null comment '姓名',
gender varchar(16) not null comment '性别',
age int not null comment '年龄',
birthday date null comment '出生时间',
mobile varchar(32) not null comment '手机号码',
email varchar(32) null comment '邮箱',
native_place varchar(32) not null comment '籍贯',
hobby json not null comment '兴趣爱好',
marriage bit not null comment '婚否',
introduce text null,
attachment text null,
school_experience text null,
status varchar(16) null comment '用户状态'
)
comment '人员信息表';
DAO
UserDAO.java
@Repository
public class UserDAO extends EntityDAOImpl<User, Long> {
}
UserFormAdvice
@Component("userFormAdvice")
public class UserFormAdvice implements FormAdvice {
@Override
public void beforeInstanceHandle(FormBO form, Long instanceId, Map<String, Object> values) {
// checkbox List => boolean
if (CollectionUtils.isEmpty((Collection<?>) values.get("marriage"))) {
values.put("marriage", false);
} else {
values.put("marriage", true);
}
}
@Override
public void afterInstanceHandle(FormBO form, Long instanceId, Map<String, Object> values) {
}
}
创建UI控件
@Test
public void testAddConfigurerToForm() {
// 设计控件
List<CpnConfigurer> cpnConfigurerList = createCpnConfigurerList();
cpnConfigurerService.saveOrUpdate(cpnConfigurerList);
// 创建表
Form form = formService.save(Form.builder()
.code("t_user")
.tableName("t_user")
.name("人员信息表")
.repositoryName("userDAO")
.formAdviceName("userFormAdvice")
.storageStrategy(Form.StorageStrategyEnum.CREATE_TABLE)
.build());
// 关联关系
formCpnService.saveOrUpdateByConfigIds(form.getId(), cpnConfigurerList.stream().map(CpnConfigurer::getId).collect(Collectors.toList()));
}
public List<CpnConfigurer> createCpnConfigurerList() {
// 文本校验器
Set<Validator> textValidatorList = Sets.newHashSetWithExpectedSize(2);
textValidatorList.add(new Required(true));
textValidatorList.add(new Length(16));
Set<Validator> requiredValidatorList = Sets.newHashSetWithExpectedSize(1);
requiredValidatorList.add(new Required(true));
CpnConfigurer nameCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.TEXT)
.name("name")
.label("姓名")
.placeholder("请输入姓名")
.defaultValue("Rick.Xu")
.validatorList(textValidatorList)
.build();
CpnConfigurer genderCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.RADIO)
.name("gender")
.label("性别")
.options(Arrays.asList(new CpnConfigurer.CpnOption("0", "未知"), new CpnConfigurer.CpnOption("1", "男"), new CpnConfigurer.CpnOption("2", "女")))
.defaultValue("1")
.validatorList(requiredValidatorList)
.build();
Set<Validator> ageValidatorList = Sets.newHashSetWithExpectedSize(1);
ageValidatorList.add(new Size(18, 100));
ageValidatorList.add(new Required(true));
CpnConfigurer ageCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.NUMBER_TEXT)
.name("age")
.label("年龄")
.placeholder("请输入年龄")
.defaultValue("28")
.validatorList(ageValidatorList)
.build();
CpnConfigurer birthdayCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.DATE)
.name("birthday")
.label("出生时间")
.placeholder("请输入出生时间")
.defaultValue("1989-12-11")
.build();
CpnConfigurer mobileCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.MOBILE)
.name("mobile")
.label("手机号码")
.placeholder("请输入手机号码")
.defaultValue("18898765543")
.validatorList(requiredValidatorList)
.build();
CpnConfigurer emailCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.EMAIL)
.name("email")
.label("邮箱")
.placeholder("请输入邮箱")
.defaultValue("jkxyx@163.com")
.build();
CpnConfigurer nativePlaceCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.SELECT)
.name("native_place")
.label("籍贯")
.options(Arrays.asList(new CpnConfigurer.CpnOption("陕西"), new CpnConfigurer.CpnOption("江苏"), new CpnConfigurer.CpnOption("四川"), new CpnConfigurer.CpnOption("上海")))
.defaultValue("江苏")
.validatorList(requiredValidatorList)
.build();
CpnConfigurer hobbyCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.CHECKBOX)
.name("hobby")
.label("兴趣爱好")
.options(Arrays.asList(new CpnConfigurer.CpnOption("BASKETBALL", "篮球"), new CpnConfigurer.CpnOption("FOOTBALL", "足球"), new CpnConfigurer.CpnOption("BADMINTON", "羽毛球"), new CpnConfigurer.CpnOption("VOLLEYBALL", "排球")) )
.defaultValue("[\"BASKETBALL\", \"FOOTBALL\"]")
.validatorList(requiredValidatorList)
.build();
CpnConfigurer marriageCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.CHECKBOX)
.name("marriage")
.label("婚否")
// .options(Arrays.asList(new CpnConfigurer.CpnOption("true", "")) )
.options(Arrays.asList(new CpnConfigurer.CpnOption("1", "")) )
.defaultValue("true")
.build();
CpnConfigurer introduceCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.TEXTAREA)
.name("introduce")
.label("自我介绍")
.placeholder("请输入自我介绍")
.defaultValue("我叫Rick...")
.validatorList(textValidatorList)
.build();
CpnConfigurer attachmentCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.FILE)
.name("attachment")
.label("附件")
.validatorList(requiredValidatorList)
.build();
CpnConfigurer yearCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.TEXT)
.name("school_year")
.label("年份")
.defaultValue("Rick.Xu")
.validatorList(textValidatorList)
.build();
CpnConfigurer schoolNameCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.TEXT)
.name("school_name")
.label("学校名称")
.defaultValue("Rick.Xu")
.validatorList(textValidatorList)
.build();
CpnConfigurer schoolExperienceCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.TABLE)
.name("school_experience")
.label("学习经历")
.additionalInfo(Params.builder()
.pv("columns", Arrays.asList(yearCpn, schoolNameCpn))
.build())
.defaultValue("[[\"2021-2022\", \"四川大学\"], [\"2012-2015\", \"永安高中\"]]")
.build();
CpnConfigurer statusCpn = CpnConfigurer.builder()
.cpnType(CpnTypeEnum.SELECT)
.name("status")
.label("用户状态")
.options(Arrays.asList(new CpnConfigurer.CpnOption("LOCKED", "锁定"), new CpnConfigurer.CpnOption("NORMAL", "正常")))
.defaultValue("LOCKED")
.build();
List<CpnConfigurer> cpnConfigurerList = Lists.newArrayList(nameCpn, genderCpn, ageCpn, birthdayCpn,
mobileCpn, emailCpn, nativePlaceCpn, hobbyCpn, marriageCpn, introduceCpn, attachmentCpn, schoolExperienceCpn, statusCpn);
return cpnConfigurerList;
}
访问表单
新增 POST /{form_id}
修改 POST /{form_id}/{instance_id}
查找 GET /{form_id}/{instance_id}
创建报表
@Test
public void testAddReport() {
reportService.saveOrUpdate(Report.builder()
.id(668074769748373504L)
.name("人员信息表")
.querySql("SELECT t_user.name AS \"name\",\n" +
"# t_user.gender AS \"gender\",\n" +
" sd.label AS \"gender\",\n" +
" t_user.age AS \"age\",\n" +
" t_user.birthday AS \"birthday\",\n" +
" t_user.mobile AS \"mobile\",\n" +
" t_user.email AS \"email\",\n" +
" t_user.native_place AS \"nativePlace\",\n" +
" t_user.hobby AS \"hobbyList\",\n" +
" IF(t_user.marriage, '是', '否') AS \"marriage\",\n" +
" t_user.introduce AS \"introduce\",\n" +
" t_user.attachment AS \"attachmentList\",\n" +
" t_user.school_experience AS \"schoolExperienceList\",\n" +
" t_user.status AS \"status\",\n" +
" t_user.created_by AS \"createdBy\",\n" +
" t_user.created_at AS \"createdAt\",\n" +
" t_user.updated_by AS \"updatedBy\",\n" +
" t_user.updated_at AS \"updatedAt\",\n" +
" t_user.is_deleted AS \"deleted\",\n" +
" t_user.id AS \"id\"\n" +
"FROM t_user left JOIN sys_dict sd ON t_user.gender = sd.name" +
" WHERE is_deleted = 0 AND t_user.name like :name AND t_user.gender = :gender AND t_user.mobile = :mobile " +
"AND t_user.native_place IN (:nativePlace) AND t_user.status = :status AND t_user.hobby like :hobbyList" +
" AND t_user.birthday >= :birthday0 AND t_user.birthday <= :birthday1 AND marriage = :marriage")
.reportColumnList(Arrays.asList(
new ReportColumn("name", "姓名", true),
new ReportColumn("gender", "性别"),
new ReportColumn("age", "年龄"),
new ReportColumn("birthday", "出生日期",false, null, Arrays.asList("localDateConverter")),
new ReportColumn("mobile", "手机号码"),
new ReportColumn("email", "邮箱"),
new ReportColumn("nativePlace", "籍贯"),
new ReportColumn("hobbyList", "兴趣爱好", false, "hobbyList", Arrays.asList("arrayDictConverter")),
new ReportColumn("marriage", "婚否"),
new ReportColumn("introduce", "自我介绍"),
// new ReportColumn("attachmentList", "附件"),
// new ReportColumn("schoolExperienceList", "学习经历"),
new ReportColumn("status", "状态", false, "status", Arrays.asList("dictConverter"))
))
.queryFieldList(Arrays.asList(
new QueryField("name", "姓名"),
new QueryField("mobile", "手机号码"),
// sys_dic#gender
new QueryField("gender", "性别", QueryField.Type.SELECT, "gender"),
new QueryField("birthday", "出生日期", QueryField.Type.DATE_RANGE),
// 配置文件
new QueryField("nativePlace", "籍贯", QueryField.Type.MULTIPLE_SELECT, "nativePlace"),
// 接口实现
new QueryField("hobbyList", "兴趣爱好", QueryField.Type.SELECT, "hobbyList"),
// 配置文件
new QueryField("status", "状态", QueryField.Type.SELECT, "status"),
new QueryField("marriage", "婚否", QueryField.Type.SELECT, "bol")
))
.pageable(true)
// .summary(true)
.summaryColumnNames("age, mobile")
.sidx("name")
.sord(SordEnum.ASC)
.build());
}
参数
SELECT t_user.name AS "name",
sd.label AS "gender",
t_user.age AS "age",
t_user.birthday AS "birthday",
t_user.mobile AS "mobile",
t_user.email AS "email",
t_user.native_place AS "nativePlace",
t_user.hobby AS "hobbyList",
IF(t_user.marriage, '是', '否') AS "marriage",
t_user.introduce AS "introduce",
t_user.attachment AS "attachmentList",
t_user.school_experience AS "schoolExperienceList",
t_user.status AS "status",
t_user.created_by AS "createdBy",
t_user.created_at AS "createdAt",
t_user.updated_by AS "updatedBy",
t_user.updated_at AS "updatedAt",
t_user.is_deleted AS "deleted",
t_user.id AS "id"
FROM t_user
LEFT JOIN sys_dict sd ON t_user.gender = sd.name
WHERE is_deleted = 0
AND UPPER(t_user.name) LIKE CONCAT('%', UPPER(:name), '%') ESCAPE
'\\' AND t_user.gender = :gender AND t_user.mobile = :mobile AND t_user.native_place IN (:nativePlace0) AND
t_user.status = :status AND t_user.birthday >= :birthday0 AND t_user.birthday <= :birthday1 AND
marriage = :marriage
[{gender=2, marriage=1, name=凡夫俗子, mobile=17798765543, nativePlace0=上海, birthday1=1994-01-17, birthday0=1984-01-17, status=NORMAL}]