public Result InterfaceConditionAddNode(Guid brotherNodeId, InterfaceCondition entity)
        {
            return(Result.Success("添加成功")
                   .Continue(_ =>
            {
                //如果是固定值,则校验值是否和类型一致
                if (entity.ConditionValueType == (int)ConditionValueTypeEnum.FixedValue)
                {
                    return _.ContinueAssert(re => _metaFieldService.CheckAndGetFieldValueByFieldType(entity.MetaFieldId, entity.ConditionValue).IsSuccess, "设置的值和字段值格式不匹配");
                }

                return _;
            })
                   .Continue(_ => _interfaceConditionService.AddNode(brotherNodeId, entity)));
        }
Exemple #2
0
        public Result BatchAdd(InterfaceSetting interfaceSetting, IEnumerable <BsonDocument> bsonsList)
        {
            if (interfaceSetting == null)
            {
                return(Result.Error("接口设置参数不能为空"));
            }

            if (bsonsList == null || !bsonsList.Any())
            {
                return(Result.Success($"没有任何数据需要插入"));
            }

            //获取全部接口校验
            var verificationDic = _interfaceVerificationRepository.GetMetaFieldUpperKeyDicByInterfaceVerificationId(interfaceSetting.InterfaceVerificationId);

            //获取到字段列表以编码为Key大写的字典
            var metaFields = _metaFieldRepository.GetMetaFieldShortCodeUpperDicByMetaObjectId(interfaceSetting.MetaObjectId);

            List <BsonDocument> insertBsonsList = new List <BsonDocument>(bsonsList.Count());

            foreach (var bsonDocument in bsonsList)
            {
                if (bsonDocument == null)
                {
                    return(Result.Error("数据为空,插入终止"));
                }

                BsonDocument bsonElementsToAdd = new BsonDocument();

                foreach (var bsonElement in bsonDocument)
                {
                    string upperKey = bsonElement.Name.ToUpperInvariant();

                    if (!metaFields.ContainsKey(upperKey))
                    {
                        continue;
                    }

                    //校验值是否符合接口校验设置
                    if (verificationDic.ContainsKey(upperKey))
                    {
                        var verification = verificationDic[upperKey];
                        if (!_interfaceVerificationService.IsMatch(verification, Convert.ToString(bsonElement.Value)))
                        {
                            return(Result.Error(!string.IsNullOrEmpty(verification.VerificationTips) ? verification.VerificationTips : $"字段[{bsonElement.Name}]传递的值[{bsonElement.Value}]格式不正确"));
                        }
                    }

                    //检查字段的值是否符合字段类型
                    var checkResult = _metaFieldService.CheckAndGetFieldValueByFieldType(metaFields[upperKey], bsonElement.Value);

                    if (checkResult.IsSuccess)
                    {
                        bsonElementsToAdd.Add(new BsonElement(metaFields[upperKey].ShortCode, BsonValue.Create(checkResult.Data)));
                    }
                    else
                    {
                        return(Result.Error($"字段[{bsonElement.Name}]传递的值[{bsonElement.Value}]不符合字段定义的类型"));
                    }
                }

                //获取系统内置的bson元素
                var systemBsonDocument = _metaFieldService.GetSystemFieldBsonDocument();

                //设置系统字段及其默认值
                foreach (var presetBsonElement in systemBsonDocument)
                {
                    //如果传入的字段已经有了,那么这里就不预置了
                    if (!bsonElementsToAdd.Contains(presetBsonElement.Name))
                    {
                        bsonElementsToAdd.Add(presetBsonElement);
                    }
                }

                //补充字段
                bsonElementsToAdd.SetElement(new BsonElement("MetaObject", interfaceSetting.MetaObjectCode));

                if (bsonElementsToAdd.Any())
                {
                    insertBsonsList.Add(bsonElementsToAdd);
                }
            }

            if (insertBsonsList.Any())
            {
                _chameleonDataDbContext.GetCollectionBson(interfaceSetting.MetaObjectCode).InsertMany(insertBsonsList);
            }

            return(Result.Success($"插入成功! 成功{insertBsonsList.Count}条,失败{bsonsList.Count() - insertBsonsList.Count}条."));
        }
        public ResultModel Add(MetaObject metaObject, BsonDocument bsons)
        {
            //错误信息返回值
            HashSet <string> ErrorInfo = new HashSet <string>();

            //获取到字段列表
            var metaFields = metaFieldService.GetMetaFieldUpperKeyDicUnDeleted(metaObject.Id);

            for (int i = bsons.ElementCount - 1; i >= 0; i--)
            {
                var    item     = bsons.GetElement(i);
                string upperKey = item.Name.ToUpperInvariant();
                if (metaFields.ContainsKey(upperKey))
                {
                    //检查字段的值是否符合字段类型
                    var checkResult = metaFieldService.CheckAndGetFieldValueByFieldType(metaFields[upperKey], item.Value);
                    if (checkResult.IsSuccess)
                    {
                        //如果大小写不匹配,则都转化成配置的字段Code形式
                        if (!item.Name.Equals(metaFields[upperKey].Code))
                        {
                            bsons.RemoveElement(item);
                            bsons.Add(new BsonElement(metaFields[upperKey].Code, BsonValue.Create(checkResult.Data)));
                        }
                        else
                        {
                            //重置字段的真实类型的值
                            bsons.SetElement(new BsonElement(metaFields[upperKey].Code, BsonValue.Create(checkResult.Data)));
                        }
                    }
                    else
                    {
                        bsons.RemoveElement(item);
                        ErrorInfo.Add($"字段[{item.Name}]传递的值[{item.Value}]不符合字段定义的类型");
                    }
                }
                else
                {
                    //如果字段不在配置字段中,则不进行添加
                    bsons.RemoveElement(item);
                    ErrorInfo.Add($"字段[{item.Name}]不属于对象[{metaObject.Code}({metaObject.Name})]定义的字段");
                }
            }

            //预置字段及其默认值
            foreach (var item in metaFieldService.GetPresetFieldBsonElements())
            {
                //如果传入的字段已经有了,那么这里就不预置了
                if (!bsons.Contains(item.Name))
                {
                    bsons.Add(item);
                }
            }

            //补充字段
            //bsons.SetElement(new BsonElement("_id", Guid.NewGuid().ToString()));//id已经补充到预置字段
            bsons.SetElement(new BsonElement("MetaObjectCode", metaObject.Code));

            db.GetCollectionBson(metaObject.Code).InsertOne(bsons);

            return(ResultModel.Success($"插入成功,日志:{string.Join(",", ErrorInfo)}"));
        }
        //组织接口搜索条件
        public Result <SearchConditionNode> AggregateCondition(int interfaceConditionId, int brotherNodeId, int conditionJointTypeId, int fieldId, int conditionTypeId, string conditionValue, int conditionValueTypeId)
        {
            //如果不是参数传递值,则根据传入的字段校验数据
            if (conditionValueTypeId != (int)ConditionValueType.Parameter)
            {
                if (!metaFieldService.CheckAndGetFieldValueByFieldType(fieldId, conditionValue).IsSuccess)
                {
                    return(Result <SearchConditionNode> .Error("字段值和字段定义的类型不匹配"));
                }
            }

            return(TransactionHelper.Transaction(() =>
            {
                int parentId = brotherNodeId;
                //如果兄弟节点!=-1,说明当前树有值。反之,则构建新树
                if (parentId != -1)
                {
                    //判断是否有树存在
                    List <SearchConditionNode> conditionListExist = GetListBySearchConditionId(interfaceConditionId);
                    //查看当前兄弟节点的父节点id
                    SearchConditionNode brotherCondition = conditionListExist.FirstOrDefault(t => t.Id == brotherNodeId);
                    parentId = brotherCondition.ParentId;
                    //拿到父节点的信息
                    SearchConditionNode parentCondition = conditionListExist.FirstOrDefault(t => t.Id == brotherCondition.ParentId);
                    //如果父节点的连接条件和当前新建的条件一致,则不需要新建条件节点,直接附加在已有的条件下面
                    if (parentCondition == null || parentCondition.ConditionType != conditionJointTypeId)
                    {
                        //先添加一个父节点,然后把兄弟节点的父节点指向新建的父节点
                        string tempKey = DateTime.Now.ToString("yyyyMMddhhmmss");
                        SearchConditionNode newParentCondition = new SearchConditionNode
                        {
                            SearchConditionId = interfaceConditionId,
                            ParentId = conditionListExist.Count > 0 ? parentId : -1, //如果有树,则插入节点的父节点为刚才的兄弟节点的父节点,否则,插入-1作为根节点
                            FieldId = -1,                                            //连接节点没有field
                            FieldCode = "-1",
                            FieldName = tempKey,
                            FieldType = -1,
                            ConditionType = conditionJointTypeId,
                            Name = ConditionJointTranslator.ToLabelWithExplain(conditionJointTypeId),
                            Value = "-1",
                            ValueType = -1
                        };
                        base.Add(newParentCondition);
                        //查询刚才插入的节点
                        newParentCondition = dbContext.Queryable <SearchConditionNode>().Where(t => t.FieldName.Contains(tempKey)).ToOne();

                        //将兄弟节点的父节点指向新插入的节点
                        brotherCondition.ParentId = newParentCondition.Id;
                        base.Update(brotherCondition);

                        //重新赋值parentId
                        parentId = newParentCondition.Id;
                    }
                }
                //检验是否没有条件节点
                if (parentId == -1)
                {
                    if (dbContext.Queryable <SearchConditionNode>().Where(t => t.Id == parentId).Any())
                    {
                        return Result <SearchConditionNode> .Error("已经存在条件节点,请查证后操作!");
                    }
                }
                //新增节点
                MetaField metaField = metaFieldService.GetById(fieldId);
                SearchConditionNode newCondition = new SearchConditionNode
                {
                    SearchConditionId = interfaceConditionId,
                    ParentId = parentId,
                    FieldId = fieldId,
                    FieldName = metaField.Name,
                    FieldCode = metaField.Code,
                    FieldType = metaField.FieldType,
                    ConditionType = conditionTypeId,
                    Name = $"{metaField.Name} {ConditionTypeTranslator.ToLabel(conditionTypeId)} {conditionValue}",
                    Value = conditionValue,
                    ValueType = conditionValueTypeId,
                    Text = metaField.Name,
                    Visible = (int)TrueFalse.True
                };
                base.Add(newCondition);

                return Result <SearchConditionNode> .Success("保存成功!");
            }));
        }
        public FilterDefinition <BsonDocument> GetFilterDefinitionByCondition(Guid conditionId, Dictionary <string, string> conditionUpperKeyDic, bool isIgnoreArgumentsCheck = false)
        {
            List <InterfaceCondition> conditions = _InterfaceConditionRepository.GetInterfaceConditionByBelongToId(conditionId);

            var bf = Builders <BsonDocument> .Filter;

            if (conditions == null || !conditions.Any())
            {
                return(bf.Empty);
            }

            //全部字段字典缓存
            var metaFieldUpperShortCodeKeyDic = _metaFieldRepository.GetMetaFieldShortCodeUpperDicByMetaObjectId(conditions.First().MetaObjectId);

            InterfaceCondition condition = conditions.FirstOrDefault(t => t.ParentId == Guid.Empty);

            if (condition == null)
            {
                return(bf.Empty);
            }

            //如果连接条件
            if (condition.GetConditionNodeType() == NodeTypeEnum.Joint)
            {
                //通过链接条件解析器进行解析
                return(ConditionRouter(condition));
            }
            //语句
            else
            {
                //通过条件表达式语句解析器解析
                return(ConditionValue(condition));
            }

            //连接条件解析器。如果是连接条件, 则执行下面逻辑将左...右子条件解析
            FilterDefinition <BsonDocument> ConditionRouter(InterfaceCondition routeCondition)
            {
                FilterDefinition <BsonDocument> filterDefinition = Builders <BsonDocument> .Filter.Empty;
                //将子节点全部取出
                var routeConditionChildren = conditions.Where(t => t.ParentId == routeCondition.Id).ToList();
                var first = routeConditionChildren.FirstOrDefault();

                if (first != null)
                {
                    //如果字节点是连接条件
                    if (first.GetConditionNodeType() == NodeTypeEnum.Joint)
                    {
                        filterDefinition = ConditionRouter(first);
                    }
                    //如果是语句
                    else
                    {
                        filterDefinition = ConditionValue(first);
                        //根据根节点的连接条件执行不同的连接操作
                        switch (routeCondition.GetConditionJointType())
                        {
                        case ConditionJointTypeEnum.And:
                            //子节点全部是与逻辑
                            foreach (var item in routeConditionChildren.Except(new[] { first }))
                            {
                                //如果是连接条件
                                if (item.GetConditionNodeType() == NodeTypeEnum.Joint)
                                {
                                    var tempCondition = ConditionRouter(item);
                                    if (tempCondition != null)
                                    {
                                        filterDefinition = bf.And(filterDefinition, tempCondition);
                                    }
                                }
                                //如果是表达式语句
                                else
                                {
                                    var tempCondition = ConditionValue(item);
                                    if (tempCondition != null)
                                    {
                                        filterDefinition = bf.And(filterDefinition, tempCondition);
                                    }
                                }
                            }
                            break;

                        case ConditionJointTypeEnum.Or:
                            //子节点全部是或逻辑
                            foreach (var item in routeConditionChildren.Except(new[] { first }))
                            {
                                //如果是连接条件
                                if (item.GetConditionNodeType() == NodeTypeEnum.Joint)
                                {
                                    var tempCondition = ConditionRouter(item);
                                    if (tempCondition != null)
                                    {
                                        filterDefinition = bf.Or(filterDefinition, tempCondition);
                                    }
                                }
                                //如果是表达式语句
                                else
                                {
                                    var tempCondition = ConditionValue(item);
                                    if (tempCondition != null)
                                    {
                                        filterDefinition = bf.Or(filterDefinition, tempCondition);
                                    }
                                }
                            }
                            break;

                        default:
                            return(bf.Empty);
                        }
                    }
                    return(filterDefinition);
                }
                return(bf.Empty);
            }

            //条件值解析器
            FilterDefinition <BsonDocument> ConditionValue(InterfaceCondition routeCondition)
            {
                //如果条件值来自参数,则从参数列表里面获取
                if (routeCondition.ConditionValue.Equals("?"))
                {
                    //从参数获取到值
                    string key      = routeCondition.MetaFieldShortCode;
                    var    keyUpper = key.ToUpperInvariant();
                    //如果没有传递参数值,则抛出异常
                    if (!conditionUpperKeyDic.ContainsKey(keyUpper))
                    {
                        //如果忽略参数检查,则直接返回null
                        if (isIgnoreArgumentsCheck)
                        {
                            return(Builders <BsonDocument> .Filter.Empty);
                        }
                        //如果不忽略参数检查,则抛出异常
                        else
                        {
                            throw new ArgumentNullException(key, $"Conditions define field parameters [{key}] but do not provide values.");
                        }
                    }

                    var arguemntValue = conditionUpperKeyDic.SafeGet(keyUpper);

                    //将值转化为字段同类型的类型值
                    var metaField = metaFieldUpperShortCodeKeyDic[routeCondition.MetaFieldShortCode.ToUpperInvariant()];

                    var convertResult = _metaFieldService.CheckAndGetFieldValueByFieldType(metaField, arguemntValue);

                    if (!convertResult.IsSuccess)
                    {
                        throw new InvalidCastException($"Condition parameters data type of field [{metaField.ShortCode}] invalid. field define is [{metaField.GetFieldType().GetDescription()}], but value is [{arguemntValue}]");
                    }

                    object value = convertResult.Data;

                    switch (routeCondition.GetConditionType())
                    {
                    case ConditionTypeEnum.Equal:
                        return(bf.Eq(key, value));

                    case ConditionTypeEnum.GreaterThan:
                        return(bf.Gt(key, value));

                    case ConditionTypeEnum.GreaterThanEqual:
                        return(bf.Gte(key, value));

                    case ConditionTypeEnum.LessThan:
                        return(bf.Lt(key, value));

                    case ConditionTypeEnum.LessThanEqual:
                        return(bf.Lte(key, value));

                    case ConditionTypeEnum.NotEqual:
                        return(bf.Ne(key, value));

                    default:
                        return(Builders <BsonDocument> .Filter.Empty);
                    }
                }
                //如果来自配置,则直接从配置里面获取到值
                else
                {
                    //校验字段以及转换字段值为目标类型
                    var convertResult = _metaFieldService.CheckAndGetFieldValueByFieldType(metaFieldUpperShortCodeKeyDic[routeCondition.MetaFieldShortCode.ToUpperInvariant()], routeCondition.ConditionValue);
                    if (!convertResult.IsSuccess)
                    {
                        throw new ArgumentException("配置的字段值不符合字段的类型");
                    }

                    switch (routeCondition.GetConditionType())
                    {
                    case ConditionTypeEnum.Equal:
                        return(bf.Eq(routeCondition.MetaFieldShortCode, convertResult.Data));

                    case ConditionTypeEnum.GreaterThan:
                        return(bf.Gt(routeCondition.MetaFieldShortCode, convertResult.Data));

                    case ConditionTypeEnum.GreaterThanEqual:
                        return(bf.Gte(routeCondition.MetaFieldShortCode, convertResult.Data));

                    case ConditionTypeEnum.LessThan:
                        return(bf.Lt(routeCondition.MetaFieldShortCode, convertResult.Data));

                    case ConditionTypeEnum.LessThanEqual:
                        return(bf.Lte(routeCondition.MetaFieldShortCode, convertResult.Data));

                    case ConditionTypeEnum.NotEqual:
                        return(bf.Ne(routeCondition.MetaFieldShortCode, convertResult.Data));

                    default:
                        return(Builders <BsonDocument> .Filter.Empty);
                    }
                }
            }
        }