qqmusic-api-enhanced 1.0.1 → 1.0.2

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/main.js CHANGED
@@ -13,7 +13,7 @@ import song_detail_fn from "./module/song_detail.js";
13
13
  import song_url_fn from "./module/song_url.js";
14
14
  import user_detail_fn from "./module/user_detail.js";
15
15
  import user_playlist_fn from "./module/user_playlist.js";
16
- import user_vip_info_fn, { deriveVipInfo, } from "./module/user_vip_info.js";
16
+ import user_vip_info_fn, { deriveVipInfo, parseVipFromIcons, } from "./module/user_vip_info.js";
17
17
  import { cookieToJson, cookieToString, parseSetCookie } from "./util/cookie.js";
18
18
  import { getGtk, getGuid, getSearchId, hash33, qrcDecrypt } from "./util/crypto.js";
19
19
  import { request, requestCgi, requestRaw } from "./util/request.js";
@@ -34,7 +34,7 @@ export const song_url = (query = {}) => song_url_fn(query, request);
34
34
  export const user_detail = (query = {}) => user_detail_fn(query, request);
35
35
  export const user_playlist = (query = {}) => user_playlist_fn(query, request);
36
36
  export const user_vip_info = (query = {}) => user_vip_info_fn(query, request);
37
- export { request, requestCgi, requestRaw, zzcSign, qrcDecrypt, hash33, getGtk, getGuid, getSearchId, cookieToJson, cookieToString, parseSetCookie, deriveVipInfo, };
37
+ export { request, requestCgi, requestRaw, zzcSign, qrcDecrypt, hash33, getGtk, getGuid, getSearchId, cookieToJson, cookieToString, parseSetCookie, deriveVipInfo, parseVipFromIcons, };
38
38
  const api = {
39
39
  artist_detail,
40
40
  artist_songs,
@@ -53,6 +53,7 @@ const api = {
53
53
  user_playlist,
54
54
  user_vip_info,
55
55
  deriveVipInfo,
56
+ parseVipFromIcons,
56
57
  request,
57
58
  requestCgi,
58
59
  requestRaw,
package/main.ts CHANGED
@@ -18,6 +18,7 @@ import user_detail_fn from "./module/user_detail.js";
18
18
  import user_playlist_fn from "./module/user_playlist.js";
19
19
  import user_vip_info_fn, {
20
20
  deriveVipInfo,
21
+ parseVipFromIcons,
21
22
  type NormalizedVipInfo,
22
23
  } from "./module/user_vip_info.js";
23
24
 
@@ -88,6 +89,7 @@ export {
88
89
  cookieToString,
89
90
  parseSetCookie,
90
91
  deriveVipInfo,
92
+ parseVipFromIcons,
91
93
  type ApiResponse,
92
94
  type NormalizedVipInfo,
93
95
  type NormalizedLoginAccount,
@@ -112,6 +114,7 @@ const api = {
112
114
  user_playlist,
113
115
  user_vip_info,
114
116
  deriveVipInfo,
117
+ parseVipFromIcons,
115
118
  request,
116
119
  requestCgi,
117
120
  requestRaw,
@@ -1,6 +1,7 @@
1
1
  import { request, requestCgi } from "../util/request.js";
2
2
  import { getGtk, getGuid } from "../util/crypto.js";
3
3
  import { cookieToString, parseSetCookie } from "../util/cookie.js";
4
+ import { getMobileSession, registerMobileSession } from "../util/mobile_qr_session.js";
4
5
  /**
5
6
  * 轮询检查二维码登录状态.
6
7
  *
@@ -147,65 +148,104 @@ export default async function login_qr_check(query = {}, req = request) {
147
148
  body: { code: 400, message: "缺少必要参数 qrcodeID" },
148
149
  };
149
150
  }
150
- const cgiRes = await requestCgi("music.login.LoginServer", "CheckQRCode", {
151
- qrcodeID,
152
- tmeAppID: "qqmusic",
153
- }, {
154
- platform: "android",
155
- });
156
- const cgiBody = (cgiRes.body || {});
157
- const code = cgiBody.code;
158
- if (code === 40000) {
151
+ // 1. 确保后台 MQTT 会话已启动
152
+ let session = getMobileSession(qrcodeID);
153
+ if (!session) {
154
+ try {
155
+ registerMobileSession(qrcodeID);
156
+ }
157
+ catch { }
158
+ session = getMobileSession(qrcodeID);
159
+ }
160
+ // 2. 优先检查实时会话事件
161
+ if (session && session.code === 200) {
159
162
  return {
160
163
  status: 200,
161
- body: { code: 801, message: "等待 QQ 音乐 App 扫码" },
164
+ body: {
165
+ code: 200,
166
+ message: "登录成功",
167
+ uin: session.uin || "",
168
+ musickey: session.musickey || "",
169
+ nickname: session.nickname || "",
170
+ avatarUrl: session.avatarUrl || "",
171
+ cookieStr: session.cookieStr || "",
172
+ },
162
173
  };
163
174
  }
164
- if (code === 40001) {
175
+ if (session && session.code === 802) {
165
176
  return {
166
177
  status: 200,
167
- body: { code: 802, message: "已扫码,等待确认" },
178
+ body: { code: 802, message: session.message || "已扫码,等待确认" },
168
179
  };
169
180
  }
170
- if (code === 40002) {
181
+ if (session && session.code === 800) {
171
182
  return {
172
183
  status: 200,
173
- body: { code: 800, message: "二维码已过期,请刷新" },
184
+ body: { code: 800, message: session.message || "二维码已过期,请刷新" },
174
185
  };
175
186
  }
176
- if (code === 0) {
177
- const cookies = cgiRes.cookie || [];
178
- const cookieObj = parseSetCookie(cookies);
179
- if (cgiBody.musicid && !cookieObj.uin)
180
- cookieObj.uin = String(cgiBody.musicid);
181
- if (cgiBody.musickey && !cookieObj.qm_keyst)
182
- cookieObj.qm_keyst = String(cgiBody.musickey);
183
- if (cgiBody.musickey && !cookieObj.qqmusic_key)
184
- cookieObj.qqmusic_key = String(cgiBody.musickey);
185
- if (cgiBody.openid && !cookieObj.openid)
186
- cookieObj.openid = String(cgiBody.openid);
187
- if (cgiBody.refresh_token && !cookieObj.refresh_token)
188
- cookieObj.refresh_token = String(cgiBody.refresh_token);
189
- const cookieStr = cookieToString(cookieObj);
187
+ if (session && session.code === 803) {
190
188
  return {
191
189
  status: 200,
192
- body: {
193
- code: 200,
194
- message: "登录成功",
195
- uin: cookieObj.uin || String(cgiBody.musicid || ""),
196
- musickey: cookieObj.qm_keyst || String(cgiBody.musickey || ""),
197
- cookieStr,
198
- data: cgiBody,
199
- },
200
- cookie: cookies,
190
+ body: { code: 803, message: session.message || "用户取消授权" },
201
191
  };
202
192
  }
193
+ // 3. 兜底轮询 CheckQRCode CGI 状态
194
+ try {
195
+ const cgiRes = await req("music.login.LoginServer", "CheckQRCode", {
196
+ qrcodeID,
197
+ tmeAppID: "qqmusic",
198
+ }, {
199
+ platform: "android",
200
+ });
201
+ const cgiBody = (cgiRes.body || {});
202
+ const code = cgiBody.code !== undefined ? cgiBody.code : cgiBody.ret;
203
+ if (code === 40001) {
204
+ return {
205
+ status: 200,
206
+ body: { code: 802, message: "已扫码,等待确认" },
207
+ };
208
+ }
209
+ if (code === 40002) {
210
+ return {
211
+ status: 200,
212
+ body: { code: 800, message: "二维码已过期,请刷新" },
213
+ };
214
+ }
215
+ if (code === 0) {
216
+ const cookies = cgiRes.cookie || [];
217
+ const cookieObj = parseSetCookie(cookies);
218
+ if (cgiBody.musicid && !cookieObj.uin)
219
+ cookieObj.uin = String(cgiBody.musicid);
220
+ if (cgiBody.musickey && !cookieObj.qm_keyst)
221
+ cookieObj.qm_keyst = String(cgiBody.musickey);
222
+ if (cgiBody.musickey && !cookieObj.qqmusic_key)
223
+ cookieObj.qqmusic_key = String(cgiBody.musickey);
224
+ if (cgiBody.openid && !cookieObj.openid)
225
+ cookieObj.openid = String(cgiBody.openid);
226
+ if (cgiBody.refresh_token && !cookieObj.refresh_token)
227
+ cookieObj.refresh_token = String(cgiBody.refresh_token);
228
+ const cookieStr = cookieToString(cookieObj);
229
+ return {
230
+ status: 200,
231
+ body: {
232
+ code: 200,
233
+ message: "登录成功",
234
+ uin: cookieObj.uin || String(cgiBody.musicid || ""),
235
+ musickey: cookieObj.qm_keyst || String(cgiBody.musickey || ""),
236
+ cookieStr,
237
+ data: cgiBody,
238
+ },
239
+ cookie: cookies,
240
+ };
241
+ }
242
+ }
243
+ catch { }
203
244
  return {
204
245
  status: 200,
205
246
  body: {
206
- code: 801,
207
- message: cgiBody.msg || "等待扫码",
208
- data: cgiBody,
247
+ code: session?.code || 801,
248
+ message: session?.message || "等待 QQ 音乐 App 扫码",
209
249
  },
210
250
  };
211
251
  }
@@ -1,6 +1,7 @@
1
1
  import { request, requestCgi, type ApiResponse } from "../util/request.js";
2
2
  import { getGtk, getGuid } from "../util/crypto.js";
3
3
  import { cookieToString, parseSetCookie } from "../util/cookie.js";
4
+ import { getMobileSession, registerMobileSession } from "../util/mobile_qr_session.js";
4
5
 
5
6
  /**
6
7
  * 轮询检查二维码登录状态.
@@ -191,69 +192,111 @@ export default async function login_qr_check(
191
192
  };
192
193
  }
193
194
 
194
- const cgiRes = await requestCgi(
195
- "music.login.LoginServer",
196
- "CheckQRCode",
197
- {
198
- qrcodeID,
199
- tmeAppID: "qqmusic",
200
- },
201
- {
202
- platform: "android",
203
- }
204
- );
205
-
206
- const cgiBody = (cgiRes.body || {}) as any;
207
- const code = cgiBody.code;
195
+ // 1. 确保后台 MQTT 会话已启动
196
+ let session = getMobileSession(qrcodeID);
197
+ if (!session) {
198
+ try {
199
+ registerMobileSession(qrcodeID);
200
+ } catch {}
201
+ session = getMobileSession(qrcodeID);
202
+ }
208
203
 
209
- if (code === 40000) {
204
+ // 2. 优先检查实时会话事件
205
+ if (session && session.code === 200) {
210
206
  return {
211
207
  status: 200,
212
- body: { code: 801, message: "等待 QQ 音乐 App 扫码" },
208
+ body: {
209
+ code: 200,
210
+ message: "登录成功",
211
+ uin: session.uin || "",
212
+ musickey: session.musickey || "",
213
+ nickname: session.nickname || "",
214
+ avatarUrl: session.avatarUrl || "",
215
+ cookieStr: session.cookieStr || "",
216
+ },
213
217
  };
214
218
  }
215
- if (code === 40001) {
219
+
220
+ if (session && session.code === 802) {
216
221
  return {
217
222
  status: 200,
218
- body: { code: 802, message: "已扫码,等待确认" },
223
+ body: { code: 802, message: session.message || "已扫码,等待确认" },
219
224
  };
220
225
  }
221
- if (code === 40002) {
226
+
227
+ if (session && session.code === 800) {
222
228
  return {
223
229
  status: 200,
224
- body: { code: 800, message: "二维码已过期,请刷新" },
230
+ body: { code: 800, message: session.message || "二维码已过期,请刷新" },
225
231
  };
226
232
  }
227
- if (code === 0) {
228
- const cookies = cgiRes.cookie || [];
229
- const cookieObj = parseSetCookie(cookies);
230
- if (cgiBody.musicid && !cookieObj.uin) cookieObj.uin = String(cgiBody.musicid);
231
- if (cgiBody.musickey && !cookieObj.qm_keyst) cookieObj.qm_keyst = String(cgiBody.musickey);
232
- if (cgiBody.musickey && !cookieObj.qqmusic_key) cookieObj.qqmusic_key = String(cgiBody.musickey);
233
- if (cgiBody.openid && !cookieObj.openid) cookieObj.openid = String(cgiBody.openid);
234
- if (cgiBody.refresh_token && !cookieObj.refresh_token) cookieObj.refresh_token = String(cgiBody.refresh_token);
235
-
236
- const cookieStr = cookieToString(cookieObj);
233
+
234
+ if (session && session.code === 803) {
237
235
  return {
238
236
  status: 200,
239
- body: {
240
- code: 200,
241
- message: "登录成功",
242
- uin: cookieObj.uin || String(cgiBody.musicid || ""),
243
- musickey: cookieObj.qm_keyst || String(cgiBody.musickey || ""),
244
- cookieStr,
245
- data: cgiBody,
246
- },
247
- cookie: cookies,
237
+ body: { code: 803, message: session.message || "用户取消授权" },
248
238
  };
249
239
  }
250
240
 
241
+ // 3. 兜底轮询 CheckQRCode CGI 状态
242
+ try {
243
+ const cgiRes = await req(
244
+ "music.login.LoginServer",
245
+ "CheckQRCode",
246
+ {
247
+ qrcodeID,
248
+ tmeAppID: "qqmusic",
249
+ },
250
+ {
251
+ platform: "android",
252
+ }
253
+ );
254
+
255
+ const cgiBody = (cgiRes.body || {}) as any;
256
+ const code = cgiBody.code !== undefined ? cgiBody.code : cgiBody.ret;
257
+
258
+ if (code === 40001) {
259
+ return {
260
+ status: 200,
261
+ body: { code: 802, message: "已扫码,等待确认" },
262
+ };
263
+ }
264
+ if (code === 40002) {
265
+ return {
266
+ status: 200,
267
+ body: { code: 800, message: "二维码已过期,请刷新" },
268
+ };
269
+ }
270
+ if (code === 0) {
271
+ const cookies = cgiRes.cookie || [];
272
+ const cookieObj = parseSetCookie(cookies);
273
+ if (cgiBody.musicid && !cookieObj.uin) cookieObj.uin = String(cgiBody.musicid);
274
+ if (cgiBody.musickey && !cookieObj.qm_keyst) cookieObj.qm_keyst = String(cgiBody.musickey);
275
+ if (cgiBody.musickey && !cookieObj.qqmusic_key) cookieObj.qqmusic_key = String(cgiBody.musickey);
276
+ if (cgiBody.openid && !cookieObj.openid) cookieObj.openid = String(cgiBody.openid);
277
+ if (cgiBody.refresh_token && !cookieObj.refresh_token) cookieObj.refresh_token = String(cgiBody.refresh_token);
278
+
279
+ const cookieStr = cookieToString(cookieObj);
280
+ return {
281
+ status: 200,
282
+ body: {
283
+ code: 200,
284
+ message: "登录成功",
285
+ uin: cookieObj.uin || String(cgiBody.musicid || ""),
286
+ musickey: cookieObj.qm_keyst || String(cgiBody.musickey || ""),
287
+ cookieStr,
288
+ data: cgiBody,
289
+ },
290
+ cookie: cookies,
291
+ };
292
+ }
293
+ } catch {}
294
+
251
295
  return {
252
296
  status: 200,
253
297
  body: {
254
- code: 801,
255
- message: cgiBody.msg || "等待扫码",
256
- data: cgiBody,
298
+ code: session?.code || 801,
299
+ message: session?.message || "等待 QQ 音乐 App 扫码",
257
300
  },
258
301
  };
259
302
  }
@@ -1,6 +1,7 @@
1
1
  import { request } from "../util/request.js";
2
2
  import { hash33 } from "../util/crypto.js";
3
3
  import { parseSetCookie } from "../util/cookie.js";
4
+ import { registerMobileSession } from "../util/mobile_qr_session.js";
4
5
  /**
5
6
  * 获取登录二维码 (QQ / 微信 / 移动端App).
6
7
  *
@@ -78,13 +79,20 @@ export default async function login_qr_create(query = {}, req = request) {
78
79
  const cgiRes = await req("music.login.LoginServer", "CreateQRCode", {
79
80
  tmeAppID: "qqmusic",
80
81
  }, { platform: "android" });
82
+ const qrcodeID = cgiRes.body?.qrcodeID;
83
+ if (qrcodeID) {
84
+ try {
85
+ registerMobileSession(qrcodeID);
86
+ }
87
+ catch { }
88
+ }
81
89
  return {
82
90
  status: cgiRes.status,
83
91
  body: {
84
92
  code: 200,
85
93
  type: "mobile",
86
94
  qrcode: cgiRes.body?.qrcode,
87
- qrcodeID: cgiRes.body?.qrcodeID,
95
+ qrcodeID,
88
96
  },
89
97
  cookie: cgiRes.cookie,
90
98
  };
@@ -1,6 +1,7 @@
1
1
  import { request, type ApiResponse } from "../util/request.js";
2
2
  import { hash33 } from "../util/crypto.js";
3
3
  import { parseSetCookie } from "../util/cookie.js";
4
+ import { registerMobileSession } from "../util/mobile_qr_session.js";
4
5
 
5
6
  /**
6
7
  * 获取登录二维码 (QQ / 微信 / 移动端App).
@@ -99,13 +100,20 @@ export default async function login_qr_create(
99
100
  { platform: "android" }
100
101
  );
101
102
 
103
+ const qrcodeID = cgiRes.body?.qrcodeID;
104
+ if (qrcodeID) {
105
+ try {
106
+ registerMobileSession(qrcodeID);
107
+ } catch {}
108
+ }
109
+
102
110
  return {
103
111
  status: cgiRes.status,
104
112
  body: {
105
113
  code: 200,
106
114
  type: "mobile",
107
115
  qrcode: cgiRes.body?.qrcode,
108
- qrcodeID: cgiRes.body?.qrcodeID,
116
+ qrcodeID,
109
117
  },
110
118
  cookie: cgiRes.cookie,
111
119
  };
@@ -11,10 +11,12 @@ export default async function login_refresh(query = {}, req = request) {
11
11
  const cookieObj = cookieToJson(query.cookie);
12
12
  const uin = cookieObj.uin || cookieObj.qqmusic_uin || cookieObj.wxuin || "0";
13
13
  const musickey = cookieObj.qm_keyst || cookieObj.qqmusic_key || "";
14
+ const loginType = cookieObj.tmeLoginType || (musickey.startsWith("W_X") ? "1" : "2");
14
15
  const param = {
15
16
  openid: query.openid || cookieObj.openid || "",
16
17
  refresh_token: query.refresh_token || cookieObj.refresh_token || "",
17
18
  refresh_key: query.refresh_key || cookieObj.refresh_key || "",
19
+ access_token: cookieObj.access_token || "",
18
20
  musicid: Number(uin) || 0,
19
21
  str_musicid: uin,
20
22
  musickey,
@@ -22,16 +24,28 @@ export default async function login_refresh(query = {}, req = request) {
22
24
  };
23
25
  const cgiRes = await req("music.login.LoginServer", "Login", param, {
24
26
  cookie: query.cookie,
25
- platform: "web",
27
+ platform: "android",
28
+ comm: { tmeLoginType: Number(loginType) || 2 },
26
29
  });
27
30
  const resBody = (cgiRes.body || {});
28
31
  const newCookies = parseSetCookie(cgiRes.cookie || []);
29
32
  const mergedCookies = { ...cookieObj, ...newCookies };
30
- if (resBody.musickey && !mergedCookies.qm_keyst) {
33
+ if (resBody.musickey) {
31
34
  mergedCookies.qm_keyst = resBody.musickey;
32
- }
33
- if (resBody.musickey && !mergedCookies.qqmusic_key) {
34
35
  mergedCookies.qqmusic_key = resBody.musickey;
36
+ mergedCookies.musickey = resBody.musickey;
37
+ }
38
+ if (resBody.musicid) {
39
+ mergedCookies.uin = String(resBody.musicid);
40
+ mergedCookies.qqmusic_uin = String(resBody.musicid);
41
+ mergedCookies.musicid = String(resBody.musicid);
42
+ }
43
+ if (resBody.encryptUin) {
44
+ mergedCookies.euin = resBody.encryptUin;
45
+ mergedCookies.encryptUin = resBody.encryptUin;
46
+ }
47
+ if (resBody.refresh_token) {
48
+ mergedCookies.refresh_token = resBody.refresh_token;
35
49
  }
36
50
  const cookieStr = cookieToString(mergedCookies);
37
51
  return {
@@ -21,10 +21,13 @@ export default async function login_refresh(
21
21
  const uin = cookieObj.uin || cookieObj.qqmusic_uin || cookieObj.wxuin || "0";
22
22
  const musickey = cookieObj.qm_keyst || cookieObj.qqmusic_key || "";
23
23
 
24
+ const loginType = cookieObj.tmeLoginType || (musickey.startsWith("W_X") ? "1" : "2");
25
+
24
26
  const param = {
25
27
  openid: query.openid || cookieObj.openid || "",
26
28
  refresh_token: query.refresh_token || cookieObj.refresh_token || "",
27
29
  refresh_key: query.refresh_key || cookieObj.refresh_key || "",
30
+ access_token: cookieObj.access_token || "",
28
31
  musicid: Number(uin) || 0,
29
32
  str_musicid: uin,
30
33
  musickey,
@@ -37,18 +40,31 @@ export default async function login_refresh(
37
40
  param,
38
41
  {
39
42
  cookie: query.cookie,
40
- platform: "web",
43
+ platform: "android",
44
+ comm: { tmeLoginType: Number(loginType) || 2 },
41
45
  }
42
46
  );
43
47
 
44
48
  const resBody = (cgiRes.body || {}) as any;
45
49
  const newCookies = parseSetCookie(cgiRes.cookie || []);
46
50
  const mergedCookies = { ...cookieObj, ...newCookies };
47
- if (resBody.musickey && !mergedCookies.qm_keyst) {
51
+
52
+ if (resBody.musickey) {
48
53
  mergedCookies.qm_keyst = resBody.musickey;
49
- }
50
- if (resBody.musickey && !mergedCookies.qqmusic_key) {
51
54
  mergedCookies.qqmusic_key = resBody.musickey;
55
+ mergedCookies.musickey = resBody.musickey;
56
+ }
57
+ if (resBody.musicid) {
58
+ mergedCookies.uin = String(resBody.musicid);
59
+ mergedCookies.qqmusic_uin = String(resBody.musicid);
60
+ mergedCookies.musicid = String(resBody.musicid);
61
+ }
62
+ if (resBody.encryptUin) {
63
+ mergedCookies.euin = resBody.encryptUin;
64
+ mergedCookies.encryptUin = resBody.encryptUin;
65
+ }
66
+ if (resBody.refresh_token) {
67
+ mergedCookies.refresh_token = resBody.refresh_token;
52
68
  }
53
69
  const cookieStr = cookieToString(mergedCookies);
54
70
 
@@ -9,14 +9,20 @@ import user_vip_info_fn from "./user_vip_info.js";
9
9
  */
10
10
  export default async function login_status(query = {}, req = request) {
11
11
  const cookieObj = cookieToJson(query.cookie);
12
- let uin = cookieObj.uin || cookieObj.qqmusic_uin || cookieObj.wxuin || "";
13
- const cgiRes = await req("music.UserInfo.userInfoServer", "GetLoginUserInfo", {}, {
14
- cookie: query.cookie,
15
- platform: "web",
16
- });
12
+ let uin = cookieObj.uin || cookieObj.qqmusic_uin || cookieObj.musicid || cookieObj.wxuin || "";
13
+ const musickey = cookieObj.qm_keyst || cookieObj.qqmusic_key || cookieObj.musickey || "";
14
+ let cgiRes = { status: 200, body: {} };
15
+ try {
16
+ cgiRes = await req("music.UserInfo.userInfoServer", "GetLoginUserInfo", {}, {
17
+ cookie: query.cookie,
18
+ platform: "android",
19
+ });
20
+ }
21
+ catch { }
17
22
  const data = (cgiRes.body || {});
18
23
  const userData = data.user || data.userInfo || data;
19
- const isLogin = data.code === 0 && Boolean(userData.uin || userData.encryptUin || uin);
24
+ let isLogin = (data.code === 0 || (data.code === undefined && Boolean(userData.uin || userData.encryptUin))) &&
25
+ Boolean(userData.uin || userData.encryptUin || uin);
20
26
  if (userData.uin) {
21
27
  uin = String(userData.uin).trim();
22
28
  }
@@ -25,15 +31,18 @@ export default async function login_status(query = {}, req = request) {
25
31
  }
26
32
  let nickname = userData.nick || userData.nickname || "";
27
33
  let avatarUrl = userData.headurl || userData.avatar;
28
- // 若基本信息不全且处于已登录状态,尝试从 user_detail 补全昵称与头像
29
- if (isLogin && (!nickname || !avatarUrl)) {
34
+ // 若基本信息不全,只要有 uin,调用 user_detail 补全真实昵称与高清头像
35
+ if (uin && (!nickname || !avatarUrl)) {
30
36
  try {
31
37
  const detailRes = await user_detail_fn({ uin, cookie: query.cookie }, req);
32
- const header = detailRes.body?.data?.data || detailRes.body?.data || {};
33
- if (header.nick && !nickname)
34
- nickname = header.nick;
35
- if (header.headurl && !avatarUrl)
36
- avatarUrl = header.headurl;
38
+ const detailData = detailRes.body?.data || {};
39
+ if (detailData.nick && !nickname)
40
+ nickname = detailData.nick;
41
+ if (detailData.headurl && !avatarUrl)
42
+ avatarUrl = detailData.headurl;
43
+ if (detailData.nick && Boolean(musickey || uin)) {
44
+ isLogin = true;
45
+ }
37
46
  }
38
47
  catch { }
39
48
  }
@@ -42,9 +51,9 @@ export default async function login_status(query = {}, req = request) {
42
51
  }
43
52
  // 补全 VIP 会员信息
44
53
  let vip = { vipStatus: "nonVip" };
45
- if (isLogin) {
54
+ if (isLogin || uin) {
46
55
  try {
47
- const vipRes = await user_vip_info_fn({ cookie: query.cookie }, req);
56
+ const vipRes = await user_vip_info_fn({ cookie: query.cookie, uin }, req);
48
57
  vip = vipRes.body.vip;
49
58
  }
50
59
  catch {
@@ -62,7 +71,7 @@ export default async function login_status(query = {}, req = request) {
62
71
  vipExpireTime: vip.vipExpireTime,
63
72
  };
64
73
  return {
65
- status: cgiRes.status,
74
+ status: cgiRes.status || 200,
66
75
  body: {
67
76
  code: isLogin ? 200 : 301,
68
77
  isLogin,