package cn.ibizlab.core.data.model;

import cn.ibizlab.core.data.dto.BaseData;
import cn.ibizlab.core.data.dto.FilterData;
import cn.ibizlab.core.data.enums.DefaultValueType;
import cn.ibizlab.core.data.enums.Predefined;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.DataObject;
import cn.ibizlab.util.helper.Inflector;
import cn.ibizlab.util.security.AuthenticationUser;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.util.AlternativeJdkIdGenerator;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.sql.Timestamp;
import java.util.*;

@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonIgnoreProperties(ignoreUnknown = true)
public class PojoSchema {




    @JSONField(ordinal = 1)
    private String id;

    @JSONField(ordinal = 2)
    private String type;


    @JSONField(serialize = false)
    @JsonIgnore
    private String name;

    @JSONField(serialize = false)
    @JsonIgnore
    public String getName()
    {
        if(name==null)
            name=this.getOptions().getName();
        return name;
    }

    public PojoSchema setName(String name)
    {
        if(!StringUtils.isEmpty(name))
        {
            this.name=name;
            if(options==null)
                options=new PojoOption();
            options.setName(name);
        }
        return this;
    }

    @JSONField(serialize = false)
    @JsonIgnore
    public String getCodeName()
    {
        return this.getOptions().getStringValue("code_name",this.getName());
    }

    @JSONField(serialize = false)
    @JsonIgnore
    public String getSystem()
    {
        return this.getOptions().getSystem();
    }

    @JSONField(serialize = false)
    @JsonIgnore
    public String getDefaultDataSoruce()
    {
        return this.getOptions().getDefaultDataSoruce();
    }

    @JSONField(serialize = false)
    @JsonIgnore
    public String getDefaultTableName()
    {
        return this.getOptions().getTableName();
    }

    @JSONField(serialize = false)
    @JsonIgnore
    public String getPackage()
    {
        return this.getOptions().getSystem();
    }



    @JSONField(ordinal = 3)
    private String title;

    @JSONField(ordinal = 4)
    private String description;

    @JSONField(ordinal = 5)
    private Integer propertyOrder;

    @JSONField(ordinal = 6)
    private PojoOption options;

    public PojoOption getOptions()
    {
        if(options==null)
            options=new PojoOption();
        return options;
    }

    public PojoSchema setOptions(PojoOption options)
    {
        if(options==null)
            return this;

        if(this.options!=null)
            options.putAll(this.options);
        this.options=options;
        return this;
    }

    @JSONField(ordinal = 7)
    private String ref;

    @JSONField(serialize = false)
    @JsonIgnore
    public PojoSchema copy()
    {
        return JSONObject.parseObject(JSON.toJSONString(this),PojoSchema.class);
    }

    @JSONField(serialize = false)
    @JsonIgnore
    private boolean built = false;

    @JSONField(serialize = false)
    @JsonIgnore
    public PojoSchema build()
    {
        if((!built)&&Type.object.getCode().equalsIgnoreCase(this.getType()))
        {
            if(properties!=null)
            {
                properties.values().forEach(prop->{
                    PojoSchema item=null;
                    if(Type.object.getCode().equalsIgnoreCase(prop.getType())&&(!StringUtils.isEmpty(prop.getRef())))
                        item=prop;
                    else if(Type.array.getCode().equalsIgnoreCase(prop.getType())
                            &&prop.getItems()!=null&&Type.object.getCode().equalsIgnoreCase(prop.getItems().getType())
                            &&(!StringUtils.isEmpty(prop.getItems().getRef())))
                        item=prop.getItems();
                    else
                        return;
                });
            }
            built=true;
        }
        return this;
    }

    /// object

    @JSONField(ordinal = 11)
    private Map<String,PojoSchema> properties;

    public PojoSchema setProperties(Map<String,PojoSchema> properties)
    {
        if(properties!=null)
        {
            properties.keySet().forEach(key->{
                properties.get(key).setName(key).setOwner(this);
            });
            this.properties=properties;
        }
        return this;
    }

    public Map<String,PojoSchema> getProperties()
    {
        if(!Type.object.getCode().equals(this.type))
        {
            properties=null;
            return properties;
        }
        if(properties==null)
            properties = new LinkedHashMap<>();
        return properties;
    }

    public PojoSchema addProperty(String name,PojoSchema property)
    {
        if(StringUtils.isEmpty(name))
            return this;
        Map<String,PojoSchema> props = this.getProperties();
        if(props!=null) {
            props.put(name, property.setName(name).setOwner(this));
        }
        return this;
    }


    @JsonIgnore
    @JSONField(serialize = false)
    private List<PojoSchema> references;
    public List<PojoSchema> getReferences()
    {
        if(references==null)
        {
            references=new ArrayList<>();
            getProperties().values().forEach(prop->{
                if(Type.object.getCode().equalsIgnoreCase(prop.getType())&&(!StringUtils.isEmpty(prop.getOptions().getRelationName()))) {
                    references.add(prop);
                }
            });
        }
        return references;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    private Map<String,PojoSchema> referenceMap;

    @JsonIgnore
    @JSONField(serialize = false)
    public Map<String,PojoSchema> getReferenceMap()
    {
        if(referenceMap==null)
        {
            referenceMap=new LinkedHashMap<>();
            getProperties().keySet().forEach(key->{
                PojoSchema prop=getProperties().get(key);
                if(Type.object.getCode().equalsIgnoreCase(prop.getType())&&(!StringUtils.isEmpty(prop.getOptions().getRelationName()))) {
                    referenceMap.put(key, prop);
                    if(!key.equals(key.toLowerCase()))
                        referenceMap.put(key.toLowerCase(),prop);
                    referenceMap.put(prop.getOptions().getRelationName(),prop);
                    if(!StringUtils.isEmpty(prop.getOptions().getEntityName())) {
                        if(!referenceMap.containsKey(prop.getOptions().getEntityName()))
                            referenceMap.put(prop.getOptions().getEntityName(), prop);
                        if(!referenceMap.containsKey(prop.getOptions().getEntityName().toLowerCase()))
                            referenceMap.put(prop.getOptions().getEntityName().toLowerCase(),prop);
                    }
                    if(!StringUtils.isEmpty(prop.getOptions().getCodeName())) {
                        if(!referenceMap.containsKey(prop.getOptions().getCodeName()))
                            referenceMap.put(prop.getOptions().getCodeName(), prop);
                        if(!referenceMap.containsKey(prop.getOptions().getCodeName().toLowerCase()))
                            referenceMap.put(prop.getOptions().getCodeName().toLowerCase(), prop);
                    }
                    String pluralize=Inflector.getInstance().pluralize(StringUtils.isEmpty(prop.getOptions().getCodeName())?prop.getOptions().getEntityName():prop.getOptions().getCodeName()).toLowerCase();
                    if(!referenceMap.containsKey(pluralize))
                        referenceMap.put(pluralize, prop);
                }
            });
        }
        return referenceMap;
    }

    public PojoSchema getRefSchema(String tag)
    {
        if(getReferenceMap()!=null)
        {
            return this.getReferenceMap().get(tag);
        }
        return null;
    }

    public Map<String,PojoSchema> getRefProperties()
    {
        Map<String,PojoSchema> refProperties=new LinkedHashMap<>();
        if(this.getOwner()!=null&&Type.object.getCode().equalsIgnoreCase(this.getType())&&(!StringUtils.isEmpty(this.getOptions().getRelationName())))
        {
            this.getOwner().getProperties().entrySet().forEach(entry-> {
                String key=entry.getKey();
                if(key.equals(this.getName()))
                    return;
                PojoSchema prop = entry.getValue();
                if((!StringUtils.isEmpty(prop.getOptions().getRelationName()))&&prop.getOptions().getRelationName().equals(this.getOptions().getRelationName()))
                {
                    refProperties.put(key,prop);
                }
            });
        }
        return refProperties;
    }

    public Map<String,PojoSchema> getRefProperties(String tag)
    {
        Map<String,PojoSchema> refProperties=new LinkedHashMap<>();
        PojoSchema refSchema=this.getRefSchema(tag);
        if(refSchema!=null)
        {
            getProperties().entrySet().forEach(entry-> {
                String key=entry.getKey();
                if(key.equals(refSchema.getName()))
                    return;
                PojoSchema prop = entry.getValue();
                if((!StringUtils.isEmpty(prop.getOptions().getRelationName()))&&prop.getOptions().getRelationName().equals(refSchema.getOptions().getRelationName()))
                {
                    refProperties.put(key,prop);
                }
            });
        }
        return refProperties;
    }


    @JSONField(serialize = false)
    @JsonIgnore
    private PojoSchema owner;

    @JSONField(ordinal = 12)
    private Set<String> required;

    public Set<String> getRequired()
    {
        if(!Type.object.getCode().equals(this.type))
        {
            required=null;
            return required;
        }
        if(required==null&&properties!=null)
        {
            required=new LinkedHashSet<>();
            properties.values().forEach(prop->{
                if (!prop.getOptions().isNullable())
                    required.add(prop.getName());
            });
        }
        return required;
    }

    @JSONField(ordinal = 13)
    private Integer minProperties;

    @JSONField(ordinal = 14)
    private Integer maxProperties;


    @JsonIgnore
    @JSONField(serialize = false)
    private Map<String,PojoSchema> keyMap;

    @JsonIgnore
    @JSONField(serialize = false)
    private PojoSchema keyProperty;


    @JsonIgnore
    @JSONField(serialize = false)
    private Map<String,PojoSchema> unionKeys;

    public PojoSchema getKeyProperty() {
        if(keyProperty==null)
            getKeyMap();
        return keyProperty;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public synchronized Map<String,PojoSchema> getKeyMap()
    {
        if(Type.object.getCode().equals(this.type))
        {
            if(keyMap==null)
            {
                List<PojoSchema> keys=new ArrayList<>();
                keyMap=new LinkedHashMap<>();
                getProperties().values().forEach(sub->{
                    if(Type.array.getCode().equals(sub.getType())||Type.object.getCode().equals(sub.getType()))
                        return;
                    if(sub.getOptions().isKeyField())
                        keyProperty=sub;
                    if(sub.getOptions().isKeyField()&&sub.getOptions().isPhysicalField())
                        keys.add(sub);
                });
                if(keys.isEmpty())
                {
                    getProperties().values().forEach(sub->{
                        if(Type.array.getCode().equals(sub.getType())||Type.object.getCode().equals(sub.getType()))
                            return;
                        if(sub.getOptions().isUnionKeyField()&&sub.getOptions().isPhysicalField())
                            keys.add(sub);
                    });
                }
                if(keys.size()>0)
                    keys.sort( (o1, o2) -> o1.getOptions().getUnionKey().compareTo(o2.getOptions().getUnionKey()) );

                keys.forEach(sub->keyMap.put(sub.getOptions().getFieldName(),sub));
            }

        }
        return keyMap;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public synchronized Map<String,PojoSchema> getUnionKeys()
    {
        if(Type.object.getCode().equals(this.type)) {
            if (unionKeys == null) {
                List<PojoSchema> keys=new ArrayList<>();
                Map<String,PojoSchema> unions=new LinkedHashMap<>();

                getProperties().values().forEach(sub->{
                    if(Type.array.getCode().equals(sub.getType())||Type.object.getCode().equals(sub.getType()))
                        return;
                    if(sub.getOptions().isUnionKeyField()&&sub.getOptions().isPhysicalField())
                        keys.add(sub);
                });
                if(keys.size()>0) {
                    keys.sort((o1, o2) -> o1.getOptions().getUnionKey().compareTo(o2.getOptions().getUnionKey()));
                    keys.forEach(sub -> unions.put(sub.getOptions().getFieldName(),sub));
                    unionKeys=unions;
                }
            }
        }
        return unionKeys;
    }


    ////  array

    @JSONField(ordinal = 21)
    private PojoSchema items;

    @JSONField(ordinal = 22)
    private Integer minItems;

    @JSONField(ordinal = 23)
    private Boolean uniqueItems;

    public void setUniqueItems(Boolean uniqueItems) {
        this.uniqueItems = uniqueItems;
    }

    ///  String

    @JSONField(ordinal = 33)
    private Integer minLength;

    @JSONField(ordinal = 34)
    private Integer maxLength;

    @JSONField(ordinal = 35)
    private String pattern;

    @JSONField(ordinal = 36)
    private String format;

    ///  integer number

    @JSONField(ordinal = 41)
    private BigDecimal minimum;

    @JSONField(ordinal = 42)
    private BigDecimal maximum;

    @JSONField(ordinal = 43)
    private Boolean exclusiveMinimum;

    @JSONField(ordinal = 44)
    private Boolean exclusiveMaximum;

    @JSONField(ordinal = 45)
    private Integer multipleOf;


    public PojoSchema writeTo(Path path)
    {
        return writeTo(this,path);
    }

    public static PojoSchema fromPath(Path path)
    {
        try {
            if(!Files.exists(path))
                throw new IllegalArgumentException("读取文件失败PojoSchema:"+path.toString());
            return JSON.parseObject(Files.readAllBytes(path),PojoSchema.class);

        } catch (Exception e) {
            throw new RuntimeException("解析文件失败PojoSchema:"+path.toString());
        }
    }

    public static PojoSchema writeTo(PojoSchema pojoSchema,Path path)
    {
        try {
            File dir=path.getParent().toFile();
            if(!dir.exists())
                dir.mkdirs();

            Files.write(path, JSON.toJSONBytes(pojoSchema));
        } catch (Exception e) {
            throw new RuntimeException("保存文件失败PojoSchema:"+path.toString());
        }
        return pojoSchema;
    }


    public static enum Type {
        string("string", "字符"),
        integer("integer", "整型"),
        number("number", "数值"),
        object("object", "对象"),
        array("array", "数组");
        public final String code;
        public final String name;

        private Type(String code, String name) {
            this.code = code;
            this.name = name;
        }

        public String getCode() {
            return code;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return "Type{" +
                    "code='" + code + '\'' +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

    public Serializable getKeyValue(BaseData data, boolean genKeyWhenNotExists)
    {
        Object key=data.getKey();
        Map<String,PojoSchema> keyMap= this.getKeyMap();
        if(keyMap!=null)
        {
            PojoSchema keyProperty=this.getKeyProperty();
            if(ObjectUtils.isEmpty(key))
                key=data.get(keyProperty.getName().toLowerCase());

            if(ObjectUtils.isEmpty(key))
            {
                Map<String,PojoSchema> unionKeys=this.getUnionKeys();
                if(!ObjectUtils.isEmpty(unionKeys))
                {
                    for(PojoSchema keySchema:unionKeys.values())
                    {
                        if(ObjectUtils.isEmpty(data.get(keySchema.getName().toLowerCase()))) {
                            key=null;
                            break;
                        }
                        if(!StringUtils.isEmpty(key))
                            key+="||";
                        else
                            key+=data.getStringValue(keySchema.getName().toLowerCase());
                    }
                    if((!ObjectUtils.isEmpty(key))&&unionKeys.size()>1&&keyProperty.getOptions().isPhysicalField())
                        key= DigestUtils.md5DigestAsHex(key.toString().getBytes());
                }
            }
            if(ObjectUtils.isEmpty(key)&&genKeyWhenNotExists&&keyMap.size()==1)
            {
                if(PojoSchema.Type.integer.getCode().equals(keyProperty.getType())||PojoSchema.Type.number.getCode().equals(keyProperty.getType()))
                    key= IdWorker.getId();
                else
                    key=IdWorker.get32UUID();
            }
            if(ObjectUtils.isEmpty(key))
                return null;

            setKeyValue(data,key);

        }
        if(ObjectUtils.isEmpty(key))
            return null;
        return (Serializable)key;
    }

    public BaseData newData(Object keyValue)
    {
        return setKeyValue(new BaseData(),keyValue);
    }

    public BaseData setKeyValue(BaseData data,Object keyValue)
    {
        if(ObjectUtils.isEmpty(keyValue))
            return null;
        Map<String,PojoSchema> keyMap= this.getKeyMap();
        data.setKey(keyValue);
        if(keyMap!=null)
        {
            PojoSchema keyProperty=this.getKeyProperty();
            data.set(keyProperty.getName().toLowerCase(),keyValue);
            Map<String,PojoSchema> unionKeys=this.getUnionKeys();
            if(!ObjectUtils.isEmpty(unionKeys))
            {
                String[] keys=DataObject.getStringValue(keyValue,"").split("\\|\\|");
                if(unionKeys.size()!=keys.length&&keyMap.size()>1)
                    return null;

                if(unionKeys.size()==keys.length)
                {
                    int i=0;
                    for(PojoSchema keySchema:unionKeys.values())
                    {
                        if(ObjectUtils.isEmpty(data.get(keySchema.getName().toLowerCase()))) {
                            if(PojoSchema.Type.integer.getCode().equals(keySchema.getType()))
                                data.set(keySchema.getName().toLowerCase(),DataObject.getLongValue(keys[i],null));
                            else if(PojoSchema.Type.number.getCode().equals(keySchema.getType()))
                                data.set(keySchema.getName().toLowerCase(),DataObject.getBigDecimalValue(keys[i],null));
                            else if(PojoSchema.Type.string.getCode().equals(keySchema.getType())&&(!StringUtils.isEmpty(keySchema.getFormat()))&&keySchema.getFormat().indexOf("data")==0)
                                data.set(keySchema.getName().toLowerCase(),DataObject.getTimestampValue(keys[i],null));
                            else
                                data.set(keySchema.getName().toLowerCase(),keys[i]);
                        }
                        i++;
                    }
                }
            }
            return data;
        }

        return null;
    }

    public BaseData fillParentKey(BaseData data)
    {
        this.getReferences().forEach(refSchema->{
            Object obj=data.get(refSchema.getName().toLowerCase());
            if(obj!=null&&obj instanceof Map)
            {
                data.addParentData(refSchema.getName(),(Map)obj);
            }
        });
        if(ObjectUtils.isEmpty(data.getParentDatas()))
        {
            return data;
        }
        Map<String,BaseData> parentDatas=new LinkedHashMap();
        data.getParentDatas().entrySet().forEach(entry->{
            String refSchemaKey=entry.getKey();
            PojoSchema refSchema=this.getRefSchema(refSchemaKey);
            if(refSchema!=null)
            {
                BaseData parent=entry.getValue();
                if(parent.keySet().size()==0)
                    return;


                Map<String,PojoSchema> refProperties = refSchema.getRefProperties();
                for(Map.Entry<String,PojoSchema> entrySet:refProperties.entrySet())
                {
                    PojoSchema prop=entrySet.getValue();
                    if("PICKUP".equalsIgnoreCase(prop.getOptions().getFieldType())) {
                        if(!ObjectUtils.isEmpty(parent.getKey()))
                            data.set(entrySet.getKey().toLowerCase(), parent.getKey());
                        if(parent.keySet().size()==1)
                            break;
                    }
                    String refFieldCodeName=prop.getOptions().getRefFieldCodeName();
                    if((!StringUtils.isEmpty(refFieldCodeName))&&parent.get(refFieldCodeName.toLowerCase())!=null)
                        data.set(entrySet.getKey().toLowerCase(), parent.get(refFieldCodeName.toLowerCase()));

                }

                if(refProperties.size()>1)
                {
                    if(!parentDatas.containsKey(refSchema.getName()))
                        parentDatas.put(refSchema.getName(),parent);
                    else
                        parentDatas.get(refSchema.getName()).setAll(parent);
                }

            }
        });
        data.setParentDatas(parentDatas);
        return data;
    }

    public BaseData fillDefaultValue(BaseData data,boolean newFlag)
    {
        AuthenticationUser curUser=AuthenticationUser.getAuthenticationUser();
        if(StringUtils.isEmpty(curUser.getUserid()))
        {
            curUser.setUserid(data.getStringValue("SRF_PERSONID"));
            curUser.setPersonname(data.getStringValue("SRF_PERSONNAME"));
        }
        Timestamp now=new Timestamp(System.currentTimeMillis());
        getProperties().values().forEach(sub-> {
            if (Type.array.getCode().equals(sub.getType()) || Type.object.getCode().equals(sub.getType()) || !sub.getOptions().isPhysicalField() ||
                    (StringUtils.isEmpty(sub.getOptions().getDefaultValue())&&StringUtils.isEmpty(sub.getOptions().getPredefined())))
                return;
            String name=sub.getName().toLowerCase();
            Object value=data.get(name);
            if(!StringUtils.isEmpty(sub.getOptions().getPredefined()))
            {
                try
                {
                    Predefined predefinedType=Predefined.valueOf(sub.getOptions().getPredefined());
                    if(newFlag)
                    {
                        switch(predefinedType) {
                            case CREATEMAN:
                                data.set(name, curUser.getUserid());
                                break;
                            case CREATEMANNAME:
                                data.set(name, curUser.getPersonname());
                                break;
                            case UPDATEMAN:
                                data.set(name, curUser.getUserid());
                                break;
                            case UPDATEMANNAME:
                                data.set(name, curUser.getPersonname());
                                break;
                            case CREATEDATE:
                                data.set(name, now);
                                break;
                            case UPDATEDATE:
                                data.set(name, now);
                                break;
                            case ORGID:
                                if(ObjectUtils.isEmpty(value)) {
                                    data.set(name, curUser.getOrgid());
                                }
                                break;
                            case ORGNAME:
                                if(ObjectUtils.isEmpty(value)) {
                                    data.set(name, curUser.getOrgname());
                                }
                                break;
                            case ORGSECTORID:
                                if(ObjectUtils.isEmpty(value)) {
                                    data.set(name, curUser.getMdeptid());
                                }
                                break;
                            case ORGSECTORNAME:
                                if(ObjectUtils.isEmpty(value)) {
                                    data.set(name, curUser.getMdeptname());
                                }
                                break;
                            case LOGICVALID:
                                data.set(name, this.getOptions().getLogicVal());
                                break;
                        }
                    }
                    else
                    {
                        {
                            switch(predefinedType) {
                                case UPDATEMAN:
                                    data.set(name, curUser.getUserid());
                                    break;
                                case UPDATEMANNAME:
                                    data.set(name, curUser.getPersonname());
                                    break;
                                case UPDATEDATE:
                                    data.set(name, now);
                                    break;
                            }
                        }
                    }
                }catch (Exception ex) {}
                return;

            }
            if((!newFlag)||ObjectUtils.isEmpty(data.get(name)))
                return;
            String DV=sub.getOptions().getDefaultValue();
            if(StringUtils.isEmpty(DV))
                return;
            String defaultValueType="";
            String defaultValue="";
            if(DV.startsWith("$"))
            {
                DV=DV.replace("${","").replace("}","");
                String dvs[] = DV.split("[.]");
                if(dvs.length>=1)
                    defaultValueType=dvs[0];
                if(dvs.length>=2)
                    defaultValue=dvs[1].toLowerCase();
            }
            else
                defaultValue=DV;
            if(!StringUtils.isEmpty(defaultValueType))
            {
                try
                {
                    DefaultValueType dvt=DefaultValueType.valueOf(defaultValueType);
                    switch(dvt) {
                        case SESSION:
                            if(!StringUtils.isEmpty(defaultValue)) {
                                Object sessionFieldValue = curUser.getSessionParams().get(defaultValue);
                                if(!ObjectUtils.isEmpty(sessionFieldValue)) {
                                    data.set(name, sessionFieldValue);
                                }
                            }
                            break;
                        case APPLICATION:
                            //暂未实现
                            break;
                        case UNIQUEID:
                            data.set(name, IdWorker.get32UUID());
                            break;
                        case CONTEXT:
                            if(!StringUtils.isEmpty(defaultValue)) {
                                Object paramFieldValue=data.get(defaultValue);
                                if(!ObjectUtils.isEmpty(paramFieldValue)) {
                                    data.set(name, paramFieldValue);
                                }
                            }
                            break;
                        case PARAM:
                            if(!StringUtils.isEmpty(defaultValue)) {
                                Object paramFieldValue=data.get(defaultValue);
                                if(!ObjectUtils.isEmpty(paramFieldValue)) {
                                    data.set(name, paramFieldValue);
                                }
                            }
                            break;
                        case OPERATOR:
                            data.set(name, curUser.getUserid());
                            break;
                        case OPERATORNAME:
                            data.set(name, curUser.getPersonname());
                            break;
                        case CURTIME:
                            data.set(name, now);
                            break;
                        case APPDATA:
                            //暂未实现
                            break;
                        case NONE:
                            data.set(name, defaultValue);
                            break;
                    }
                }catch (Exception ex){}
            }
            else if(!StringUtils.isEmpty(defaultValue))
                data.set(name, defaultValue);

        });

        return data;
    }

    public FilterData fillParentFilter(FilterData data)
    {
        if(ObjectUtils.isEmpty(data.getParentDatas()))
        {
            return data;
        }
        data.getParentDatas().entrySet().forEach(entry->{
            String refSchema=entry.getKey();
            BaseData parent=entry.getValue();
            for(Map.Entry<String,PojoSchema> keyset:this.getRefProperties(refSchema).entrySet())
            {
                PojoSchema prop=keyset.getValue();
                if("PICKUP".equalsIgnoreCase(prop.getOptions().getFieldType())) {
                    if(!StringUtils.isEmpty(prop.getOptions().getFieldName()))
                        data.set("n_"+prop.getOptions().getFieldName()+"_eq", parent.getKey());
                    break;
                }
            }

        });
        return data;
    }

}
