@newbeebox/newbeebox-client-web-sdk 1.0.13 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/index.js +70 -111
- package/package.json +1 -1
- package/types/index.d.ts +38 -0
package/README.md
CHANGED
|
@@ -25,6 +25,10 @@ await client.ShowSubscriptionPage();
|
|
|
25
25
|
// 获取当前用户订阅信息
|
|
26
26
|
let info = await client.GetUserSubscription();
|
|
27
27
|
console.log(info);
|
|
28
|
+
|
|
29
|
+
// 获取当前登录用户信息
|
|
30
|
+
let user = await client.GetUserInfo();
|
|
31
|
+
console.log(user);
|
|
28
32
|
```
|
|
29
33
|
|
|
30
34
|
### API
|
|
@@ -45,6 +49,10 @@ console.log(info);
|
|
|
45
49
|
|
|
46
50
|
获取当前用户的订阅信息。
|
|
47
51
|
|
|
52
|
+
#### `GetUserInfo(): Promise<UserAccountInfo>`
|
|
53
|
+
|
|
54
|
+
获取当前登录用户的基础信息。用户未登录时抛出错误。
|
|
55
|
+
|
|
48
56
|
#### `InstallWoWAddon(game_version_id, addon_id, secret_key?): Promise<any>`
|
|
49
57
|
|
|
50
58
|
安装魔兽世界插件。
|
|
@@ -64,6 +72,18 @@ console.log(info);
|
|
|
64
72
|
| tool_name | string | 完整API路径,如 `/tool/some_api` |
|
|
65
73
|
| data | object | 请求数据(可选) |
|
|
66
74
|
|
|
75
|
+
### 错误处理
|
|
76
|
+
|
|
77
|
+
所有接口失败时都会抛出 `Error`,`message` 格式统一为 `<操作>发生错误:<原因>`。
|
|
78
|
+
|
|
79
|
+
如果用户安装的客户端版本过低、没有所调用的接口,`<原因>` 固定为:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
当前客户端不支持该接口,请升级新手盒子客户端
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
所有接口(含 `Patch`)行为一致,第三方应用可据此提示用户升级客户端。
|
|
86
|
+
|
|
67
87
|
---
|
|
68
88
|
|
|
69
89
|
**订阅信息返回结构**:
|
|
@@ -86,3 +106,20 @@ console.log(info);
|
|
|
86
106
|
"sign": "485d82860578ff..." // 签名,用于服务端验证
|
|
87
107
|
}
|
|
88
108
|
```
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
**用户信息返回结构**:
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
{
|
|
115
|
+
"id": 10001, // 用户ID
|
|
116
|
+
"username": "Kyuu", // 用户名
|
|
117
|
+
"avatar": "https://cdn8.newbeebox.com/....",
|
|
118
|
+
"isVip": true, // 是否是 VIP
|
|
119
|
+
"vip": { // 非 VIP 时为 null
|
|
120
|
+
"isYearly": false, // 是否年费会员
|
|
121
|
+
"adFree": true, // 是否免广告
|
|
122
|
+
"endTime": 1790000000000 // 会员到期时间戳
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
package/index.js
CHANGED
|
@@ -105,6 +105,10 @@ function probeFirstPort(ports) {
|
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
// 客户端接口不存在(老版本客户端没有对应路由)时,SDK 统一合成的错误响应
|
|
109
|
+
const CODE_NOT_SUPPORTED = -404;
|
|
110
|
+
const MSG_NOT_SUPPORTED = "当前客户端不支持该接口,请升级新手盒子客户端";
|
|
111
|
+
|
|
108
112
|
export class NewBeeClient {
|
|
109
113
|
app_id = "";
|
|
110
114
|
|
|
@@ -119,6 +123,45 @@ export class NewBeeClient {
|
|
|
119
123
|
}
|
|
120
124
|
}
|
|
121
125
|
|
|
126
|
+
// 统一请求客户端:POST JSON 到 path,自动带上 app_id,返回客户端标准响应 {code, data, message}
|
|
127
|
+
// - 接口不存在(老版本客户端返回 404):返回统一的错误响应 {code: -404, message: MSG_NOT_SUPPORTED}
|
|
128
|
+
// - 网络错误 / 超时 / 响应非 JSON:返回 null
|
|
129
|
+
// 调用方只需判断 code === 1
|
|
130
|
+
async _post(path, data, timeout) {
|
|
131
|
+
this._ensureInitialized();
|
|
132
|
+
|
|
133
|
+
const controller = new AbortController();
|
|
134
|
+
const timeoutId = timeout ? setTimeout(() => controller.abort("请求超时"), timeout) : null;
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
const response = await fetch(CLIENT_SERVICE_BASE_URL + ":" + this.newbee_client_port + path, {
|
|
138
|
+
method: "POST",
|
|
139
|
+
signal: controller.signal,
|
|
140
|
+
headers: {
|
|
141
|
+
"Content-Type": 'application/json',
|
|
142
|
+
},
|
|
143
|
+
body: JSON.stringify({
|
|
144
|
+
app_id: this.app_id,
|
|
145
|
+
...data
|
|
146
|
+
})
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
if (response.status === 404) {
|
|
150
|
+
console.log("客户端不支持该接口:", path);
|
|
151
|
+
return { code: CODE_NOT_SUPPORTED, data: null, message: MSG_NOT_SUPPORTED };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const result = await response.json();
|
|
155
|
+
console.log(path, "响应:", result);
|
|
156
|
+
return result;
|
|
157
|
+
} catch (e) {
|
|
158
|
+
console.log(path, "请求错误:", e);
|
|
159
|
+
return null;
|
|
160
|
+
} finally {
|
|
161
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
122
165
|
async Init(app_id) {
|
|
123
166
|
console.log(`[NewBeeBox SDK] version ${SDK_VERSION}`);
|
|
124
167
|
|
|
@@ -154,44 +197,10 @@ export class NewBeeClient {
|
|
|
154
197
|
|
|
155
198
|
// 打开应用订阅界面
|
|
156
199
|
async ShowSubscriptionPage() {
|
|
157
|
-
this.
|
|
158
|
-
|
|
159
|
-
// 创建 AbortController 实例
|
|
160
|
-
const controller = new AbortController();
|
|
161
|
-
|
|
162
|
-
const signal = controller.signal;
|
|
163
|
-
|
|
164
|
-
const timeoutId = setTimeout(() => {
|
|
165
|
-
controller.abort("请求超时"); // 超时后取消请求
|
|
166
|
-
console.log('打开订单页面超时');
|
|
167
|
-
}, TASK_REQUEST_TIMEOUT);
|
|
168
|
-
|
|
169
|
-
let show_page_response;
|
|
170
|
-
|
|
171
|
-
try {
|
|
172
|
-
// 测试成功就请求客户端授权
|
|
173
|
-
let response = await fetch(CLIENT_SERVICE_BASE_URL + ":" + this.newbee_client_port + "/tool/open_subscription_dialog", {
|
|
174
|
-
method: "POST",
|
|
175
|
-
signal: signal,
|
|
176
|
-
headers: {
|
|
177
|
-
"Content-Type": 'application/json',
|
|
178
|
-
},
|
|
179
|
-
body: JSON.stringify({
|
|
180
|
-
app_id: this.app_id
|
|
181
|
-
})
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
clearTimeout(timeoutId);
|
|
185
|
-
|
|
186
|
-
show_page_response = await response.json();
|
|
187
|
-
|
|
188
|
-
console.log("开启页面结果:", show_page_response);
|
|
189
|
-
} catch (e) {
|
|
190
|
-
console.log("打开订单页面超时", e);
|
|
191
|
-
}
|
|
200
|
+
const res = await this._post("/tool/open_subscription_dialog", null, TASK_REQUEST_TIMEOUT);
|
|
192
201
|
|
|
193
|
-
if (!
|
|
194
|
-
throw new Error("打开订单页面发生错误:" + (
|
|
202
|
+
if (!res || res.code !== 1) {
|
|
203
|
+
throw new Error("打开订单页面发生错误:" + (res?.message || "未知错误"));
|
|
195
204
|
}
|
|
196
205
|
|
|
197
206
|
return true;
|
|
@@ -199,99 +208,49 @@ export class NewBeeClient {
|
|
|
199
208
|
|
|
200
209
|
// 获取当前使用的用户的订阅信息
|
|
201
210
|
async GetUserSubscription() {
|
|
202
|
-
this.
|
|
211
|
+
const res = await this._post("/tool/subscription_status");
|
|
203
212
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
let response = await fetch(CLIENT_SERVICE_BASE_URL + ":" + this.newbee_client_port + "/tool/subscription_status", {
|
|
208
|
-
method: "POST",
|
|
209
|
-
headers: {
|
|
210
|
-
"Content-Type": 'application/json',
|
|
211
|
-
},
|
|
212
|
-
body: JSON.stringify({
|
|
213
|
-
app_id: this.app_id
|
|
214
|
-
})
|
|
215
|
-
});
|
|
213
|
+
if (!res || res.code !== 1 || !res.data) {
|
|
214
|
+
throw new Error("获取用户订阅信息发生错误:" + (res?.message || "未知错误"));
|
|
215
|
+
}
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
return res.data;
|
|
218
|
+
}
|
|
218
219
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
220
|
+
// 获取当前登录用户的基础信息(未登录时抛错)
|
|
221
|
+
async GetUserInfo() {
|
|
222
|
+
const res = await this._post("/user/info");
|
|
223
223
|
|
|
224
|
-
if (!
|
|
225
|
-
throw new Error("
|
|
224
|
+
if (!res || res.code !== 1 || !res.data) {
|
|
225
|
+
throw new Error("获取用户信息发生错误:" + (res?.message || "未知错误"));
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
return
|
|
228
|
+
return res.data;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
// 安装魔兽世界插件
|
|
232
232
|
async InstallWoWAddon(game_version_id, addon_id, secret_key) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
try {
|
|
237
|
-
const body = {
|
|
238
|
-
app_id: this.app_id,
|
|
239
|
-
game_version_id: game_version_id,
|
|
240
|
-
addon_id: addon_id
|
|
241
|
-
};
|
|
242
|
-
if (secret_key) {
|
|
243
|
-
body.secret_key = secret_key;
|
|
244
|
-
}
|
|
245
|
-
let response = await fetch(CLIENT_SERVICE_BASE_URL + ":" + this.newbee_client_port + "/tool/wow_install_addon", {
|
|
246
|
-
method: "POST",
|
|
247
|
-
headers: {
|
|
248
|
-
"Content-Type": 'application/json',
|
|
249
|
-
},
|
|
250
|
-
body: JSON.stringify(body)
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
install_response = await response.json();
|
|
254
|
-
|
|
255
|
-
console.log("安装插件响应:", install_response);
|
|
256
|
-
} catch (e) {
|
|
257
|
-
console.log("安装插件错误:", e);
|
|
233
|
+
const body = { game_version_id, addon_id };
|
|
234
|
+
if (secret_key) {
|
|
235
|
+
body.secret_key = secret_key;
|
|
258
236
|
}
|
|
237
|
+
const res = await this._post("/tool/wow_install_addon", body);
|
|
259
238
|
|
|
260
|
-
if (!
|
|
261
|
-
throw new Error("安装魔兽世界插件发生错误:" + (
|
|
239
|
+
if (!res || res.code !== 1) {
|
|
240
|
+
throw new Error("安装魔兽世界插件发生错误:" + (res?.message || "未知错误"));
|
|
262
241
|
}
|
|
263
242
|
|
|
264
|
-
return
|
|
243
|
+
return res.data;
|
|
265
244
|
}
|
|
266
245
|
|
|
267
246
|
// 通用请求 当没有导出指定接口时可以使用这个函数补充请求
|
|
268
247
|
async Patch(tool_name, data) {
|
|
269
|
-
this.
|
|
248
|
+
const res = await this._post(tool_name, data);
|
|
270
249
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
let response = await fetch(CLIENT_SERVICE_BASE_URL + ":" + this.newbee_client_port + tool_name, {
|
|
274
|
-
method: "POST",
|
|
275
|
-
headers: {
|
|
276
|
-
"Content-Type": 'application/json',
|
|
277
|
-
},
|
|
278
|
-
body: JSON.stringify({
|
|
279
|
-
app_id: this.app_id,
|
|
280
|
-
...data
|
|
281
|
-
})
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
patch_response = await response.json();
|
|
285
|
-
|
|
286
|
-
console.log("Patch响应:", patch_response);
|
|
287
|
-
} catch (e) {
|
|
288
|
-
console.log("Patch请求错误:", e);
|
|
250
|
+
if (!res || res.code !== 1) {
|
|
251
|
+
throw new Error("Patch请求发生错误:" + (res?.message || "未知错误"));
|
|
289
252
|
}
|
|
290
253
|
|
|
291
|
-
|
|
292
|
-
throw new Error("Patch请求发生错误:" + (patch_response?.message || "未知错误"));
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return patch_response.data;
|
|
254
|
+
return res.data;
|
|
296
255
|
}
|
|
297
|
-
}
|
|
256
|
+
}
|
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -34,6 +34,14 @@ export class NewBeeClient {
|
|
|
34
34
|
*/
|
|
35
35
|
GetUserSubscription(): Promise<UserSubscribeInfo>;
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* 获取当前登录用户信息
|
|
39
|
+
* @constructor GetUserInfo
|
|
40
|
+
* @return {Promise<UserAccountInfo>}
|
|
41
|
+
* @throws 未登录、客户端版本过低时抛出错误
|
|
42
|
+
*/
|
|
43
|
+
GetUserInfo(): Promise<UserAccountInfo>;
|
|
44
|
+
|
|
37
45
|
/**
|
|
38
46
|
* 安装魔兽世界插件
|
|
39
47
|
* @param game_version_id 游戏版本ID
|
|
@@ -82,6 +90,36 @@ export interface UserInfo {
|
|
|
82
90
|
avatar:string;
|
|
83
91
|
}
|
|
84
92
|
|
|
93
|
+
/**
|
|
94
|
+
* @interface UserVipInfo
|
|
95
|
+
* @description 用户 VIP 信息
|
|
96
|
+
* @property {boolean} isYearly - 是否年费会员
|
|
97
|
+
* @property {boolean} adFree - 是否免广告
|
|
98
|
+
* @property {number | null} endTime - 会员到期时间戳
|
|
99
|
+
*/
|
|
100
|
+
export interface UserVipInfo {
|
|
101
|
+
isYearly: boolean;
|
|
102
|
+
adFree: boolean;
|
|
103
|
+
endTime: number | null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @interface UserAccountInfo
|
|
108
|
+
* @description 当前登录用户信息(GetUserInfo 返回)
|
|
109
|
+
* @property {number | null} id - 用户ID
|
|
110
|
+
* @property {string} username - 用户名
|
|
111
|
+
* @property {string} avatar - 用户头像
|
|
112
|
+
* @property {boolean} isVip - 是否是 VIP
|
|
113
|
+
* @property {UserVipInfo | null} vip - VIP 信息,非 VIP 时为 null
|
|
114
|
+
*/
|
|
115
|
+
export interface UserAccountInfo {
|
|
116
|
+
id: number | null;
|
|
117
|
+
username: string;
|
|
118
|
+
avatar: string;
|
|
119
|
+
isVip: boolean;
|
|
120
|
+
vip: UserVipInfo | null;
|
|
121
|
+
}
|
|
122
|
+
|
|
85
123
|
/**
|
|
86
124
|
* @interface UserSubscribeInfo
|
|
87
125
|
* @description 用户订阅信息
|