feat: ios add choose invoice

This commit is contained in:
Tom Xu 2020-12-26 14:24:14 +08:00
parent 2e1a33be8d
commit 98c31c7c9f
3 changed files with 193 additions and 135 deletions

167
index.d.ts vendored
View File

@ -2,13 +2,13 @@
*
*/
enum WXScene {
WXSceneSession = 0, /**< 聊天界面 */
WXSceneTimeline = 1, /**< 朋友圈 */
WXSceneFavorite = 2, /**< 收藏 */
WXSceneSpecifiedSession = 3, /**< 指定联系人 */
};
WXSceneSession = 0 /**< 聊天界面 */,
WXSceneTimeline = 1 /**< 朋友圈 */,
WXSceneFavorite = 2 /**< 收藏 */,
WXSceneSpecifiedSession = 3 /**< 指定联系人 */,
}
declare module "react-native-wechat-lib" {
declare module 'react-native-wechat-lib' {
export function registerApp(appId: string, universalLink?: string): Promise<boolean>;
export function isWXAppInstalled(): Promise<boolean>;
export function isWXAppSupportApi(): Promise<boolean>;
@ -24,35 +24,24 @@ declare module "react-native-wechat-lib" {
country?: string;
}
export interface WeChatReq {
type?: string,
errStr?: string,
extMsg?: string,
country?: string,
state?: string,
returnKey?: string
type?: string;
errStr?: string;
extMsg?: string;
country?: string;
state?: string;
returnKey?: string;
}
export interface WeChatResp {
type?: string,
errStr?: string,
extMsg?: string,
country?: string,
state?: string,
returnKey?: string
type?: string;
errStr?: string;
extMsg?: string;
country?: string;
state?: string;
returnKey?: string;
}
export function sendAuthRequest(
scope: string | string[],
state?: string
): Promise<AuthResponse>;
export function sendAuthRequest(scope: string | string[], state?: string): Promise<AuthResponse>;
export interface ShareMetadata {
type:
| "news"
| "text"
| "imageUrl"
| "imageFile"
| "imageResource"
| "video"
| "audio"
| "file";
type: 'news' | 'text' | 'imageUrl' | 'imageFile' | 'imageResource' | 'video' | 'audio' | 'file';
thumbImage?: string;
description?: string;
webpageUrl?: string;
@ -63,88 +52,88 @@ declare module "react-native-wechat-lib" {
fileExtension?: string;
}
export interface ShareTextMetadata {
text: string,
scene?: WXScene
text: string;
scene?: WXScene;
}
export interface ShareImageMetadata {
imageUrl: string,
scene?: WXScene
imageUrl: string;
scene?: WXScene;
}
export interface ShareMusicMetadata {
musicUrl: string,
musicLowBandUrl?: string,
musicDataUrl?: string,
musicLowBandDataUrl?: string,
title?: string,
description?: string,
thumbImageUrl?: string,
scene?: WXScene
musicUrl: string;
musicLowBandUrl?: string;
musicDataUrl?: string;
musicLowBandDataUrl?: string;
title?: string;
description?: string;
thumbImageUrl?: string;
scene?: WXScene;
}
export interface ShareVideoMetadata {
videoUrl: string,
videoLowBandUrl?: string,
title?: string,
description?: string,
thumbImageUrl?: string,
scene?: WXScene
videoUrl: string;
videoLowBandUrl?: string;
title?: string;
description?: string;
thumbImageUrl?: string;
scene?: WXScene;
}
export interface ShareWebpageMetadata {
webpageUrl: string,
title?: string,
description?: string,
thumbImageUrl?: string,
scene?: WXScene
webpageUrl: string;
title?: string;
description?: string;
thumbImageUrl?: string;
scene?: WXScene;
}
export interface ShareMiniProgramMetadata {
webpageUrl: string,
userName: string,
path?: string,
hdImageUrl?: string,
withShareTicket?: string,
miniProgramType?: number,
title?: string,
description?: string,
thumbImageUrl?: string,
scene?: WXScene
webpageUrl: string;
userName: string;
path?: string;
hdImageUrl?: string;
withShareTicket?: string;
miniProgramType?: number;
title?: string;
description?: string;
thumbImageUrl?: string;
scene?: WXScene;
}
export interface LaunchMiniProgramMetadata {
userName: string,
miniProgramType?: number,
path?: string
userName: string;
miniProgramType?: number;
path?: string;
}
export interface SubscribeMessageMetadata {
scene?: WXScene,
templateId: string,
reserved?: string
scene?: WXScene;
templateId: string;
reserved?: string;
}
export function shareText(
message: ShareTextMetadata
message: ShareTextMetadata,
): Promise<{ errCode?: number; errStr?: string }>;
export function shareImage(
message: ShareImageMetadata
message: ShareImageMetadata,
): Promise<{ errCode?: number; errStr?: string }>;
export function shareLocalImage(
message: ShareImageMetadata
message: ShareImageMetadata,
): Promise<{ errCode?: number; errStr?: string }>;
export function shareMusic(
message: ShareMusicMetadata
message: ShareMusicMetadata,
): Promise<{ errCode?: number; errStr?: string }>;
export function shareVideo(
message: ShareVideoMetadata
message: ShareVideoMetadata,
): Promise<{ errCode?: number; errStr?: string }>;
export function shareWebpage(
message: ShareWebpageMetadata
message: ShareWebpageMetadata,
): Promise<{ errCode?: number; errStr?: string }>;
export function shareMiniProgram(
message: ShareMiniProgramMetadata
message: ShareMiniProgramMetadata,
): Promise<{ errCode?: number; errStr?: string }>;
export function launchMiniProgram(
message: LaunchMiniProgramMetadata
message: LaunchMiniProgramMetadata,
): Promise<{ errCode?: number; errStr?: string }>;
export function subscribeMessage(
message: SubscribeMessageMetadata
message: SubscribeMessageMetadata,
): Promise<{ errCode?: number; errStr?: string }>;
export interface PaymentLoad {
partnerId: string;
@ -154,7 +143,21 @@ declare module "react-native-wechat-lib" {
package: string;
sign: string;
}
export function pay(
payload: PaymentLoad
): Promise<{ errCode?: number; errStr?: string }>;
export function pay(payload: PaymentLoad): Promise<{ errCode?: number; errStr?: string }>;
export interface ChooseInvoice {
signType?: string;
nonceStr?: string;
timeStamp?: number;
cardSign?: string;
}
export interface Invoice {
cardId: string;
encryptCode: string;
}
export function chooseInvoice(
data: ChooseInvoice,
): Promise<{ errCode?: number; errStr?: string; cards: Invoice[] }>;
}

101
index.js
View File

@ -1,7 +1,7 @@
'use strict';
import { EventEmitter } from 'events';
import { DeviceEventEmitter, NativeModules, Platform } from 'react-native';
import { EventEmitter } from 'events';
let isAppRegistered = false;
const { WeChat } = NativeModules;
@ -9,11 +9,11 @@ const { WeChat } = NativeModules;
// Event emitter to dispatch request and response from WeChat.
const emitter = new EventEmitter();
DeviceEventEmitter.addListener('WeChat_Resp', resp => {
DeviceEventEmitter.addListener('WeChat_Resp', (resp) => {
emitter.emit(resp.type, resp);
});
DeviceEventEmitter.addListener('WeChat_Req', resp => {
DeviceEventEmitter.addListener('WeChat_Req', (resp) => {
emitter.emit(resp.type, resp);
});
@ -25,12 +25,12 @@ function wrapRegisterApp(nativeFunc) {
if (isAppRegistered) {
return Promise.resolve(true);
}
isAppRegistered = true;
return new Promise((resolve, reject) => {
nativeFunc.apply(null, [
...args,
(error, result) => {
if (!error) {
isAppRegistered = true;
return resolve(result);
}
if (typeof error === 'string') {
@ -158,6 +158,7 @@ const nativeShareWebpage = wrapApi(WeChat.shareWebpage);
const nativeShareMiniProgram = wrapApi(WeChat.shareMiniProgram);
const nativeSubscribeMessage = wrapApi(WeChat.subscribeMessage);
const nativeChooseInvoice = wrapApi(WeChat.chooseInvoice);
/**
* @method sendAuthRequest
@ -167,7 +168,7 @@ const nativeSubscribeMessage = wrapApi(WeChat.subscribeMessage);
export function sendAuthRequest(scopes, state) {
return new Promise((resolve, reject) => {
WeChat.sendAuthRequest(scopes, state, () => {});
emitter.once('SendAuth.Resp', resp => {
emitter.once('SendAuth.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -184,11 +185,29 @@ export function sendAuthRequest(scopes, state) {
*/
export function shareText(data) {
if (data && data.scene == null) {
data.scene = 0
data.scene = 0;
}
return new Promise((resolve, reject) => {
nativeShareText(data);
emitter.once('SendMessageToWX.Resp', resp => {
emitter.once('SendMessageToWX.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
reject(new WechatError(resp));
}
});
});
}
/**
* Choose Invoice
* @method chooseInvoice
* @param {Object} data
*/
export function chooseInvoice(data) {
return new Promise((resolve, reject) => {
nativeChooseInvoice(data);
emitter.once('WXChooseInvoiceResp.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -205,11 +224,11 @@ export function shareText(data) {
*/
export function shareImage(data) {
if (data && data.scene == null) {
data.scene = 0
data.scene = 0;
}
return new Promise((resolve, reject) => {
nativeShareImage(data);
emitter.once('SendMessageToWX.Resp', resp => {
emitter.once('SendMessageToWX.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -226,11 +245,11 @@ export function shareImage(data) {
*/
export function shareLocalImage(data) {
if (data && data.scene == null) {
data.scene = 0
data.scene = 0;
}
return new Promise((resolve, reject) => {
nativeShareLocalImage(data);
emitter.once('SendMessageToWX.Resp', resp => {
emitter.once('SendMessageToWX.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -247,11 +266,11 @@ export function shareLocalImage(data) {
*/
export function shareMusic(data) {
if (data && data.scene == null) {
data.scene = 0
data.scene = 0;
}
return new Promise((resolve, reject) => {
nativeShareMusic(data);
emitter.once('SendMessageToWX.Resp', resp => {
emitter.once('SendMessageToWX.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -268,11 +287,11 @@ export function shareMusic(data) {
*/
export function shareVideo(data) {
if (data && data.scene == null) {
data.scene = 0
data.scene = 0;
}
return new Promise((resolve, reject) => {
nativeShareVideo(data);
emitter.once('SendMessageToWX.Resp', resp => {
emitter.once('SendMessageToWX.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -289,11 +308,11 @@ export function shareVideo(data) {
*/
export function shareWebpage(data) {
if (data && data.scene == null) {
data.scene = 0
data.scene = 0;
}
return new Promise((resolve, reject) => {
nativeShareWebpage(data);
emitter.once('SendMessageToWX.Resp', resp => {
emitter.once('SendMessageToWX.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -309,14 +328,14 @@ export function shareWebpage(data) {
*/
export function shareMiniProgram(data) {
if (data && data.scene == null) {
data.scene = 0
data.scene = 0;
}
if (data && data.miniProgramType == null) {
data.miniProgramType = 0
data.miniProgramType = 0;
}
return new Promise((resolve, reject) => {
nativeShareMiniProgram(data);
emitter.once('SendMessageToWX.Resp', resp => {
emitter.once('SendMessageToWX.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -334,20 +353,25 @@ export function shareMiniProgram(data) {
* @param {Integer} miniProgramType - 拉起小程序的类型. 0-正式版 1-开发版 2-体验版
* @param {String} path - 拉起小程序页面的可带参路径不填默认拉起小程序首页
*/
export function launchMiniProgram({userName, miniProgramType = 0, path = ''}) {
export function launchMiniProgram({ userName, miniProgramType = 0, path = '' }) {
return new Promise((resolve, reject) => {
if (miniProgramType !== 0 && miniProgramType !== 1 && miniProgramType !== 2) {
reject(new WechatError({errStr: '拉起小程序的类型不对0-正式版 1-开发版 2-体验版', errCode: -1}))
return
if (miniProgramType !== 0 && miniProgramType !== 1 && miniProgramType !== 2) {
reject(
new WechatError({
errStr: '拉起小程序的类型不对0-正式版 1-开发版 2-体验版',
errCode: -1,
}),
);
return;
}
nativeLaunchMiniProgram({ userName, miniProgramType, path });
emitter.once('WXLaunchMiniProgramReq.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
reject(new WechatError(resp));
}
nativeLaunchMiniProgram({userName, miniProgramType, path});
emitter.once('WXLaunchMiniProgramReq.Resp', resp => {
if (resp.errCode === 0) {
resolve(resp);
} else {
reject(new WechatError(resp));
}
});
});
});
}
@ -358,11 +382,11 @@ export function launchMiniProgram({userName, miniProgramType = 0, path = ''}) {
*/
export function subscribeMessage(data) {
if (data && data.scene == null) {
data.scene = 0
data.scene = 0;
}
return new Promise((resolve, reject) => {
nativeSubscribeMessage(data);
emitter.once('WXSubscribeMsgReq.Resp', resp => {
emitter.once('WXSubscribeMsgReq.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -388,7 +412,7 @@ export function subscribeMessage(data) {
export function shareToFavorite(data) {
return new Promise((resolve, reject) => {
nativeShareToFavorite(data);
emitter.once('SendMessageToWX.Resp', resp => {
emitter.once('SendMessageToWX.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -423,13 +447,13 @@ export function pay(data) {
// FIXME(94cstyles)
// Android requires the type of the timeStamp field to be a string
if (Platform.OS === 'android') data.timeStamp = String(data.timeStamp)
if (Platform.OS === 'android') data.timeStamp = String(data.timeStamp);
return new Promise((resolve, reject) => {
WeChat.pay(data, result => {
WeChat.pay(data, (result) => {
if (result) reject(result);
});
emitter.once('PayReq.Resp', resp => {
emitter.once('PayReq.Resp', (resp) => {
if (resp.errCode === 0) {
resolve(resp);
} else {
@ -458,4 +482,3 @@ export class WechatError extends Error {
}
}
}

View File

@ -173,7 +173,7 @@ RCT_EXPORT_METHOD(sendAuthRequest:(NSString *)scope
callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return;
};
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
[WXApi sendAuthReq:req viewController:rootViewController delegate:self completion:completion];
}
@ -240,6 +240,26 @@ RCT_EXPORT_METHOD(shareText:(NSDictionary *)data
[WXApi sendReq:req completion:completion];
}
//
RCT_EXPORT_METHOD(chooseInvoice:(NSDictionary *)data
:(RCTResponseSenderBlock)callback)
{
WXChooseInvoiceReq *req = [[WXChooseInvoiceReq alloc] init];
req.appID = self.appId;
req.timeStamp = [data[@"timeStamp"] intValue];
req.nonceStr = data[@"nonceStr"];
req.cardSign = data[@"cardSign"];
req.signType = data[@"signType"];
void ( ^ completion )( BOOL );
completion = ^( BOOL success )
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return;
};
[WXApi sendReq:req completion:completion];
}
//
RCT_EXPORT_METHOD(shareImage:(NSDictionary *)data
:(RCTResponseSenderBlock)callback)
@ -558,9 +578,9 @@ RCT_EXPORT_METHOD(pay:(NSDictionary *)data
if (resp.errCode == WXSuccess) {
if (self.appId && r) {
// iosappidOK
[body addEntriesFromDictionary:@{@"appid":self.appId, @"code":r.code}];
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
// iosappidOK
[body addEntriesFromDictionary:@{@"appid":self.appId, @"code":r.code}];
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
}
}
else {
@ -581,6 +601,18 @@ RCT_EXPORT_METHOD(pay:(NSDictionary *)data
body[@"extMsg"] = r.extMsg;
body[@"type"] = @"WXLaunchMiniProgramReq.Resp";
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
} else if ([resp isKindOfClass:[WXChooseInvoiceResp class]]){
WXChooseInvoiceResp *r = (WXChooseInvoiceResp *)resp;
NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy;
body[@"errStr"] = r.errStr;
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (WXCardItem* cardItem in r.cardAry) {
NSMutableDictionary *item = @{@"cardId":cardItem.cardId,@"encryptCode":cardItem.encryptCode}.mutableCopy;
[arr addObject:item];
}
body[@"cards"] = arr;
body[@"type"] = @"WXChooseInvoiceResp.Resp";
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
}
}