diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..ebb4af5 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "printWidth": 100, + "trailingComma": "all" +} diff --git a/android/src/main/java/com/theweflex/react/WeChatModule.java b/android/src/main/java/com/theweflex/react/WeChatModule.java index 99d4518..c563522 100644 --- a/android/src/main/java/com/theweflex/react/WeChatModule.java +++ b/android/src/main/java/com/theweflex/react/WeChatModule.java @@ -31,6 +31,7 @@ import com.facebook.react.bridge.WritableMap; import com.facebook.react.modules.core.DeviceEventManagerModule; import com.tencent.mm.opensdk.modelbase.BaseReq; import com.tencent.mm.opensdk.modelbase.BaseResp; +import com.tencent.mm.opensdk.modelbiz.ChooseCardFromWXCardPackage; import com.tencent.mm.opensdk.modelmsg.SendAuth; import com.tencent.mm.opensdk.modelmsg.SendMessageToWX; import com.tencent.mm.opensdk.modelmsg.ShowMessageFromWX; @@ -51,6 +52,7 @@ import com.tencent.mm.opensdk.openapi.WXAPIFactory; import com.tencent.mm.opensdk.constants.ConstantsAPI; import com.tencent.mm.opensdk.modelbiz.SubscribeMessage; +import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -58,7 +60,10 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; +import java.net.URL; import java.util.ArrayList; import java.util.UUID; @@ -197,8 +202,84 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv callback.invoke(null, api.sendReq(req)); } + /** + * 选择发票 + * + * @param data + * @param callback + */ + @ReactMethod + public void chooseInvoice(ReadableMap data, Callback callback) { + ChooseCardFromWXCardPackage.Req req = new ChooseCardFromWXCardPackage.Req(); + + req.appId = this.appId; + req.cardType = "INVOICE"; + req.timeStamp = String.valueOf(data.getInt("timeStamp")); + req.nonceStr = data.getString("nonceStr"); + req.cardSign = data.getString("cardSign"); + req.signType = data.getString("signType"); + + callback.invoke(null, api.sendReq(req)); + } + + public byte[] loadRawDataFromURL(String u) throws Exception { + URL url = new URL(u); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + + InputStream is = conn.getInputStream(); + BufferedInputStream bis = new BufferedInputStream(is); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + final int BUFFER_SIZE = 2048; + final int EOF = -1; + + int c; + byte[] buf = new byte[BUFFER_SIZE]; + + while (true) { + c = bis.read(buf); + if (c == EOF) + break; + + baos.write(buf, 0, c); + } + + conn.disconnect(); + is.close(); + + byte[] data = baos.toByteArray(); + baos.flush(); + + return data; + } + + /** * 分享文本 + * + * @param data + * @param callback + */ + @ReactMethod + public void shareFile(ReadableMap data, Callback callback) throws Exception { + WXFileObject fileObj = new WXFileObject(); + fileObj.fileData = loadRawDataFromURL(data.getString("url")); + + WXMediaMessage msg = new WXMediaMessage(); + msg.mediaObject = fileObj; + msg.title = data.getString("title"); + + SendMessageToWX.Req req = new SendMessageToWX.Req(); + req.transaction = String.valueOf(System.currentTimeMillis()); + req.message = msg; + req.scene = data.hasKey("scene") ? data.getInt("scene") : SendMessageToWX.Req.WXSceneSession; + callback.invoke(null, api.sendReq(req)); + } + + /** + * 分享文本 + * * @param data * @param callback */ @@ -222,6 +303,7 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv /** * 分享图片 + * * @param data * @param callback */ @@ -255,8 +337,10 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv } // private static final String SDCARD_ROOT = Environment.getExternalStorageDirectory().getAbsolutePath(); + /** * 分享本地图片 + * * @param data * @param callback */ @@ -270,7 +354,7 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv } // int maxWidth = data.hasKey("maxWidth") ? data.getInt("maxWidth") : -1; fs = new FileInputStream(path); - Bitmap bmp = BitmapFactory.decodeStream(fs); + Bitmap bmp = BitmapFactory.decodeStream(fs); // if (maxWidth > 0) { // bmp = Bitmap.createScaledBitmap(bmp, maxWidth, bmp.getHeight() / bmp.getWidth() * maxWidth, true); @@ -318,6 +402,7 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv /** * 分享音乐 + * * @param data * @param callback */ @@ -365,6 +450,7 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv /** * 分享视频 + * * @param data * @param callback */ @@ -407,6 +493,7 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv /** * 分享网页 + * * @param data * @param callback */ @@ -449,6 +536,7 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv /** * 分享小程序 + * * @param data * @param callback */ @@ -525,6 +613,7 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv /** * 一次性订阅消息 + * * @param data * @param callback */ @@ -895,6 +984,10 @@ public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEv map.putString("type", "WXLaunchMiniProgramReq.Resp"); map.putString("extraData", extraData); map.putString("extMsg", extraData); + } else if (baseResp instanceof ChooseCardFromWXCardPackage.Resp) { + ChooseCardFromWXCardPackage.Resp resp = (ChooseCardFromWXCardPackage.Resp) baseResp; + map.putString("type", "WXChooseInvoiceResp.Resp"); + map.putString("cardItemList", resp.cardItemList); } this.getReactApplicationContext() diff --git a/index.d.ts b/index.d.ts index 7df408a..4d07935 100644 --- a/index.d.ts +++ b/index.d.ts @@ -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; export function isWXAppInstalled(): Promise; export function isWXAppSupportApi(): Promise; @@ -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; + export function sendAuthRequest(scope: string | string[], state?: string): Promise; 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,32 @@ declare module "react-native-wechat-lib" { package: string; sign: string; } - export function pay( - payload: PaymentLoad + export function pay(payload: PaymentLoad): Promise<{ errCode?: number; errStr?: string }>; + + export interface ChooseInvoice { + signType?: string; + nonceStr?: string; + timeStamp?: number; + cardSign?: string; + } + + export interface Invoice { + appId: string; + cardId: string; + encryptCode: string; + } + + export function chooseInvoice( + data: ChooseInvoice, + ): Promise<{ errCode?: number; errStr?: string; cards: Invoice[] }>; + + export interface ShareFileMetadata { + url: string; + title?: string; + ext?: string; + scene?: WXScene; + } + export function shareFile( + data: ShareFileMetadata, ): Promise<{ errCode?: number; errStr?: string }>; } diff --git a/index.js b/index.js index 1f0dac8..05997bf 100644 --- a/index.js +++ b/index.js @@ -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,8 @@ const nativeShareWebpage = wrapApi(WeChat.shareWebpage); const nativeShareMiniProgram = wrapApi(WeChat.shareMiniProgram); const nativeSubscribeMessage = wrapApi(WeChat.subscribeMessage); +const nativeChooseInvoice = wrapApi(WeChat.chooseInvoice); +const nativeShareFile = wrapApi(WeChat.shareFile); /** * @method sendAuthRequest @@ -167,7 +169,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 +186,54 @@ 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) { + if (Platform.OS === 'android') { + const cardItemList = JSON.parse(resp.cardItemList); + resp.cards = cardItemList.map((item) => ({ + cardId: item.card_id, + encryptCode: item.encrypt_code, + })); + } + resolve(resp); + } else { + reject(new WechatError(resp)); + } + }); + }); +} + +/** + * Share File + * @method shareFile + * @param {Object} data + */ +export function shareFile(data) { + return new Promise((resolve, reject) => { + nativeShareFile(data); + emitter.once('SendMessageToWX.Resp', (resp) => { if (resp.errCode === 0) { resolve(resp); } else { @@ -205,11 +250,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 +271,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 +292,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 +313,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 +334,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 +354,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 +379,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 +408,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 +438,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 { @@ -420,16 +470,16 @@ export function pay(data) { correct('noncestr', 'nonceStr'); correct('partnerid', 'partnerId'); correct('timestamp', 'timeStamp'); - + // 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 +508,3 @@ export class WechatError extends Error { } } } - diff --git a/ios/RCTWeChat.m b/ios/RCTWeChat.m index 88a15c2..e236589 100644 --- a/ios/RCTWeChat.m +++ b/ios/RCTWeChat.m @@ -35,7 +35,7 @@ RCT_EXPORT_MODULE() { NSString * aURLString = [aNotification userInfo][@"url"]; NSURL * aURL = [NSURL URLWithString:aURLString]; - + if ([WXApi handleOpenURL:aURL delegate:self]) { return YES; @@ -67,7 +67,7 @@ RCT_EXPORT_MODULE() CGFloat compression = 1; NSData *data = UIImageJPEGRepresentation(image, compression); if (data.length < maxLength) return data; - + CGFloat max = 1; CGFloat min = 0; for (int i = 0; i < 6; ++i) { @@ -83,7 +83,7 @@ RCT_EXPORT_MODULE() } UIImage *resultImage = [UIImage imageWithData:data]; if (data.length < maxLength) return data; - + // Compress by size NSUInteger lastDataLength = 0; while (data.length > maxLength && data.length != lastDataLength) { @@ -97,7 +97,7 @@ RCT_EXPORT_MODULE() UIGraphicsEndImageContext(); data = UIImageJPEGRepresentation(resultImage, compression); } - + if (data.length > maxLength) { return [self compressImage:resultImage toByte:maxLength]; } @@ -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,53 @@ 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(shareFile:(NSDictionary *)data + :(RCTResponseSenderBlock)callback) +{ + NSString *url = data[@"url"]; + WXFileObject *file = [[WXFileObject alloc] init]; + file.fileExtension = data[@"ext"]; + NSData *fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString: url]]; + file.fileData = fileData; + + WXMediaMessage *message = [WXMediaMessage message]; + message.title = data[@"title"]; + message.mediaObject = file; + + SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; + req.bText = NO; + req.message = message; + req.scene = [data[@"scene"] integerValue]; + 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) @@ -270,7 +317,7 @@ RCT_EXPORT_METHOD(shareImage:(NSDictionary *)data message.mediaObject = imageObject; message.title = data[@"title"]; message.description = data[@"description"]; - + SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; req.bText = NO; req.message = message; @@ -315,7 +362,7 @@ RCT_EXPORT_METHOD(shareLocalImage:(NSDictionary *)data message.mediaObject = imageObject; message.title = data[@"title"]; message.description = data[@"description"]; - + SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; req.bText = NO; req.message = message; @@ -339,7 +386,7 @@ RCT_EXPORT_METHOD(shareMusic:(NSDictionary *)data musicObject.musicLowBandUrl = data[@"musicLowBandUrl"]; musicObject.musicDataUrl = data[@"musicDataUrl"]; musicObject.musicLowBandDataUrl = data[@"musicLowBandDataUrl"]; - + WXMediaMessage *message = [WXMediaMessage message]; message.title = data[@"title"]; message.description = data[@"description"]; @@ -540,7 +587,7 @@ RCT_EXPORT_METHOD(pay:(NSDictionary *)data if([resp isKindOfClass:[SendMessageToWXResp class]]) { SendMessageToWXResp *r = (SendMessageToWXResp *)resp; - + NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; body[@"errStr"] = r.errStr; body[@"lang"] = r.lang; @@ -555,12 +602,12 @@ RCT_EXPORT_METHOD(pay:(NSDictionary *)data body[@"lang"] = r.lang; body[@"country"] =r.country; body[@"type"] = @"SendAuth.Resp"; - + if (resp.errCode == WXSuccess) { if (self.appId && r) { - // ios第一次获取不到appid会卡死,加个判断OK - [body addEntriesFromDictionary:@{@"appid":self.appId, @"code":r.code}]; - [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; + // ios第一次获取不到appid会卡死,加个判断OK + [body addEntriesFromDictionary:@{@"appid":self.appId, @"code":r.code}]; + [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; } } else { @@ -581,6 +628,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,@"appId":cardItem.appID}.mutableCopy; + [arr addObject:item]; + } + body[@"cards"] = arr; + body[@"type"] = @"WXChooseInvoiceResp.Resp"; + [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; } }