iOS 第三方登录、分享、支付管理工具类

· 转载请标明出处:http://www.jianshu.com/p/5ea1a0d9ee8a

1、登录:微信、QQ、Sina,分享:微信、QQ、Sina,支付:微信支付,支付宝支付;
2、集成一起的初衷是源于分享一直是原生写的,登录用友盟之类的,回调这块觉得麻烦,就统一集成了,统一回调 URL:


appDelegate.m

3、代码结构介绍:


4、开始项目
4.1、第一步导入第三方 SDK 到项目,然后配置 info.plist,和 URL Schemes;QQ 和Wechat 注册应用一定要审核通过才有登录能力,Sina 要设置 bundleID(bundleid 和项目不一样登录会报错) 和回调 URL 才能正常登录,添加私有库;


01

cpmmand + v 到自己项目中

URL Schemes

1251534A-C395-41EB-95A6-2C3A96DA3388.png

4.2、QQ、WeChat、Sina 注册应用在 APPdelegate.m中的

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    [[YZThirdManager thirdManager] registerApp:@"微博 APPID" WithType:YZRegisterTypeSina];
    [[YZThirdManager thirdManager] registerApp:@"微信 APPID" WithType:YZRegisterTypeWechat];
    [[YZThirdManager thirdManager] registerApp:@"QQ APPID" WithType:YZRegisterTypeQQ];
    
    return YES;
}

4.3、YZThirdManager �这个工具类主要做的就是分享、登录、支付集成在一起,统一回到 URL,代码如下:

/********************
第三方管理工具类:
1、微信分享、登录、支付
2、微博分享、登录
3、QQ分享、登录
4、支付宝支付。
********************/
#import <Foundation/Foundation.h>
#import <TencentOpenAPI/QQApiInterface.h>
#import <TencentOpenAPI/TencentOAuth.h>
#import "WXApi.h"
#import "WeiboSDK.h"
#import <AlipaySDK/AlipaySDK.h>

/** 分享后的跳转链接 */
extern NSString * const Share_URL;
/** 分享标题 */
extern NSString * const Share_title;
/** 分享内容 */
extern NSString * const Share_desc;
/** 分享显示的图片 */
extern NSString * const Share_imageData;

/**
 分享类型
 */
typedef NS_ENUM(NSInteger, YZShareType) {
    YZShareTypeWechatSession,   // 分享到微信好友
    YZShareTypeWechatTimeLine,  // 分享到微信朋友圈
    YZShareTypeQQ,              // 分享到QQ
    YZShareTypeSina             // 分享到sina微博
};

/**
 注册类型
 */
typedef NS_ENUM(NSInteger, YZRegisterType) {
    YZRegisterTypeWechat,       // 微信
    YZRegisterTypeQQ,           // QQ
    YZRegisterTypeSina          // sina微博
};

/**
 登录类型
 */
typedef NS_ENUM(NSInteger, YZOAuthType) {
    YZOAuthTypeWechat,       // 微信
    YZOAuthTypeQQ,           // QQ
    YZOAuthTypeSina          // sina微博
};

/**
 协议
 */
@protocol YZThirdManagerDelegate <NSObject>

@optional

#pragma mark 第三方登录回调
/**
 WeChat 登录成功

 @param userDict WeChat 用户信息
 */
- (void)wechat_loginSuccess:(NSDictionary *)userDict;

/**
 Sina 登录成功

 @param userDict Sina 用户信息
 */
- (void)sina_loginSuccess:(NSDictionary *)userDict;

/**
 QQ 登录成功

 @param userDict  QQ 用户信息
 */
- (void)tencent_loginSuccess:(NSDictionary *)userDict;

#pragma mark 第三方分享回调

/**
 微信分享后收到微信的响应
 分享是否成功 需要判断 errCode 属性 WXErrCode
 
 @param response 响应消息
 */
- (void)wechat_shareDidReceiveResponse:(BaseResp *)response;
/**
 QQ分享后收到QQ的响应
 分享是否成功 需要判断 result 属性, QQApiSendResultCode
 
 @param response 响应消息
 */
- (void)tencent_shareDidReceiveResponse:(SendMessageToQQResp *)response;
/**
 微博分享后收到微博的响应
 分享是否成功 需要判断 statusCode 码 WeiboSDKResponseStatusCode
 
 @param response 响应消息
 */
- (void)sina_shareDidReceiveResponse:(WBBaseResponse *)response;

#pragma mark 支付回调

/**
 微信支付后收到微信的响应,支付是否成功需要判断 errCode 属性 WXErrCode
 
 @param response 响应消息
 */
- (void)wechat_PayDidReceiveResponse:(PayResp *)response;

/**
 支付宝支付收到支付宝的响应,支付是否成功需要判断 resultDic的key resultStatus = 9000 成功
 
 @param resultDic 结果信息
 */
- (void)aliPay_DidReceiveResponse:(NSDictionary *)resultDic;

@end

@interface YZThirdManager : NSObject <WXApiDelegate,WeiboSDKDelegate,TencentSessionDelegate, QQApiInterfaceDelegate>

@property (nonatomic, weak) id<YZThirdManagerDelegate> third_delegate;

+ (instancetype)thirdManager;

/**
 注册应用
 
 @param appid 微信和QQ请传入appid,微博传入appkey
 @param type  分享类型
 */
- (void)registerApp:(NSString *)appid WithType:(YZRegisterType)type;

/**
 分享到第三方,示例:@{Share_URL:@"http://www.baidu.com",Share_title:@"测试分享",Share_imageData:UIImageJPEGRepresentation(img,1),Share_desc:@"文本内容"};

 @param dict 分享的内容
 @param type 分享的类型
 */
- (void)shareWithDictionary:(NSDictionary *)dict shareType:(YZShareType)type;

/**
 第三方登录

 @param type 登录的类型
 */
- (void)thirdLoginWithOAuthType:(YZOAuthType)type;

/**
 第三方 URL 回调
 */
- (void)handleOpenURL:(NSURL *)url;

/**
 微信支付,order 的 key 是按照 PayReq 的属性设置

 @param order 订单信息
 */
- (void)thirdPayWechat:(NSDictionary *)order;

/**
 支付宝支付

 @param sign 签名字符串
 */
- (void)thirdAliPaySign:(NSString *)sign;

@end

//
//  YZThirdManager.m
//  ECGoudeli
//
//  Created by Leaf on 2017/8/10.
//  Copyright © 2017年 Leaf. All rights reserved.
//

/** 下面信息是需要去对应第三方开发平台注册应用获得 */
#define WX_APP_ID           @"微信 APP_ID"
#define WX_APP_AppSecret    @"微信 AppSecret"

#define QQ_APP_ID           @"QQ APP_ID"
#define QQ_APP_KEY          @"QQ APP_KEY"

#define WB_APP_KEY          @"微博 APP_KEY"
#define WB_APP_Secret       @"微博 APP_Secret"
#define WB_REDIRECT_URL     @"http://www.sina.com"


NSString * const Share_URL       = @"url";
NSString * const Share_title     = @"title";
NSString * const Share_desc      = @"desc";
NSString * const Share_imageData = @"imageData";


#import "YZThirdManager.h"

@interface YZThirdManager ()<NSURLSessionDelegate>
{
    TencentOAuth    *_tencentOAuth;
    NSMutableArray  *_permissionArray; // QQ 需要的权限
    
    NSData   *_imageData;
    NSString *_title;
    NSString *_description;
    NSString *_urlString;
}

@property (nonatomic, strong) AFHTTPSessionManager *manager;
@end

@implementation YZThirdManager

+ (instancetype)thirdManager {
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

// 注册第三方
- (void)registerApp:(NSString *)appid WithType:(YZRegisterType)type {
    switch (type) {
        case YZRegisterTypeWechat:
            [WXApi registerApp:appid];
            break;
            
        case YZRegisterTypeQQ:
            _tencentOAuth = [[TencentOAuth alloc]initWithAppId:appid andDelegate:self];
            break;
            
        case YZRegisterTypeSina:
            [WeiboSDK registerApp:appid];
            break;
    }
}

#pragma mark - Share: Wechat & Sina & QQ
- (void)shareWithDictionary:(NSDictionary *)dict shareType:(YZShareType)type {
    _title       = dict[Share_title];
    _urlString   = dict[Share_URL];
    _description = dict[Share_desc];
    _imageData   = dict[Share_imageData];
    
    if (type == YZShareTypeQQ) {
        [self shareToQQ];
        
    }else if (type == YZShareTypeWechatSession || type == YZShareTypeWechatTimeLine){
        [self shareToWeChatWithWechatType:type];
        
    }else if (type == YZShareTypeSina){
        [self shareToWeibo];
    }
}

/**
 分享到wechat
 
 @param wechatType 分享到微信的类型
 */
- (void)shareToWeChatWithWechatType:(YZShareType)wechatType{
    SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
    
    WXMediaMessage *message = [WXMediaMessage message];
    
    if (_urlString.length) {
        WXWebpageObject *web = [WXWebpageObject object];
        web.webpageUrl = _urlString;
        message.mediaObject = web;
    } else {
        WXImageObject *image = [WXImageObject object];
        image.imageData = _imageData;
        message.mediaObject = image;
        req.bText = NO;
    }
    
    message.title = _title ?: @"";
    message.description = _description?:@"";
    // 微信分享图片大小不能超过 32K
    
    [message setThumbImage:[UIImage imageWithData:_imageData]];
    
    // 分享给好友
    if (wechatType == YZShareTypeWechatSession) {
        req.scene = WXSceneSession;
    }
    // 分享到朋友圈
    if (wechatType == YZShareTypeWechatTimeLine) {
        
        message.title = _description;
        req.scene = WXSceneTimeline;
    }
    req.message = message;
    [WXApi sendReq:req];
}

/**
 *  分享到微博
 */
-(void)shareToWeibo{
    WBMessageObject *message = [WBMessageObject message];
    WBImageObject *imageObject = [WBImageObject object];
    
    imageObject.imageData = _imageData;
    message.imageObject = imageObject;
    
    message.text = [NSString stringWithFormat:@"%@%@",_title,_urlString] ;
    
    WBSendMessageToWeiboRequest *request = [WBSendMessageToWeiboRequest requestWithMessage:message authInfo:nil access_token:nil];
    request.userInfo = nil;
    [WeiboSDK sendRequest:request];
}

/**
 *  分享到QQ
 */
-(void)shareToQQ{
    NSURL *url = [NSURL URLWithString:_urlString];
    QQBaseReq *request = nil;
    if (_urlString.length) {
        QQApiNewsObject *news = [QQApiNewsObject objectWithURL:url title:_title description:_description previewImageData:_imageData];
        request = [SendMessageToQQReq reqWithContent:news];
    } else {
        QQApiImageObject *image = [[QQApiImageObject alloc] initWithData:_imageData previewImageData:_imageData title:_title description:_description];
        request = [SendMessageToQQReq reqWithContent:image];
    }
    
    [QQApiInterface sendReq:request];
    
}

#pragma mark - OAuth: wechat & QQ & sina

-(void)thirdLoginWithOAuthType:(YZOAuthType)type {
    
    if (type == YZOAuthTypeQQ) {
        _permissionArray = [NSMutableArray arrayWithArray:@[/** 移动端获取用户信息 */
                                                            kOPEN_PERMISSION_GET_SIMPLE_USER_INFO,
                                                            ]];
        [_tencentOAuth authorize:_permissionArray inSafari:NO];
    }else if (type == YZOAuthTypeWechat) {
        SendAuthReq *req = [[SendAuthReq alloc] init];
        req.scope = @"snsapi_userinfo";
        req.state = @"App";
        [WXApi sendReq:req];
        
    }else if (type == YZOAuthTypeSina) {
        WBAuthorizeRequest *request = [WBAuthorizeRequest request];
        //回调地址与 新浪微博开放平台中 我的应用  --- 应用信息 -----高级应用    -----授权设置 ---应用回调中的url保持一致就好了
        request.redirectURI = WB_REDIRECT_URL;
        [WeiboSDK sendRequest:request];
        
    }
}

#pragma mark - WXApiDelegate & QQApiInterfaceDelegate & WeiboSDKDelegate

/*
 1、处理来至QQ的响应
 2、处理来至微信的响应
 */
- (void)onResp:(BaseResp *)resp {
    if ([resp isKindOfClass:[BaseResp class]]) {
        // 处理来自微信的响应
        if ([resp isKindOfClass:[SendAuthResp class]]) {
            if (resp.errCode == WXSuccess) {
                SendAuthResp *resp2 = (SendAuthResp *)resp;
                [self getWechatOpenidAndToken:resp2.code];
                
            }else{
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"登录失败" message:[NSString stringWithFormat:@"%@",resp.errStr] delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
                [alert show];
            }
        }else if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
            DebugLog(@"微信分享了");
            if ([self.third_delegate respondsToSelector:@selector(wechat_shareDidReceiveResponse:)]) {
                [self.third_delegate wechat_shareDidReceiveResponse:resp];
            }
            
        }else if ([resp isKindOfClass:[PayResp class]]) {
            DebugLog(@"微信支付");
            if ([self.third_delegate respondsToSelector:@selector(wechat_PayDidReceiveResponse:)]) {
                [self.third_delegate wechat_PayDidReceiveResponse:(PayResp *)resp];
            }
        }
        
    }else if ([resp isKindOfClass:[QQBaseResp class]]) {
        // 处理来自QQ的响应
        
        if ([resp isKindOfClass:[SendMessageToQQResp class]]) {
            DebugLog(@"share:QQ分享");
            if ([self.third_delegate respondsToSelector:@selector(tencent_shareDidReceiveResponse:)]) {
                [self.third_delegate tencent_shareDidReceiveResponse:(SendMessageToQQResp *)resp];
            }
        }
    }
}

/*
 1、处理来至QQ的请求
 2、处理来至微信的请求
 */
- (void)onReq:(BaseReq *)req {
    if ([req isKindOfClass:[BaseReq class]]) {
        // 处理来自微信的请求
        
    }else if ([req isKindOfClass:[QQBaseReq class]]) {
        // 处理来自QQ的请求
        
    }
}

/**
 处理QQ在线状态的回调
 */
- (void)isOnlineResponse:(NSDictionary *)response{
    
}

/**
 收到一个来自微博客户端程序的请求
 */
- (void)didReceiveWeiboRequest:(WBBaseRequest *)request{
    DebugLog(@"request %@",request);
}

/**
 收到一个来自微博客户端程序的响应
 */
- (void)didReceiveWeiboResponse:(WBBaseResponse *)response{
    
    if ([response isKindOfClass:[WBSendMessageToWeiboResponse class]]) {
        DebugLog(@"share:微博分享");
        if ([self.third_delegate respondsToSelector:@selector(sina_shareDidReceiveResponse:)]) {
            [self.third_delegate sina_shareDidReceiveResponse:response];
        }
        
    }else if ([response isKindOfClass:[WBAuthorizeResponse class]]) {
        DebugLog(@"微博登录");
        if (response.statusCode == WeiboSDKResponseStatusCodeSuccess) {
            NSString *uid = [(WBAuthorizeResponse *)response userID];
            NSString *token = [(WBAuthorizeResponse *)response accessToken];
            [self getSinaUserInfo:uid token:token];
            
        }else {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"登录失败" message:[NSString stringWithFormat:@"statusCode: %zd",response.statusCode] delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
            [alert show];
        }

    }
}

#pragma mark - TencentLoginDelegate
//委托
- (void)tencentDidLogin
{
    [_tencentOAuth getUserInfo];
}

- (void)getUserInfoResponse:(APIResponse *)response
{
    if (response.retCode == URLREQUEST_SUCCEED) {
        NSDictionary *userDict = @{@"third_id"    : [_tencentOAuth openId],
                                   @"third_name"  : [response.jsonResponse valueForKeyPath:@"nickname"],
                                   @"third_image" : [response.jsonResponse valueForKeyPath:@"figureurl_qq_2"],
                                   @"access_token": [_tencentOAuth accessToken]};
        
        if ([self.third_delegate respondsToSelector:@selector(tencent_loginSuccess:)]) {
            [self.third_delegate tencent_loginSuccess:userDict];
        }
        DebugLog(@"userDict %@",userDict);
    } else {
        DebugLog(@"登录失败!");
    }
}

- (void)tencentDidLogout {
    
}

/**
 * 登录失败后的回调
 * param cancelled 代表用户是否主动退出登录
 */
- (void)tencentDidNotLogin:(BOOL)cancelled {
    
}

- (void)tencentDidNotNetWork {
    
}

#pragma mark - 获取第三方用户信息
// 获取 Sina 的用户信息
- (void)getSinaUserInfo:(NSString *)uid token:(NSString *)token {
    NSString *urlStr =[NSString stringWithFormat:@"https://api.weibo.com/2/users/show.json?uid=%@&access_token=%@&source=%@",uid,token,WB_APP_KEY];
    __weak typeof(self) weakself = self;
    [self.manager GET:urlStr parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
        NSDictionary *userDict = @{
                                   @"third_id" :   [dic valueForKeyPath:@"idstr"],
                                   @"third_name" : [dic valueForKeyPath:@"screen_name"],
                                   @"third_image": [dic valueForKeyPath:@"avatar_hd"],
                                   @"access_token":token
                                   };
        if ([weakself.third_delegate respondsToSelector:@selector(sina_loginSuccess:)]) {
            [weakself.third_delegate sina_loginSuccess:userDict];
        }
    
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        DebugLog(@"error %@",error);
    }];
}

//通过 appid  secret 认证code . 来发送获取 access_token的请求
- (void)getWechatOpenidAndToken:(NSString *)code {
    NSString *urlStr = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",WX_APP_ID,WX_APP_AppSecret,code];
    
    __weak typeof(self) weakself = self;
    [self.manager GET:urlStr parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
        /*
         access_token   接口调用凭证
         expires_in     access_token接口调用凭证超时时间,单位(秒)
         refresh_token  用户刷新access_token
         openid         授权用户唯一标识
         scope          用户授权的作用域,使用逗号(,)分隔
         unionid        当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段
         */
        NSString* accessToken=[dic valueForKey:@"access_token"];
        NSString* openID=[dic valueForKey:@"openid"];
        [weakself getWechatUserInfo:accessToken openid:openID];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        DebugLog(@"error %@",error.localizedFailureReason);
    }];
}

// 通过 access_token 获取微信用户信息
- (void)getWechatUserInfo:(NSString *)token openid:(NSString *)openid {
    NSString *urlStr = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",token,openid];
    __weak typeof(self) weakself = self;
    [self.manager GET:urlStr parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSDictionary *dic = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
        NSDictionary *userDict = @{
                               @"way"       :   @"1",                       // 登录方式:微信
                               @"openid"    :   openid,                     // 用户唯一标识
                               @"headimgurl":   dic[@"headimgurl"],         // 头像URL
                               @"nickname"  :   dic[@"nickname"],           // 昵称
                               @"sex"       :   [dic[@"sex"] stringValue],  // 性别
                               @"country"   :   dic[@"country"],            // 国家
                               @"province"  :   dic[@"province"],           // 省份
                               @"city"      :   dic[@"city"],               // 城市
                               @"language"  :   dic[@"language"]            // 语言
                               };
        if ([weakself.third_delegate respondsToSelector:@selector(wechat_loginSuccess:)]) {
            [weakself.third_delegate wechat_loginSuccess:userDict];
        }
        DebugLog(@"userDict = %@",userDict);
    }failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        DebugLog(@"error %ld",(long)error.code);
    }];
}

#pragma mark - Wechat Pay & AliPay

- (void)thirdPayWechat:(NSDictionary *)order {
    
    PayReq *payOrder = [[PayReq alloc] init];
    payOrder.openID = [order objectForKey:@"openID"];
    payOrder.partnerId = [order objectForKey:@"partnerId"];
    payOrder.prepayId = [order objectForKey:@"prepayId"];
    payOrder.package = [order objectForKey:@"package"];
    payOrder.nonceStr = [order objectForKey:@"nonceStr"];
    payOrder.timeStamp = (UInt32)[[order objectForKey:@"timeStamp"] integerValue];
    payOrder.sign = [order objectForKey:@"sign"];
    
    if (![WXApi sendReq:payOrder]) {
        
        DebugLog(@"支付出错,请稍后再试");
    }
}

- (void)thirdAliPaySign:(NSString *)sign {
    __weak typeof(self) weakself = self;
    [[AlipaySDK defaultService] payOrder:sign fromScheme:@"com.kyx.eduParents" callback:^(NSDictionary *resultDic) {
        [weakself didReceiveAliPayRequest:resultDic];
    }];
}

#pragma mark - Private

- (void)didReceiveAliPayRequest:(NSDictionary *)resultDic {
    if ([self.third_delegate respondsToSelector:@selector(aliPay_DidReceiveResponse:)]) {
        [self.third_delegate aliPay_DidReceiveResponse:resultDic];
    }
}

#pragma mark - 第三方请求结果URL回调

-(void)handleOpenURL:(NSURL *)url {
    __weak typeof(self) weakself = self;
    if ([url.scheme isEqualToString:WX_APP_ID]) {
        [WXApi handleOpenURL:url delegate:self];
        
    } else if ([url.scheme isEqualToString:[NSString stringWithFormat:@"tencent%@",QQ_APP_ID]]) {
        [QQApiInterface handleOpenURL:url delegate:self];
        [TencentOAuth HandleOpenURL:url];
        
    }else if ([url.scheme isEqualToString:[NSString stringWithFormat:@"wb%@",WB_APP_KEY]]) {
        [WeiboSDK handleOpenURL:url delegate:self];
        
    } else if ([url.host isEqualToString:@"safepay"]) {
        
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            // 处理支付宝支付结果
            [weakself didReceiveAliPayRequest:resultDic];
        }];
    } else if ([url.host isEqualToString:@"alipayclient"]) {
        
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            // 处理支付宝支付结果
            [weakself didReceiveAliPayRequest:resultDic];
        }];
    }
}

#pragma mark - 懒加载

-(AFHTTPSessionManager *)manager {
    if (_manager == nil) {
        _manager = [AFHTTPSessionManager manager];
        _manager.requestSerializer = [AFJSONRequestSerializer serializer];//请求
        _manager.responseSerializer = [AFHTTPResponseSerializer serializer];//响应
        _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json", @"text/json",@"text/plain", nil];
    }
    return _manager;
}

@end

5、登录成功通过代理回调返回用户信息出来:

6、上面的 YZThirdManager 类的代码已经贴出来了,如果要demo,下面回复邮箱地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容