美文网首页
商品选择SKUDataFilter

商品选择SKUDataFilter

作者: Cyan_Queen | 来源:发表于2018-12-06 15:50 被阅读0次

 *  github:https://github.com/SunriseOYR/SKUDataFilter

 *  bigo:https://www.jianshu.com/p/295737e2ac77

#import

#import

@class ORSKUDataFilter;

@class ORSKUProperty;

@protocolORSKUDataFilterDataSource

@required

//属性种类个数

- (NSInteger)numberOfSectionsForPropertiesInFilter:(ORSKUDataFilter*)filter;

/*

 * 每个种类所有的的属性值

 * 这里不关心具体的值,可以是属性ID, 属性名,字典、model

 */

- (NSArray*)filter:(ORSKUDataFilter*)filter propertiesInSection:(NSInteger)section;

//满足条件 的 个数

- (NSInteger)numberOfConditionsInFilter:(ORSKUDataFilter*)filter;

/*

 * 对应的条件式

 * 这里条件式的属性值,需要和propertiesInSection里面的数据类型保持一致

 */

- (NSArray*)filter:(ORSKUDataFilter*)filter conditionForRow:(NSInteger)row;

//条件式 对应的 结果数据(库存、价格等)

- (id)filter:(ORSKUDataFilter*)filter resultOfConditionForRow:(NSInteger)row;

@end

@interfaceORSKUDataFilter :NSObject

@property (nonatomic, assign) id<ORSKUDataFilterDataSource> dataSource;

//当前 选中的属性indexPath

@property(nonatomic,strong,readonly)NSArray *selectedIndexPaths;

//当前 可选的属性indexPath

@property(nonatomic,strong,readonly)NSSet *availableIndexPathsSet;

//当前 结果

@property (nonatomic, strong, readonly) id  currentResult;

//init

- (instancetype)initWithDataSource:(id)dataSource;

//选中 属性的时候 调用

- (void)didSelectedPropertyWithIndexPath:(NSIndexPath*)indexPath;

//重新加载数据

- (void)reloadData;

@end

@interfaceORSKUCondition :NSObject

@property (nonatomic, strong) NSArray<ORSKUProperty *> *properties;

@property (nonatomic, strong, readonly) NSArray<NSNumber *> *conditionIndexs;

@property (nonatomic, strong) id result;

@end

@interfaceORSKUProperty :NSObject

@property (nonatomic, copy, readonly) NSIndexPath * indexPath;

@property (nonatomic, copy, readonly) id value;

- (instancetype)initWithValue:(id)value indexPath:(NSIndexPath*)indexPath;

@end

#import "ORSKUDataFilter.h"

@interface ORSKUDataFilter()

@property (nonatomic, strong) NSSet <ORSKUCondition *> *conditions;

@property(nonatomic,strong)NSMutableArray *selectedIndexPaths;

@property(nonatomic,strong)NSMutableSet *availableIndexPathsSet;

//全可用的

@property(nonatomic,strong)NSSet *allAvailableIndexPaths;

@property (nonatomic, strong) id  currentResult;

@end

@implementationORSKUDataFilter

- (instancetype)initWithDataSource:(id)dataSource

{

    self= [superinit];

    if(self) {

        _dataSource= dataSource;

        _selectedIndexPaths = [NSMutableArray array];

        [self initPropertiesSkuListData];

    }

    return self;

}

- (instancetype)init

{

    self= [superinit];

    if(self) {

        _selectedIndexPaths = [NSMutableArray array];

    }

    return self;

}

- (void)reloadData {

    [_selectedIndexPaths removeAllObjects];

    [self initPropertiesSkuListData];

    [self updateCurrentResult];

}

#pragma mark -- public method

//选中某个属性

- (void)didSelectedPropertyWithIndexPath:(NSIndexPath*)indexPath {

    if (![_availableIndexPathsSet containsObject:indexPath]) {

        //不可选

        return;

    }

    if(indexPath.section> [_dataSourcenumberOfSectionsForPropertiesInFilter:self] || indexPath.item>= [[_dataSourcefilter:selfpropertiesInSection:indexPath.section]count]) {

        //越界

        NSLog(@"indexPath is out of range");

        return;

    }

    if([_selectedIndexPathscontainsObject:indexPath]) {

        //已被选

        [_selectedIndexPathsremoveObject:indexPath];

        [self updateAvailableIndexPaths];

        [self updateCurrentResult];

        return;

    }

    __blockNSIndexPath*lastIndexPath =nil;

    [_selectedIndexPathsenumerateObjectsUsingBlock:^(NSIndexPath*_Nonnullobj,NSUIntegeridx,BOOL*_Nonnullstop) {

        if(indexPath.section== obj.section) {

            lastIndexPath = obj;

        }

    }];

    if(!lastIndexPath) {

        //添加新属性

        [_selectedIndexPathsaddObject:indexPath];

        [_availableIndexPathsSet intersectSet:[self availableIndexPathsFromSelctedIndexPath:indexPath sectedIndexPaths:_selectedIndexPaths]];

        [self updateCurrentResult];

        return;

    }

    if(lastIndexPath.item!= indexPath.item) {

        //切换属性

        [_selectedIndexPathsaddObject:indexPath];

        [_selectedIndexPathsremoveObject:lastIndexPath];

        [self updateAvailableIndexPaths];

        [self updateCurrentResult];

    }

}

#pragma mark -- private method

//获取初始数据

- (void)initPropertiesSkuListData {

    NSMutableSet *modelSet = [NSMutableSet set];

    for(inti =0; i < [_dataSourcenumberOfConditionsInFilter:self]; i ++) {

        ORSKUCondition *model = [ORSKUCondition new];

        NSArray* conditions = [_dataSourcefilter:selfconditionForRow:i];

        if(![selfcheckConformToSkuConditions:conditions]) {

            NSLog(@"第 %d 个 condition 不完整 \n %@", i, conditions);

            continue;

        }

        model.properties= [selfpropertiesWithConditionRawData:conditions];

        model.result = [_dataSource filter:self resultOfConditionForRow:i];

        [modelSetaddObject:model];

    }

    _conditions= [modelSetcopy];

    [self getAllAvailableIndexPaths];

}

//检查数据是否正确

- (BOOL)checkConformToSkuConditions:(NSArray*)conditions {

    if (conditions.count != [_dataSource numberOfSectionsForPropertiesInFilter:self]) {

        returnNO;

    }

    __blockBOOL  flag =YES;

    [conditionsenumerateObjectsUsingBlock:^(id  _Nonnullobj,NSUIntegeridx,BOOL*_Nonnullstop) {

        NSArray*properties = [_dataSourcefilter:selfpropertiesInSection:idx];

        if(![propertiescontainsObject:obj]) {

            flag =NO;

            *stop =YES;

        }

    }];

    returnflag;

}

//获取属性

- (NSArray *)propertiesWithConditionRawData:(NSArray*)data {

    NSMutableArray *array = [NSMutableArray array];

    [dataenumerateObjectsUsingBlock:^(id  _Nonnullobj,NSUIntegeridx,BOOL*_Nonnullstop) {

        [arrayaddObject:[selfpropertyOfValue:objinSection:idx]];

    }];

    returnarray;

}

- (ORSKUProperty*)propertyOfValue:(id)value inSection:(NSInteger)section {

    NSArray*properties = [_dataSourcefilter:selfpropertiesInSection:section];

    NSString *str = [NSString stringWithFormat:@"Properties for %ld dosen‘t exist %@", (long)section, value];

    NSAssert([properties containsObject:value], str);

    NSIndexPath*indexPath = [NSIndexPathindexPathForItem:[propertiesindexOfObject:value]inSection:section];

    return[[ORSKUPropertyalloc]initWithValue:valueindexPath:indexPath];

}

//获取条件式 对应 的数据

- (id)skuResultWithConditionIndexs:(NSArray *)conditionIndexs {

    __blockidresult =nil;

    [_conditionsenumerateObjectsUsingBlock:^(ORSKUCondition*_Nonnullobj,BOOL*_Nonnullstop) {

        if([obj.conditionIndexsisEqual:conditionIndexs]) {

            result = obj.result;

            *stop =YES;

        }

    }];

    returnresult;

}

//获取初始可选的所有IndexPath

- (NSMutableSet *)getAllAvailableIndexPaths {

    NSMutableSet *set = [NSMutableSet set];

    [_conditionsenumerateObjectsUsingBlock:^(ORSKUCondition*_Nonnullobj,BOOL*_Nonnullstop) {

        [obj.conditionIndexsenumerateObjectsUsingBlock:^(NSNumber*_Nonnullobj1,NSUIntegeridx1,BOOL*_Nonnullstop1) {

            [setaddObject:[NSIndexPathindexPathForItem:obj1.integerValueinSection:idx1]];

        }];

    }];

    _availableIndexPathsSet = set;

    _allAvailableIndexPaths = [set copy];

    returnset;

}

//选中某个属性时 根据已选中的系列属性 获取可选的IndexPath

- (NSMutableSet *)availableIndexPathsFromSelctedIndexPath:(NSIndexPath*)selectedIndexPath sectedIndexPaths:(NSArray *)indexPaths{

    NSMutableSet *set = [NSMutableSet set];

    [_conditionsenumerateObjectsUsingBlock:^(ORSKUCondition*_Nonnullobj,BOOL*_Nonnullstop) {

        if([obj.conditionIndexsobjectAtIndex:selectedIndexPath.section].integerValue== selectedIndexPath.item) {

            [obj.propertiesenumerateObjectsUsingBlock:^(ORSKUProperty*_Nonnullproperty,NSUIntegeridx2,BOOL*_Nonnullstop1) {

                //从condition中添加种类不同的属性时,需要根据已选中的属性过滤

                //过滤方式为 condition要么包含已选中 要么和已选中属性是同级

                if(property.indexPath.section!= selectedIndexPath.section) {

                    __blockBOOLflag =YES;

                    [indexPathsenumerateObjectsUsingBlock:^(NSIndexPath*_Nonnullobj1,NSUIntegeridx,BOOL*_Nonnullstop) {

                        flag = (([obj.conditionIndexs[obj1.section]integerValue] == obj1.row) || (obj1.section== property.indexPath.section)) && flag;

                    }];

                    if(flag) {

                        [setaddObject:property.indexPath];

                    }

                }else{

                    [setaddObject:property.indexPath];

                }

            }];

        }

    }];

    //合并本行数据

    [_allAvailableIndexPathsenumerateObjectsUsingBlock:^(NSIndexPath*_Nonnullobj,BOOL*_Nonnullstop) {

        if(obj.section== selectedIndexPath.section) {

            [setaddObject:obj];

        }

    }];

    returnset;

}

//当前可用的

- (void)updateAvailableIndexPaths {

    if (_selectedIndexPaths.count == 0) {

        _availableIndexPathsSet = [_allAvailableIndexPaths mutableCopy];

        return;

    }

    __block NSMutableSet *set = [NSMutableSet set];

    NSMutableArray *seleted = [NSMutableArray array];

    [_selectedIndexPathsenumerateObjectsUsingBlock:^(NSIndexPath*_Nonnullobj,NSUIntegeridx,BOOL*_Nonnullstop) {

        [seletedaddObject:obj];

        NSMutableSet*tempSet =nil;

        tempSet = [self availableIndexPathsFromSelctedIndexPath:obj sectedIndexPaths:seleted];

        if(set.count==0) {

            set = [tempSetmutableCopy];

        }else{

            [setintersectSet:tempSet];

        }

    }];

    _availableIndexPathsSet = set;

}

// 当前结果

- (void)updateCurrentResult {

    if (_selectedIndexPaths.count != [_dataSource numberOfSectionsForPropertiesInFilter:self]) {

        _currentResult = nil;

        return;

    }

    NSMutableArray *conditions = [NSMutableArray array];

    for (int i = 0; i < [_dataSource numberOfSectionsForPropertiesInFilter:self]; i ++) {

        [_selectedIndexPathsenumerateObjectsUsingBlock:^(NSIndexPath*_Nonnullobj,NSUIntegeridx,BOOL*_Nonnullstop) {

            if(obj.section== i) {

                [conditionsaddObject:@(obj.row)];

            }

        }];

    }

    _currentResult = [self skuResultWithConditionIndexs:[conditions copy]];

}

- (BOOL)isAvailableWithPropertyIndexPath:(NSIndexPath*)indexPath {

    __blockBOOLisAvailable =NO;

    [_conditionsenumerateObjectsUsingBlock:^(ORSKUCondition*_Nonnullobj,BOOL*_Nonnullstop) {

        if([obj.conditionIndexsobjectAtIndex:indexPath.section].integerValue== indexPath.row) {

            isAvailable =YES;

            *stop =YES;

        }

    }];;

    returnisAvailable;

}

#pragma mark -- setter

- (void)setDataSource:(id)dataSource {

    _dataSource= dataSource;

    [self initPropertiesSkuListData];

}

@end

@implementation ORSKUCondition

- (void)setProperties:(NSArray *)properties {

    _properties= properties;

    NSMutableArray *array = [NSMutableArray array];

    [propertiesenumerateObjectsUsingBlock:^(ORSKUProperty*_Nonnullobj,NSUIntegeridx,BOOL*_Nonnullstop) {

        [arrayaddObject:@(obj.indexPath.item)];

    }];

    _conditionIndexs = [array copy];

}

@end

@implementation ORSKUProperty

- (instancetype)initWithValue:(id)value indexPath:(NSIndexPath*)indexPath

{

    self= [superinit];

    if(self) {

        _value= value;

        _indexPath= indexPath;

    }

    return self;

}

@end

相关文章

  • 商品选择SKUDataFilter

    * github:https://github.com/SunriseOYR/SKUDataFilter * bi...

  • 商品选择控件

    在项目中写这个控件的时候,细节还是很多的,比如如何根据后台传过来的json来布局里面的子控件。 1.先来看看效果图...

  • 分布式商城项目总结三之异步目录树的实现

    2. 实现商品类目选择功能 2.1 需求 在商品添加页面,点击“选择类目”显示商品类目列表: 2.1.1结果...

  • 商品分类有误

    商品应该选择合适的分类,当分类选择不合理时,将会在商品体检中体检出“商品分类有误”,严重的甚至面临商品下架、禁售的...

  • 质数在商品规格选择中的应用

    向淘宝京东商品选择的时候,会有规格选择,多种规格联动,如下三个截图淘宝的商品规格选择,在有的规格下没有商品或没货需...

  • iOS 内购流程(二)——创建内购项目

    1、添加内购项目 2、选择内购类型 3、根据自己APP的需求选择类型 4、继续 5、商品列表 6、选择APP商品 ...

  • 购物系统Mini

    Python源码 (暂时无数据库)。。。 输入工资,打印商品列表。根据商品编号购买商品。选择商品后,检测余额。可随...

  • iOS 选择商品规格

    由实现选规格的效果来记录下所用到的基础控件和知识点 控件: UIcollectionview 初始化 collec...

  • SKU商品规格选择

    在线demo地址 https://qdnzv.csb.app/[https://qdnzv.csb.app/] G...

  • 淘宝购物如何返利

    1.打开淘宝,选择商品,点击分享,如下图 2.选择微信将商品分享给“小淘返利多” 3.将商品链接分享给“小淘返利多...

网友评论

      本文标题:商品选择SKUDataFilter

      本文链接:https://www.haomeiwen.com/subject/rayocqtx.html