【内部或二开】星瀚合并报表:取数公式开发指导文档(2022115update)
一、 公式配置
• 公式分类配置及本领域取数微服务定义
公式分类顾名思义就是当存在多个公式时,需要对公式进行一个分类使用户更能明确的找到对应的公式;微服务定义因存在跨领域取数,所以需要定义对应的微服务调用的领域APPID及接口信息,暴露由合并报表应用所调用,范例:
{
//-------公式分类定义列表
"catalogs": [
{
"name": "财务取数公式",
"number": "financial"
},
{
"name": "报表辅助公式",
"number": "assistant"
}
],
//-------微服务接口定义,用于接收公式取数参数及返回公式计算结果
"mservice": {
"appId": "bcm",
"cloudId": "fi",
//单个公式的取数接口
"method": "dispatchFormula",
//【可选】针对浮动表按列批量取数使用,常规下不需要设置
“batchMethod”:”dispatchBatchFormula”,
"service": "CslService"
}
}
• 公式定义列表配置
[
{
//----公式编码
"number": "rptdate",
//----公式名称
"name": "获取报表日期数据",
//----公式分类,与上面分类相对应
"catalog": "assistant",
//公式支持浮动批量取数,与上面设置的批量接口相对应,默认可不设该参数则不支持批量取数
"isSupportedBatch": "true",
//----公式描述
"description": "数据来源:不可为空日期格式:不可为空,用于设置日期显示格式",
//向导界面
"guidepage": 公式向导需要打开的动态表单,
//----公式参数列表定义
"param": [
{
//----参数名,对应组件上的唯一标识
"number": "datesource",
//----显示名称
"name": "日期来源",
//----组件类型
"type": "combofield",
//-----如下拉列表的值列表
"value": {
"modifytime": "报表日期"
},
//-----是否必录项
"mustinput": true
},
{
"mustinput": true,
"name": "日期格式",
"number": "datefield",
"type": "combofield",
"items": {
"DD/MM/YYYY": "DD/MM/YYYY",
"MM/DD/YYYY": "MM/DD/YYYY",
"YYYY-MM-DD": "YYYY-MM-DD",
"YYYY.MM.DD": "YYYY.MM.DD",
"YYYY/MM/DD": "YYYY/MM/DD"
}
}
]
}
]
说明:
公式参数定义支持的组件类型有,列举不全,后面根据需要可追加:
a) combofield下列列表
b) basedatafield 基础资料组件
c) integerfield数值组件
注意:具体组件编码看元数据上的默认值,新增一个控件,生成的默认编码就是该编码,会根据此配置生成向导的控件
d) 对于F7如果需要设置过滤条件的,可以在公式定义中增加类似如下的设置:
"filter":{"sql":"number =? and name =?","param":[v1,v2]};
Param可以是具体的值或者公式里定义的其他组件值,比如前后有联动关系的情况可以这么使用。
e) 对于多类别基础资料组件暂不支持,建议做成多个公式进行处理
2、 调用微服务统一接口接收参数格式public String dispatchXXX(String formulaName,String paramJson);
参数说明:
• dispatchXXX:对应的微服务接口命名,该接口建议一个领域定义一个统一入口,该微服务用于公式调用取数的分发功能,这样就不需要每个公式暴露一个接口给合并报表调用,避免对外暴露过多定义信息。
• formulaName:要处理的公式名
• paramJson:对应接收的公式的参数,json格式如下:
{
"commParam": { //公共参数
"fy": 2020, //财年
"org": "ZSJ001", //组织
"period": 2 //期间
},
"formulaName": "ACCT",
"param": {
"A": //对应公式的唯一ID
[
参数1,
参数2,
…….
]
}
}
例如:
{
//------公共参数信息,包括执行的组织编码,财年、和期间,以后有需要可增加
"commParam": {
"fy": 2020,
"org": "ZSJ001",
"period": 2
},
//--------对应公式名
"formulaName": "ACCT",
//--------多个公式参数列表
"param": {
"A": [
"org-A",
2020,
2,
"2020-02-13"
],
"B": [
"org-B",
2020,
2,
"2020-02-12"
],
"C": [
"org-C",
2020,
2,
"2020-02-11"
]
}
}
• 返回结果:json格式,格式如下:
{
“id”: //公式id,传参数时对应的公式参数ID
{
“v”: //取数结果,当取数异常时可返回错误信息
“type”: //值类型,-1:异常;1:数值,默认可不填,2:文本;3:日期;
}
}
3、 【可选】调用微服务批量取数统一接口接收参数格式public String dispatchBatchXXX(String formulaName,String paramJson);
参数说明:
• dispatchBatchXXX:对应的微服务批量取数接口命名,该接口建议一个领域定义一个统一入口,该微服务用于公式调用取数的分发功能,这样就不需要每个公式暴露一个接口给合并报表调用,避免对外暴露过多定义信息。
• formulaName:要处理的公式名
• paramJson:对应接收的公式的参数,json格式如下:
{
"commParam": { //公共参数
"fy": 2020, //财年
"org": "ZSJ001", //组织
"period": 2 //期间
},
“ref_param”:{
“p1”:[v1,v2], //多浮动的场景下各个填充参数值列表
“p2”:[v3,v4],
……
},
"formulaName": "ACCT",
"param": {
"A": //对应公式的唯一ID
[
参数1,
参数2,
…….
]
}
}
例如:
{
//------公共参数信息,包括执行的组织编码,财年、和期间,以后有需要可增加
"commParam": {
"fy": 2020,
"org": "ZSJ001",
"period": 2
},
“ref_param”:{
“p1”:[v1,v2], //多浮动的场景下各个填充参数值列表
“p2”:[v3,v4],
……
},
//--------对应公式名
"formulaName": "ACCT",
//--------多个公式参数列表
"param": {
"A": [
"org-A",
2020,
2,
"2020-02-13"
],
"B": [
"org-B",
2020,
2,
"2020-02-12"
],
"C": [
"org-C",
2020,
2,
"2020-02-11"
]
}
}
• 返回结果:json格式,格式如下:
{
“id”: //公式id,传参数时对应的公式参数ID
{
“v”:{“p1|p2”:100,“p3|p4”:200},//取数结果, 返回浮动填充成员组合key的值
“success”:”true”,//false:查询出现异常,这是个整体状态,不烦回该参数默认为true
“failmsg”:”取数错误信息”
}
}
4、 公式注册机制
因合并报表需要知道哪些公式需要加入到合并报表公式平台中,其他领域需往合并报表的公式登记表中插入记录完成登记,登记信息需告知获取配置公式的相关微服务接口,返回公式定义信息,以供合并报表公式平台进行公式向导展示及公式计算所调用的微服务接口。登记表信息字段如下:
表:T_BCM_FormulaRegister
字段 | 字段名 | 类型 | 说明 |
FID | 主键ID | bigint | |
FcloudId | 云服务编码 | VARCHAR(50) | |
FAppId | 应用编码 | VARCHAR(50) | |
FService | 微服务类 | VARCHAR(100) | |
FMethod | 方法 | VARCHAR(100) | 该接口为无参数接口,返回上述公式配置信息的json串;返回json格式如下: { “formula_catalog_list”:””, //对应公式分类文件内容 “formula_def_list”:””//对应公式定义文件内容 } |
FClasspath | 微服务工厂类,包含完整的包路径 | VARCHAR(200) | 因计算框架是适用于标准产品及二开适用,标准化的产品代码路径可以直接构造出来(标准代码构造工厂类路径方式:String.format("kd.%s.%s.servicehelper.ServiceFactory", cloudId, appId)),而二开的类包路径可能非kd开头或非标准的构造,则需要直接指定完整的微服务工厂类路径,类中必须提供public static Object getService(String serviceName)方法获取服务类 |
fisenable | 启用 | Char(1) | 1:生效 0:失效,默认1 |
5、 建议
• 公式取数时,建议对公式进行分类,可批量进行取数,避免一个公式查询一次,减少sql的查询次数。
• 配置文件的读取以及反序列化可以参考:
InputStream in = this.getClass().getClassLoader().getResourceAsStream("resources/cal_formula_list.json");
String content = IOUtils.toString(in);
List<Map<String, Object>> configList = SerializationUtils.fromJsonString(content, List.class);
• 读取配置文件代码示例:
public String getFormulaDef() throws ParseException, IOException {
InputStream formula_def_list = null;
String formula_def;
InputStream formula_catalog_list = null;
String formula_catalog;
try {
formula_def_list=this.getClass().getClassLoader().getResourceAsStream("resources/cal_formula_list_tg.json");
formula_def = IOUtils.toString(formula_def_list);
formula_catalog_list = this.getClass().getClassLoader()
.getResourceAsStream("resources/cal_formula_catalog_list_tg.json");
formula_catalog = IOUtils.toString(formula_catalog_list);
} finally {
if(formula_def_list != null){
formula_def_list.close();
}
if(formula_catalog_list != null){
formula_catalog_list.close();
}
}
Map<String, String> configMap = new HashMap<>();
if (StringUtils.isNotEmpty(formula_def) && StringUtils.isNotEmpty(formula_catalog)) {
configMap.put("formula_catalog_list", formula_catalog);
configMap.put("formula_def_list", formula_def);
}
return SerializationUtils.toJsonString(configMap);
}
参考配置文件:
6、 测试验证
以上代码和配置都完成后,需进行验证,除了在模板中设置公式验证外,还提供另外两种验证方式:
1) 随便打开一张模板或者报表,按下快捷键ctrl+alt+shift+F11打开公式验证界面,输入公式进行公式取数,如果涉及多维取数则需要选择体系、财年、期间,界面如下:
2) 通过微服务方式调试公式计算结果,代码案例如下:
//设置公式及公共参数体系、财年、期间信息(如涉及多维取数则要用到),
//key:公式编号,value:公式表达式
Map<String,String> formulas = MapInitHelper.ofMap("1", “IF(OR(1>2,1<3),10,20”);
Map<String,String> args = new HashMap<>();
args.put("model", model.getString("shownumber"));
args.put("fy", year.getString("number"));
args.put("period", period.getString("number"));
//微服务调用
Object v= kd.fi.bcm.business.serviceHelper.MsServiceHelper.invokeService("fi", "bcm","CalculateMsService","calculateFormulas", ObjectSerialUtil.toJson(formulas),ObjectSerialUtil.toJson(args));
Map<String,Map<String,Object>> argsMap = v == null ? new HashMap<>(0) : ObjectSerialUtil.parseObject(v.toString(), Map.class);
v= argsMap.get("1").get("v");//根据key获取公式值
System.out.println(“value:”+v);
7、 问题分析
• 如果公式向导中未加载到所配置的公式,则确定已完成如下检查:
1) 配置文件需放到resource目录下,最好检查下工程目录下是否构建输出该文件;
2) 在t_bcm_formulaRegister中进行了注册
3) 二开需指定微服务工厂类的完整路径,类中必须提供public static Object getService(String serviceName)方法
4) 以上都没问题,则跟踪下代码kd.fi.bcm.business.formula.register.ExternalFormulaLoader.loadExternalFormulaConfig()处,看是否读取到配置信息。
取数公式开发指导new.docx
【内部或二开】星瀚合并报表:取数公式开发指导文档(2022115update)
本文2024-09-22 23:13:16发表“云星瀚知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-xinghan-131649.html