cocos2dx3.15接入微信SDK实现登录和分享android studio2.3.3

cocos2dx3.15接入微信SDK实现登录和分享android studio2.3.3,首先开始呢,我必须得吐槽一下网上的教程以及微信开放平台官网,网上的教程主要是太老了代码虽然都能用但是不完整有的东西已经改了,官网就不用说了,文档垃圾,是很垃圾。参考作用几乎等于没有,唯一作用就是查看返回值以及一些参数有什么用。嗯对的。没话说。

现在开始教程:

第一步:

?
1
2
3
准备好你的APP_ID这个东西不解释了。如果不知道请先去[微信开放平台](https: //open.weixin.qq.com/) 查看一下注册你的应用程序。然后登录功能是收费的,分享是免费的
  下面是注册应用程序的步骤:
      打开微信开放平台官网:

第一步

点击创建应用,按照提示输入好之后点击下一步。:
第二步

填写完了之后就提交审核,一般的话审核可能1-3天就好了
第三步

以安卓为例子,签名和包名必须要和你要接入的cocos项目的包名和签名一致,对于签名的获取请看下图:
第四步

打开 Android资源下载之后在右边下滑找到:
第四步

下载安装到手机上,我这里用的模拟器,然后把你们要接入的cocos项目也打包好安装的手机上之后打开之前安装的签名生成工具:
第五步

打开工具之后输入你的包名:
第六步
这个就是签名的获取

应用注册审核通过之后开始下一步

第二步:
将你的cocos项目导入到android studio2.3.3,其他环境参照相应的教程导入项目,但是推荐用android studio方便,导入方法如下:
第一步
第二步
第四步

项目导入之后配置一下微信SDK的环境只需要一句话就可以了,但是前提是你电脑能够联网下载微信SDK:
第五步

?
1
把这一句话加上就行了: 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'

接下来就可以开始写代码了,首先是Java端的代码,代码比较简单,我也不是很了解Java所以我就不逐行解释了,基本上直接复制就可以使用了。

首先打开这个文件:
第一步

下面是java端的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package org.cocos2dx.cpp;
 
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
 
import com.qt.NiuBuTing.R;
import com.qt.NiuBuTing.wxapi.WXEntryActivity;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
 
import org.cocos2dx.lib.Cocos2dxActivity;
 
import java.io.ByteArrayOutputStream;
 
public class AppActivity extends Cocos2dxActivity {
     public static final String TAG = "NiuBuTing_Weixin_SDK" ;
     public static final String APP_ID = "这里填写你的Appid" ;
     public static IWXAPI api;
     private static AppActivity instance = null ;
 
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         instance = this ;
         // 注册到微信
         regToWx();
     }
 
     //注册到微信
     private void regToWx() {
         //工厂模式创建微信api
         api = WXAPIFactory.createWXAPI( this , APP_ID, false );
 
         //注册程序
         api.registerApp(APP_ID);
     }
 
     //启动微信
     private static boolean LaunchWX() {
         boolean ret = false ;
         if (!api.isWXAppInstalled())
         { //判断是否安装微信
             Toast.makeText(instance, "没有安装微信,请先安装微信!" , Toast.LENGTH_LONG).show();
             return ret;
         }
         if (api.openWXApp())
         { //判断打开微信是否成功
             Log.d(TAG, "微信打开成功!" );
             ret = true ;
         }
         else
         {
             Log.d(TAG, "微信打开失败!" );
             ret = false ;
         }
 
         return ret;
     }
 
     //将图片解析成一个二进制数组
     private byte [] bmpToByteArrar( final Bitmap bitmap, final boolean isRecycle){
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         bitmap.compress(Bitmap.CompressFormat.PNG, 100 , outputStream);
         if (isRecycle)
         {
             bitmap.recycle();
         }
 
         byte [] result = outputStream.toByteArray();
 
         try
         {
             outputStream.close();
         }
         catch (Exception e)
         {
             e.printStackTrace();
         }
         return result;
     }
 
     //微信登录
     public static void WXLogin(){
         Log.d(TAG, "login-------------" );
         WXEntryActivity.ReqState = 0 ;
         final SendAuth.Req req = new SendAuth.Req();
         req.scope = "snsapi_userinfo" //这里不能改
         req.state = "QTNiuBuTing" //这里改成你自己的数据
         api.sendReq(req);
     }
 
     //分享到聊天窗口
     public static void WXShareMsgToFriends( final String userNickName,
                                            final String roomNum,
                                            final String inningsNum,
                                            final String peopleNum,
                                            final int playType){
         //这里的参数是看你自己你需要的话就行,但是在cocos里面调用这个方法的你也传递数值过来
 
         String strPlayType = "轮庄牛牛" ;
 
         if (playType == 1 )   //2为轮庄
         {
             strPlayType = "抢庄牛牛" ;
         }
 
         WXEntryActivity.ReqState = 1 ;
 
         //封装一个链接,点击跳转到指定网址
         WXWebpageObject webpag = new WXWebpageObject();
         webpag.webpageUrl = "https://www.0791youxi.com/" ;
 
         //封装游戏图标
         Bitmap bitmap = BitmapFactory.decodeResource(instance.getResources(), R.mipmap.icon);
         Bitmap thumb = Bitmap.createScaledBitmap(bitmap, 108 , 108 , true );
         bitmap.recycle();
 
         //封装分享内容
         WXMediaMessage msg = new WXMediaMessage(webpag);
         msg.thumbData = instance.bmpToByteArrar(thumb, true );
         msg.title = "我是 " + userNickName;  //这个是标题
         msg.description = "[" + strPlayType + "]"  //这个是描述
                 + " 房间号:" + roomNum + "。"
                 + " 局数:" + inningsNum + "。"
                 + " 人数:" + peopleNum + "人。"
                 + "约么? 我在QT牛不停创建了房间,一起来玩一玩吧!" ;
 
         //封装请求
         SendMessageToWX.Req req = new SendMessageToWX.Req();
         req.transaction = buildTransaction( "webpag" );
         req.message = msg;
         req.scene = SendMessageToWX.Req.WXSceneSession;
 
         //发送请求
         api.sendReq(req);
     }
 
     //生成一个微信唯一请求标识符
     private static String buildTransaction( final String type) {
         return (type == null ) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
     }
}

微信登录请求和分享请求发送后还需要创建一个类提供给微信SDK回调,现在你需要新建一个包,包名必须为wxapi,而且这个包必须要在cocos包名的目录下,比如你包名是com.csn.cocosNew 那么新建的这包就是com.csn.cocosNew.wxapi,然后在这个包下面新建一个WXEntryActivity类,类名也是必须这样,没办法微信的要求,下面是创建的方法:
首先是创建包:
第一步
第二步
包名输你自己的别输我演示的这个,然后点击OK

接下来是创建类:
第三步
类创建的时候在你刚才新建的包名目录下右键单击就可以了

记得类名必须是WXEntryActivity!!! 其他的默认就行了

全部创建好之后文件结构是这样的:
结果

然后双击打开,开始写回调:

下面是WXEntryActivity类里面的完整代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package 你的项目包名.wxapi;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
 
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
 
import org.cocos2dx.cpp.AppActivity;
import org.cocos2dx.cpp.tools.JniHelper;
 
/**
  * Created by Administrator on 2017/6/5.
  */
 
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
     private final String TAG = "NiuBuTing_Weixin_SDK" ;
     public static int ReqState = - 1 //0为登录, 1为分享
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
 
         AppActivity.api.handleIntent( this .getIntent(), this );
         //如果没回调onResp,八成是这句没有写
     }
 
     @Override
     protected void onNewIntent(Intent intent) {
         super .onNewIntent(intent);
 
         setIntent(intent);
         AppActivity.api.handleIntent(intent, this );
     }
 
     // 微信发送请求到第三方应用时,会回调到该方法
     @Override
     public void onReq(BaseReq req) {
         finish();
     }
 
     @Override
     public void onResp(BaseResp resp) {
         Log.d(TAG, "onResp:" );
         switch (resp.errCode) {
             case BaseResp.ErrCode.ERR_OK:
                 Log.d(TAG, "请求成功" );
                 if (ReqState == 0 //这个是自己加用于判断是登录还是分享,你们可以去掉判断只要里面的代码就行了
                 {
                     SendAuth.Resp sendResp = (SendAuth.Resp) resp;
                     JniHelper.onResp(sendResp.code); //这个登录了之后用于回调cocos端函数的映射代码
                     Log.d(TAG, sendResp.code);
                 }
                 break ;
             case BaseResp.ErrCode.ERR_USER_CANCEL:
                 //发送取消
                 Toast.makeText( this , "请求取消" , Toast.LENGTH_LONG).show();
                 break ;
             case BaseResp.ErrCode.ERR_AUTH_DENIED:
                 //发送被拒绝
                 Toast.makeText( this , "请求被拒绝" , Toast.LENGTH_LONG).show();
                 break ;
             default :
                 //发送返回
                 Toast.makeText( this , "请求返回" , Toast.LENGTH_LONG).show();
                 break ;
         }
         ReqState = - 1 ;
         finish();
     }
}

这里是JniHelper这个类里面的代码。这里面你们要自己创建一个,创建在那个包下面都无所谓:
我是创建在这儿:
JniHelper

下面是代码

?
1
2
3
4
5
6
7
8
9
package org.cocos2dx.cpp.tools;
 
/**
  * Created by Administrator on 2017/6/5.
  */
 
public class JniHelper {
     public static native void onResp(String code);
}

做完这些之后还需要添加相应的权限,在AndroidMainfest.xml文件里面添加,下面附上我的文件,你们根据要求自己更改:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!--?xml version= "1.0" encoding= "utf-8" ?-->
<manifest android:installlocation= "auto" package = "com.qt.NiuBuTing" xmlns:android= "https://schemas.android.com/apk/res/android" >
 
     <uses-feature android:glesversion= "0x00020000" >
      <!--这些是微信必须的权限 -->
     <uses-permission android:name= "android.permission.INTERNET" >
     <uses-permission android:name= "android.permission.ACCESS_NETWORK_STATE" >
     <uses-permission android:name= "android.permission.ACCESS_WIFI_STATE" >
     <uses-permission android:name= "android.permission.READ_PHONE_STATE" >
     <uses-permission android:name= "android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
     <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" >
 
     
 
         <!-- Tell Cocos2dxActivity the name of our .so -->
         <meta-data android:name= "android.app.lib_name" android:value= "MyGame" >
 
         
             <intent-filter>
                 
 
                 <category android:name= "android.intent.category.LAUNCHER" >
             </category></action></intent-filter>
         </activity>
 
         <!--注册微信回调 WXEntryActivity -->
         
 
     </activity></meta-data></application><meta-data android:name= "android.app.lib_name" android:value= "MyGame" ><meta-data android:name= "android.app.lib_name" android:value= "MyGame" >
 
</meta-data></meta-data></uses-permission></uses-permission></uses-permission></uses-permission></uses-permission></uses-permission></uses-feature></manifest>

以上步骤完成了之后就可以还可以在cocos里面使用了。

下面开始说cocos里面的使用,我的使用方法是新建一个类专门用访问微信的是一个单例:
下面附上完整代码,首先是.h文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#ifndef __WXAPIMANAGER_H__
#define __WXAPIMANAGER_H__
 
#include "cocos2d.h"
#include "network/HttpClient.h"
 
USING_NS_CC;
using namespace network;
 
typedef std::function< void (std::string> LastCallBack;
 
# if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)  //判断是不是安卓环境
#include "platform/android/jni/JniHelper.h"
#endif
 
typedef enum {
     REQ_ERROR = 0 ,
     REQ_SUCCESS,
     CMD_ACCESS_TOKEN,
     CMD_USER_INFO,
     DEFAULT
}reqTag;
 
class WXAPIManager : Ref
{
public :
     static WXAPIManager *getInstance();
 
     //分享到好友
     void sendToFriend( const char *userNickName, const char *roomNum, const char *inningsNum, const char *peopleNum, const int playType);
 
     //微信登录
     void loginWX();
 
public :
     static WXAPIManager *_instance;
 
     //http请求
     void WX_RequestHttp( const char *url, const std::string &data);
 
     //请求的回调
     void onResponse(HttpClient *client, HttpResponse *response);
 
     //最终回调
     void onTheEndResponse(std::string &data);
 
private :
     WXAPIManager();
     ~WXAPIManager();
 
     reqTag lastTag;
};
#endif // __WXAPIMANAGER_H__</void(std::string>

接下来是.cpp的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include "WXAPIManager.h"
 
WXAPIManager *WXAPIManager::_instance = nullptr;
 
WXAPIManager::WXAPIManager()
:lastTag(reqTag::CMD_ACCESS_TOKEN)
{
}
 
WXAPIManager::~WXAPIManager()
{
}
 
WXAPIManager *WXAPIManager::getInstance()
{
     if (_instance == nullptr)
     {
         _instance = new (std::nothrow) WXAPIManager();
         _instance->autorelease();
         _instance->retain();
     }
 
     return _instance;
}
 
//分享给好友
void WXAPIManager::sendToFriend( const char *userNickName, const char *roomNum, const char *inningsNum, const char *peopleNum, const int playType)
{
# if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断是不是Android环境
     JniMethodInfo minfo;
 
         //调用java端的静态函数
         bool isHave = JniHelper::getStaticMethodInfo(minfo,
             "org/cocos2dx/cpp/AppActivity" , //这个是固定的
             "WXShareMsgToFriends" ,   //这个是你要调用的java端的函数名
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V" );
             //后面跟的是java那边需要接收的参数
 
     if (!isHave) {
         log( "jni:WXShareImgToFriends is null" );
     }
     else {
         //这里需要把参数转换为java格式
         jstring jUserNickName = minfo.env->NewStringUTF(userNickName);
         jstring jRoomNum = minfo.env->NewStringUTF(roomNum);
         jstring jInnings = minfo.env->NewStringUTF(inningsNum);
         jstring jpeopleNum = minfo.env->NewStringUTF(peopleNum);
         jint jPlayType = playType;
 
         minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID, jUserNickName, jRoomNum, jInnings, jpeopleNum, jPlayType);  //开始调用函数
 
         //删除参数
         minfo.env->DeleteLocalRef(jUserNickName);
         minfo.env->DeleteLocalRef(jRoomNum);
         minfo.env->DeleteLocalRef(jInnings);
         minfo.env->DeleteLocalRef(jpeopleNum);
     }
#endif
}
 
//微信登录
void WXAPIManager::loginWX()
{
# if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
     JniMethodInfo minfo;
 
     bool isHave = JniHelper::getStaticMethodInfo(minfo,
         "org/cocos2dx/cpp/AppActivity" ,
         "WXLogin" ,
         "()V" );  //没有参数
 
     if (!isHave) {
         log( "jni:WXLogin is null" );
     }
     else
     {
         minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
     }  
#endif
}
 
//http请求
void WXAPIManager::WX_RequestHttp( const char *url, const std::string &data)
{
     log( "WXAPIManager----------------WX_RequestHttp:" );
     HttpRequest* request = new HttpRequest();
     //设置请求类型 
     request->setRequestType(HttpRequest::Type::GET);
     request->setUrl(url);
     //设置回调函数 
     request->setResponseCallback(CC_CALLBACK_2(WXAPIManager::onResponse, this ));
     request->setRequestData(data.c_str(), data.size());
 
     HttpClient* httpClient = HttpClient::getInstance();
     void onResponse(HttpClient *client, HttpResponse *response);
     //设置超时时间
     httpClient->setTimeoutForConnect( 10 );
     httpClient->setTimeoutForRead( 10 );
     httpClient->send(request);
     request->release();
}
 
//请求回调
void WXAPIManager::onResponse(HttpClient *client, HttpResponse *response)
{
     log( "WXAPIManager----------------onResponse:" );
     if (!response) {
         CCLOG( "Log:response =null,plase check it." );
         return ;
     }
 
     //请求失败 
     if (!response->isSucceed())
     {
         CCLOG( "ERROR BUFFER:%s" , response->getErrorBuffer());
         return ;
     }
 
     int codeIndex = response->getResponseCode();
     const char * tag = response->getHttpRequest()->getTag();
 
     //请求成功 
     std::vector< char >* buffer = response->getResponseData();
     std::string temp(buffer->begin(), buffer->end());
     log( "temp OpenID = %s" , temp.c_str());
 
     if (lastTag == reqTag::CMD_ACCESS_TOKEN)
     {
         //拿到access_token之后还需要继续请求,最终才能拿到用户信息,这点官网上有解释
         LastCallBack callback = CC_CALLBACK_1(WXAPIManager::onTheEndResponse, this );
         callback(temp);
     }
     else if (lastTag == reqTag::CMD_USER_INFO)
     {
         //这里代表拿到用户信息,你就可以开始做你自己的处理了
     }
}
 
//最终回调
void WXAPIManager::onTheEndResponse(std::string &data)
{
     log( "data = %s" , data.c_str());
     if (data == "" )
     {
         return ;
     }
 
 
     const char *WX_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=" ;
     const char *WX_USER_OPEN_ID = "&openid=" ;
 
     char url[ 512 ];
     strcpy(url, WX_USER_INFO_URL);
     strcat(url, access_token);  //上一步拿到的access_token
     strcat(url, WX_USER_OPEN_ID);
     strcat(url, openid);  //上一步拿到的openid
 
     CCLOG( "%s" , url);
     lastTag = reqTag::CMD_USER_INFO;
 
     //继续请求用户信息
     WXAPIManager::WX_RequestHttp(url, "" );
}
 
# if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
//必须是C语言的函数,因为C++的函数会有不同的符号生成规则 
//1.Java_:是格式,必须加的 
//2.org_cocos2dx_cpp_tools_JniHelper:是包名+类名 
//3.onResp:是Andriod工程中声明的名字 
//4.中间需要_分开 
extern "C" {
 
     //给android调用的native代码,微信回调后会调用这个函数
     //这个代码是给安卓调用,那边传了一个code过来直接转换之后使用就行了
     /*
         微信的登录的流程:
             1、拉起微信登录界面,用户确认之后就回调java端的回调。
             2、Java端的回调执行之后根据代码在调用这个函数。
             3、接下来的步骤有cocos基础的基本都知道怎么执行了
             所以在cocos端首先执行的就是这里的代码。
     */
     JNIEXPORT void Java_org_cocos2dx_cpp_tools_JniHelper_onResp(JNIEnv *env, jobject thiz, jstring code)
     {
         const char *szCode = env->GetStringUTFChars(code, NULL);
 
         const char *WX_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" ;
         const char *WX_APP_ID = "这里是你的APPID" ;
         const char *WX_SECRET = "&secret=官网查询你的AppSecret" //没有获取过的就点旁边的生成就可以了
         const char *WX_CODE = "&code=" ;
         const char *WX_GRANT_TYPE = "&grant_type=authorization_code" ;
 
         char url[ 512 ];
         strcpy(url, WX_ACCESS_TOKEN_URL);
         strcat(url, WX_APP_ID);
         strcat(url, WX_SECRET);
         strcat(url, WX_CODE);
         strcat(url, szCode);
         strcat(url, WX_GRANT_TYPE);
 
         CCLOG( "JniHelper_onResp url = %s" , url);
         CCLOG( "szCode = %s" , szCode);
         WXAPIManager *_twm = WXAPIManager::getInstance();
         _twm->WX_RequestHttp(url, "" );
 
         env->ReleaseStringUTFChars(code, szCode);
     }
}
#endif</ char >

代码完成之后,自己修改好就可以开始调试了。不要被我的代码影响,只是给你一个参考和告诉你执行流程而已。cocos端的知道流程之后更多的就看你自己的基础了。

还有两点有的人可能看了别人教程之后才看到我的,用的也是别人的代码,有部分代码是有BUG的,比如你发现分享之后选择回到自己的游戏的时候,回不去被卡在那儿了。这种情况主要是你在 ”分享“的这个函数的最后加入一个finish();函数。遇到这个问题的可以把这个函数删了再试试。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值