From d07f6b561eb24c4ea8829369a1e7fe8b7821240c Mon Sep 17 00:00:00 2001 From: unknown <627433532@qq.com> Date: Fri, 27 Dec 2024 15:56:21 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0report=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runtime/report/eon/RpConstant.java | 2 +- .../uca/combiner/StepGeneratorData.java | 72 +++++++++++++++++-- .../runtime/report/uca/feature/OData.java | 60 ++++++++++++++++ .../report/uca/feature/ODataClass.java | 45 ++++++++++++ .../runtime/report/uca/feature/OGroup.java | 55 ++++++++++++++ .../report/uca/feature/OGroupClass.java | 28 ++++++++ .../report/uca/feature/RDataComponent.java | 15 ++++ .../report/uca/feature/RGrupComponent.java | 12 ++++ .../report/uca/process/DimProcTree.java | 4 +- .../report/uca/pull/AbstractDataSet.java | 44 ++++++++++-- .../runtime/report/uca/pull/DataSet.java | 13 +++- .../runtime/report/uca/pull/DataSetTable.java | 11 ++- .../uca/pull/io/AbstractRDataComponent.java | 9 +++ .../uca/pull/io/AbstractRGroupComponent.java | 10 +++ .../report/uca/util/FormulaEvaluator.java | 51 +++++++++++++ 15 files changed, 415 insertions(+), 16 deletions(-) create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OData.java create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/ODataClass.java create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroup.java create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroupClass.java create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RDataComponent.java create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RGrupComponent.java create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRDataComponent.java create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRGroupComponent.java create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/eon/RpConstant.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/eon/RpConstant.java index f91db31f..2b1bb4e2 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/eon/RpConstant.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/eon/RpConstant.java @@ -22,7 +22,7 @@ public interface RpConstant { interface DimValue { String FIELD_GROUP = "field.group"; - String FIELD_VECTOR = "field.vector"; + String NEW_GROUP = "newGroup"; } interface ValuePath { diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java index 280e6889..ade1e082 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java @@ -16,10 +16,12 @@ import io.zerows.extension.runtime.report.domain.tables.pojos.KpReportInstance; import io.zerows.extension.runtime.report.eon.RpConstant; import io.zerows.extension.runtime.report.eon.em.EmReport; import io.zerows.extension.runtime.report.uca.feature.OFeature; +import io.zerows.extension.runtime.report.uca.feature.OGroup; +import io.zerows.extension.runtime.report.uca.util.FormulaEvaluator; -import java.util.List; -import java.util.Objects; -import java.util.Set; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -71,6 +73,14 @@ class StepGeneratorData extends AbstractStepGenerator { final JsonArray featureA = new JsonArray(); features.forEach(feature -> { final JsonObject featureItem = new JsonObject(); + String valueConfig = feature.getValueConfig(); + if(valueConfig!=null){ + JsonObject entries = new JsonObject(valueConfig); + if(entries.getJsonObject("css")!=null){ + featureItem.mergeIn(entries.getJsonObject("css")); + } + } + featureItem.put("dataIndex", feature.getName()); featureItem.put("title", feature.getValueDisplay()); featureA.add(featureItem); @@ -90,7 +100,7 @@ class StepGeneratorData extends AbstractStepGenerator { private Future calculateContent(final JsonArray sourceData, final JsonObject params) { final RGeneration generation = this.metadata(); final List featureDim = generation.featureDim(); - if (VValue.ONE != featureDim.size()) { + if (VValue.ONE < featureDim.size()) { // TODO: 多维度计算 this.logger().warn("Current Version Does not support. key = {}", generation.key()); return Ux.futureA(); @@ -126,6 +136,7 @@ class StepGeneratorData extends AbstractStepGenerator { // 抽取维度配置 final JsonObject dimConfig = Ut.toJObject(featureOfDim.getValueConfig()); final String dimField = Ut.valueString(dimConfig, RpConstant.DimValue.FIELD_GROUP); + final String newGroup = Ut.valueString(dimConfig, RpConstant.DimValue.NEW_GROUP); // 先根据特征处理重新提取数据,保留维度字段 final JsonArray dataProcessed = new JsonArray(); @@ -166,15 +177,21 @@ class StepGeneratorData extends AbstractStepGenerator { // 构造最终报表形态,先按维度分组 final ConcurrentMap groupMap = Ut.elementGroup(dataProcessed, RpConstant.DimField.KEY); + if(newGroup!=null){ + OGroup of = OGroup.of("C:"); + of.dataAsync(groupMap,newGroup); + } final Set dimKeys = dimension.dateKeys(); // combine 节点,追加维度行 final KpReport report = this.metadata().reportMeta(); final JsonObject reportConfig = Ut.toJObject(report.getReportConfig()); final JsonObject combine = Ut.valueJObject(reportConfig, "combine"); - + final JsonObject bottomTotal = Ut.valueJObject(reportConfig,"bottomTotal"); + final JsonObject TotalCount = Ut.valueJObject(reportConfig,"TotalCount"); // 重新构造数据记录 final JsonArray reportData = new JsonArray(); + ConcurrentHashMap total = new ConcurrentHashMap<>(); dimKeys.stream().filter(groupMap::containsKey).forEach(dimKey -> { final JsonObject dimRecord = new JsonObject(); final JsonArray dimSource = groupMap.get(dimKey); @@ -209,8 +226,53 @@ class StepGeneratorData extends AbstractStepGenerator { } }); dimRecord.put(KName.CHILDREN, dimSource); + JsonArray dimSourceCopy = dimSource.copy(); + bottomTotal.fieldNames().forEach(dimFeature -> { + // 提取 Feature + final KpFeature feature = Ut.elementFind(features, item -> item.getName().equals(dimFeature)); + final EmReport.FeatureType featureType = Ut.toEnum(feature.getType(), EmReport.FeatureType.class, EmReport.FeatureType.NONE); + if (EmReport.FeatureType.AGGR == featureType) { + dimSourceCopy.forEach(item -> { + JsonObject entries = Ux.toJson(item); + String string = entries.getString(feature.getName()); + // 使用 BigDecimal.valueOf 保留两位小数 + BigDecimal value = (string == null || string.isEmpty()) + ? BigDecimal.ZERO + : BigDecimal.valueOf(Double.parseDouble(string)).setScale(2, RoundingMode.HALF_UP); + // 转换为字符串,确保两位小数 + String valueString = value.toString(); + // 使用 compute 方法累加值 + total.compute(feature.getName(), (key, current) -> { + if (current == null) { + return valueString; // 如果该键没有值,直接使用当前值 + } else { + // 将当前值和新值转换为 BigDecimal,进行累加 + BigDecimal currentValue = new BigDecimal(current); + BigDecimal newValue = new BigDecimal(valueString); + BigDecimal sum = currentValue.add(newValue).setScale(2, RoundingMode.HALF_UP); + return sum.toString(); // 返回累加后的值 + } + }); + }); + } + }); reportData.add(dimRecord); }); + + TotalCount.fieldNames().forEach(count->{ + final String formula = TotalCount.getString(count); + final String result = FormulaEvaluator.calculateFormula(formula, total); + total.put(count, result); + }); + JsonObject entries = Ux.toJson(total); + entries.put("key", UUID.randomUUID().toString()); + bottomTotal.fieldNames().forEach(item->{ + boolean b = total.containsKey(item); + if(!b){ + entries.put(item,bottomTotal.getString(item)); + } + }); + reportData.add(entries); return Ux.future(reportData); }); } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OData.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OData.java new file mode 100644 index 00000000..f7be7b5f --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OData.java @@ -0,0 +1,60 @@ +package io.zerows.extension.runtime.report.uca.feature; + +import io.horizon.uca.cache.Cc; +import io.vertx.core.Future; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import io.vertx.up.eon.KName; +import io.vertx.up.util.Ut; +import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; +import io.zerows.extension.runtime.report.domain.tables.pojos.KpFeature; +import io.zerows.extension.runtime.report.eon.RpConstant; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.util.Objects; +import java.util.concurrent.ConcurrentMap; + +/** + * @author lang : 2024-11-27 + */ +public interface OData { + + Cc CC_SKELETON = Cc.openThread(); + + static OData of(final String valuePath) { + Objects.requireNonNull(valuePath); + return CC_SKELETON.pick(ODataClass::new, valuePath); + + } + + /** + *

+     *     params -> data 数据
+     *               input 输入参数
+     * 
+ * + * @return 计算的值 + */ + Future dataAsync(JsonArray dataSource, JsonObject params, KpDataSet dataSet); + interface T { + + static Object formatValue(final Object value, final JsonObject valueConfig) { + final Object valueResult; + if (Ut.isNotNil(valueConfig) && valueConfig.containsKey(KName.FORMAT)) { + final String pattern = Ut.valueString(valueConfig, KName.FORMAT); + // 时间格式 + if (value instanceof final Instant valueInstant) { + final LocalDateTime parsed = Ut.toDateTime(valueInstant); + valueResult = Ut.fromDate(parsed, pattern); + } else { + final LocalDateTime parsed = Ut.toDateTime(Ut.parseFull(value.toString())); + valueResult = Ut.fromDate(parsed, pattern); + } + } else { + valueResult = value; + } + return valueResult; + } + } +} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/ODataClass.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/ODataClass.java new file mode 100644 index 00000000..39316bcf --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/ODataClass.java @@ -0,0 +1,45 @@ +package io.zerows.extension.runtime.report.uca.feature; + +import io.horizon.uca.cache.Cc; +import io.vertx.core.Future; +import io.vertx.core.json.Json; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import io.vertx.up.eon.KName; +import io.vertx.up.util.Ut; +import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; +import io.zerows.extension.runtime.report.domain.tables.pojos.KpFeature; + +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author lang : 2024-11-27 + */ +class ODataClass implements OData { + + private static final Cc CC_OUT = Cc.openThread(); + + + @Override + public Future dataAsync(JsonArray dataSource, JsonObject params, KpDataSet dataSet) { + final String dataComponent = dataSet.getDataComponent(); + if (Ut.isNil(dataComponent)) { + return Ut.future(dataSource); + } + final RDataComponent outComponent = CC_OUT.pick(() -> Ut.instance(dataComponent), dataComponent); + if (Objects.isNull(outComponent)) { + return Ut.future(dataSource); + } + + final JsonObject parameters = new JsonObject(); + parameters.put(KName.INPUT, params); + return outComponent.dataAsync(dataSource, parameters).compose(result -> { + if (Objects.isNull(result)) { + return Ut.future(dataSource); + } + return Ut.future(result); + }); + } +} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroup.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroup.java new file mode 100644 index 00000000..078dc58e --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroup.java @@ -0,0 +1,55 @@ +package io.zerows.extension.runtime.report.uca.feature; + +import io.horizon.uca.cache.Cc; +import io.vertx.core.Future; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import io.vertx.up.eon.KName; +import io.vertx.up.util.Ut; +import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.util.Objects; +import java.util.concurrent.ConcurrentMap; + +public interface OGroup { + Cc CC_SKELETON = Cc.openThread(); + + static OGroup of(final String valuePath) { + Objects.requireNonNull(valuePath); + return CC_SKELETON.pick(OGroupClass::new, valuePath); + + } + + /** + *

+     *     params -> data 数据
+     *               input 输入参数
+     * 
+ * + * @return 计算的值 + */ + Future> dataAsync(ConcurrentMap map, String params); + + interface T { + + static Object formatValue(final Object value, final JsonObject valueConfig) { + final Object valueResult; + if (Ut.isNotNil(valueConfig) && valueConfig.containsKey(KName.FORMAT)) { + final String pattern = Ut.valueString(valueConfig, KName.FORMAT); + // 时间格式 + if (value instanceof final Instant valueInstant) { + final LocalDateTime parsed = Ut.toDateTime(valueInstant); + valueResult = Ut.fromDate(parsed, pattern); + } else { + final LocalDateTime parsed = Ut.toDateTime(Ut.parseFull(value.toString())); + valueResult = Ut.fromDate(parsed, pattern); + } + } else { + valueResult = value; + } + return valueResult; + } + } +} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroupClass.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroupClass.java new file mode 100644 index 00000000..8db12dde --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroupClass.java @@ -0,0 +1,28 @@ +package io.zerows.extension.runtime.report.uca.feature; + +import io.horizon.uca.cache.Cc; +import io.vertx.core.Future; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import io.vertx.up.eon.KName; +import io.vertx.up.util.Ut; +import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; + +import java.util.Objects; +import java.util.concurrent.ConcurrentMap; + +public class OGroupClass implements OGroup{ + + private static final Cc CC_OUT = Cc.openThread(); + + @Override + public Future> dataAsync(ConcurrentMap map, String params) { + final RGrupComponent outComponent = CC_OUT.pick(() -> Ut.instance(params), params); + return outComponent.dataAsync(map, params).compose(result -> { + if (Objects.isNull(result)) { + return Ut.future(map); + } + return Ut.future(result); + }); + } +} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RDataComponent.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RDataComponent.java new file mode 100644 index 00000000..49e7cd72 --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RDataComponent.java @@ -0,0 +1,15 @@ +package io.zerows.extension.runtime.report.uca.feature; + +import io.vertx.core.Future; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +import java.util.concurrent.ConcurrentMap; + +/** + * @author lang : 2024-11-04 + */ +public interface RDataComponent { + + Future dataAsync(JsonArray dataSource, JsonObject parameters); +} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RGrupComponent.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RGrupComponent.java new file mode 100644 index 00000000..17e83da6 --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RGrupComponent.java @@ -0,0 +1,12 @@ +package io.zerows.extension.runtime.report.uca.feature; + +import io.vertx.core.Future; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +import java.util.concurrent.ConcurrentMap; + +public interface RGrupComponent { + + Future> dataAsync(ConcurrentMap map, String params); +} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcTree.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcTree.java index 8c07c0dd..bec9ae75 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcTree.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcTree.java @@ -92,8 +92,8 @@ class DimProcTree extends AbstractDimProc { itemFinal.put(RpConstant.DimField.CHILDREN, this.dimChildren(item, data, keyId)); // 自身 itemFinal.put(RpConstant.DimField.DISPLAY, this.dimDisplay(item, data, labelConfig)); // 注意区别 - itemFinal.put(RpConstant.DimField.KEY, Ut.valueString(item, keyId)); - result.add(item); + itemFinal.put(RpConstant.DimField.KEY, Ut.valueString(item, labelField)); + result.add(itemFinal); }); } return result; diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/AbstractDataSet.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/AbstractDataSet.java index 9f55f677..f322d1ea 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/AbstractDataSet.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/AbstractDataSet.java @@ -53,9 +53,26 @@ public abstract class AbstractDataSet implements DataSet { final JsonArray ids = Ut.valueJArray(data, whereField); final JsonObject condition = Ux.whereAnd(); + if (refConfig.containsKey("byField")) { + Object byFieldValue = refConfig.getValue("byField"); - condition.put(this.loadKey(refConfig) + ",i", ids); - + if (byFieldValue instanceof Boolean) { + // 如果 byField 是布尔类型 + if ((Boolean) byFieldValue) { + condition.put(refField + ",i", ids); + }else { + condition.put(this.loadKey(refConfig) + ",i", ids); + } + } else if (byFieldValue instanceof String byFieldStr) { + // 如果 byField 是字符串类型list = {ArrayList@32413} size = 2 + condition.put(byFieldStr + ",i", ids); + } else { + // 默认处理 + condition.put(this.loadKey(refConfig) + ",i", ids); + } + } else { + condition.put(this.loadKey(refConfig) + ",i", ids); + } final DataSet dataSet = DataSet.of(refConfig); dataMap.put(whereField, dataSet.loadAsync(condition)); // input / refField -> output @@ -78,9 +95,25 @@ public abstract class AbstractDataSet implements DataSet { final String whereField = this.loadKey(refField, refConfig); final String keyField = this.loadKey(refConfig); // 数据连接 - final ConcurrentMap whereMap = Ut.elementMap(queryData, keyField); - // 开始连接 - childData.put(whereField, Ut.toJObject(whereMap)); + if (refConfig.containsKey("byField")) { + Object byFieldValue = refConfig.getValue("byField"); + if (byFieldValue instanceof Boolean) { + // 如果 byField 是布尔类型 + if ((Boolean) byFieldValue) { + final ConcurrentMap whereMap = Ut.elementMap(queryData, whereField); + // 开始连接 + childData.put(whereField, Ut.toJObject(whereMap)); + } + } + if(byFieldValue instanceof String byFieldStr){ + final ConcurrentMap whereMap = Ut.elementMap(queryData, byFieldStr); + childData.put(whereField, Ut.toJObject(whereMap)); + } + } else { + final ConcurrentMap whereMap = Ut.elementMap(queryData, keyField); + // 开始连接 + childData.put(whereField, Ut.toJObject(whereMap)); + } }); Ut.itJArray(data).forEach(dataEach -> { @@ -88,7 +121,6 @@ public abstract class AbstractDataSet implements DataSet { final Set fieldSet = childData.fieldNames(); fieldSet.forEach(inputField -> { final String inputValue = dataEach.getString(inputField); - // 原始记录是否包含 field 对应值 final JsonObject outData = childData.getJsonObject(inputField); final JsonObject outValue = outData.getJsonObject(inputValue); diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSet.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSet.java index c7c9034e..2abe896d 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSet.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSet.java @@ -7,11 +7,14 @@ import io.vertx.core.Future; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import io.vertx.up.eon.KName; +import io.vertx.up.unity.Ux; import io.vertx.up.util.Ut; import io.zerows.core.metadata.uca.logging.OLog; import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; import io.zerows.extension.runtime.report.eon.RpConstant; import io.zerows.extension.runtime.report.eon.em.EmReport; +import io.zerows.extension.runtime.report.uca.feature.OData; +import io.zerows.extension.runtime.report.uca.feature.OFeature; /** * 数据源加载器,用于处理 dataSource 字段定义的数据源的相关信息加载,主要依赖 @@ -89,7 +92,15 @@ public interface DataSet { final DataSet executor = DataSet.of(sourceJ); final JsonObject queryDef = Ut.toJObject(dataSet.getDataQuery()); - return executor.loadAsync(params, queryDef); + + return executor.loadAsync(params, queryDef).compose(data->{ + if(dataSet.getDataComponent()==null){ + return Ux.future(data); + }else { + OData of = OData.of("C:"); + return of.dataAsync(data,params,dataSet); + } + }); } } } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSetTable.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSetTable.java index 8924c1cd..6d6acfd9 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSetTable.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSetTable.java @@ -56,6 +56,15 @@ class DataSetTable extends AbstractDataSet { this.connect.getTable(), parameters.encode()); // 提取 UxJooq final UxJooq jq = Ux.Jooq.bridge(this.connect); - return jq.fetchJAndAsync(parameters).compose(data -> this.loadChildren(data, this.children)); + if(parameters.getBoolean("")!=null){ + if(!parameters.getBoolean("")){ + return jq.fetchJOrAsync(parameters).compose(data -> this.loadChildren(data, this.children)); + }else { + return jq.fetchJAndAsync(parameters).compose(data -> this.loadChildren(data, this.children)); + } + }else { + return jq.fetchJAndAsync(parameters).compose(data -> this.loadChildren(data, this.children)); + + } } } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRDataComponent.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRDataComponent.java new file mode 100644 index 00000000..fa22c53a --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRDataComponent.java @@ -0,0 +1,9 @@ +package io.zerows.extension.runtime.report.uca.pull.io; + +import io.zerows.extension.runtime.report.uca.feature.RDataComponent; + +/** + * @author lang : 2024-11-14 + */ +public abstract class AbstractRDataComponent implements RDataComponent { +} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRGroupComponent.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRGroupComponent.java new file mode 100644 index 00000000..1f161980 --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRGroupComponent.java @@ -0,0 +1,10 @@ +package io.zerows.extension.runtime.report.uca.pull.io; + +import io.zerows.extension.runtime.report.uca.feature.RDataComponent; +import io.zerows.extension.runtime.report.uca.feature.RGrupComponent; + +/** + * @author lang : 2024-11-14 + */ +public abstract class AbstractRGroupComponent implements RGrupComponent { +} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java new file mode 100644 index 00000000..fa78d29c --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java @@ -0,0 +1,51 @@ +package io.zerows.extension.runtime.report.uca.util; + +import org.apache.commons.jexl3.*; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class FormulaEvaluator { + + + public static String calculateFormula(String formula, ConcurrentHashMap total) { + // 匹配公式中的变量(如 sellRoom, roomTotal) + Pattern pattern = Pattern.compile("([a-zA-Z]+\\w*)"); + Matcher matcher = pattern.matcher(formula); + + // 替换公式中的变量为对应的值 + while (matcher.find()) { + String variable = matcher.group(1); + if (total.containsKey(variable)) { + BigDecimal value = new BigDecimal(total.get(variable)); + formula = formula.replace(variable, value.toString()); + } + } + + // 执行替换后的公式计算 + BigDecimal result = evaluateFormula(formula); + + // 保留两位小数 + result = result.setScale(2, RoundingMode.DOWN); + + return result.toString(); + } + + public static BigDecimal evaluateFormula(String formula) { + try { + JexlEngine jexl = new JexlBuilder().create(); + JexlExpression e = jexl.createExpression(formula); + JexlContext context = new MapContext(); + + // 执行公式计算 + Object result = e.evaluate(context); + return new BigDecimal(result.toString()).setScale(2, RoundingMode.DOWN); + } catch (Exception e) { + e.printStackTrace(); + return BigDecimal.ZERO; // 如果计算失败,返回 0 + } + } +} -- Gitee From 6252145a50bf59e2a4944d89a785a46b540647d2 Mon Sep 17 00:00:00 2001 From: unknown <627433532@qq.com> Date: Fri, 27 Dec 2024 16:02:37 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0report=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../report/uca/util/FormulaEvaluator.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java index fa78d29c..2dc183e3 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java @@ -11,10 +11,10 @@ import java.util.regex.Pattern; public class FormulaEvaluator { - public static String calculateFormula(String formula, ConcurrentHashMap total) { + public static String calculateFormula(String formula, final ConcurrentHashMap total) { // 匹配公式中的变量(如 sellRoom, roomTotal) - Pattern pattern = Pattern.compile("([a-zA-Z]+\\w*)"); - Matcher matcher = pattern.matcher(formula); + final Pattern pattern = Pattern.compile("([a-zA-Z]+\\w*)"); + final Matcher matcher = pattern.matcher(formula); // 替换公式中的变量为对应的值 while (matcher.find()) { @@ -34,14 +34,14 @@ public class FormulaEvaluator { return result.toString(); } - public static BigDecimal evaluateFormula(String formula) { + public static BigDecimal evaluateFormula(final String formula) { try { - JexlEngine jexl = new JexlBuilder().create(); - JexlExpression e = jexl.createExpression(formula); - JexlContext context = new MapContext(); + final JexlEngine jexl = new JexlBuilder().create(); + final JexlExpression e = jexl.createExpression(formula); + final JexlContext context = new MapContext(); // 执行公式计算 - Object result = e.evaluate(context); + final Object result = e.evaluate(context); return new BigDecimal(result.toString()).setScale(2, RoundingMode.DOWN); } catch (Exception e) { e.printStackTrace(); -- Gitee From f2addd9d153fae609ef2ee974767a0338b513d39 Mon Sep 17 00:00:00 2001 From: unknown <627433532@qq.com> Date: Wed, 1 Jan 2025 01:42:24 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../report/api/service/ReportService.java | 1 + .../runtime/report/atom/RDimension.java | 25 +++-- .../extension/runtime/report/refine/Rp.java | 29 +++++ .../runtime/report/refine/RpValue.java | 23 ++++ .../uca/combiner/StepGeneratorData.java | 53 --------- .../uca/combiner/StepGeneratorFacade.java | 9 +- .../uca/combiner/StepGeneratorTotal.java | 101 ++++++++++++++++++ .../runtime/report/uca/feature/OData.java | 60 ----------- .../report/uca/feature/ODataClass.java | 45 -------- .../runtime/report/uca/feature/OGroup.java | 55 ---------- .../report/uca/feature/OGroupClass.java | 28 ----- .../report/uca/feature/RGrupComponent.java | 12 --- ...ataComponent.java => RQueryComponent.java} | 4 +- .../report/uca/process/DimProcImpl.java | 36 ++++++- .../report/uca/process/DimProcTree.java | 1 + .../runtime/report/uca/pull/DataSet.java | 43 +++++--- .../uca/pull/io/AbstractRDataComponent.java | 4 +- .../uca/pull/io/AbstractRGroupComponent.java | 10 -- .../report/uca/util/FormulaEvaluator.java | 51 --------- 19 files changed, 241 insertions(+), 349 deletions(-) create mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java delete mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OData.java delete mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/ODataClass.java delete mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroup.java delete mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroupClass.java delete mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RGrupComponent.java rename Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/{RDataComponent.java => RQueryComponent.java} (82%) delete mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRGroupComponent.java delete mode 100644 Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/api/service/ReportService.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/api/service/ReportService.java index 247c19fe..efbf0dd3 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/api/service/ReportService.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/api/service/ReportService.java @@ -91,6 +91,7 @@ public class ReportService implements ReportStub { // ERR-80702 return Ut.Bnd.failOut(_400ReportDataSetException.class, this.getClass(), reportId); } + return DataSet.Tool.outputArray(params, dataSet); }); } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/atom/RDimension.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/atom/RDimension.java index 202c5fec..d95c41ea 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/atom/RDimension.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/atom/RDimension.java @@ -7,6 +7,8 @@ import io.zerows.extension.runtime.report.eon.RpConstant; import io.zerows.extension.runtime.report.eon.em.EmDim; import java.io.Serializable; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.LinkedHashSet; import java.util.Objects; import java.util.Set; @@ -85,22 +87,27 @@ public class RDimension implements Serializable { return sourceData.size(); } final Stream waiting = Ut.itJArray(sourceData) - .map(item -> item.getValue(aggregator.field())) - .filter(Objects::nonNull) - .map(Object::toString) - .filter(Ut::isDecimal) - .map(Double::parseDouble); + .map(item -> item.getValue(aggregator.field())) + .filter(Objects::nonNull) + .map(Object::toString) + .filter(Ut::isDecimal) + .map(Double::parseDouble); + if (EmDim.Aggregator.SUM == type) { - return waiting.reduce(Double::sum).orElse(0.0); + double result = waiting.reduce(Double::sum).orElse(0.00); + return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN).doubleValue(); } if (EmDim.Aggregator.AVG == type) { - return waiting.reduce(Double::sum).orElse(0.0) / sourceData.size(); + double result = waiting.reduce(Double::sum).orElse(0.00) / sourceData.size(); + return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN).doubleValue(); } if (EmDim.Aggregator.MAX == type) { - return waiting.reduce(Double::max).orElse(0.0); + double result = waiting.reduce(Double::max).orElse(0.00); + return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN).doubleValue(); } if (EmDim.Aggregator.MIN == type) { - return waiting.reduce(Double::min).orElse(0.0); + double result = waiting.reduce(Double::min).orElse(0.00); + return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN).doubleValue(); } return null; } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/Rp.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/Rp.java index 22e34460..39a792b8 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/Rp.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/Rp.java @@ -2,6 +2,12 @@ package io.zerows.extension.runtime.report.refine; import io.vertx.core.json.JsonObject; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * @author lang : 2024-11-14 */ @@ -38,4 +44,27 @@ public final class Rp { }); return output; } + + public static String calculateFormula(String formula, final ConcurrentHashMap total) { + // 匹配公式中的变量(如 sellRoom, roomTotal) + final Pattern pattern = Pattern.compile("([a-zA-Z]+\\w*)"); + final Matcher matcher = pattern.matcher(formula); + + // 替换公式中的变量为对应的值 + while (matcher.find()) { + String variable = matcher.group(1); + if (total.containsKey(variable)) { + BigDecimal value = new BigDecimal(total.get(variable)); + formula = formula.replace(variable, value.toString()); + } + } + + // 执行替换后的公式计算 + BigDecimal result = RpValue.evaluateFormula(formula); + + // 保留两位小数 + result = result.setScale(2, RoundingMode.DOWN); + + return result.toString(); + } } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/RpValue.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/RpValue.java index 4993a5b4..006afca9 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/RpValue.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/RpValue.java @@ -3,7 +3,10 @@ package io.zerows.extension.runtime.report.refine; import io.horizon.eon.VValue; import io.vertx.core.json.JsonObject; import io.vertx.up.util.Ut; +import org.apache.commons.jexl3.*; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -76,4 +79,24 @@ class RpValue { } return formatIn(modes, params); } + + /** + * 通过公式进行计算 + * @param formula + * @return + */ + static BigDecimal evaluateFormula(final String formula) { + try { + final JexlEngine jexl = new JexlBuilder().create(); + final JexlExpression e = jexl.createExpression(formula); + final JexlContext context = new MapContext(); + + // 执行公式计算 + final Object result = e.evaluate(context); + return new BigDecimal(result.toString()).setScale(2, RoundingMode.DOWN); + } catch (Exception e) { + e.printStackTrace(); + return BigDecimal.ZERO; // 如果计算失败,返回 0 + } + } } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java index ade1e082..c37b9588 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java @@ -16,11 +16,7 @@ import io.zerows.extension.runtime.report.domain.tables.pojos.KpReportInstance; import io.zerows.extension.runtime.report.eon.RpConstant; import io.zerows.extension.runtime.report.eon.em.EmReport; import io.zerows.extension.runtime.report.uca.feature.OFeature; -import io.zerows.extension.runtime.report.uca.feature.OGroup; -import io.zerows.extension.runtime.report.uca.util.FormulaEvaluator; -import java.math.BigDecimal; -import java.math.RoundingMode; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -177,10 +173,6 @@ class StepGeneratorData extends AbstractStepGenerator { // 构造最终报表形态,先按维度分组 final ConcurrentMap groupMap = Ut.elementGroup(dataProcessed, RpConstant.DimField.KEY); - if(newGroup!=null){ - OGroup of = OGroup.of("C:"); - of.dataAsync(groupMap,newGroup); - } final Set dimKeys = dimension.dateKeys(); // combine 节点,追加维度行 @@ -226,53 +218,8 @@ class StepGeneratorData extends AbstractStepGenerator { } }); dimRecord.put(KName.CHILDREN, dimSource); - JsonArray dimSourceCopy = dimSource.copy(); - bottomTotal.fieldNames().forEach(dimFeature -> { - // 提取 Feature - final KpFeature feature = Ut.elementFind(features, item -> item.getName().equals(dimFeature)); - final EmReport.FeatureType featureType = Ut.toEnum(feature.getType(), EmReport.FeatureType.class, EmReport.FeatureType.NONE); - if (EmReport.FeatureType.AGGR == featureType) { - dimSourceCopy.forEach(item -> { - JsonObject entries = Ux.toJson(item); - String string = entries.getString(feature.getName()); - // 使用 BigDecimal.valueOf 保留两位小数 - BigDecimal value = (string == null || string.isEmpty()) - ? BigDecimal.ZERO - : BigDecimal.valueOf(Double.parseDouble(string)).setScale(2, RoundingMode.HALF_UP); - // 转换为字符串,确保两位小数 - String valueString = value.toString(); - // 使用 compute 方法累加值 - total.compute(feature.getName(), (key, current) -> { - if (current == null) { - return valueString; // 如果该键没有值,直接使用当前值 - } else { - // 将当前值和新值转换为 BigDecimal,进行累加 - BigDecimal currentValue = new BigDecimal(current); - BigDecimal newValue = new BigDecimal(valueString); - BigDecimal sum = currentValue.add(newValue).setScale(2, RoundingMode.HALF_UP); - return sum.toString(); // 返回累加后的值 - } - }); - }); - } - }); reportData.add(dimRecord); }); - - TotalCount.fieldNames().forEach(count->{ - final String formula = TotalCount.getString(count); - final String result = FormulaEvaluator.calculateFormula(formula, total); - total.put(count, result); - }); - JsonObject entries = Ux.toJson(total); - entries.put("key", UUID.randomUUID().toString()); - bottomTotal.fieldNames().forEach(item->{ - boolean b = total.containsKey(item); - if(!b){ - entries.put(item,bottomTotal.getString(item)); - } - }); - reportData.add(entries); return Ux.future(reportData); }); } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorFacade.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorFacade.java index ddae570f..936b47b2 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorFacade.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorFacade.java @@ -17,6 +17,8 @@ class StepGeneratorFacade extends AbstractStepGenerator { private final StepGenerator generatorAudit; private final StepGenerator generatorData; + private final StepGenerator generatorTotal; + StepGeneratorFacade(final RGeneration generation) { super(generation); @@ -24,6 +26,7 @@ class StepGeneratorFacade extends AbstractStepGenerator { this.generatorBelong = of(generation, StepGeneratorBelong.class); this.generatorAudit = of(generation, StepGeneratorAudit.class); this.generatorData = of(generation, StepGeneratorData.class); + this.generatorTotal = of(generation, StepGeneratorTotal.class); } @Override @@ -59,6 +62,10 @@ class StepGeneratorFacade extends AbstractStepGenerator { * reportData * reportContent */ - .compose(processed -> this.generatorData.build(processed, params, sourceData)); + .compose(processed -> this.generatorData.build(processed, params, sourceData)) + /* + * 在最底部加上合计 + */ + .compose(processed->this.generatorTotal.build(processed,params,sourceData)); } } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java new file mode 100644 index 00000000..0a5dbddf --- /dev/null +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java @@ -0,0 +1,101 @@ +package io.zerows.extension.runtime.report.uca.combiner; + +import io.vertx.core.Future; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import io.vertx.up.eon.KName; +import io.vertx.up.unity.Ux; +import io.vertx.up.util.Ut; +import io.zerows.extension.runtime.report.atom.RGeneration; +import io.zerows.extension.runtime.report.domain.tables.pojos.KpFeature; +import io.zerows.extension.runtime.report.domain.tables.pojos.KpReport; +import io.zerows.extension.runtime.report.domain.tables.pojos.KpReportInstance; +import io.zerows.extension.runtime.report.eon.em.EmReport; +import io.zerows.extension.runtime.report.refine.Rp; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author Yu : 2024-12-31 + */ +public class StepGeneratorTotal extends AbstractStepGenerator { + StepGeneratorTotal(final RGeneration generation) { + super(generation); + } + + /** + * 在最底部添加合计行,根据对应的配置进行公式计算 + * @param instance + * @param request + * @param sourceData + * @return + */ + @Override + public Future build(KpReportInstance instance, JsonObject request, JsonArray sourceData) { + final KpReport report = this.metadata().reportMeta(); + final RGeneration metadata = this.metadata(); + final List features = metadata.featureData(); + final JsonObject reportConfig = Ut.toJObject(report.getReportConfig()); + final JsonObject bottomTotal = Ut.valueJObject(reportConfig, "total"); + final JsonObject totalCount = Ut.valueJObject(reportConfig, "totalCount"); + final JsonObject reportContent = new JsonObject(instance.getReportContent()); + final JsonArray data = reportContent.getJsonArray("data"); + final JsonArray children = new JsonArray(); + data.forEach(item -> { + final JsonObject entries = Ux.toJson(item); + final JsonArray jsonArray = entries.getJsonArray(KName.CHILDREN); + jsonArray.forEach(children::add); + }); + final ConcurrentHashMap total = new ConcurrentHashMap<>(); + bottomTotal.fieldNames().forEach(dimFeature -> { + // 提取 Feature + final KpFeature feature = Ut.elementFind(features, item -> item.getName().equals(dimFeature)); + final EmReport.FeatureType featureType = Ut.toEnum(feature.getType(), EmReport.FeatureType.class, EmReport.FeatureType.NONE); + if (EmReport.FeatureType.AGGR == featureType) { + children.forEach(item -> { + JsonObject entries = Ux.toJson(item); + String string = entries.getString(feature.getName()); + // 使用 BigDecimal.valueOf 保留两位小数 + BigDecimal value = (string == null || string.isEmpty()) ? BigDecimal.ZERO : BigDecimal.valueOf(Double.parseDouble(string)).setScale(2, RoundingMode.HALF_UP); + // 转换为字符串,确保两位小数 + String valueString = value.toString(); + // 使用 compute 方法累加值 + total.compute(feature.getName(), (key, current) -> { + if (current == null) { + return valueString; // 如果该键没有值,直接使用当前值 + } else { + // 将当前值和新值转换为 BigDecimal,进行累加 + BigDecimal currentValue = new BigDecimal(current); + BigDecimal newValue = new BigDecimal(valueString); + BigDecimal sum = currentValue.add(newValue).setScale(2, RoundingMode.HALF_UP); + return sum.toString(); // 返回累加后的值 + } + }); + }); + } + }); + if (totalCount != null) { + totalCount.fieldNames().forEach(count -> { + final String formula = totalCount.getString(count); + final String result = Rp.calculateFormula(formula, total); + total.put(count, result); + }); + } + final JsonObject entries = Ux.toJson(total); + entries.put("key", UUID.randomUUID().toString()); + bottomTotal.fieldNames().forEach(item -> { + boolean b = total.containsKey(item); + if (!b) { + entries.put(item, bottomTotal.getString(item)); + } + }); + final JsonArray add = data.add(entries); + reportContent.put("data", add); + instance.setReportContent(reportContent.toString()); + return Ux.future(instance); + } +} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OData.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OData.java deleted file mode 100644 index f7be7b5f..00000000 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OData.java +++ /dev/null @@ -1,60 +0,0 @@ -package io.zerows.extension.runtime.report.uca.feature; - -import io.horizon.uca.cache.Cc; -import io.vertx.core.Future; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import io.vertx.up.eon.KName; -import io.vertx.up.util.Ut; -import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; -import io.zerows.extension.runtime.report.domain.tables.pojos.KpFeature; -import io.zerows.extension.runtime.report.eon.RpConstant; - -import java.time.Instant; -import java.time.LocalDateTime; -import java.util.Objects; -import java.util.concurrent.ConcurrentMap; - -/** - * @author lang : 2024-11-27 - */ -public interface OData { - - Cc CC_SKELETON = Cc.openThread(); - - static OData of(final String valuePath) { - Objects.requireNonNull(valuePath); - return CC_SKELETON.pick(ODataClass::new, valuePath); - - } - - /** - *

-     *     params -> data 数据
-     *               input 输入参数
-     * 
- * - * @return 计算的值 - */ - Future dataAsync(JsonArray dataSource, JsonObject params, KpDataSet dataSet); - interface T { - - static Object formatValue(final Object value, final JsonObject valueConfig) { - final Object valueResult; - if (Ut.isNotNil(valueConfig) && valueConfig.containsKey(KName.FORMAT)) { - final String pattern = Ut.valueString(valueConfig, KName.FORMAT); - // 时间格式 - if (value instanceof final Instant valueInstant) { - final LocalDateTime parsed = Ut.toDateTime(valueInstant); - valueResult = Ut.fromDate(parsed, pattern); - } else { - final LocalDateTime parsed = Ut.toDateTime(Ut.parseFull(value.toString())); - valueResult = Ut.fromDate(parsed, pattern); - } - } else { - valueResult = value; - } - return valueResult; - } - } -} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/ODataClass.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/ODataClass.java deleted file mode 100644 index 39316bcf..00000000 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/ODataClass.java +++ /dev/null @@ -1,45 +0,0 @@ -package io.zerows.extension.runtime.report.uca.feature; - -import io.horizon.uca.cache.Cc; -import io.vertx.core.Future; -import io.vertx.core.json.Json; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import io.vertx.up.eon.KName; -import io.vertx.up.util.Ut; -import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; -import io.zerows.extension.runtime.report.domain.tables.pojos.KpFeature; - -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author lang : 2024-11-27 - */ -class ODataClass implements OData { - - private static final Cc CC_OUT = Cc.openThread(); - - - @Override - public Future dataAsync(JsonArray dataSource, JsonObject params, KpDataSet dataSet) { - final String dataComponent = dataSet.getDataComponent(); - if (Ut.isNil(dataComponent)) { - return Ut.future(dataSource); - } - final RDataComponent outComponent = CC_OUT.pick(() -> Ut.instance(dataComponent), dataComponent); - if (Objects.isNull(outComponent)) { - return Ut.future(dataSource); - } - - final JsonObject parameters = new JsonObject(); - parameters.put(KName.INPUT, params); - return outComponent.dataAsync(dataSource, parameters).compose(result -> { - if (Objects.isNull(result)) { - return Ut.future(dataSource); - } - return Ut.future(result); - }); - } -} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroup.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroup.java deleted file mode 100644 index 078dc58e..00000000 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroup.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.zerows.extension.runtime.report.uca.feature; - -import io.horizon.uca.cache.Cc; -import io.vertx.core.Future; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import io.vertx.up.eon.KName; -import io.vertx.up.util.Ut; -import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; - -import java.time.Instant; -import java.time.LocalDateTime; -import java.util.Objects; -import java.util.concurrent.ConcurrentMap; - -public interface OGroup { - Cc CC_SKELETON = Cc.openThread(); - - static OGroup of(final String valuePath) { - Objects.requireNonNull(valuePath); - return CC_SKELETON.pick(OGroupClass::new, valuePath); - - } - - /** - *

-     *     params -> data 数据
-     *               input 输入参数
-     * 
- * - * @return 计算的值 - */ - Future> dataAsync(ConcurrentMap map, String params); - - interface T { - - static Object formatValue(final Object value, final JsonObject valueConfig) { - final Object valueResult; - if (Ut.isNotNil(valueConfig) && valueConfig.containsKey(KName.FORMAT)) { - final String pattern = Ut.valueString(valueConfig, KName.FORMAT); - // 时间格式 - if (value instanceof final Instant valueInstant) { - final LocalDateTime parsed = Ut.toDateTime(valueInstant); - valueResult = Ut.fromDate(parsed, pattern); - } else { - final LocalDateTime parsed = Ut.toDateTime(Ut.parseFull(value.toString())); - valueResult = Ut.fromDate(parsed, pattern); - } - } else { - valueResult = value; - } - return valueResult; - } - } -} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroupClass.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroupClass.java deleted file mode 100644 index 8db12dde..00000000 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/OGroupClass.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.zerows.extension.runtime.report.uca.feature; - -import io.horizon.uca.cache.Cc; -import io.vertx.core.Future; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import io.vertx.up.eon.KName; -import io.vertx.up.util.Ut; -import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; - -import java.util.Objects; -import java.util.concurrent.ConcurrentMap; - -public class OGroupClass implements OGroup{ - - private static final Cc CC_OUT = Cc.openThread(); - - @Override - public Future> dataAsync(ConcurrentMap map, String params) { - final RGrupComponent outComponent = CC_OUT.pick(() -> Ut.instance(params), params); - return outComponent.dataAsync(map, params).compose(result -> { - if (Objects.isNull(result)) { - return Ut.future(map); - } - return Ut.future(result); - }); - } -} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RGrupComponent.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RGrupComponent.java deleted file mode 100644 index 17e83da6..00000000 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RGrupComponent.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.zerows.extension.runtime.report.uca.feature; - -import io.vertx.core.Future; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; - -import java.util.concurrent.ConcurrentMap; - -public interface RGrupComponent { - - Future> dataAsync(ConcurrentMap map, String params); -} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RDataComponent.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RQueryComponent.java similarity index 82% rename from Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RDataComponent.java rename to Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RQueryComponent.java index 49e7cd72..e4b10954 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RDataComponent.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/feature/RQueryComponent.java @@ -7,9 +7,9 @@ import io.vertx.core.json.JsonObject; import java.util.concurrent.ConcurrentMap; /** - * @author lang : 2024-11-04 + * @author Yu : 2024-11-27 */ -public interface RDataComponent { +public interface RQueryComponent { Future dataAsync(JsonArray dataSource, JsonObject parameters); } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcImpl.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcImpl.java index 9ca8e148..0515f02a 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcImpl.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcImpl.java @@ -1,5 +1,6 @@ package io.zerows.extension.runtime.report.uca.process; +import io.horizon.uca.cache.Cc; import io.vertx.core.Future; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; @@ -14,6 +15,7 @@ import io.zerows.extension.runtime.report.domain.tables.pojos.KpDimension; import io.zerows.extension.runtime.report.eon.em.EmDim; import io.zerows.extension.runtime.report.eon.em.EmReport; import io.zerows.extension.runtime.report.exception._400ReportDimTypeException; +import io.zerows.extension.runtime.report.uca.feature.RQueryComponent; import io.zerows.extension.runtime.report.uca.pull.DataSet; import org.osgi.framework.Bundle; @@ -31,6 +33,8 @@ import java.util.stream.Collectors; */ class DimProcImpl extends AbstractDimProc { + private static final Cc CC_OUT = Cc.openThread(); + private static final ConcurrentMap> SUPPLIER = new ConcurrentHashMap<>() { { this.put(EmDim.Type.TREE, (owner) -> AbstractDimProc.of(owner, DimProcTree.class)); @@ -63,11 +67,33 @@ class DimProcImpl extends AbstractDimProc { final Set dataSet = dimensions.stream().map(KpDimension::getDataSetId).collect(Collectors.toSet()); return Ux.Jooq.on(KpDataSetDao.class).fetchInAsync(KName.KEY, dataSet).compose(dataSets -> { final ConcurrentMap> resultMap = new ConcurrentHashMap<>(); - dataSets.forEach(dataSetItem -> { - final Future result = DataSet.Tool.outputArray(params, dataSetItem); - resultMap.put(dataSetItem.getKey(), result); - }); - return Fn.combineM(resultMap); + KpDataSet kpDataSet = dataSets.get(0); + final JsonObject sourceJ = Ut.toJObject(kpDataSet.getDataSource()); + final DataSet executor = DataSet.of(sourceJ); + final JsonObject queryDef = Ut.toJObject(kpDataSet.getDataQuery()); + + if(kpDataSet.getDataComponent()!=null){ + return executor.loadAsync(params, queryDef).compose(dataSouce->{ + String dataComponent = kpDataSet.getDataComponent(); + RQueryComponent queryComponent = CC_OUT.pick(() -> Ut.instance(dataComponent), dataComponent); + final JsonObject parameters = new JsonObject(); + parameters.put(KName.INPUT, params); + Future compose = queryComponent.dataAsync(dataSouce, parameters).compose(result -> { + if (Objects.isNull(result)) { + return Ut.future(dataSouce); + } + return Ut.future(result); + }); + resultMap.put(kpDataSet.getKey(), compose); + return Fn.combineM(resultMap); + }); + }else { + dataSets.forEach(dataSetItem -> { + final Future result = DataSet.Tool.outputArray(params, dataSetItem); + resultMap.put(dataSetItem.getKey(), result); + }); + return Fn.combineM(resultMap); + } }); } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcTree.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcTree.java index bec9ae75..7f2d25ce 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcTree.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcTree.java @@ -92,6 +92,7 @@ class DimProcTree extends AbstractDimProc { itemFinal.put(RpConstant.DimField.CHILDREN, this.dimChildren(item, data, keyId)); // 自身 itemFinal.put(RpConstant.DimField.DISPLAY, this.dimDisplay(item, data, labelConfig)); // 注意区别 + //todo itemFinal.put(RpConstant.DimField.KEY, Ut.valueString(item, labelField)); result.add(itemFinal); }); diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSet.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSet.java index 2abe896d..1955b312 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSet.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/DataSet.java @@ -7,14 +7,16 @@ import io.vertx.core.Future; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import io.vertx.up.eon.KName; +import io.vertx.up.fn.Fn; import io.vertx.up.unity.Ux; import io.vertx.up.util.Ut; import io.zerows.core.metadata.uca.logging.OLog; import io.zerows.extension.runtime.report.domain.tables.pojos.KpDataSet; import io.zerows.extension.runtime.report.eon.RpConstant; import io.zerows.extension.runtime.report.eon.em.EmReport; -import io.zerows.extension.runtime.report.uca.feature.OData; -import io.zerows.extension.runtime.report.uca.feature.OFeature; +import io.zerows.extension.runtime.report.uca.feature.RQueryComponent; + +import java.util.Objects; /** * 数据源加载器,用于处理 dataSource 字段定义的数据源的相关信息加载,主要依赖 @@ -29,10 +31,11 @@ import io.zerows.extension.runtime.report.uca.feature.OFeature; public interface DataSet { Cc CC_SKELETON = Cc.openThread(); + Cc CC_OUT = Cc.openThread(); static DataSet of(final JsonObject sourceJ) { final EmReport.SourceType type = Ut.toEnum( - () -> Ut.valueString(sourceJ, "sourceType"), EmReport.SourceType.class); + () -> Ut.valueString(sourceJ, "sourceType"), EmReport.SourceType.class); final String dsTarget; // TABLE if (EmReport.SourceType.TABLE == type) { @@ -42,7 +45,7 @@ public interface DataSet { paramConstructor.put(KName.SOURCE, dsTarget); paramConstructor.put(KName.CHILDREN, sourceJ.getValue(KName.CHILDREN)); return CC_SKELETON.pick( - () -> new DataSetTable(paramConstructor), type + VString.SLASH + dsTarget + () -> new DataSetTable(paramConstructor), type + VString.SLASH + dsTarget ); } // JOIN_2 @@ -50,7 +53,7 @@ public interface DataSet { final JsonObject paramConstructor = Ut.valueJObject(sourceJ, RpConstant.SourceTypeField.SOURCE); paramConstructor.put(KName.CHILDREN, sourceJ.getValue(KName.CHILDREN)); return CC_SKELETON.pick( - () -> new DataSetJoin2(paramConstructor), type + VString.SLASH + paramConstructor.hashCode() + () -> new DataSetJoin2(paramConstructor), type + VString.SLASH + paramConstructor.hashCode() ); } // Not Support @@ -62,7 +65,6 @@ public interface DataSet { * * @param params 读取参数 * @param queryJ 查询配置 - * * @return 返回读取的数据 */ Future loadAsync(JsonObject params, JsonObject queryJ); @@ -87,20 +89,29 @@ public interface DataSet { } static Future outputArray(final JsonObject params, final KpDataSet dataSet) { - // 新版只通过 dataSource 来构造数据源,不再使用 dataSet + /** + * 先分流 不能二义性 + * + */ final JsonObject sourceJ = Ut.toJObject(dataSet.getDataSource()); final DataSet executor = DataSet.of(sourceJ); - final JsonObject queryDef = Ut.toJObject(dataSet.getDataQuery()); - return executor.loadAsync(params, queryDef).compose(data->{ - if(dataSet.getDataComponent()==null){ - return Ux.future(data); - }else { - OData of = OData.of("C:"); - return of.dataAsync(data,params,dataSet); - } - }); + if (dataSet.getDataComponent() != null) { + return executor.loadAsync(params, queryDef).compose(dataSouce -> { + String dataComponent = dataSet.getDataComponent(); + RQueryComponent queryComponent = CC_OUT.pick(() -> Ut.instance(dataComponent), dataComponent); + final JsonObject parameters = new JsonObject(); + parameters.put(KName.INPUT, params); + return queryComponent.dataAsync(dataSouce, parameters).compose(result -> { + if (Objects.isNull(result)) { + return Ut.future(dataSouce); + } + return Ut.future(result); + }); + }); + } + return executor.loadAsync(params, queryDef); } } } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRDataComponent.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRDataComponent.java index fa22c53a..19895565 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRDataComponent.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRDataComponent.java @@ -1,9 +1,9 @@ package io.zerows.extension.runtime.report.uca.pull.io; -import io.zerows.extension.runtime.report.uca.feature.RDataComponent; +import io.zerows.extension.runtime.report.uca.feature.RQueryComponent; /** * @author lang : 2024-11-14 */ -public abstract class AbstractRDataComponent implements RDataComponent { +public abstract class AbstractRDataComponent implements RQueryComponent { } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRGroupComponent.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRGroupComponent.java deleted file mode 100644 index 1f161980..00000000 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/pull/io/AbstractRGroupComponent.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.zerows.extension.runtime.report.uca.pull.io; - -import io.zerows.extension.runtime.report.uca.feature.RDataComponent; -import io.zerows.extension.runtime.report.uca.feature.RGrupComponent; - -/** - * @author lang : 2024-11-14 - */ -public abstract class AbstractRGroupComponent implements RGrupComponent { -} diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java deleted file mode 100644 index 2dc183e3..00000000 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/util/FormulaEvaluator.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.zerows.extension.runtime.report.uca.util; - -import org.apache.commons.jexl3.*; - -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class FormulaEvaluator { - - - public static String calculateFormula(String formula, final ConcurrentHashMap total) { - // 匹配公式中的变量(如 sellRoom, roomTotal) - final Pattern pattern = Pattern.compile("([a-zA-Z]+\\w*)"); - final Matcher matcher = pattern.matcher(formula); - - // 替换公式中的变量为对应的值 - while (matcher.find()) { - String variable = matcher.group(1); - if (total.containsKey(variable)) { - BigDecimal value = new BigDecimal(total.get(variable)); - formula = formula.replace(variable, value.toString()); - } - } - - // 执行替换后的公式计算 - BigDecimal result = evaluateFormula(formula); - - // 保留两位小数 - result = result.setScale(2, RoundingMode.DOWN); - - return result.toString(); - } - - public static BigDecimal evaluateFormula(final String formula) { - try { - final JexlEngine jexl = new JexlBuilder().create(); - final JexlExpression e = jexl.createExpression(formula); - final JexlContext context = new MapContext(); - - // 执行公式计算 - final Object result = e.evaluate(context); - return new BigDecimal(result.toString()).setScale(2, RoundingMode.DOWN); - } catch (Exception e) { - e.printStackTrace(); - return BigDecimal.ZERO; // 如果计算失败,返回 0 - } - } -} -- Gitee From 4849f7ae2d3939d0f5e350d5d1322fe3209e3b59 Mon Sep 17 00:00:00 2001 From: unknown <627433532@qq.com> Date: Wed, 1 Jan 2025 01:48:54 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../extension/runtime/report/eon/RpConstant.java | 7 +++++-- .../report/uca/combiner/StepGeneratorData.java | 6 +----- .../report/uca/combiner/StepGeneratorTotal.java | 11 ++++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/eon/RpConstant.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/eon/RpConstant.java index 2b1bb4e2..3f0582ce 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/eon/RpConstant.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/eon/RpConstant.java @@ -13,7 +13,11 @@ public interface RpConstant { String EXTENSION = "ds.extension"; String SOURCE = "ds.source"; } - + interface ConfigField{ + String COMBINE = "combine"; + String TOTAL = "total"; + String TOTAL_COUNT = "totalCount"; + } interface DimField { String KEY = "dimKey"; String DISPLAY = "dimDisplay"; @@ -22,7 +26,6 @@ public interface RpConstant { interface DimValue { String FIELD_GROUP = "field.group"; - String NEW_GROUP = "newGroup"; } interface ValuePath { diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java index c37b9588..03f39be5 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorData.java @@ -132,7 +132,6 @@ class StepGeneratorData extends AbstractStepGenerator { // 抽取维度配置 final JsonObject dimConfig = Ut.toJObject(featureOfDim.getValueConfig()); final String dimField = Ut.valueString(dimConfig, RpConstant.DimValue.FIELD_GROUP); - final String newGroup = Ut.valueString(dimConfig, RpConstant.DimValue.NEW_GROUP); // 先根据特征处理重新提取数据,保留维度字段 final JsonArray dataProcessed = new JsonArray(); @@ -178,12 +177,9 @@ class StepGeneratorData extends AbstractStepGenerator { // combine 节点,追加维度行 final KpReport report = this.metadata().reportMeta(); final JsonObject reportConfig = Ut.toJObject(report.getReportConfig()); - final JsonObject combine = Ut.valueJObject(reportConfig, "combine"); - final JsonObject bottomTotal = Ut.valueJObject(reportConfig,"bottomTotal"); - final JsonObject TotalCount = Ut.valueJObject(reportConfig,"TotalCount"); + final JsonObject combine = Ut.valueJObject(reportConfig, RpConstant.ConfigField.COMBINE); // 重新构造数据记录 final JsonArray reportData = new JsonArray(); - ConcurrentHashMap total = new ConcurrentHashMap<>(); dimKeys.stream().filter(groupMap::containsKey).forEach(dimKey -> { final JsonObject dimRecord = new JsonObject(); final JsonArray dimSource = groupMap.get(dimKey); diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java index 0a5dbddf..5e165800 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java @@ -10,6 +10,7 @@ import io.zerows.extension.runtime.report.atom.RGeneration; import io.zerows.extension.runtime.report.domain.tables.pojos.KpFeature; import io.zerows.extension.runtime.report.domain.tables.pojos.KpReport; import io.zerows.extension.runtime.report.domain.tables.pojos.KpReportInstance; +import io.zerows.extension.runtime.report.eon.RpConstant; import io.zerows.extension.runtime.report.eon.em.EmReport; import io.zerows.extension.runtime.report.refine.Rp; @@ -40,10 +41,10 @@ public class StepGeneratorTotal extends AbstractStepGenerator { final RGeneration metadata = this.metadata(); final List features = metadata.featureData(); final JsonObject reportConfig = Ut.toJObject(report.getReportConfig()); - final JsonObject bottomTotal = Ut.valueJObject(reportConfig, "total"); - final JsonObject totalCount = Ut.valueJObject(reportConfig, "totalCount"); + final JsonObject bottomTotal = Ut.valueJObject(reportConfig, RpConstant.ConfigField.TOTAL); + final JsonObject totalCount = Ut.valueJObject(reportConfig, RpConstant.ConfigField.TOTAL_COUNT); final JsonObject reportContent = new JsonObject(instance.getReportContent()); - final JsonArray data = reportContent.getJsonArray("data"); + final JsonArray data = reportContent.getJsonArray(KName.DATA); final JsonArray children = new JsonArray(); data.forEach(item -> { final JsonObject entries = Ux.toJson(item); @@ -86,7 +87,7 @@ public class StepGeneratorTotal extends AbstractStepGenerator { }); } final JsonObject entries = Ux.toJson(total); - entries.put("key", UUID.randomUUID().toString()); + entries.put(KName.KEY, UUID.randomUUID().toString()); bottomTotal.fieldNames().forEach(item -> { boolean b = total.containsKey(item); if (!b) { @@ -94,7 +95,7 @@ public class StepGeneratorTotal extends AbstractStepGenerator { } }); final JsonArray add = data.add(entries); - reportContent.put("data", add); + reportContent.put(KName.DATA, add); instance.setReportContent(reportContent.toString()); return Ux.future(instance); } -- Gitee From b4b5f05a5c177dc1c535f85561d960ccacd0bc47 Mon Sep 17 00:00:00 2001 From: unknown <627433532@qq.com> Date: Thu, 20 Feb 2025 00:08:07 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=9B=B4=E6=96=B0PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/service/ReportInstanceService.java | 17 +++++-- .../runtime/report/atom/RDimension.java | 18 ++++--- .../extension/runtime/report/refine/Rp.java | 28 ----------- .../runtime/report/refine/RpValue.java | 23 --------- .../uca/combiner/StepGeneratorTotal.java | 41 ++++++++-------- .../report/uca/process/DimProcImpl.java | 49 ++++++++++--------- 6 files changed, 72 insertions(+), 104 deletions(-) diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/api/service/ReportInstanceService.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/api/service/ReportInstanceService.java index 974e730f..daf5c5e0 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/api/service/ReportInstanceService.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/api/service/ReportInstanceService.java @@ -105,9 +105,20 @@ public class ReportInstanceService implements ReportInstanceStub { { // 很重要的参数提取 paramMap.forEach(paramsMiddle::put); - final String timeStr = Ut.valueString(params, "reportAt"); - final String time = Ut.fromDate(Ut.parseFull(timeStr), "yyyy-MM-dd"); - paramsMiddle.put("time", time); + final String reportStartTime = Ut.valueString(params, "reportStartTime"); + final String reportEndTime = Ut.valueString(params, "reportEndTime"); + if(reportStartTime==null&&reportEndTime==null){ + final String timeStr = Ut.valueString(params, "reportAt"); + final String time = Ut.fromDate(Ut.parseFull(timeStr), "yyyy-MM-dd"); + paramsMiddle.put("time", time); + }else { + final String time = Ut.fromDate(Ut.parseFull(reportStartTime), "yyyy-MM-dd"); + final String time2 = Ut.fromDate(Ut.parseFull(reportEndTime), "yyyy-MM-dd"); + paramsMiddle.put("time", time); + paramsMiddle.put("time2", time2); + } + + } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/atom/RDimension.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/atom/RDimension.java index d95c41ea..b833efa8 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/atom/RDimension.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/atom/RDimension.java @@ -90,24 +90,30 @@ public class RDimension implements Serializable { .map(item -> item.getValue(aggregator.field())) .filter(Objects::nonNull) .map(Object::toString) - .filter(Ut::isDecimal) - .map(Double::parseDouble); + .filter(value -> Ut.isDecimal(value) || Ut.isInteger(value)) // 支持整数和小数 + .map(value -> { + // 将字符串解析为 Double,无论是整数还是小数 + if (Ut.isInteger(value)) { + return Double.valueOf(Integer.parseInt(value)); + } + return Double.parseDouble(value); + }); if (EmDim.Aggregator.SUM == type) { double result = waiting.reduce(Double::sum).orElse(0.00); - return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN).doubleValue(); + return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN); } if (EmDim.Aggregator.AVG == type) { double result = waiting.reduce(Double::sum).orElse(0.00) / sourceData.size(); - return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN).doubleValue(); + return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN); } if (EmDim.Aggregator.MAX == type) { double result = waiting.reduce(Double::max).orElse(0.00); - return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN).doubleValue(); + return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN); } if (EmDim.Aggregator.MIN == type) { double result = waiting.reduce(Double::min).orElse(0.00); - return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN).doubleValue(); + return BigDecimal.valueOf(result).setScale(2, RoundingMode.DOWN); } return null; } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/Rp.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/Rp.java index 39a792b8..b1a6f070 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/Rp.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/Rp.java @@ -2,11 +2,6 @@ package io.zerows.extension.runtime.report.refine; import io.vertx.core.json.JsonObject; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author lang : 2024-11-14 @@ -44,27 +39,4 @@ public final class Rp { }); return output; } - - public static String calculateFormula(String formula, final ConcurrentHashMap total) { - // 匹配公式中的变量(如 sellRoom, roomTotal) - final Pattern pattern = Pattern.compile("([a-zA-Z]+\\w*)"); - final Matcher matcher = pattern.matcher(formula); - - // 替换公式中的变量为对应的值 - while (matcher.find()) { - String variable = matcher.group(1); - if (total.containsKey(variable)) { - BigDecimal value = new BigDecimal(total.get(variable)); - formula = formula.replace(variable, value.toString()); - } - } - - // 执行替换后的公式计算 - BigDecimal result = RpValue.evaluateFormula(formula); - - // 保留两位小数 - result = result.setScale(2, RoundingMode.DOWN); - - return result.toString(); - } } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/RpValue.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/RpValue.java index 006afca9..4993a5b4 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/RpValue.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/refine/RpValue.java @@ -3,10 +3,7 @@ package io.zerows.extension.runtime.report.refine; import io.horizon.eon.VValue; import io.vertx.core.json.JsonObject; import io.vertx.up.util.Ut; -import org.apache.commons.jexl3.*; -import java.math.BigDecimal; -import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -79,24 +76,4 @@ class RpValue { } return formatIn(modes, params); } - - /** - * 通过公式进行计算 - * @param formula - * @return - */ - static BigDecimal evaluateFormula(final String formula) { - try { - final JexlEngine jexl = new JexlBuilder().create(); - final JexlExpression e = jexl.createExpression(formula); - final JexlContext context = new MapContext(); - - // 执行公式计算 - final Object result = e.evaluate(context); - return new BigDecimal(result.toString()).setScale(2, RoundingMode.DOWN); - } catch (Exception e) { - e.printStackTrace(); - return BigDecimal.ZERO; // 如果计算失败,返回 0 - } - } } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java index 5e165800..cb164449 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/combiner/StepGeneratorTotal.java @@ -12,7 +12,6 @@ import io.zerows.extension.runtime.report.domain.tables.pojos.KpReport; import io.zerows.extension.runtime.report.domain.tables.pojos.KpReportInstance; import io.zerows.extension.runtime.report.eon.RpConstant; import io.zerows.extension.runtime.report.eon.em.EmReport; -import io.zerows.extension.runtime.report.refine.Rp; import java.math.BigDecimal; import java.math.RoundingMode; @@ -28,13 +27,6 @@ public class StepGeneratorTotal extends AbstractStepGenerator { super(generation); } - /** - * 在最底部添加合计行,根据对应的配置进行公式计算 - * @param instance - * @param request - * @param sourceData - * @return - */ @Override public Future build(KpReportInstance instance, JsonObject request, JsonArray sourceData) { final KpReport report = this.metadata().reportMeta(); @@ -79,23 +71,30 @@ public class StepGeneratorTotal extends AbstractStepGenerator { }); } }); - if (totalCount != null) { + if (totalCount.fieldNames().size()!=0) { totalCount.fieldNames().forEach(count -> { final String formula = totalCount.getString(count); - final String result = Rp.calculateFormula(formula, total); - total.put(count, result); + Object result = Ut.fromExpressionT(formula, Ux.toJson(total)); + if(result==null){ + result= "0.00"; + } + final BigDecimal bigDecimal = new BigDecimal(result.toString()); + final BigDecimal truncatedValue = bigDecimal.setScale(2, RoundingMode.DOWN); + total.put(count, truncatedValue.toString()); }); + final JsonObject entries = Ux.toJson(total); + entries.put(KName.KEY, UUID.randomUUID().toString()); + bottomTotal.fieldNames().forEach(item -> { + boolean b = total.containsKey(item); + if (!b) { + entries.put(item, bottomTotal.getString(item)); + } + }); + JsonObject entries1 = Ux.cloneT(entries); + entries.put(KName.CHILDREN,new JsonArray().add(entries1)); + data.add(entries); } - final JsonObject entries = Ux.toJson(total); - entries.put(KName.KEY, UUID.randomUUID().toString()); - bottomTotal.fieldNames().forEach(item -> { - boolean b = total.containsKey(item); - if (!b) { - entries.put(item, bottomTotal.getString(item)); - } - }); - final JsonArray add = data.add(entries); - reportContent.put(KName.DATA, add); + reportContent.put(KName.DATA, data); instance.setReportContent(reportContent.toString()); return Ux.future(instance); } diff --git a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcImpl.java b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcImpl.java index 0515f02a..8dc6a532 100644 --- a/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcImpl.java +++ b/Zero.Extension.Runtime.Report.DB/src/main/java/io/zerows/extension/runtime/report/uca/process/DimProcImpl.java @@ -67,31 +67,34 @@ class DimProcImpl extends AbstractDimProc { final Set dataSet = dimensions.stream().map(KpDimension::getDataSetId).collect(Collectors.toSet()); return Ux.Jooq.on(KpDataSetDao.class).fetchInAsync(KName.KEY, dataSet).compose(dataSets -> { final ConcurrentMap> resultMap = new ConcurrentHashMap<>(); - KpDataSet kpDataSet = dataSets.get(0); - final JsonObject sourceJ = Ut.toJObject(kpDataSet.getDataSource()); - final DataSet executor = DataSet.of(sourceJ); - final JsonObject queryDef = Ut.toJObject(kpDataSet.getDataQuery()); - - if(kpDataSet.getDataComponent()!=null){ + if(dataSets.size() > 0){ + KpDataSet kpDataSet = dataSets.get(0); + final JsonObject sourceJ = Ut.toJObject(kpDataSet.getDataSource()); + final DataSet executor = DataSet.of(sourceJ); + final JsonObject queryDef = Ut.toJObject(kpDataSet.getDataQuery()); return executor.loadAsync(params, queryDef).compose(dataSouce->{ - String dataComponent = kpDataSet.getDataComponent(); - RQueryComponent queryComponent = CC_OUT.pick(() -> Ut.instance(dataComponent), dataComponent); - final JsonObject parameters = new JsonObject(); - parameters.put(KName.INPUT, params); - Future compose = queryComponent.dataAsync(dataSouce, parameters).compose(result -> { - if (Objects.isNull(result)) { - return Ut.future(dataSouce); - } - return Ut.future(result); - }); - resultMap.put(kpDataSet.getKey(), compose); - return Fn.combineM(resultMap); - }); + if(kpDataSet.getDataComponent()!=null){ + String dataComponent =kpDataSet.getDataComponent(); + RQueryComponent queryComponent = CC_OUT.pick(() -> Ut.instance(dataComponent), dataComponent); + final JsonObject parameters = new JsonObject(); + parameters.put(KName.INPUT, params); + Future compose = queryComponent.dataAsync(dataSouce, parameters).compose(result -> { + if (Objects.isNull(result)) { + return Ut.future(dataSouce); + } + return Ut.future(result); + }); + resultMap.put(kpDataSet.getKey(), compose); + }else { + dataSets.forEach(dataSetItem -> { + final Future result = DataSet.Tool.outputArray(params, dataSetItem); + resultMap.put(dataSetItem.getKey(), result); + }); + } + return Fn.combineM(resultMap); + + }); }else { - dataSets.forEach(dataSetItem -> { - final Future result = DataSet.Tool.outputArray(params, dataSetItem); - resultMap.put(dataSetItem.getKey(), result); - }); return Fn.combineM(resultMap); } }); -- Gitee