对于一个页面来说,它需要从服务端获取数据用于展示,也需要进行一些增删改的操作。 在平台中,模型层的概念使得能够语义化的提供对模型资源操作的API,也就是各种业务动作。这些业务动作与前端的UI控件应当是解耦的。 另外,对于单个场景的页面来说,例如表单、清单、图表等,它的数据源是单一的,无需复用的。而对于一个复杂页面来说,它的数据往往存在复用性。例如明细表中的表格数据同时使用图表来展现。 因此,为了解耦与复用,我们定义了数据源。
数据源具备以下基本特性:
关联一个可提供数据服务的元素
提供增删改查、自定义等对资源的操作
目前,UX支持使用对象、领域模型、DeepQL、财务模型、Dataframe(Python)作为数据源。
创建好UX元素,进入UX页面后,切换到数据源管理的菜单,点击添加按钮创建数据源,选择数据源的类型
对象/业务模型数据源主要用于基于模型3.0的数据的增删改查。基于其创建数据源后,可以进一步创建清单表、明细表等控件。
业务模型创建: 通过业务模型创建后会带出模型下所有对象及对象的属性与链接,可以通过勾选开选择启用哪些属性、链接、对象。
对象创建: 创建出的数据源只会包含该对象的属性与链接。
创建数据源后默认的查询模式为批量,批量的查询方式会带出该数据源的多条数据,可用于清单表等多条数据的展示。此时包含的配置有:过滤条件,参数变化时自动执行,排序方式。
过滤方式的配置可以实现对数据源获取的多条数据做筛选。配置为过滤条件的属性或链接可以作为一个条件与一个FX表达式/一个UX变量/一个控件值/一个固定值/做比较。
设置为单条的查询模式后,支持配置业务主键等于FX表达式/UX变量/控件值/某固定值(UX变量支持配置被跳转时传参)以获取唯一的一条数据。可用于明细表等对单条数据增删改查的场景。此时的业务主键必填。
打开后该数据源的属性与链接的值发生变化时,会刷新对应数据源下绑定的所有控件。
支持配置默认排序与按指定列排序。选择指定列排序后可以选择多条属性与链接,并按升序或降序的顺序进行排序。
财务模型数据源可以关联财务模型,并配置相应的维度表达式,用于从财务模型取数。
取数模式包括UI模式与脚本模式两种,支持多行多列的取数形式。
由于其目前主要用于图表的展示,可参考图表相关的说明文档:
对于DeepModel而言,往往需要进行复杂的关联查询与数据展示,目前可以通过编写Deepql实现,其原理类似于编写sql。并可以通过变量实现页面筛选条件与数据的联动关系。
配置步骤如下:
1、在模型主视图中,选择查询器,并编写deepql查询语句。具体语法详见模型相关配置文档。
2、在UX中添加DeepQL数据源,则将自动获取语句返回数据的结构与变量信息。在变量中填入页面的表达式,则可实现相应的联动效果
为了能够实现更复杂的数据处理并支持定制化开发,UX也支持了python数据源来进行任意的接口请求。
可以通过特定形式编写一个python脚本,实现将一个dataframe返回至前端页面用于图表展示或其他后端数据获取。
相应语法细节可参考Python sdk文档:
1、编写python脚本,返回维度相关数据
from deepfos.lib.deepux import Struct, String, to_desc, Json, as_datasource
from deepfos.element import Dimension
import pandas as pd
import json
class Data(Struct):
entity = Json('entity')
@as_datasource(struct=Data)
def main(p2):
dim = Dimension('Entity')
res = dim.query('Descendant(#root,0)', fields=['name', 'ud1'], as_model=False)
dims = []
for dim in res:
if dim['ud1'] == 'otbase':
dims.append(dim['name'])
return pd.DataFrame(
{
"entity":dims
}
)
2、在UX中添加python数据源
3、通过表达式获取到数据源的值,以实现例如动态显隐等效果
($dataSources.data_py_get_entity_ud_KKZS.data || []).map(i => i.entity)?.includes($components.entity.value) ? true : false
1、编写python脚本,获取财务模型数据并进行计算
import numpy as np
from deepfos.lib.deepux import Struct, UUID, Json, Float, Integer, DateTime, Boolean, String, as_datasource
import pandas as pd
from deepfos.element.finmodel import FinancialCube
from deepfos.lib.deepux import to_desc, as_datasource
from deepfos.element.dimension import Dimension
class Data(Struct):
Version: String
Period: String
Entity_p: String
Category1: String
Material: String
Account: String
Category2: String
Currency: String
Scenario: String
SaleNo: String
Entity_s: String
Supplier: String
Customer: String
Brand: String
Misc: String
Year: Float
Year_last: Float
colour: String
@as_datasource(struct=Data)
def main(p1, p2):
if None in [p2['Year'], p2['Period'], p2['Category1'], p2['Entity_p']]:
return pd.DataFrame()
Year = p2['Year']
Year_last = str(int(p2['Year']) - 1)
Period = p2['Period']
Category1 = list_to_str(p2['Category1'])
Entity_p = p2['Entity_p']
cube = FinancialCube('bgbz_planning_cube')
fix = f'Version{{WorkVersion}}->Year{{{Year};{Year_last}}}->' \
f'Period{{{Period}}}->Entity_p{{{Entity_p}}}' \
f'->Category1{{{Category1}}}->' \
f'Material{{Mat1}}->' \
f'Supplier{{NoSupplier}}->' \
f'Account{{BOM11}}' \
f'->Category2{{NoCategory}}->Currency{{CNY}}->Scenario{{Actual}}->Misc{{NoMisc}}->' \
f'SaleNo{{NoSaleNo}}->Customer{{NoCustomer}}->Brand{{NoBrand}}->Entity_s{{NoEntity}}'
df = cube.query(fix, compact=False, pivot_dim='Year')
if df.empty:
raise ValueError("数据为空")
if Year not in df.columns:
raise ValueError(f"当年({Year}年)数据为空")
if Year_last not in df.columns:
df['Year_last'] = np.nan
df.rename(columns={Year: 'Year', Year_last: 'Year_last'}, inplace=True)
df = df[df['Year'].notnull()]
df['colour'] = df.apply(lambda x: get_color(x), axis=1)
desc_Category1 = Dimension(element_name='Category1')
Category1_dim_desc = {'Category1': to_desc(desc_Category1.query(expression='Base(#root, 0)'))}
return df, Category1_dim_desc
def get_color(x):
if np.isnan(x['Year_last']):
return '本年当期 '
else:
if x['Year'] >= x['Year_last']:
return '本年当期'
else:
return '本年当期 '
def list_to_str(string_list):
string = ''
for i in string_list:
string += i
string += ';'
string.rsplit(';')
return string
if __name__ == '__main__':
try:
from _debug_alpha import para1, para2
except ImportError:
para1 = para2 = {}
para2 = {'Year': '2023', 'Period': '1', 'Entity_p': 'An10301',
'Category1': ['A330_N', 'A500_N', 'A321117_N', 'A341111_N', 'A311213_N', 'A321114_N', 'A321118_N',
'A355_N', 'A550_N', 'A321116_N', 'stubby250_N', 'ASLEEK250_N', 'AZ21114_N', 'B221215_N',
'B211112_N', 'B221115_N', 'AZ11212_N', 'A311217_N', 'A473_SLIM_N', 'A321115_N', 'B211212_N',
'AZ11211_N', 'AZ11114_N', 'ASIp250_N', 'ASIp310_N', 'ASIp270_N', 'ASIp200_N', 'ASLEEK270_N']}
main(para1, para2)
2、在UX中添加python数据源
3、图表可以选择该python数据源,并进行图表的可视化配置
回到顶部
咨询热线