@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 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._ensureInitialized();
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 (!show_page_response || show_page_response?.code !== 1) {
194
- throw new Error("打开订单页面发生错误:" + (show_page_response?.message || "未知错误"));
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._ensureInitialized();
211
+ const res = await this._post("/tool/subscription_status");
203
212
 
204
- let user_subscribe_response = null;
205
- try {
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
- user_subscribe_response = await response.json();
217
+ return res.data;
218
+ }
218
219
 
219
- console.log("用户订阅信息响应:", user_subscribe_response);
220
- } catch (e) {
221
- console.log("获取用户订阅错误:", e);
222
- }
220
+ // 获取当前登录用户的基础信息(未登录时抛错)
221
+ async GetUserInfo() {
222
+ const res = await this._post("/user/info");
223
223
 
224
- if (!user_subscribe_response || user_subscribe_response?.code !== 1 || !user_subscribe_response?.data) {
225
- throw new Error("获取用户订阅信息发生错误:" + (user_subscribe_response?.message || "未知错误"));
224
+ if (!res || res.code !== 1 || !res.data) {
225
+ throw new Error("获取用户信息发生错误:" + (res?.message || "未知错误"));
226
226
  }
227
227
 
228
- return user_subscribe_response.data
228
+ return res.data;
229
229
  }
230
230
 
231
231
  // 安装魔兽世界插件
232
232
  async InstallWoWAddon(game_version_id, addon_id, secret_key) {
233
- this._ensureInitialized();
234
-
235
- let install_response = null;
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 (!install_response || install_response?.code !== 1) {
261
- throw new Error("安装魔兽世界插件发生错误:" + (install_response?.message || "未知错误"));
239
+ if (!res || res.code !== 1) {
240
+ throw new Error("安装魔兽世界插件发生错误:" + (res?.message || "未知错误"));
262
241
  }
263
242
 
264
- return install_response.data;
243
+ return res.data;
265
244
  }
266
245
 
267
246
  // 通用请求 当没有导出指定接口时可以使用这个函数补充请求
268
247
  async Patch(tool_name, data) {
269
- this._ensureInitialized();
248
+ const res = await this._post(tool_name, data);
270
249
 
271
- let patch_response = null;
272
- try {
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
- if (!patch_response || patch_response?.code !== 1) {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newbeebox/newbeebox-client-web-sdk",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "NewBeeBox Client SDK for Web",
5
5
  "main": "index.js",
6
6
  "type": "module",
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 用户订阅信息