一.总说内购的内容

  1. 协议、税务和银行业务 信息填写

  2. 内购商品的添加

  3. 添加沙盒测试账号

  4. 内购代码的具体实现

  5. 内购的注意事项

二.协议、税务和银行业务 信息填写

  • 2.1、协议、税务和银行业务 信息填写 的入口

协议、税务和银行业务 信息填写 的入口

  • 2.2、选择申请合同类型

  • 进入协议、税务和银行业务页面后,会有3种合同类型,如果你之前没有主动申请过去合同,那么一般你现在激活的合同只有iOS Free Application一种。

  • 页面内容分为两块:

    Request Contracts(申请合同)

    Contracts In Effect(已生效合同)。

  • 合同类型分为3种:

    iOS Free Application(免费应用合同)

    iOS Paid Application(付费应用合同)

    iAd App NetNetwork(广告合同)

这里我们主要主要讲一下付费应用合同的申请流程。

付费应用合同的申请流程

  • 2.3、申请iOS Paid Application合同(协议、税务和银行业务3个都要填写)

协议、税务和银行业务

  • 2.4、Contact Info(填写联系方式)

填写联系方式

如果你没有添加过联系人,你需要通过Add New Contact按钮来添加一个新的联系人。然后指定联系人的职务,

职务如下:

  • Senior Management:高管

  • Financial:财务

  • Technical:技术支持

  • Legal:法务

  • Marketing:市场推广

如果你是独立开发者,可以全部填你自己一个人。

  • 2.5、填写银行信息

填写银行信息

选择你的银行账户,如果你没有,点击旁边的Add Bank Account添加一个账户。下面是添加一个账户的流程。

2.5.1、选择银行所在的国家

选择银行所在的国家

2.5.2、填写银行标识CNAPS Code

如果你不知道CNAPS Code是多少,可以百度搜CNAPS Code来查询,查询时会根据3个关键信息来查询,如下:

  • Bank Name:银行的英文名称(不能是拼音)

  • City:银行所在的城市英文名称(中国的城市用拼音)

  • Postal Code:邮编

然后在下面就会出来备选的银行,选择正确的银行后,点击next,进入下一步。

百度搜CNAPS Code来查询

银行信息的填写

2.5.3、确认银行信息

确认银行信息

2.5.4、填写银行账号信息

  • Bank Account Number:银行账号

  • Confirm Bank Account Number:再次输入银行账号

  • Account Holder Name:持卡人姓名,中文名用拼写,名在前,姓在后

  • Bank Account Currency:货币类型,一般国内的开发者选择CNY

填写银行账号信息

2.5.5、确认所有信息

确认所有信息

  • 2.6.填写税务信息(这个内容比较多)

2.6.1.税务信息这一块了解不是很多,不过因为是国内开发者,可以不用太费心,税务信息分3种:

  • U.S Tax Forms: 美国税务

  • Australia Tax Forms:澳大利亚税务

  • Canada Tax Forms: 加拿大税务

税务信息

2.6.2.一堆条约

我选择的是U.S Tax Forms,选择后会问你两个问题:

第1个问题如下:询问你是否是美国居民,有没有美国伙伴关系或者美国公司,如果没有直接选择No。

询问你是否是美国居民,有没有美国伙伴关系或者美国公司,如果没有直接选择No

接下来第二个问题如下:询问你有没有在美国的商业性活动,没有也直接选No

接下来第二个问题如下:询问你有没有在美国的商业性活动,没有也直接选No

2.6.3.然后填写你的税务信息,包括以下几点:

  • Individual or Organization Name:个人或者组织名称

  • Country of incorporation: 所在国家

  • Type of Beneficial Owner:受益方式,独立开发者选个人

  • Permanent Residence:居住地址

  • Mailing address:邮寄地址

  • Name of Person Making this Declaration:声明人

  • Title:头衔

填写你的税务信息

2.6.4.打钩

打钩

2.6.5.澳大利亚的不要管了

澳大利亚的不要管了

2.6.6.加拿大的也不用管了

加拿大的也不用管了

  • 2.7.填写完成

填写完成

  • 2.8.待审核

    你填写完所有资料后,合同状态就会变成Processing, 大概24小时内就会有结果。

三.内购商品的添加

  • 3.1.创建内购商品

创建内购商品

  • 3.2.选择内购类型

    3.2.1.消耗型商品:类似游戏中的钻石,还有现在某些APP中的货币,比如斗鱼里的鱼丸、映客里的映票。会被消耗的,要选择消耗型商品

    注意:大多数的消耗型商品都是需要登录的,因为需要在数据库存余额。

    需要注意的是:在登录之前,你最好不要让用户看到商品,有可能会因为这个原因被拒(大家都说看运气)

    3.2.2.非消耗型商品:无法被消耗的商品,比如上文提到的视频课程,一次购买,就应该永久可以观看

    注意:当你使用非消耗型商品时,你需要添加一个恢复购买的按钮

    这个常见于各种游戏中,其实知道这个规定以后还是挺好理解的,非消耗型商品是不可被消耗的,一次购买终身使用的,非消耗型的商品是跟appleId绑定的,就是你平时下载APP让你输入账号密码的内个。

    你需要一个恢复购买的按钮,来让用户恢复他购买的内容

    3.2.3.订阅类型商品:如果你的公司是外包公司,有订阅类型商品的APP一定要用客户的账号提交审核,因为当APP中有过订阅类型商品,注意是有过,创建过再删除也算,这个APP无法被转移账号

    注意:使用或曾经使用过订阅型商品的APP无法转移

选择内购类型

具体内购类型

选择语言

FA40E42F-400E-4A85-949A-ED90C9B6B475.png

  • 3.3.创建好的产品

创建好的产品

3.4.在上线的时候记得添加内购的商品

添加内购商品

选择内购产品之后的状态

四.添加沙盒测试账号

  • 4.1.添加沙盒测试的入口

添加沙盒测试的入口

  • 4.2.添加沙盒测试账号

添加沙盒测试账号

  • 4.3.具体的测试账号信息填写

具体的测试账号信息填写

五.内购代码的具体实现(这才是大家所期望看到的)

  • 5.1.我创建了一个购买金币的内购控制器ApplePayCIOViewController

在此,我仅仅向大家贴出.m的详细代码

  • 5.2.内购的流程详细讲解

    5.2.1. 用户先拿到购买产品的单子,

    5.2.2.拿着单子去苹果那里交钱,交完钱让苹果在单子上盖个章

    5.2.3.拿着盖了章的单子传给自己的服务器来验证是否真的支付成功

    5.2.4.根据服务器返回的信息做具体的处理

内购的流程详细讲解

  • 5.3.上代码

    5.3.1.先导入StoreKit.framework库;

    5.3.2.创建ApplePayCIOViewController,遵守协议

    5.3.3.ApplePayCIOViewController.m代码

#import "ApplePayCIOViewController.h"
#import // 产品的ID
#define ProductID1 @"CIOCourses1"
@interface ApplePayCIOViewController (){NSString *selectProductID;
}
@end
@implementation ApplePayCIOViewController
-(void)viewWillAppear:(BOOL)animated{[super viewWillAppear:animated];// 添加观察者[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
-(void)viewWillDisappear:(BOOL)animated{[super viewWillDisappear:animated];// 移除观察者[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}- (void)viewDidLoad {[super viewDidLoad];self.title = @"内购";self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"测试" style:UIBarButtonItemStylePlain target:self action:@selector(test)];// 恢复购买的按钮UIButton * revert = [[UIButton alloc]initWithFrame:CGRectMake(20, 100, 100, 80)];[revert setBackgroundColor:JKRandomColor];[revert addTarget:self action:@selector(replyToBuy) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview: revert];self.view.backgroundColor =[UIColor redColor];
}#pragma mark 恢复购买(主要是针对非消耗产品)
-(void)replyToBuy{[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
#pragma mark 测试内购
-(void)test{if([SKPaymentQueue canMakePayments]){// productID就是你在创建购买项目时所填写的产品IDselectProductID = [NSString stringWithFormat:@"%@",ProductID1];[self requestProductID:selectProductID];}else{6        // NSLog(@"不允许程序内付费");UIAlertView *alertError = [[UIAlertView alloc] initWithTitle:@"温馨提示"message:@"请先开启应用内付费购买功能。"delegate:nilcancelButtonTitle:@"确定"otherButtonTitles: nil];[alertError show];}
}
#pragma mark 1.请求所有的商品ID
-(void)requestProductID:(NSString *)productID{// 1.拿到所有可卖商品的ID数组NSArray *productIDArray = [[NSArray alloc]initWithObjects:productID, nil];NSSet *sets = [[NSSet alloc]initWithArray:productIDArray];// 2.向苹果发送请求,请求所有可买的商品// 2.1.创建请求对象SKProductsRequest *sKProductsRequest = [[SKProductsRequest alloc]initWithProductIdentifiers:sets];// 2.2.设置代理(在代理方法里面获取所有的可卖的商品)sKProductsRequest.delegate = self;// 2.3.开始请求[sKProductsRequest start];}
#pragma mark 2.苹果那边的内购监听
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{NSLog(@"可卖商品的数量=%ld",response.products.count);NSArray *product = response.products;if([product count] == 0){NSLog(@"没有商品");return;}for (SKProduct *sKProduct in product) {NSLog(@"pro info");NSLog(@"SKProduct 描述信息:%@", sKProduct.description);NSLog(@"localizedTitle 产品标题:%@", sKProduct.localizedTitle);NSLog(@"localizedDescription 产品描述信息:%@",sKProduct.localizedDescription);NSLog(@"price 价格:%@",sKProduct.price);NSLog(@"productIdentifier Product id:%@",sKProduct.productIdentifier);if([sKProduct.productIdentifier isEqualToString: selectProductID]){[self buyProduct:sKProduct];break;}else{//NSLog(@"不不不相同");}}}#pragma mark 内购的代码调用
-(void)buyProduct:(SKProduct *)product{// 1.创建票据SKPayment *skpayment = [SKPayment paymentWithProduct:product];// 2.将票据加入到交易队列[[SKPaymentQueue defaultQueue] addPayment:skpayment];// 3.添加观察者,监听用户是否付钱成功(不在此处添加观察者)//[[SKPaymentQueue defaultQueue] addTransactionObserver:self];}#pragma mark 4.实现观察者监听付钱的代理方法,只要交易发生变化就会走下面的方法
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{/*SKPaymentTransactionStatePurchasing,    正在购买SKPaymentTransactionStatePurchased,     已经购买SKPaymentTransactionStateFailed,        购买失败SKPaymentTransactionStateRestored,      回复购买中SKPaymentTransactionStateDeferred       交易还在队列里面,但最终状态还没有决定*/for (SKPaymentTransaction *transaction in transactions) {switch (transaction.transactionState) {case SKPaymentTransactionStatePurchasing:{NSLog(@"正在购买");}break;case SKPaymentTransactionStatePurchased:{NSLog(@"购买成功");// 购买后告诉交易队列,把这个成功的交易移除掉[queue finishTransaction:transaction];[self buyAppleStoreProductSucceedWithPaymentTransactionp:transaction];}break;case SKPaymentTransactionStateFailed:{NSLog(@"购买失败");// 购买失败也要把这个交易移除掉[queue finishTransaction:transaction];}break;case SKPaymentTransactionStateRestored:{NSLog(@"回复购买中,也叫做已经购买");// 回复购买中也要把这个交易移除掉[queue finishTransaction:transaction];}break;case SKPaymentTransactionStateDeferred:{NSLog(@"交易还在队列里面,但最终状态还没有决定");}break;default:break;}}}// 苹果内购支付成功
- (void)buyAppleStoreProductSucceedWithPaymentTransactionp:(SKPaymentTransaction *)paymentTransactionp {NSString * productIdentifier = paymentTransactionp.payment.productIdentifier;// NSLog(@"productIdentifier Product id:%@", productIdentifier);NSString *transactionReceiptString= nil;//系统IOS7.0以上获取支付验证凭证的方式应该改变,切验证返回的数据结构也不一样了。NSString *version = [UIDevice currentDevice].systemVersion;if([version intValue] >= 7.0){// 验证凭据,获取到苹果返回的交易凭据// appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址NSURLRequest * appstoreRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle]appStoreReceiptURL]];NSError *error = nil;NSData * receiptData = [NSURLConnection sendSynchronousRequest:appstoreRequest returningResponse:nil error:&error];transactionReceiptString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];}else{NSData * receiptData = paymentTransactionp.transactionReceipt;//  transactionReceiptString = [receiptData base64EncodedString];transactionReceiptString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];}// 去验证是否真正的支付成功了[self checkAppStorePayResultWithBase64String:transactionReceiptString];}- (void)checkAppStorePayResultWithBase64String:(NSString *)base64String {/* 生成订单参数,注意沙盒测试账号与线上正式苹果账号的验证途径不一样,要给后台标明 *//*注意:自己测试的时候使用的是沙盒购买(测试环境)App Store审核的时候也使用的是沙盒购买(测试环境)上线以后就不是用的沙盒购买了(正式环境)所以此时应该先验证正式环境,在验证测试环境正式环境验证成功,说明是线上用户在使用正式环境验证不成功返回21007,说明是自己测试或者审核人员在测试*//*苹果AppStore线上的购买凭证地址是: https://buy.itunes.apple.com/verifyReceipt测试地址是:https://sandbox.itunes.apple.com/verifyReceipt*///    NSNumber *sandbox;NSString *sandbox;#if (defined(APPSTORE_ASK_TO_BUY_IN_SANDBOX) && defined(DEBUG))//sandbox = @(0);sandbox = @"0";#else//sandbox = @(1);sandbox = @"1";#endifNSMutableDictionary *prgam = [[NSMutableDictionary alloc] init];;[prgam setValue:sandbox forKey:@"sandbox"];[prgam setValue:base64String forKey:@"reciept"];/*请求后台接口,服务器处验证是否支付成功,依据返回结果做相应逻辑处理0 代表沙盒  1代表 正式的内购最后最验证后的*//*内购验证凭据返回结果状态码说明21000 App Store无法读取你提供的JSON数据  21002 收据数据不符合格式  21003 收据无法被验证  21004 你提供的共享密钥和账户的共享密钥不一致  21005 收据服务器当前不可用  21006 收据是有效的,但订阅服务已经过期。当收到这个信息时,解码后的收据信息也包含在返回内容中  21007 收据信息是测试用(sandbox),但却被发送到产品环境中验证  21008 收据信息是产品环境中使用,但却被发送到测试环境中验证*/NSLog(@"字典==%@",prgam);}#pragma mark 客户端验证购买凭据
- (void)verifyTransactionResult
{// 验证凭据,获取到苹果返回的交易凭据// appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];// 从沙盒中获取到购买凭据NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];// 传输的是BASE64编码的字符串/**BASE64 常用的编码方案,通常用于数据传输,以及加密算法的基础算法,传输过程中能够保证数据传输的稳定性BASE64是可以编码和解码的*/NSDictionary *requestContents = @{@"receipt-data": [receipt base64EncodedStringWithOptions:0]};NSError *error;// 转换为 JSON 格式NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContentsoptions:0error:&error];// 不存在if (!requestData) { /* ... Handle error ... */ }// 发送网络POST请求,对购买凭据进行验证NSString *verifyUrlString;#if (defined(APPSTORE_ASK_TO_BUY_IN_SANDBOX) && defined(DEBUG))verifyUrlString = @"https://sandbox.itunes.apple.com/verifyReceipt";#elseverifyUrlString = @"https://buy.itunes.apple.com/verifyReceipt";#endif// 国内访问苹果服务器比较慢,timeoutInterval 需要长一点NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:[[NSURL alloc] initWithString:verifyUrlString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];[storeRequest setHTTPMethod:@"POST"];[storeRequest setHTTPBody:requestData];// 在后台对列中提交验证请求,并获得官方的验证JSON结果NSOperationQueue *queue = [[NSOperationQueue alloc] init];[NSURLConnection sendAsynchronousRequest:storeRequest queue:queuecompletionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {if (connectionError) {NSLog(@"链接失败");} else {NSError *error;NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];if (!jsonResponse) {NSLog(@"验证失败");}// 比对 jsonResponse 中以下信息基本上可以保证数据安全/*bundle_idapplication_versionproduct_idtransaction_id*/NSLog(@"验证成功");}}];}
@end

六.内购的注意事项

  • 6.1.一般发生于首次提交app或添加新商品,当你的app通过审核以后,你发现在生产环境下获取不到商品,这是因为app虽然过审核了,但是内购商品还没有正式添加到苹果的服务器里,耐心等待一段时间就可以啦~

  • 6.2. 代码中的_currentProId所填写的是你的购买项目的的ID,这个和第二步创建的内购的productID要一致;本例中是 123。

  • 6.3. 在监听购买结果后,一定要调用[[SKPaymentQueue defaultQueue] finishTransaction:tran];来允许你从支付队列中移除交易。

  • 6.4. 沙盒环境测试appStore内购流程的时候,请使用没越狱的设备。

  • 6.5. 请务必使用真机来测试,一切以真机为准。

  • 6.6. 项目Bundle identifier需要与您申请AppID时填写的bundleID一致,不然会无法请求到商品信息。

  • 6.7. 真机测试的时候,一定要退出原来的账号,才能用沙盒测试账号

  • 6.8. 二次验证,请注意区分宏, 测试用沙盒验证,App Store审核的时候也使用的是沙盒购买,所以验证购买凭证的时候需要判断返回Status Code决定是否去沙盒进行二次验证,为了线上用户的使用,验证的顺序肯定是先验证正式环境,此时若返回值为21007,就需要去沙盒二次验证,因为此购买的是在沙盒进行的。

  • 6.9.您的应用是否处于等待开发者发布(Pending Developer Release)状态?等待发布状态的IAP是无法测试的。

  • 6.10.您的内购项目是否是最近才新建的,或者进行了更改?内购项目需要一段时间才能反应到所有服务器上,这个过程一般是一两小时,也可能再长一些达到若干小时。

  • 6.11.您在iTC中Contracts, Tax, and Banking Information项目中是否有还没有设置或者过期了的项目?不完整的财务信息无法进行内购测试。

  • 6.12.您是在越狱设备上进行内购测试么?越狱设备不能用于正常内购,您需要重装或者寻找一台没有越狱的设备。

  • 6.13.您的应用是否是被拒状态(Rejected)或自己拒绝(Developer Rejected)了?被拒绝状态的应用的话对应还未通过的内购项目也会一起被拒,因此您需要重新将IAP项目设为Cleared for Sale。

  • 6.14.您使用的测试账号是否是美国区账号?虽然不是一定需要,但是鉴于其他地区的测试账号经常抽风,加上美国区账号一直很稳定,因此强烈建议使用美国区账号。正常情况下IAP不需要进行信用卡绑定和其他信息填写,如果你遇到了这种情况,可以试试删除这个测试账号再新建一个其他地区的。

  • 6.15.您是否将设备上原来的app删除了,并重新进行了安装?记得在安装前做一下Clean和Clean Build Folder。

  • 6.16.您的plist中的Bundle identifier的内容是否和您的AppID一致?

iOS 内购最新讲解相关推荐

  1. ios 内购正式环境_iOS 内购最新讲解

    本文为CocoaChina网友IIronMan投稿 一.总说内购的内容协议.税务和银行业务 信息填写 内购商品的添加 添加沙盒测试账号 内购代码的具体实现 内购的注意事项 二.协议.税务和银行业务 信 ...

  2. iOS内购-防越狱破解刷单

    ---------------------------2018.10.16更新--------------------------- 最近我们公司丢单率上涨,尤其是10月份比9月份来说丢单率翻了3倍, ...

  3. IOS 内购IAP 自动订阅收据验证文档服务端翻译

    将收据数据发送到App Store: 提交此JSON对象作为HTTP POST请求的有效负载. 中文文档:https://help.apple.com/app-store-connect/#/dev7 ...

  4. java集成ios内购\与ios退款通知处理

    使用ios内购,需在项目数据库建立虚拟币相关表(虚拟币余额表.充值面额表.充值订单表等)上代码 苹果IAP内购验证工具类 IosVerifyUtil import javax.net.ssl.*; i ...

  5. U3D如何添加IOS内购,自制内购小插件

    参考资料:http://www.cocoachina.com/bbs/read.php?tid-69165-fpage-2.html 网上很多IAP的教程,但是较少有结合U3D的教程.所以我在此进行简 ...

  6. Unity iOS内购

    前言:最近项目需要切换到iOS平台做一些提交审核和支付对接相关的工作,上一篇刚分享了最新的iOS10提交审核的一些坑,这篇分享一些内购相关的流程. Unity iOS内购 思路: Unity调用iOS ...

  7. ios内购二次验证安全性问题_iOS内购之二次验证

    开篇:关于iOS内购整体流程网上能找到很多.我抽丝剥茧,着重说一下二次验证及收据回传的数据问题. 二次验证 关于二次验证,其实有两种做法,第一种是在app端验证,第二种也是安全防盗的一种,在服务端进行 ...

  8. iOS内购:自动续期订阅总结

    前言:内购类型有四种:消耗型商品,非消耗型商品,非续期订阅,自动续期订阅. 顾名思义,从中最有难度的就是自动续期订阅的实现,开通自动续期订阅后,订阅会员的处理将会遇到如下问题:自动订阅的到期继续自动订 ...

  9. IOS内购流程从0-1手把手教会

    苹果掌握着可能是全球最重要的APP分发渠道,然而30%的抽成近年来也被人批评,现在苹果似乎也看到反对意见了,从2021年1月1日开始,部分小型企业的分成费用降低到15%. 据报道,苹果将于2021年1 ...

  10. IOS内购验证 (Java版)

    此处给各位贴出apple官方文档 App 内购买项目配置流程 apple 收据文档 apple 收据responseBody字段释义 IOS内购逻辑图 IOS内购验证相关代码 package xxxx ...

最新文章

  1. php限定名称写法,php命名空间:非限定名称、限定名称、完全限定名称实例详解...
  2. Android 数据库 ANR的例子
  3. Python3 JSON处理
  4. 「Python」Command “python setup.py egg_info“ failed with error code 1 in /tmp/pip-build-Yt_rRN/grpcio
  5. 十八个超经典故事 绝对不会后悔
  6. java代码,继承。。。主要是传值,赋值。
  7. PHP获取IP地址的方法,防止伪造IP地址注入攻击
  8. 海量数据寻找最频繁的数据_寻找数据科学家的“原因”
  9. 构建之法第11、12章
  10. MySQL命令梳理_MySQL操作命令梳理(2)
  11. python type help copyright_python学习 第二天
  12. 【软件项目管理】滨江学院 李振宏 软件项目管理 试卷考点知识点整理
  13. Beini FeedingBottle[小巧的无线密码破解系统]
  14. 计算机网络毕业设计选题背景,毕业设计论文选题依据与背景
  15. 教你如何玩转豆瓣(douban) 豆瓣使用入门!
  16. vue-baidu-map添加覆盖物-点
  17. arcgis符号方向_arcgis符号
  18. docker ps 不显示问题,
  19. 线性代数基本知识-思维导图
  20. aiaidaxue.com 爱爱大学最新地址发布页

热门文章

  1. React 备忘录 v16
  2. android m3u8 合并,M3u8合并APP
  3. MACD、KDJ、DMA等常用技术指标的python实现
  4. 让你的系统无懈可击 史上优秀防火墙一览
  5. linux终端vi怎么输入日历,Remind: 命令行的 calendar 及 todo list
  6. 金庸武侠小说之我的见解
  7. DataFrame切片
  8. 博士申请——Research Proposal
  9. python提取图片中的文字自动填表,python提取图片中的文字并生成word文档
  10. 通过脚手架安装Ant+react+umi+dva项目(一)