常规功能和模块自定义系统 (cfcmms)—016模块字段的定义
这一节开始模块字段的自定义设计。模块字段作为模块的属性也是这个系统中自定义的核心内容。它不仅定义了字段的一些基本属性,还可描述模块之间的从属关系,以及相关的一些权限和行为属性。
从和数据库对应的角度来看,模块字段对应于表中的字段。但是也不是完全一一对应,可以创建一些自定义的字段(计算字段)而不必在表中有相应的字段。自定义的字段可以使用数据库中的系统函数或者用户自定义函数来创建表达式,这对于扩充模块的功能有很大的用处。
模块字段的大概属性如下图:
这里只是暂时想到和用到的属性,在实际的应用中如果有新的需求要加入新的属性,那么只要在字段表中加一个字段,修改一下bean文件即可。我的系统的自定义的方面也采用这种可扩充的设计模式,任何想到的功能,先将其可配置化,然后前后台协同合作来完成此功能。
在上面的字段定义中,将字段的属性分成了若干个大类,包括基本信息、设置信息、单字段验证、字段权限、附加信息等。又新增了form, grid中该字段的设置,将form,grid 加在此处是因为一个模块可以有若干个form和若干个grid,将一些公用的form和grid 中用到的信息写在此处。每个form和grid 又有其自己的设置。
字段还有一个重要要的功能,就是保存各个模块之间的关联关系。这种关系是根据字段类型和关联类型来获得。例如有省、市二个模块,市的模块中应该有一个省份的字段,其关联类型为ManyToOne,我就认为省模块是市模块的父模块。最直接的用处就是可以在市模块中加上省份的导航,在选中了省份后,就可以限定只显示选中省份的市。另外模块的可视权限也是可以继承的,在上节中我们设置了一个只能查看江浙沪省份的权限,那么对于市来说也会限定在这三个省份之下,只能看见这三个省份之下的市。
字段的各个设置在界面显示、form、grid、数据导出、打印中都会使用到。
在java中,也设计了一个用于标注字段的标注类@FieldDefine。在这个文件里只加入了部分的字段属性,大多数的还是要到前台进字段管理中进行设置。
package com.jfok.cfcmms.util.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldDefine {
/**
* 字段的中文描述内容
*/
String title();
/**
* 字段的顺序号,在grid中显示字段列表的时候默认按照顺序号排序,生成模块的form和grid字段的时候也是按顺序号来确定顺序
*/
int number() default 0;
/**
* 字段的备注,可以显示在form中字段的label的tooltip上
*/
String remark() default "";
/**
* 是否是此模块的名称字段。名称字段即可以用此名称来描述此条记录的字段,例如一个合同的合同名称,或一份订单的订单号,
* 在对记录作某些操作的时候的堤示信息中会加入这个字段的信息,在form窗口中,会将名称字段的内容显示在title处;
* 在grid中会将选中的记录的名称字段内容显示在title中。
*/
boolean nameField() default false;
/**
* 是否是隐藏字段。如果是的话,在form中会创建一个hiddenfield,在grid和查询的时候都不会加入此字段。
*/
boolean hidden() default false;
/**
* 字段的分组。在生成默认的form和grid的时候,会根据fieldGroup来进行分组。
*/
String fieldGroup() default "默认组";
/**
* 如果定义了,将会在sql中使用相应的表达式(某些数据库不能使用计算字段,只能用这个代替了)
*/
String formula() default ""; // 如果是自定义的字段,将sql中能用的表达式写于此处
/**
* 此字段是否可以汇总,数值字段和有分子分母的除法的字段可以设置
*
* @return
*/
boolean allowSummary() default false;
/**
* 可以进行分组
*
* @return
*/
boolean allowGroup() default false;
/**
* 计量单位
*
* @return
*/
String unitText() default "";
/**
* 对字段值设置的一个tooltip的tpl表达式。例如 合同名称{agreementname},签订于{signDate:}
*
* @return
*/
String tooltipTpl() default "";
/**
* 如果是一个比率值,那么需要分子和分母,这样在分类汇总和总计的时候,分子分母分别相加再除,即为加权平均
*/
String divisor() default "";
String denominator() default "";
/**
* 是否可以用个,千,万,百万,亿的数值单位来显示在grid中,在form中显示原值
*
* @return
*/
boolean isMonetary() default false;
/**
* 一些附加设置,如
* formfield:{comboThisField:true},
* field : {searchCondOrder :41 }
* @return
*/
String otherSetting() default "";
}
字段类为_ModuleField.java,其部分定义如下:
@TableDefine(group = "系统模块", id = 9903, title = "模块字段")
public class _ModuleField implements Serializable, _IModuleControlInterface {
@Id
@FieldDefine(title = "ID号", number = 10)
@Column(nullable = false)
private Integer tf_fieldId;
@JsonIgnore
@ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
@JoinColumn(name = "tf_moduleId", nullable = false)
@FieldDefine(title = "所属模块", number = 20)
private _Module tf_Module;
@JsonIgnore
@FieldDefine(title = "顺序号", number = 30)
private Integer tf_fieldOrder;
@FieldDefine(title = "字段内容", number = 40, nameField = true)
@Column(length = 50, nullable = false)
private String tf_title;
@FieldDefine(title = "字段名", number = 50)
@Column(length = 50, nullable = false)
private String tf_fieldName;
@FieldDefine(title = "类型", number = 60)
@Column(length = 50, nullable = false)
private String tf_fieldType;
@JsonProperty("l")
@FieldDefine(title = "长度", number = 70)
private Integer tf_fieldLen;
@FieldDefine(title = "字段分组", number = 75)
private String tf_fieldGroup;
// 字段的关联类型 ,ManyToOne,OneToOne,OneToMany
@JsonIgnore
@FieldDefine(title = "关联类型", number = 80)
@Column(length = 20)
private String tf_fieldRelation;
@JsonIgnore
@FieldDefine(title = "表字段实名", remark = "数据表中的实际字段名", number = 90)
@Column(length = 50)
private String tf_DBfieldName;
@JsonIgnore
@FieldDefine(title = "字段公式", remark = "公式字段的具体内容", number = 100)
private String tf_DBformula;
@JsonIgnore
@FieldDefine(title = "百分比分子", number = 105)
@Column(length = 50)
private String tf_divisor;
@JsonIgnore
@FieldDefine(title = "百分比分母", number = 106)
@Column(length = 50)
private String tf_denominator;
......
}
模块字段的各个字段也是用该标注的。也就是说这个系统的管理部分也是由这个系统自己来管理的。就象以前pascal的编译器也是用pascal编写的一样。
模块定义和模块定段的定义是本系统最基本和最关键的二个要素。在你所要开发的的系统结构设计完善、模块定义和字段定义都设置好后,就可以一步步的搭建完一个管理系统了。