Search in sources :

Example 21 with EasyField

use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.

the class GroupAggregationController method getTargetFields.

@RequestMapping("group-aggregation-fields")
public JSON getTargetFields(@EntityParam(name = "target") Entity targetEntity) {
    // 目标-分组字段
    List<String[]> targetGroupFields = new ArrayList<>();
    // 目标字段
    List<String[]> targetFields = new ArrayList<>();
    for (Field field : MetadataSorter.sortFields(targetEntity)) {
        EasyField easyField = EasyMetaFactory.valueOf(field);
        String[] build = buildIfGroupField(easyField);
        if (build != null)
            targetGroupFields.add(build);
        DisplayType dt = easyField.getDisplayType();
        if (dt == DisplayType.NUMBER || dt == DisplayType.DECIMAL) {
            targetFields.add(buildField(field));
        }
    }
    return JSONUtils.toJSONObject(new String[] { "targetGroupFields", "targetFields" }, new Object[] { targetGroupFields, targetFields });
}
Also used : FieldAggregationController.isAllowSourceField(com.rebuild.web.robot.trigger.FieldAggregationController.isAllowSourceField) Field(cn.devezhao.persist4j.Field) FieldAggregationController.buildField(com.rebuild.web.robot.trigger.FieldAggregationController.buildField) EasyField(com.rebuild.core.metadata.easymeta.EasyField) DisplayType(com.rebuild.core.metadata.easymeta.DisplayType) ArrayList(java.util.ArrayList) EasyField(com.rebuild.core.metadata.easymeta.EasyField) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 22 with EasyField

use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.

the class FieldWriteback method buildTargetRecordData.

private Record buildTargetRecordData() {
    final Record targetRecord = EntityHelper.forNew(targetEntity.getEntityCode(), UserService.SYSTEM_USER, false);
    final JSONArray items = ((JSONObject) actionContext.getActionContent()).getJSONArray("items");
    final Set<String> fieldVars = new HashSet<>();
    for (Object o : items) {
        JSONObject item = (JSONObject) o;
        String sourceField = item.getString("sourceField");
        String updateMode = item.getString("updateMode");
        // fix: v2.2
        if (updateMode == null) {
            updateMode = sourceField.contains(DATE_EXPR) ? "FORMULA" : "FIELD";
        }
        if ("FIELD".equalsIgnoreCase(updateMode)) {
            fieldVars.add(sourceField);
        } else if ("FORMULA".equalsIgnoreCase(updateMode)) {
            if (sourceField.contains(DATE_EXPR) && !sourceField.startsWith(CODE_PREFIX)) {
                fieldVars.add(sourceField.split(DATE_EXPR)[0]);
            } else {
                Set<String> matchsVars = ContentWithFieldVars.matchsVars(sourceField);
                for (String field : matchsVars) {
                    if (MetadataHelper.getLastJoinField(sourceEntity, field) == null) {
                        throw new MissingMetaExcetion(field, sourceEntity.getName());
                    }
                    fieldVars.add(field);
                }
            }
        }
    }
    // 变量值
    Record useSourceData = null;
    if (!fieldVars.isEmpty()) {
        String sql = String.format("select %s from %s where %s = '%s'", StringUtils.join(fieldVars, ","), sourceEntity.getName(), sourceEntity.getPrimaryField().getName(), actionContext.getSourceRecord());
        useSourceData = Application.createQueryNoFilter(sql).record();
    }
    for (Object o : items) {
        JSONObject item = (JSONObject) o;
        String targetField = item.getString("targetField");
        if (!MetadataHelper.checkAndWarnField(targetEntity, targetField)) {
            continue;
        }
        EasyField targetFieldEasy = EasyMetaFactory.valueOf(targetEntity.getField(targetField));
        String updateMode = item.getString("updateMode");
        String sourceAny = item.getString("sourceField");
        // 置空
        if ("VNULL".equalsIgnoreCase(updateMode)) {
            targetRecord.setNull(targetField);
        } else // 固定值
        if ("VFIXED".equalsIgnoreCase(updateMode)) {
            RecordVisitor.setValueByLiteral(targetField, sourceAny, targetRecord);
        } else // 字段
        if ("FIELD".equalsIgnoreCase(updateMode)) {
            Field sourceFieldMeta = MetadataHelper.getLastJoinField(sourceEntity, sourceAny);
            if (sourceFieldMeta == null)
                continue;
            Object value = Objects.requireNonNull(useSourceData).getObjectValue(sourceAny);
            if (value != null) {
                if (targetFieldEasy.getDisplayType() == DisplayType.N2NREFERENCE) {
                    value = N2NReferenceSupport.items(sourceFieldMeta, actionContext.getSourceRecord());
                }
                Object newValue = EasyMetaFactory.valueOf(sourceFieldMeta).convertCompatibleValue(value, targetFieldEasy);
                targetRecord.setObjectValue(targetField, newValue);
            }
        } else // 公式
        if ("FORMULA".equalsIgnoreCase(updateMode)) {
            if (useSourceData == null) {
                log.warn("[useSourceData] is null, Set to empty");
                useSourceData = new StandardRecord(sourceEntity, null);
            }
            // 高级公式代码
            final boolean useCode = sourceAny.startsWith(CODE_PREFIX);
            // 日期兼容 fix: v2.2
            if (sourceAny.contains(DATE_EXPR) && !useCode) {
                String fieldName = sourceAny.split(DATE_EXPR)[0];
                Field sourceField2 = MetadataHelper.getLastJoinField(sourceEntity, fieldName);
                if (sourceField2 == null)
                    continue;
                Object value = useSourceData.getObjectValue(fieldName);
                Object newValue = value == null ? null : ((EasyDateTime) EasyMetaFactory.valueOf(sourceField2)).convertCompatibleValue(value, targetFieldEasy, sourceAny);
                if (newValue != null) {
                    targetRecord.setObjectValue(targetField, newValue);
                }
            } else // 高级公式(会涉及各种类型的运算)
            // @see AggregationEvaluator#evalFormula
            {
                String clearFormual = useCode ? sourceAny.substring(4, sourceAny.length() - 4) : sourceAny.replace("×", "*").replace("÷", "/").replace("`", // compatible: v2.4
                "\"");
                Map<String, Object> envMap = new HashMap<>();
                for (String fieldName : fieldVars) {
                    String replace = "{" + fieldName + "}";
                    String replaceWhitQuote = "\"" + replace + "\"";
                    String replaceWhitQuoteSingle = "'" + replace + "'";
                    boolean forceUseQuote = false;
                    if (clearFormual.contains(replaceWhitQuote)) {
                        clearFormual = clearFormual.replace(replaceWhitQuote, fieldName);
                        forceUseQuote = true;
                    } else if (clearFormual.contains(replaceWhitQuoteSingle)) {
                        clearFormual = clearFormual.replace(replaceWhitQuoteSingle, fieldName);
                        forceUseQuote = true;
                    } else if (clearFormual.contains(replace)) {
                        clearFormual = clearFormual.replace(replace, fieldName);
                    } else {
                        continue;
                    }
                    Object value = useSourceData.getObjectValue(fieldName);
                    if (value instanceof Date) {
                        value = CalendarUtils.getUTCDateTimeFormat().format(value);
                    } else if (value == null) {
                        // 数字字段置 `0`
                        Field isNumberField = MetadataHelper.getLastJoinField(sourceEntity, fieldName);
                        if (isNumberField != null && (isNumberField.getType() == FieldType.LONG || isNumberField.getType() == FieldType.DECIMAL)) {
                            value = 0;
                        } else {
                            value = StringUtils.EMPTY;
                        }
                    } else if (forceUseQuote) {
                        value = value.toString();
                    }
                    envMap.put(fieldName, value);
                }
                Object newValue = AviatorUtils.eval(clearFormual, envMap, false);
                if (newValue != null) {
                    DisplayType dt = targetFieldEasy.getDisplayType();
                    if (dt == DisplayType.NUMBER) {
                        targetRecord.setLong(targetField, CommonsUtils.toLongHalfUp(newValue));
                    } else if (dt == DisplayType.DECIMAL) {
                        targetRecord.setDouble(targetField, ObjectUtils.toDouble(newValue));
                    } else if (dt == DisplayType.DATE || dt == DisplayType.DATETIME) {
                        targetRecord.setDate(targetField, (Date) newValue);
                    } else {
                        newValue = checkoutFieldValue(newValue, targetFieldEasy);
                        if (newValue != null) {
                            targetRecord.setObjectValue(targetField, newValue);
                        }
                    }
                }
            }
        }
    }
    return targetRecord;
}
Also used : DisplayType(com.rebuild.core.metadata.easymeta.DisplayType) JSONArray(com.alibaba.fastjson.JSONArray) EasyDateTime(com.rebuild.core.metadata.easymeta.EasyDateTime) MissingMetaExcetion(cn.devezhao.persist4j.metadata.MissingMetaExcetion) EasyField(com.rebuild.core.metadata.easymeta.EasyField) EasyField(com.rebuild.core.metadata.easymeta.EasyField) Field(cn.devezhao.persist4j.Field) JSONObject(com.alibaba.fastjson.JSONObject) StandardRecord(cn.devezhao.persist4j.engine.StandardRecord) StandardRecord(cn.devezhao.persist4j.engine.StandardRecord) Record(cn.devezhao.persist4j.Record) JSONObject(com.alibaba.fastjson.JSONObject)

Example 23 with EasyField

use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.

the class GroupAggregation method prepare.

@Override
public void prepare(OperatingContext operatingContext) throws TriggerException {
    // 已经初始化
    if (sourceEntity != null)
        return;
    final JSONObject actionContent = (JSONObject) actionContext.getActionContent();
    sourceEntity = actionContext.getSourceEntity();
    targetEntity = MetadataHelper.getEntity(actionContent.getString("targetEntity"));
    // 0.分组字段关联 <Source, Target>
    Map<String, String> groupFieldsMapping = new HashMap<>();
    for (Object o : actionContent.getJSONArray("groupFields")) {
        JSONObject item = (JSONObject) o;
        String sourceField = item.getString("sourceField");
        String targetField = item.getString("targetField");
        if (MetadataHelper.getLastJoinField(sourceEntity, sourceField) == null) {
            throw new MissingMetaExcetion(sourceField, sourceEntity.getName());
        }
        if (!targetEntity.containsField(targetField)) {
            throw new MissingMetaExcetion(targetField, targetEntity.getName());
        }
        groupFieldsMapping.put(sourceField, targetField);
    }
    // 1.源记录数据
    String ql = String.format("select %s from %s where %s = ?", StringUtils.join(groupFieldsMapping.keySet().iterator(), ","), sourceEntity.getName(), sourceEntity.getPrimaryField().getName());
    Record sourceRecord = Application.getQueryFactory().createQueryNoFilter(ql).setParameter(1, actionContext.getSourceRecord()).record();
    // 2.找到目标记录
    List<String> qFields = new ArrayList<>();
    List<String> qFieldsFollow = new ArrayList<>();
    for (Map.Entry<String, String> e : groupFieldsMapping.entrySet()) {
        String sourceField = e.getKey();
        String targetField = e.getValue();
        Object val = sourceRecord.getObjectValue(sourceField);
        if (val != null) {
            EasyField sourceFieldEasy = EasyMetaFactory.valueOf(Objects.requireNonNull(MetadataHelper.getLastJoinField(sourceEntity, sourceField)));
            EasyField targetFieldEasy = EasyMetaFactory.valueOf(Objects.requireNonNull(MetadataHelper.getLastJoinField(targetEntity, targetField)));
            // 日期分组
            if (sourceFieldEasy.getDisplayType() == DisplayType.DATE || sourceFieldEasy.getDisplayType() == DisplayType.DATETIME) {
                String formatKey = sourceFieldEasy.getDisplayType() == DisplayType.DATE ? EasyFieldConfigProps.DATE_FORMAT : EasyFieldConfigProps.DATETIME_FORMAT;
                int sourceFieldLength = StringUtils.defaultIfBlank(sourceFieldEasy.getExtraAttr(formatKey), sourceFieldEasy.getDisplayType().getDefaultFormat()).length();
                // 目标字段仅日期
                int targetFieldLength = StringUtils.defaultIfBlank(targetFieldEasy.getExtraAttr(EasyFieldConfigProps.DATE_FORMAT), targetFieldEasy.getDisplayType().getDefaultFormat()).length();
                // 目标格式(长度)必须小于等于源格式
                Assert.isTrue(targetFieldLength <= sourceFieldLength, Language.L("日期字段格式不兼容") + String.format(" (%d,%d)", targetFieldLength, sourceFieldLength));
                if (targetFieldLength == 4) {
                    // 'Y'
                    sourceField = String.format("DATE_FORMAT(%s,'%s')", sourceField, "%Y");
                    targetField = String.format("DATE_FORMAT(%s,'%s')", targetField, "%Y");
                    val = CalendarUtils.format("yyyy", (Date) val);
                } else if (targetFieldLength == 7) {
                    // 'M'
                    sourceField = String.format("DATE_FORMAT(%s,'%s')", sourceField, "%Y-%m");
                    targetField = String.format("DATE_FORMAT(%s,'%s')", targetField, "%Y-%m");
                    val = CalendarUtils.format("yyyy-MM", (Date) val);
                } else {
                    // 'D' is default
                    sourceField = String.format("DATE_FORMAT(%s,'%s')", sourceField, "%Y-%m-%d");
                    targetField = String.format("DATE_FORMAT(%s,'%s')", targetField, "%Y-%m-%d");
                    val = CalendarUtils.format("yyyy-MM-dd", (Date) val);
                }
            } else // 分类分组
            if (sourceFieldEasy.getDisplayType() == DisplayType.CLASSIFICATION) {
                int sourceFieldLevel = ClassificationManager.instance.getOpenLevel(MetadataHelper.getLastJoinField(sourceEntity, sourceField));
                int targetFieldLevel = ClassificationManager.instance.getOpenLevel(MetadataHelper.getLastJoinField(targetEntity, targetField));
                // 目标等级必须小于等于源等级
                Assert.isTrue(targetFieldLevel <= sourceFieldLevel, Language.L("分类字段等级不兼容") + String.format(" (%d,%d)", targetFieldLevel, sourceFieldLevel));
                // 需要匹配等级的值
                if (sourceFieldLevel != targetFieldLevel) {
                    ID parent = getItemWithLevel((ID) val, targetFieldLevel);
                    if (parent == null) {
                        log.error("Bad source value of classification (Maybe levels?) : {}", val);
                        return;
                    }
                    val = parent;
                    sourceRecord.setID(sourceField, (ID) val);
                    for (int i = 0; i < sourceFieldLevel - targetFieldLevel; i++) {
                        // noinspection StringConcatenationInLoop
                        sourceField += ".parent";
                    }
                }
            }
            qFields.add(String.format("%s = '%s'", targetField, val));
            qFieldsFollow.add(String.format("%s = '%s'", sourceField, val));
        }
    }
    if (qFields.isEmpty()) {
        log.warn("Value(s) of group-field not specified");
        return;
    }
    this.followSourceWhere = StringUtils.join(qFieldsFollow.iterator(), " and ");
    ql = String.format("select %s from %s where ( %s )", targetEntity.getPrimaryField().getName(), targetEntity.getName(), StringUtils.join(qFields.iterator(), " and "));
    Object[] targetRecord = Application.getQueryFactory().createQueryNoFilter(ql).unique();
    if (targetRecord != null) {
        targetRecordId = (ID) targetRecord[0];
        return;
    }
    // 是否自动创建记录
    if (!actionContent.getBoolean("autoCreate"))
        return;
    // 不必担心必填字段,必填只是前端约束
    // 还可以通过设置字段默认值来完成必填字段的自动填写
    // 0425 需要业务规则,譬如自动编号、默认值等
    Record newTargetRecord = EntityHelper.forNew(targetEntity.getEntityCode(), UserService.SYSTEM_USER);
    for (Map.Entry<String, String> e : groupFieldsMapping.entrySet()) {
        String sourceField = e.getKey();
        String targetField = e.getValue();
        Object val = sourceRecord.getObjectValue(sourceField);
        if (val != null) {
            newTargetRecord.setObjectValue(targetField, val);
        }
    }
    PrivilegesGuardContextHolder.setSkipGuard(EntityHelper.UNSAVED_ID);
    try {
        Application.getEntityService(targetEntity.getEntityCode()).create(newTargetRecord);
    } finally {
        PrivilegesGuardContextHolder.getSkipGuardOnce();
    }
    RobotTriggerObserver.forceTriggerSelf();
    targetRecordId = newTargetRecord.getPrimary();
}
Also used : MissingMetaExcetion(cn.devezhao.persist4j.metadata.MissingMetaExcetion) EasyField(com.rebuild.core.metadata.easymeta.EasyField) JSONObject(com.alibaba.fastjson.JSONObject) JSONObject(com.alibaba.fastjson.JSONObject) Record(cn.devezhao.persist4j.Record) ID(cn.devezhao.persist4j.engine.ID)

Example 24 with EasyField

use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.

the class RecordTransfomer method transformRecord.

private ID transformRecord(Entity sourceEntity, Entity targetEntity, JSONObject fieldsMapping, ID sourceRecordId, Map<String, Object> defaultValue) {
    Record target = EntityHelper.forNew(targetEntity.getEntityCode(), getUser());
    if (defaultValue != null) {
        for (Map.Entry<String, Object> e : defaultValue.entrySet()) {
            target.setObjectValue(e.getKey(), e.getValue());
        }
    }
    List<String> validFields = checkAndWarnFields(sourceEntity, fieldsMapping.values());
    if (validFields.isEmpty()) {
        log.warn("No fields for transform");
        return null;
    }
    String querySource = String.format("select %s from %s where %s = '%s'", StringUtils.join(validFields, ","), sourceEntity.getName(), sourceEntity.getPrimaryField().getName(), sourceRecordId);
    Record source = Application.createQueryNoFilter(querySource).record();
    for (Map.Entry<String, Object> e : fieldsMapping.entrySet()) {
        if (e.getValue() == null)
            continue;
        String targetField = e.getKey();
        String sourceField = (String) e.getValue();
        Object sourceValue = source.getObjectValue(sourceField);
        if (sourceValue != null) {
            EasyField targetFieldEasy = EasyMetaFactory.valueOf(targetEntity.getField(targetField));
            EasyField sourceFieldEasy = EasyMetaFactory.valueOf(Objects.requireNonNull(MetadataHelper.getLastJoinField(sourceEntity, sourceField)));
            if (targetFieldEasy.getDisplayType() == DisplayType.N2NREFERENCE) {
                sourceValue = N2NReferenceSupport.items(sourceFieldEasy.getRawMeta(), sourceRecordId);
            }
            Object targetValue = sourceFieldEasy.convertCompatibleValue(sourceValue, targetFieldEasy);
            target.setObjectValue(targetField, targetValue);
        }
    }
    GeneralEntityServiceContextHolder.setRepeatedCheckMode(GeneralEntityServiceContextHolder.RCM_CHECK_MAIN);
    try {
        target = Application.getEntityService(targetEntity.getEntityCode()).createOrUpdate(target);
        return target.getPrimary();
    } finally {
        GeneralEntityServiceContextHolder.getRepeatedCheckModeOnce();
    }
}
Also used : Record(cn.devezhao.persist4j.Record) JSONObject(com.alibaba.fastjson.JSONObject) EasyField(com.rebuild.core.metadata.easymeta.EasyField)

Example 25 with EasyField

use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.

the class FormsBuilder method wrapFieldValue.

/**
 * 封装表单/布局所用的字段值
 *
 * @param data
 * @param field
 * @param user4Desensitized 不传则不脱敏
 * @return
 * @see FieldValueHelper#wrapFieldValue(Object, EasyField)
 * @see com.rebuild.core.support.general.DataListWrapper#wrapFieldValue(Object, Field)
 */
public Object wrapFieldValue(Record data, EasyField field, ID user4Desensitized) {
    Object value = data.getObjectValue(field.getName());
    // 特殊字段
    if (field.getDisplayType() == DisplayType.BARCODE || (field.getDisplayType() == DisplayType.N2NREFERENCE && FieldValueHelper.hasLength(value))) {
        value = data.getPrimary();
    }
    // 处理日期格式
    if (field.getDisplayType() == DisplayType.REFERENCE && value instanceof ID && ((ID) value).getLabelRaw() != null) {
        Field nameField = field.getRawMeta().getReferenceEntity().getNameField();
        if (nameField.getType() == FieldType.DATE || nameField.getType() == FieldType.TIMESTAMP) {
            Object newLabel = EasyMetaFactory.valueOf(nameField).wrapValue(((ID) value).getLabelRaw());
            ((ID) value).setLabel(newLabel);
        }
    }
    value = FieldValueHelper.wrapFieldValue(value, field);
    if (value != null && FieldValueHelper.isUseDesensitized(field, user4Desensitized)) {
        value = FieldValueHelper.desensitized(field, value);
    }
    return value;
}
Also used : EasyField(com.rebuild.core.metadata.easymeta.EasyField) Field(cn.devezhao.persist4j.Field) JSONObject(com.alibaba.fastjson.JSONObject) ID(cn.devezhao.persist4j.engine.ID)

Aggregations

EasyField (com.rebuild.core.metadata.easymeta.EasyField)27 Field (cn.devezhao.persist4j.Field)16 JSONObject (com.alibaba.fastjson.JSONObject)15 DisplayType (com.rebuild.core.metadata.easymeta.DisplayType)11 Entity (cn.devezhao.persist4j.Entity)10 ArrayList (java.util.ArrayList)7 JSONArray (com.alibaba.fastjson.JSONArray)6 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)6 Record (cn.devezhao.persist4j.Record)4 ID (cn.devezhao.persist4j.engine.ID)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 MissingMetaExcetion (cn.devezhao.persist4j.metadata.MissingMetaExcetion)2 FieldAggregationController.buildField (com.rebuild.web.robot.trigger.FieldAggregationController.buildField)2 FieldAggregationController.isAllowSourceField (com.rebuild.web.robot.trigger.FieldAggregationController.isAllowSourceField)2 FieldType (cn.devezhao.persist4j.dialect.FieldType)1 Type (cn.devezhao.persist4j.dialect.Type)1 StandardRecord (cn.devezhao.persist4j.engine.StandardRecord)1 JSON (com.alibaba.fastjson.JSON)1 LayoutConfigService (com.rebuild.core.configuration.general.LayoutConfigService)1