介紹
需求來自之前做過的一個項目,要求做一個多級部門的通訊錄,每一級可能包含下級部門和員工;服務端返回部門和員工數組,以一個標志位做區(qū)分;要求按照拼音(即展示所有人員)和按照部門兩種方式展示。
我的思路
我們的整個架構按照MVC模式,界面的實現比較簡單,暫時跳過不談,這里談談M的實現(其中涉及到了數據庫操作,這里也略過不談)。
1.我們把公司的整個架構看作一棵樹,樹的節(jié)點即某層次下的部門跟成員的合集。點擊到任一部門,即得到該節(jié)點的成員。
2.由于有個計數的需求,也為了減少計算,對節(jié)點的數據做了一個擴充,增加了成員的數目這個字段,在構建樹的時候即得到該節(jié)點下的成員數目。
具體實現
幾個對象:EmployeeInfo 員工信息類
? EmployeesList 員工列表(包含部門、員工)
? ContactDBManager 數據庫管理類(暫時不講)
? PinyinStructureNode 拼音樹節(jié)點
? PinyinStructure 拼音結構樹
? CompanyStructureNode 組織關系樹節(jié)點
? CompanyStructure 組織關系樹
下面對每一個結構做介紹
EmployeeInfo 員工信息類
//員工信息
@interface EmployeeInfo : NSObject
@property (nonatomic, assign) NSInteger type;//0:員工;1:部門
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *ID;
@property(nonatomic,copy)NSString *parentName;//type=0員工所在部門名稱 type=1上級部門名稱
@property(nonatomic,copy)NSString *parentId;//type=0員工所在部門ID type=1上級部門ID
@property(nonatomic,copy)NSString *mobilePhone;//移動電話
//下面增加了字段,為了便于構造不同的樹節(jié)點
@property(nonatomic,copy) NSString *namePinyin;//名字拼音
@property(nonatomic,copy) NSString *namePinyinPre;//名字拼音首字母(比方說:張三-》zs)
@property(nonatomic,copy) NSString *namePinyinFirstAlpha;//姓首字母(張三-》z)
@property(nonatomic,assign)NSInteger countOfPerson;//人員計數
- (instancetype)initWithInfo:(NSDictionary *)info;
+ (instancetype)employeeInfoWithWithDictionary:(NSDictionary *)dic;
@end
員工信息,這里我們把員工跟部門都當做員工信息,無非是類型不一樣,服務端返回員工信息(type:0 員工 1 部門)
增加幾個字段,具體實現無非是解析,增加字段,根據type,countOfPerson初始值設為0(部門)或者1(員工)。
PinyinStructureNode 拼音節(jié)點類
//拼音節(jié)點
@interface PinyinStructureNode : NSObject
@property(nonatomic,strong) NSString *alphaKey;//字母
@property(nonatomic,strong)NSMutableArray *persons;//成員數組
-(instancetype)initNodeWithPerson:(EmployeeInfo*)info;
-(void)addPerson:(EmployeeInfo*)info;
@end
這個實現比較簡單,alphaKey代表成員姓的拼音首字母。
只有兩個接口:構造,往節(jié)點增加成員。
PinyinStructure 拼音結構樹
@interface PinyinStructure : NSObject
@property(nonatomic,strong) NSMutableDictionary *alphaIndexDic;
//所有分組
@property(nonatomic,strong)NSMutableArray *groups;
-(instancetype)initPinyinStructureWithPersonList:(NSMutableArray*)personList;
@end
這個實現比較簡單,對通訊錄做一個遍歷,獲得成員的拼音首字母,判斷是否在分組字典alphaIndexDic 里面。在,則找到對應節(jié)點,往節(jié)點增加成員;不在,則構建對應的拼音節(jié)點PinyinStructureNode ,在alphaIndexDic、groups 增加成員。
CompanyStructureNode 組織關系樹節(jié)點
@interface CompanyStructureNode : NSObject
@property(nonatomic,strong) NSString *ID;
//兩個數組:一個數組記錄所有的子部門,一個數組記錄下級所有的人
@property(nonatomic,strong)NSMutableArray *departmens;
@property(nonatomic,strong)NSMutableArray *persons;
-(instancetype)initNodeWithEmployeeInfo:(EmployeeInfo*)info fromDepList:(NSMutableArray*)depList andPersonList:(NSMutableArray*)personList;
-(instancetype)initNodeWithId:(NSString*)Id fromDepList:(NSMutableArray*)depList andPersonList:(NSMutableArray*)personList;
//某節(jié)點人員個數
-(NSInteger)personNumberOfNode;
@end
為了避免反復去算人數,這直接在存數據庫到時候計算了某節(jié)點下的人數,而不是反復遞歸。
提供了三個接口:通過員工信息構造節(jié)點、通過ID構造節(jié)點、獲得節(jié)點下所有員工數量。具體實現,無非就是遍歷,遍歷部門數組跟員工數組即可獲得該級別下的所有部門和成員。
CompanyStructure 組織關系樹
@interface CompanyStructure : NSObject
@property(nonatomic,strong)NSMutableArray *allDepartments;
@property(nonatomic,strong)NSMutableArray *allPersonInfo;
//輔助數組,用來計算某ID下面所有的人
@property(nonatomic,strong)NSMutableArray *subPersonsInfos;
-(instancetype)initStructureWithInfoList:(NSArray*)infoList;
//某節(jié)點下的人
-(NSArray*)personsUnderId:(NSString*)Id employeeType:(EmployeeType)type;
-(NSArray*)searchWithKeyword:(NSString*)keyword;
@end
這個結構相對會復雜一點,從解析到實現一步一步來講可能會比較清楚。
服務端獲得數據,解析生成
EmployeeInfo員工信息,生成員工信息列表遍歷員工信息列表,往部門數組
allDepartments和員工數組增加成員allPersonInfo-
遍歷員工數組,每獲得一個員工,就更新其部門的人員計數,直到樹的根節(jié)點。
這樣,各部門的人員計數就獲得了。
-
這樣,要獲得某層級的信息,無非調用
CompanyStructureNode的構造方法。到此,整個樹形結構的通訊錄樹就完成了。