//
//  APIManager.m
//  Runner
//
//  Created by zhengdu on 2021/6/21.
//

#import "APIManager.h" 
#import "APRequestSerializer.h"
#import "AppDelegate.h"

#ifdef DEBUG
//测试环境
//NSString *const dHostUrl = @"http://api.oversea.ecellsz.com:9876";
NSString *const dHostUrl = @"http://lb-mi23utxo-em1lnrk4gizs2pu8.clb.ap-nanjing.tencentclb.com:8822";
//NSString *const dHostUrl = @"http://120.77.209.176:8822";
#else
//正式环境
NSString *const dHostUrl = @"http://lb-mi23utxo-em1lnrk4gizs2pu8.clb.ap-nanjing.tencentclb.com:8822";
#endif


NSString *const sRelogin = @"sRelogin";
NSString *const sLoginKey = @"sLoginModel";
NSString *const sDeviceKey = @"sDeviceModel";
NSString *const sUserKey = @"sUserModel";
NSString *const sDeviceListKey = @"sDeviceListKey";

NSString *const kErrorDomain = @"kErrorDomain";
NSInteger const kErrorException = 500;


@implementation APIManager

+ (instancetype)sharedManager
{
    static dispatch_once_t onceToken;
    static APIManager *apitance;
    dispatch_once(&onceToken, ^{
        apitance = [[APIManager alloc] init];
        apitance.cache = [YYCache cacheWithName:@"hx_cache_data"];
        if ([apitance.cache containsObjectForKey:sLoginKey])
        {
            id object = [apitance.cache objectForKey:sLoginKey];
            if ([object isKindOfClass:LoginModel.class])
            {
                apitance.loginModel = object;
            }
        }
        if ([apitance.cache containsObjectForKey:sDeviceKey])
        {
            id object = [apitance.cache objectForKey:sDeviceKey];
            if ([object isKindOfClass:DeviceModel.class])
            {
                apitance.deviceModel = object;
            }
        }
        if ([apitance.cache containsObjectForKey:sUserKey])
        {
            id object = [apitance.cache objectForKey:sUserKey];
            if ([object isKindOfClass:MyUserMsgModel.class])
            {
                apitance.userModel = object;
            }
        }
        if ([apitance.cache containsObjectForKey:sDeviceListKey])
        {
            id object = [apitance.cache objectForKey:sDeviceListKey];
            if ([object isKindOfClass:NSMutableArray.class])
            {
                apitance.deviceList = object;
            }
        }
    });
    return apitance;
}

/// 清除数据
- (void)clearUserInfo
{
    if ([self.cache containsObjectForKey:sLoginKey])
    {
        [self.cache removeObjectForKey:sLoginKey];
        self.loginModel.isLogin = NO;
        self.loginModel = nil;
        self.laloModel = nil;
    }
    if ([self.cache containsObjectForKey:sDeviceKey])
    {
        [self.cache removeObjectForKey:sDeviceKey];
        self.deviceModel = nil;
    }
    if ([self.cache containsObjectForKey:sUserKey])
    {
        [self.cache removeObjectForKey:sUserKey];
        self.userModel = nil;
    }
    NSLog(@"%@",self.loginModel);
}

/// 解绑清除设备数据
- (void)cleardeviceInfo
{
    if ([self.cache containsObjectForKey:sDeviceKey])
    {
        [self.cache removeObjectForKey:sDeviceKey];
        self.deviceModel = nil;
        self.laloModel = nil;
    }
    NSLog(@"%@",self.loginModel);
}

#pragma mark- POST请求
/// POST请求
/// @param URL 接口名
/// @param parameters 接口传参
/// @param isJson 是否是json
/// @param resultClass 返回数据类型模型
- (RACSignal *)APPOST:(NSString *)URL
           parameters:(id )parameters
               isJson:(BOOL)isJson
          resultClass:(Class __nullable)resultClass
{
    if ([resultClass isSubclassOfClass:LoginModel.class])
    {
        return [[self APHTTPWithMethod:MSRequestMethodPOST URL:URL isJson:isJson parameters:parameters resultClass:resultClass] doNext:^(LoginModel *model) {
            model.isLogin = YES;
            self.loginModel = model;
            [self.cache setObject:model forKey:sLoginKey];
            
        }];
    }
    else
        return [self APHTTPWithMethod:MSRequestMethodPOST URL:URL isJson:isJson parameters:parameters resultClass:resultClass];
}

#pragma mark- GET请求
/// GET请求
/// @param URL 接口名
/// @param parameters 接口传参
/// @param resultClass 返回数据类型模型
- (RACSignal *)APGET:(NSString *)URL
          parameters:(NSDictionary *)parameters
         resultClass:(Class __nullable)resultClass
{
    if ([resultClass isSubclassOfClass:LatestLocationModel.class])
   {
       return [[self APHTTPWithMethod:MSRequestMethodGET URL:URL isJson:NO parameters:parameters resultClass:resultClass] doNext:^(LatestLocationModel *model) {
           self.laloModel = model;
       }];
   }
    else if ([resultClass isSubclassOfClass:MyUserMsgModel.class])
    {
        return [[self APHTTPWithMethod:MSRequestMethodGET URL:URL isJson:NO parameters:parameters resultClass:resultClass] doNext:^(MyUserMsgModel *model) {
            self.userModel = model;
            [self.cache setObject:model forKey:sUserKey];
        }];
    }
    else if ([URL isEqualToString:BindDevice_URL])
    {
        return [[self APHTTPWithMethod:MSRequestMethodGET URL:URL isJson:NO parameters:parameters resultClass:resultClass] doNext:^(NSArray *arr) {
            [self.deviceList removeAllObjects];
            NSMutableArray *devArr = [NSMutableArray new];
            for (NSDictionary *dic in arr)
            {
                DeviceModel *model = [DeviceModel yy_modelWithJSON:dic];
                [devArr addObject:model];
            }
            self.deviceList = devArr;
            [self.cache setObject:devArr forKey:sDeviceListKey];
        }];
    }
    else
        return [self APHTTPWithMethod:MSRequestMethodGET URL:URL isJson:NO parameters:parameters resultClass:resultClass];
}


#pragma mark- DELETE请求
/// DELETE请求
/// @param URL 接口名
/// @param parameters 接口传参
/// @param resultClass 返回数据类型模型
- (RACSignal *)APDELETE:(NSString *)URL
          parameters:(NSDictionary *)parameters
         resultClass:(Class __nullable)resultClass
{
        return [self APHTTPWithMethod:MSRequestMethodDELETE URL:URL isJson:NO parameters:parameters resultClass:resultClass];
}


#pragma mark- 自定义请求方式
/// 自定义请求方式
/// @param method 请求类型
/// @param URL 接口名称
/// @param isJson 是否是json
/// @param parameters 接口传参
/// @param resultClass 返回数据类型模型
- (RACSignal *)APHTTPWithMethod:(MSRequestMethod)method
                            URL:(NSString *)URL
                         isJson:(BOOL)isJson
                     parameters:(id)parameters
                    resultClass:(Class)resultClass
{

    [MSNetwork openLog];
    [MSNetwork setBaseURL:dHostUrl];
    [MSNetwork setRequestSerializer: MSRequestSerializerHTTP];
    if (isJson)
    {
        [MSNetwork setRequestSerializer: MSRequestSerializerJSON];
    }
    
    [MSNetwork setHeader:[self setHttpHeader]];
    RACSignal *requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [MSNetwork HTTPWithMethod:method url:[NSString stringWithFormat:@"%@",URL] parameters:parameters  headers:nil cachePolicy:MSCachePolicyOnlyNetNoCache success:^(id  _Nonnull responseObject) {
            
            [subscriber sendNext:responseObject];
            [subscriber sendCompleted];
            
        } failure:^(NSError * _Nonnull error) {
            [subscriber sendError:error];
            
        }];
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"6 订阅流程结束，可清理资源");
        }];
        
    }];
    
    void (^extraHandlerSingal)(id value) = ^(RACTuple * value) {
        
    };
    return [[[requestSignal catch:^RACSignal *(NSError *error) {
        NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
        if (data) {
            NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }
        [UICommon HidenLoading];
        return [RACSignal error:error];
    }] flattenMap:^RACSignal *(id  _Nullable data) {
        
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
                {
            
            [UICommon HidenLoading];
            //@strongify(self);
            NSString *status = F(@"%@", data[@"code"]);
            id resultObj = data[@"data"];
            if ([status isKindOfClass:[NSString class]] && [status isEqualToString:@"200"])
            {
                //如果传递的class是PYBaseModel的子类,才解析成对象,否则不做处理
                if (resultObj && resultClass && [resultClass isSubclassOfClass:BaseModel.class])
                {
                    if ([resultObj isKindOfClass:[NSArray class]])
                    {
                        resultObj = [NSArray yy_modelArrayWithClass:resultClass json:resultObj];
                    }
//                    else if ([resultObj isKindOfClass:[NSDictionary class]])
//                    {
//                        resultObj = [NSDictionary yy_modelDictionaryWithClass:resultClass json:resultObj];
//                    }
                    else
                    {
                        resultObj = [resultClass yy_modelWithJSON:resultObj];
                    }
                }
                else
                { //未传递classl对象,数据不解析，有些接口直接返回基础类型，这里不需要转换
                    if ([resultObj isKindOfClass:NSNull.class])
                    {
                        resultObj = nil;
                    }
                }
                if (resultObj)
                {
                    //[self.cache setObject:resultObj forKey:[self cacheKeyWithParameters:parameters apiName:url]];
                }
                //  NSLog(@"resultObj = %@",resultObj);
                [subscriber sendNext:resultObj];
            }
            else
            {
                //有网络
                NSString *content = data[@"msg"];
                NSString *message = [content isNotBlank] ? content : @"";
                NSDictionary *userInfo = @{NSLocalizedDescriptionKey : message,@"detail":status};
                //其他错误
                NSError *error = [NSError errorWithDomain:kErrorDomain code:kErrorException userInfo:userInfo];
                [subscriber sendError:error];
                
            }
            [subscriber sendCompleted];
            if ([status isEqualToString:@"401"])
            {
                [MSNetwork cancelAllRequest];
                [[NSNotificationCenter defaultCenter] postNotificationName:sRelogin object:nil];
            }
//            else if ([status isEqualToString:@"401"])
//            {
//                [MSNetwork cancelAllRequest];
//                [[NSNotificationCenter defaultCenter] postNotificationName:hRelogin object:nil];
//            }
            return nil;
        }];
    }] doNext:extraHandlerSingal];
}



/// 下载文件
/// @param url url
/// @param path 下载目标路径
- (RACSignal *)downloadWithURL:(NSString *)url filePath:(NSString *)path
{
    [MSNetwork openLog];
    RACSignal *requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [MSNetwork downloadWithURL:url fileDir:path progress:^(NSProgress * _Nonnull progress) {
        } success:^(NSString * _Nonnull path) {
            [UICommon HidenLoading];
            [subscriber sendNext:path];
            [subscriber sendCompleted];
            
        } failure:^(NSError * _Nonnull error) {
            [subscriber sendError:error];
            [UICommon HidenLoading];
        }];
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"6 订阅流程结束，可清理资源");
        }];
        
    }];
    
    void (^extraHandlerSingal)(id value) = ^(RACTuple * value) {
        
    };
    return [[[requestSignal catch:^RACSignal *(NSError *error) {
        NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
        if (data) {
            NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }
        [UICommon HidenLoading];
        return [RACSignal error:error];
    }] flattenMap:^RACSignal *(id  _Nullable data) {
        
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
                {
            [UICommon HidenLoading];
            [subscriber sendNext:data];
            return nil;
        }];
    }] doNext:extraHandlerSingal];
}


/// 上传图片文件
/// @param url 接口名
/// @param parameters 参数
/// @param images 图片数组
- (RACSignal *)uploadImageWithURL:(NSString *)url
                      parameters:(NSDictionary *)parameters
                        images:(NSArray * __nullable)images
{
    [MSNetwork openLog];
    RACSignal *requestSignal;
    
    requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [MSNetwork uploadImageURL:[NSString stringWithFormat:@"%@%@",dHostUrl,url] parameters:parameters headers:[self setHttpHeader] images:images name:@"file" fileName:@"image" imageScale:0.3 imageType:@"png" progress:^(NSProgress * _Nonnull progress) {
            
        } success:^(id  _Nonnull responseObject) {
            [UICommon HidenLoading];
            [subscriber sendNext:responseObject];
            [subscriber sendCompleted];
        } failure:^(NSError * _Nonnull error) {
            [UICommon HidenLoading];
            [UICommon MessageErrorText:F(@"上传错误：%@",error)];
        }];
        
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"6 订阅流程结束，可清理资源");
        }];
        
    }];
    
    
    void (^extraHandlerSingal)(id value) = ^(RACTuple * value) {
        
    };
    return [[[requestSignal catch:^RACSignal *(NSError *error) {
        NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
        if (data) {
            NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }
        [UICommon HidenLoading];
        return [RACSignal error:error];
    }] flattenMap:^RACSignal *(id  _Nullable data) {
        
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
                {
            
            [UICommon HidenLoading];
            //@strongify(self);
            NSString *status = F(@"%@", data[@"code"]);
            id resultObj = data[@"data"];
            if ([status isKindOfClass:[NSString class]] && [status isEqualToString:@"200"])
            {
                [subscriber sendNext:resultObj];
            }
            else
            {
                //有网络
                NSString *content = data[@"msg"];
                NSString *message = [content isNotBlank] ? content : @"";
                NSDictionary *userInfo = @{NSLocalizedDescriptionKey : message,@"detail":status};
                //其他错误
                NSError *error = [NSError errorWithDomain:kErrorDomain code:kErrorException userInfo:userInfo];
                [subscriber sendError:error];
                
            }
            [subscriber sendCompleted];
            if ([status isEqualToString:@"401"]) {
                [[NSNotificationCenter defaultCenter] postNotificationName:sRelogin object:nil];
            }
            return nil;
        }];
    }] doNext:extraHandlerSingal];
}

/// 上传文件
/// @param url 接口名
/// @param parameters 参数
/// @param filePath 文件路径
/// @param fileData 文件 
- (RACSignal *)uploadFileWithURL:(NSString *)url
                      parameters:(NSDictionary *)parameters
                        filePath:(NSString *)filePath
                        fileData:(NSData *)fileData
{
    [MSNetwork openLog];
    RACSignal *requestSignal;
    if (filePath.length > 0)
    {
        requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            [MSNetwork uploadFileWithURL:[NSString stringWithFormat:@"%@%@",dHostUrl,url] parameters:parameters headers:[self setHttpHeader] name:@"file" filePath:filePath progress:^(NSProgress * _Nonnull progress) {
                
            } success:^(id  _Nonnull responseObject) {
                [UICommon HidenLoading];
                [subscriber sendNext:responseObject];
                [subscriber sendCompleted];
            } failure:^(NSError * _Nonnull error) {
                [UICommon HidenLoading];
                [UICommon MessageErrorText:F(@"上传错误：%@",error)];
                
            }];
            
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"6 订阅流程结束，可清理资源");
            }];
            
        }];
    }
    else
    {
        requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            [MSNetwork uploadImageURL:[NSString stringWithFormat:@"%@%@",dHostUrl,url] parameters:parameters headers:[self setHttpHeader] images:@[] name:@"file" fileName:@"image" imageScale:0.5 imageType:@"png" progress:^(NSProgress * _Nonnull progress) {
                
            } success:^(id  _Nonnull responseObject) {
                
            } failure:^(NSError * _Nonnull error) {
                
            }];
            [MSNetwork uploadFileDataWithURL:[NSString stringWithFormat:@"%@%@",dHostUrl,url] parameters:parameters headers:[self setHttpHeader] name:@"file" fileData:fileData progress:^(NSProgress * _Nonnull progress) {
                
            } success:^(id  _Nonnull responseObject) {
                [UICommon HidenLoading];
                [subscriber sendNext:responseObject];
                [subscriber sendCompleted];
            } failure:^(NSError * _Nonnull error) {
                [UICommon HidenLoading];
                [UICommon MessageErrorText:F(@"上传错误：%@",error)];
                
            }];
            
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"6 订阅流程结束，可清理资源");
            }];
            
        }];
    }
    
    void (^extraHandlerSingal)(id value) = ^(RACTuple * value) {
        
    };
    return [[[requestSignal catch:^RACSignal *(NSError *error) {
        NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
        if (data) {
            NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }
        [UICommon HidenLoading];
        return [RACSignal error:error];
    }] flattenMap:^RACSignal *(id  _Nullable data) {
        
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
                {
            
            [UICommon HidenLoading];
            //@strongify(self);
            NSString *status = F(@"%@", data[@"code"]);
            id resultObj = data[@"data"];
            if ([status isKindOfClass:[NSString class]] && [status isEqualToString:@"200"])
            {
                [subscriber sendNext:resultObj];
            }
            else
            {
                //有网络
                NSString *content = data[@"msg"];
                NSString *message = [content isNotBlank] ? content : @"";
                NSDictionary *userInfo = @{NSLocalizedDescriptionKey : message,@"detail":status};
                //其他错误
                NSError *error = [NSError errorWithDomain:kErrorDomain code:kErrorException userInfo:userInfo];
                [subscriber sendError:error];
                
            }
            [subscriber sendCompleted];
            if ([status isEqualToString:@"401"]) {
                [[NSNotificationCenter defaultCenter] postNotificationName:sRelogin object:nil];
            }
            return nil;
        }];
    }] doNext:extraHandlerSingal];
}


#pragma mark- 设置网络请求头部视图
/// 设置网络请求头部视图
- (NSMutableDictionary *)setHttpHeader
{
    NSMutableDictionary *header = [NSMutableDictionary dictionary];
    if (self.loginModel && [self.loginModel.Authorization isNotBlank])
    {
        [header setValue:self.loginModel.Authorization forKey:@"Authorization"];
        /// 当前登陆的用户ID
        [header setValue:self.loginModel.openid forKey:@"openid"];
    }
    else
    {
        [header setValue:@"0" forKey:@"Authorization"];
        /// 当前登陆的用户ID
        [header setValue:@"0" forKey:@"openid"];
        
    }
    /// 请求时间
    long long timestamp =  [[NSDate date] timeIntervalSince1970] * 1000;
    [header setValue:F(@"%lld", timestamp) forKey:@"timestamp"];
    /// bundleId
    NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
    [header setValue:bundleId forKey:@"package"];
    /// 设备id
    [header setObject:[UIDevice currentDevice].identifierForVendor.UUIDString forKey:@"deviceId"];
    /// 设备类型
    [header setValue:@"MOBILE" forKey:@"deviceType"];
    /// 设备型号
    [header setValue:[[UIDevice currentDevice] model] forKey:@"deviceModel"];
    /// 系统版本
    [header setValue:[UIDevice currentDevice].systemVersion forKey:@"osVersion"];
    /// 系统类型
    [header setValue:@"IOS" forKey:@"osType"];
    /// 必传
    [header setValue:@"APP" forKey:@"loginChannel"];
    /// 版本
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    [header setValue:version forKey:@"appVersion"];
    /// 发布渠道
#ifdef DEBUG
    [header setValue:@"develop" forKey:@"version"];
#else
    [header setValue:@"produce" forKey:@"version"];
#endif
    
    
    NSString *deviceTokens = [UserDefaults objectForKey:DeviceTokenKey];
    /// APNS Token
    [header setValue:STRINGHASVALUE(deviceTokens) ? deviceTokens : @"" forKey:@"deviceToken"];
    
    NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
    NSArray  *array = [language componentsSeparatedByString:@"-"];
    NSString *currentLanguage = array[0];
    NSString *current = [currentLanguage isEqualToString:@"en"] ? F(@"%@_US", currentLanguage) : F(@"%@_CN", currentLanguage);
    [header setValue:current forKey:@"Accept-Language"];
    
    return header;
}



/// 使用body传数据
- (RACSignal *)PostBodyWithApi:(NSString *)api json:(id)json
{
    RACSignal *requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSString*requestUrl = api;
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        NSMutableURLRequest *request = [self GetRequest:requestUrl];
        // 设置body
        NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
        [request setHTTPBody:data];
        AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer];
        responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",nil];
        manager.responseSerializer = responseSerializer;
        
        NSLog(@"\r头部请求参数：%@",request);
        [[manager dataTaskWithRequest:request uploadProgress:^(NSProgress * _Nonnull uploadProgress) {
            
        } downloadProgress:^(NSProgress * _Nonnull downloadProgress) {
            
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
           
            if (error)
            {
                [subscriber sendError:error];
            }
            else
            {
                [subscriber sendNext:responseObject];
                [subscriber sendCompleted];
            }
            
        }] resume];
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"6 订阅流程结束，可清理资源");
        }];
    }];
    
    void (^extraHandlerSingal)(id value) = ^(RACTuple * value) {
        
    };
    return [[[requestSignal catch:^RACSignal *(NSError *error) {
        NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
        if (data) {
            NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }
        [UICommon HidenLoading];
        return [RACSignal error:error];
    }] flattenMap:^RACSignal *(id  _Nullable data) {
        
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
                {
            
            [UICommon HidenLoading];
            NSDictionary *dictFromData = [NSJSONSerialization JSONObjectWithData:data
                                                                           options:NSJSONReadingAllowFragments
                                                                               error:nil];
            NSLog(@"--->%@",dictFromData);
            //@strongify(self);
            NSString *status = F(@"%@", dictFromData[@"code"]);
            id resultObj = dictFromData[@"data"];
            if ([status isKindOfClass:[NSString class]] && [status isEqualToString:@"200"])
            {
                [subscriber sendNext:resultObj];
            }
            else
            {
                //有网络
                NSString *content = dictFromData[@"msg"];
                NSString *message = [content isNotBlank] ? content : @"";
                NSDictionary *userInfo = @{NSLocalizedDescriptionKey : message,@"detail":status};
                //其他错误
                NSError *error = [NSError errorWithDomain:kErrorDomain code:kErrorException userInfo:userInfo];
                [subscriber sendError:error];
                
            }
            [subscriber sendCompleted];
            if ([status isEqualToString:@"401"]) {
                [[NSNotificationCenter defaultCenter] postNotificationName:sRelogin object:nil];
            }
            return nil;
        }];
    }] doNext:extraHandlerSingal];
}


- (NSMutableURLRequest *)GetRequest:(NSString *)URL
{
    NSString *reURL = F(@"%@%@", dHostUrl,URL);
    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:reURL parameters:nil error:nil];
    request.timeoutInterval = 30;
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    if (self.loginModel && [self.loginModel.Authorization isNotBlank])
    {
        [request setValue:self.loginModel.Authorization forHTTPHeaderField:@"Authorization"];
        /// 当前登陆的用户ID
        [request setValue:self.loginModel.openid forHTTPHeaderField:@"openid"];
    }
    else
    {
        [request setValue:@"0" forHTTPHeaderField:@"Authorization"];
        /// 当前登陆的用户ID
        [request setValue:@"0" forHTTPHeaderField:@"openid"];
        
    }
    /// 请求时间
    long long timestamp =  [[NSDate date] timeIntervalSince1970] * 1000;
    [request setValue:F(@"%lld", timestamp) forHTTPHeaderField:@"timestamp"];
    /// bundleId
    NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
    [request setValue:bundleId forHTTPHeaderField:@"package"];
    /// 设备id
    [request setValue:[UIDevice currentDevice].identifierForVendor.UUIDString forHTTPHeaderField:@"deviceId"];
    /// 设备类型
    [request setValue:@"MOBILE" forHTTPHeaderField:@"deviceType"];
    /// 设备型号
    [request setValue:[[UIDevice currentDevice] model] forHTTPHeaderField:@"deviceModel"];
    /// 系统版本
    [request setValue:[UIDevice currentDevice].systemVersion forHTTPHeaderField:@"osVersion"];
    /// 系统类型
    [request setValue:@"IOS" forHTTPHeaderField:@"osType"];
    /// 必传
    [request setValue:@"APP" forHTTPHeaderField:@"loginChannel"];
    /// 版本
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    [request setValue:version forHTTPHeaderField:@"appVersion"];
    /// 发布渠道
#ifdef DEBUG
    [request setValue:@"develop" forHTTPHeaderField:@"version"];
#else
    [request setValue:@"produce" forHTTPHeaderField:@"version"];
#endif
    
    
    NSString *deviceTokens = [UserDefaults objectForKey:DeviceTokenKey];
    /// APNS Token
    [request setValue:STRINGHASVALUE(deviceTokens) ? deviceTokens : @"" forHTTPHeaderField:@"deviceToken"];
    
    NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
    NSArray  *array = [language componentsSeparatedByString:@"-"];
    NSString *currentLanguage = array[0];
    NSString *current = [currentLanguage isEqualToString:@"en"] ? F(@"%@_US", currentLanguage) : F(@"%@_CN", currentLanguage);
    [request setValue:current forHTTPHeaderField:@"Accept-Language"];
    
    return request;
}

- (NSMutableArray *)deviceList
{
    if (!_deviceList)_deviceList = [NSMutableArray new];
    return _deviceList;
}


@end

