koishi-plugin-maibot 1.7.35 → 1.7.37
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/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +254 -50
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export interface Config {
|
|
|
29
29
|
lockRefreshConcurrency?: number;
|
|
30
30
|
confirmTimeout?: number;
|
|
31
31
|
rebindTimeout?: number;
|
|
32
|
+
sgidCacheMinutes?: number;
|
|
32
33
|
protectionCheckInterval?: number;
|
|
33
34
|
authLevelForProxy?: number;
|
|
34
35
|
protectionLockMessage?: string;
|
|
@@ -50,6 +51,7 @@ export interface Config {
|
|
|
50
51
|
enabled: boolean;
|
|
51
52
|
refIdLabel: string;
|
|
52
53
|
};
|
|
54
|
+
errorHelpUrl?: string;
|
|
53
55
|
}
|
|
54
56
|
export declare const Config: Schema<Config>;
|
|
55
57
|
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAW,MAAM,QAAQ,CAAA;AAIjD,eAAO,MAAM,IAAI,WAAW,CAAA;AAC5B,eAAO,MAAM,MAAM,UAAe,CAAA;AAElC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,WAAW,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,CAAC,EAAE;QAClB,OAAO,EAAE,OAAO,CAAA;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,aAAa,CAAC,EAAE;QACd,YAAY,EAAE,MAAM,CAAA;QACpB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,OAAO,CAAA;QAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;QAClB,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,OAAO,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,YAAY,CAAC,EAAE;QACb,OAAO,EAAE,OAAO,CAAA;QAChB,UAAU,EAAE,MAAM,CAAA;KACnB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAW,MAAM,QAAQ,CAAA;AAIjD,eAAO,MAAM,IAAI,WAAW,CAAA;AAC5B,eAAO,MAAM,MAAM,UAAe,CAAA;AAElC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,WAAW,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,CAAC,EAAE;QAClB,OAAO,EAAE,OAAO,CAAA;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,aAAa,CAAC,EAAE;QACd,YAAY,EAAE,MAAM,CAAA;QACpB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,OAAO,CAAA;QAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;QAClB,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,OAAO,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,YAAY,CAAC,EAAE;QACb,OAAO,EAAE,OAAO,CAAA;QAChB,UAAU,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,CAqEhC,CAAA;AAymCF,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QA0pJjD"}
|
package/lib/index.js
CHANGED
|
@@ -42,6 +42,7 @@ exports.Config = koishi_1.Schema.object({
|
|
|
42
42
|
lockRefreshConcurrency: koishi_1.Schema.number().default(3).description('锁定账号刷新时的并发数,默认3个账号同时刷新'),
|
|
43
43
|
confirmTimeout: koishi_1.Schema.number().default(10000).description('确认提示超时时间(毫秒),默认10秒(10000毫秒)'),
|
|
44
44
|
rebindTimeout: koishi_1.Schema.number().default(60000).description('重新绑定超时时间(毫秒),默认60秒(60000毫秒)'),
|
|
45
|
+
sgidCacheMinutes: koishi_1.Schema.number().default(10).description('SGID缓存有效期(分钟),默认10分钟(0表示禁用缓存)'),
|
|
45
46
|
protectionCheckInterval: koishi_1.Schema.number().default(60000).description('保护模式检查间隔(毫秒),默认60秒(60000毫秒)'),
|
|
46
47
|
authLevelForProxy: koishi_1.Schema.number().default(3).description('代操作功能需要的auth等级,默认3'),
|
|
47
48
|
protectionLockMessage: koishi_1.Schema.string().default('🛡️ 保护模式:{playerid}{at} 你的账号已自动锁定成功').description('保护模式锁定成功消息(支持占位符:{playerid} 玩家名,{at} @用户)'),
|
|
@@ -74,6 +75,7 @@ exports.Config = koishi_1.Schema.object({
|
|
|
74
75
|
enabled: true,
|
|
75
76
|
refIdLabel: 'Ref_ID',
|
|
76
77
|
}),
|
|
78
|
+
errorHelpUrl: koishi_1.Schema.string().default('https://awmc.cc/forums/8/').description('任务出错时引导用户提问的URL(留空则不显示引导信息)'),
|
|
77
79
|
});
|
|
78
80
|
// 我认识了很多朋友 以下是我认识的好朋友们!
|
|
79
81
|
// Fracture_Hikaritsu
|
|
@@ -555,11 +557,13 @@ class RequestQueue {
|
|
|
555
557
|
function processSGID(input) {
|
|
556
558
|
const trimmed = input.trim();
|
|
557
559
|
// 检查是否为公众号网页地址格式(https://wq.wahlap.net/qrcode/req/)
|
|
558
|
-
const
|
|
560
|
+
const isReqLink = trimmed.includes('https://wq.wahlap.net/qrcode/req/');
|
|
561
|
+
// 检查是否为二维码图片链接格式(https://wq.wahlap.net/qrcode/img/)
|
|
562
|
+
const isImgLink = trimmed.includes('https://wq.wahlap.net/qrcode/img/');
|
|
559
563
|
const isSGID = trimmed.startsWith('SGWCMAID');
|
|
560
564
|
let qrText = trimmed;
|
|
561
565
|
// 如果是网页地址,提取MAID并转换为SGWCMAID格式
|
|
562
|
-
if (
|
|
566
|
+
if (isReqLink) {
|
|
563
567
|
try {
|
|
564
568
|
// 从URL中提取MAID部分:https://wq.wahlap.net/qrcode/req/MAID2601...55.html?...
|
|
565
569
|
// 匹配 /qrcode/req/ 后面的 MAID 开头的内容(到 .html 或 ? 之前)
|
|
@@ -577,6 +581,24 @@ function processSGID(input) {
|
|
|
577
581
|
return null;
|
|
578
582
|
}
|
|
579
583
|
}
|
|
584
|
+
else if (isImgLink) {
|
|
585
|
+
try {
|
|
586
|
+
// 从图片URL中提取MAID部分:https://wq.wahlap.net/qrcode/img/MAID260128205107...png?v
|
|
587
|
+
// 匹配 /qrcode/img/ 后面的 MAID 开头的内容(到 .png 或 ? 之前)
|
|
588
|
+
const match = trimmed.match(/qrcode\/img\/(MAID[^?\.]+)/i);
|
|
589
|
+
if (match && match[1]) {
|
|
590
|
+
const maid = match[1];
|
|
591
|
+
// 在前面加上 SGWC 变成 SGWCMAID...
|
|
592
|
+
qrText = 'SGWC' + maid;
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
return null;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
580
602
|
else if (!isSGID) {
|
|
581
603
|
return null;
|
|
582
604
|
}
|
|
@@ -681,23 +703,24 @@ async function waitForUserReply(session, ctx, timeout) {
|
|
|
681
703
|
}
|
|
682
704
|
/**
|
|
683
705
|
* 交互式获取二维码文本(qr_text)
|
|
684
|
-
*
|
|
706
|
+
* 支持配置的时间内使用上次输入的SGID缓存
|
|
685
707
|
* 如果缓存存在且有效,直接使用;否则提示用户输入
|
|
686
708
|
*/
|
|
687
709
|
async function getQrText(session, ctx, api, binding, config, timeout = 60000, promptMessage, useCache = true // 是否使用缓存(默认启用)
|
|
688
710
|
) {
|
|
689
711
|
const logger = ctx.logger('maibot');
|
|
690
|
-
// 如果启用缓存且binding
|
|
691
|
-
|
|
712
|
+
// 如果启用缓存且binding存在,检查是否有缓存
|
|
713
|
+
const cacheMinutes = config.sgidCacheMinutes ?? 10;
|
|
714
|
+
if (useCache && cacheMinutes > 0 && binding && binding.lastQrCode && binding.lastQrCodeTime) {
|
|
692
715
|
const cacheAge = Date.now() - new Date(binding.lastQrCodeTime).getTime();
|
|
693
|
-
const cacheValidDuration =
|
|
716
|
+
const cacheValidDuration = cacheMinutes * 60 * 1000;
|
|
694
717
|
if (cacheAge < cacheValidDuration && binding.lastQrCode.startsWith('SGWCMAID')) {
|
|
695
718
|
logger.info(`使用缓存的SGID(${Math.floor(cacheAge / 1000)}秒前输入)`);
|
|
696
719
|
// 直接返回缓存的SGID,不验证(让调用方验证,如果失败再提示输入)
|
|
697
720
|
return { qrText: binding.lastQrCode, fromCache: true };
|
|
698
721
|
}
|
|
699
722
|
else {
|
|
700
|
-
logger.debug(`缓存已过期(${Math.floor(cacheAge / 1000)}
|
|
723
|
+
logger.debug(`缓存已过期(${Math.floor(cacheAge / 1000)}秒前输入,超过${cacheMinutes}分钟)`);
|
|
701
724
|
}
|
|
702
725
|
}
|
|
703
726
|
// 没有有效缓存,提示用户输入
|
|
@@ -720,10 +743,13 @@ async function getQrText(session, ctx, api, binding, config, timeout = 60000, pr
|
|
|
720
743
|
logger.debug(`收到用户输入: ${trimmed.substring(0, 50)}`);
|
|
721
744
|
let qrText = trimmed;
|
|
722
745
|
// 检查是否为公众号网页地址格式(https://wq.wahlap.net/qrcode/req/)
|
|
723
|
-
const
|
|
746
|
+
const isReqLink = trimmed.includes('https://wq.wahlap.net/qrcode/req/');
|
|
747
|
+
// 检查是否为二维码图片链接格式(https://wq.wahlap.net/qrcode/img/)
|
|
748
|
+
const isImgLink = trimmed.includes('https://wq.wahlap.net/qrcode/img/');
|
|
749
|
+
const isLink = isReqLink || isImgLink;
|
|
724
750
|
const isSGID = trimmed.startsWith('SGWCMAID');
|
|
725
751
|
// 如果是网页地址,提取MAID并转换为SGWCMAID格式
|
|
726
|
-
if (
|
|
752
|
+
if (isReqLink) {
|
|
727
753
|
try {
|
|
728
754
|
// 从URL中提取MAID部分:https://wq.wahlap.net/qrcode/req/MAID2601...55.html?...
|
|
729
755
|
// 匹配 /qrcode/req/ 后面的 MAID 开头的内容(到 .html 或 ? 之前)
|
|
@@ -735,19 +761,41 @@ async function getQrText(session, ctx, api, binding, config, timeout = 60000, pr
|
|
|
735
761
|
logger.info(`从网页地址提取MAID并转换: ${maid.substring(0, 20)}... -> ${qrText.substring(0, 24)}...`);
|
|
736
762
|
}
|
|
737
763
|
else {
|
|
738
|
-
await session.send('⚠️ 无法从网页地址中提取MAID,请发送SGID文本(SGWCMAID
|
|
764
|
+
await session.send('⚠️ 无法从网页地址中提取MAID,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
739
765
|
return { qrText: '', error: '无法从网页地址中提取MAID' };
|
|
740
766
|
}
|
|
741
767
|
}
|
|
742
768
|
catch (error) {
|
|
743
769
|
logger.warn('解析网页地址失败:', error);
|
|
744
|
-
await session.send('⚠️ 网页地址格式错误,请发送SGID文本(SGWCMAID
|
|
770
|
+
await session.send('⚠️ 网页地址格式错误,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
745
771
|
return { qrText: '', error: '网页地址格式错误' };
|
|
746
772
|
}
|
|
747
773
|
}
|
|
774
|
+
else if (isImgLink) {
|
|
775
|
+
try {
|
|
776
|
+
// 从图片URL中提取MAID部分:https://wq.wahlap.net/qrcode/img/MAID260128205107...png?v
|
|
777
|
+
// 匹配 /qrcode/img/ 后面的 MAID 开头的内容(到 .png 或 ? 之前)
|
|
778
|
+
const match = trimmed.match(/qrcode\/img\/(MAID[^?\.]+)/i);
|
|
779
|
+
if (match && match[1]) {
|
|
780
|
+
const maid = match[1];
|
|
781
|
+
// 在前面加上 SGWC 变成 SGWCMAID...
|
|
782
|
+
qrText = 'SGWC' + maid;
|
|
783
|
+
logger.info(`从图片地址提取MAID并转换: ${maid.substring(0, 20)}... -> ${qrText.substring(0, 24)}...`);
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
await session.send('⚠️ 无法从图片地址中提取MAID,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
787
|
+
return { qrText: '', error: '无法从图片地址中提取MAID' };
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
catch (error) {
|
|
791
|
+
logger.warn('解析图片地址失败:', error);
|
|
792
|
+
await session.send('⚠️ 图片地址格式错误,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
793
|
+
return { qrText: '', error: '图片地址格式错误' };
|
|
794
|
+
}
|
|
795
|
+
}
|
|
748
796
|
else if (!isSGID) {
|
|
749
|
-
await session.send('⚠️ 未识别到有效的SGID格式或网页地址,请发送SGID文本(SGWCMAID
|
|
750
|
-
return { qrText: '', error: '无效的二维码格式,必须是SGID
|
|
797
|
+
await session.send('⚠️ 未识别到有效的SGID格式或网页地址,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
798
|
+
return { qrText: '', error: '无效的二维码格式,必须是SGID文本或网页/图片地址' };
|
|
751
799
|
}
|
|
752
800
|
// 验证SGID格式和长度
|
|
753
801
|
if (!qrText.startsWith('SGWCMAID')) {
|
|
@@ -758,7 +806,7 @@ async function getQrText(session, ctx, api, binding, config, timeout = 60000, pr
|
|
|
758
806
|
await session.send('❌ SGID长度错误,应在48-128字符之间');
|
|
759
807
|
return { qrText: '', error: '二维码长度错误,应在48-128字符之间' };
|
|
760
808
|
}
|
|
761
|
-
logger.info(`✅ 接收到${isLink ? '
|
|
809
|
+
logger.info(`✅ 接收到${isLink ? '链接地址(已转换)' : 'SGID'}: ${qrText.substring(0, 50)}...`);
|
|
762
810
|
// 尝试撤回用户发送的消息(如果启用了自动撤回)
|
|
763
811
|
await tryRecallMessage(session, ctx, config);
|
|
764
812
|
await session.send('⏳ 正在处理,请稍候...');
|
|
@@ -853,10 +901,13 @@ async function promptForRebind(session, ctx, api, binding, config, timeout = 600
|
|
|
853
901
|
logger.debug(`收到用户输入: ${trimmed.substring(0, 50)}`);
|
|
854
902
|
let qrCode = trimmed;
|
|
855
903
|
// 检查是否为公众号网页地址格式(https://wq.wahlap.net/qrcode/req/)
|
|
856
|
-
const
|
|
904
|
+
const isReqLink = trimmed.includes('https://wq.wahlap.net/qrcode/req/');
|
|
905
|
+
// 检查是否为二维码图片链接格式(https://wq.wahlap.net/qrcode/img/)
|
|
906
|
+
const isImgLink = trimmed.includes('https://wq.wahlap.net/qrcode/img/');
|
|
907
|
+
const isLink = isReqLink || isImgLink;
|
|
857
908
|
const isSGID = trimmed.startsWith('SGWCMAID');
|
|
858
909
|
// 如果是网页地址,提取MAID并转换为SGWCMAID格式
|
|
859
|
-
if (
|
|
910
|
+
if (isReqLink) {
|
|
860
911
|
try {
|
|
861
912
|
// 从URL中提取MAID部分:https://wq.wahlap.net/qrcode/req/MAID2601...55.html?...
|
|
862
913
|
// 匹配 /qrcode/req/ 后面的 MAID 开头的内容(到 .html 或 ? 之前)
|
|
@@ -868,19 +919,41 @@ async function promptForRebind(session, ctx, api, binding, config, timeout = 600
|
|
|
868
919
|
logger.info(`从网页地址提取MAID并转换: ${maid.substring(0, 20)}... -> ${qrCode.substring(0, 24)}...`);
|
|
869
920
|
}
|
|
870
921
|
else {
|
|
871
|
-
await session.send('⚠️ 无法从网页地址中提取MAID,请发送SGID文本(SGWCMAID
|
|
922
|
+
await session.send('⚠️ 无法从网页地址中提取MAID,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
872
923
|
return { success: false, error: '无法从网页地址中提取MAID', messageId: promptMessageId };
|
|
873
924
|
}
|
|
874
925
|
}
|
|
875
926
|
catch (error) {
|
|
876
927
|
logger.warn('解析网页地址失败:', error);
|
|
877
|
-
await session.send('⚠️ 网页地址格式错误,请发送SGID文本(SGWCMAID
|
|
928
|
+
await session.send('⚠️ 网页地址格式错误,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
878
929
|
return { success: false, error: '网页地址格式错误', messageId: promptMessageId };
|
|
879
930
|
}
|
|
880
931
|
}
|
|
932
|
+
else if (isImgLink) {
|
|
933
|
+
try {
|
|
934
|
+
// 从图片URL中提取MAID部分:https://wq.wahlap.net/qrcode/img/MAID260128205107...png?v
|
|
935
|
+
// 匹配 /qrcode/img/ 后面的 MAID 开头的内容(到 .png 或 ? 之前)
|
|
936
|
+
const match = trimmed.match(/qrcode\/img\/(MAID[^?\.]+)/i);
|
|
937
|
+
if (match && match[1]) {
|
|
938
|
+
const maid = match[1];
|
|
939
|
+
// 在前面加上 SGWC 变成 SGWCMAID...
|
|
940
|
+
qrCode = 'SGWC' + maid;
|
|
941
|
+
logger.info(`从图片地址提取MAID并转换: ${maid.substring(0, 20)}... -> ${qrCode.substring(0, 24)}...`);
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
await session.send('⚠️ 无法从图片地址中提取MAID,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
945
|
+
return { success: false, error: '无法从图片地址中提取MAID', messageId: promptMessageId };
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
catch (error) {
|
|
949
|
+
logger.warn('解析图片地址失败:', error);
|
|
950
|
+
await session.send('⚠️ 图片地址格式错误,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
951
|
+
return { success: false, error: '图片地址格式错误', messageId: promptMessageId };
|
|
952
|
+
}
|
|
953
|
+
}
|
|
881
954
|
else if (!isSGID) {
|
|
882
|
-
await session.send('⚠️ 未识别到有效的SGID格式或网页地址,请发送SGID文本(SGWCMAID
|
|
883
|
-
return { success: false, error: '无效的二维码格式,必须是SGID
|
|
955
|
+
await session.send('⚠️ 未识别到有效的SGID格式或网页地址,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
956
|
+
return { success: false, error: '无效的二维码格式,必须是SGID文本或网页/图片地址', messageId: promptMessageId };
|
|
884
957
|
}
|
|
885
958
|
// 验证SGID格式和长度
|
|
886
959
|
if (!qrCode.startsWith('SGWCMAID')) {
|
|
@@ -891,7 +964,7 @@ async function promptForRebind(session, ctx, api, binding, config, timeout = 600
|
|
|
891
964
|
await session.send('❌ 识别失败:SGID长度错误,应在48-128字符之间');
|
|
892
965
|
return { success: false, error: '二维码长度错误,应在48-128字符之间', messageId: promptMessageId };
|
|
893
966
|
}
|
|
894
|
-
logger.info(`✅ 接收到${isLink ? '
|
|
967
|
+
logger.info(`✅ 接收到${isLink ? '链接地址(已转换)' : 'SGID'}: ${qrCode.substring(0, 50)}...`);
|
|
895
968
|
// 发送识别中反馈
|
|
896
969
|
await session.send('⏳ 正在处理,请稍候...');
|
|
897
970
|
// 使用新API获取用户信息
|
|
@@ -968,6 +1041,104 @@ function apply(ctx, config) {
|
|
|
968
1041
|
const requestQueue = queueConfig.enabled ? new RequestQueue(queueConfig.interval) : null;
|
|
969
1042
|
// 操作记录配置
|
|
970
1043
|
const operationLogConfig = config.operationLog || { enabled: true, refIdLabel: 'Ref_ID' };
|
|
1044
|
+
// 错误帮助URL配置
|
|
1045
|
+
const errorHelpUrl = config.errorHelpUrl || '';
|
|
1046
|
+
/**
|
|
1047
|
+
* 获取上传任务的统计信息(平均处理时长和今日成功率)
|
|
1048
|
+
* @param commandPrefix 命令前缀,用于筛选日志(如 'mai上传B50' 或 'mai上传落雪b50')
|
|
1049
|
+
* @returns 统计信息字符串
|
|
1050
|
+
*/
|
|
1051
|
+
async function getUploadStats(commandPrefix) {
|
|
1052
|
+
try {
|
|
1053
|
+
const today = new Date();
|
|
1054
|
+
today.setHours(0, 0, 0, 0);
|
|
1055
|
+
const todayStart = today.getTime();
|
|
1056
|
+
// 获取今日所有相关操作记录
|
|
1057
|
+
const allLogs = await ctx.database.get('maibot_operation_logs', {});
|
|
1058
|
+
const todayLogs = allLogs.filter(log => {
|
|
1059
|
+
const logTime = new Date(log.createdAt).getTime();
|
|
1060
|
+
return logTime >= todayStart && log.command.startsWith(commandPrefix);
|
|
1061
|
+
});
|
|
1062
|
+
if (todayLogs.length === 0) {
|
|
1063
|
+
return '';
|
|
1064
|
+
}
|
|
1065
|
+
// 统计成功率
|
|
1066
|
+
const taskCompleteLogs = todayLogs.filter(log => log.command.includes('-任务完成'));
|
|
1067
|
+
const successCount = taskCompleteLogs.filter(log => log.status === 'success').length;
|
|
1068
|
+
const failureCount = taskCompleteLogs.filter(log => log.status === 'failure').length;
|
|
1069
|
+
const totalCompleted = successCount + failureCount;
|
|
1070
|
+
// 计算平均处理时长(从任务提交到任务完成)
|
|
1071
|
+
let avgDuration = 0;
|
|
1072
|
+
let durationCount = 0;
|
|
1073
|
+
// 获取所有任务提交记录和对应的完成记录
|
|
1074
|
+
const submitLogs = todayLogs.filter(log => log.command === commandPrefix && log.status === 'success');
|
|
1075
|
+
for (const submitLog of submitLogs) {
|
|
1076
|
+
// 尝试从 apiResponse 中获取 task_id
|
|
1077
|
+
if (!submitLog.apiResponse)
|
|
1078
|
+
continue;
|
|
1079
|
+
try {
|
|
1080
|
+
const response = JSON.parse(submitLog.apiResponse);
|
|
1081
|
+
const taskId = response.task_id;
|
|
1082
|
+
if (!taskId)
|
|
1083
|
+
continue;
|
|
1084
|
+
// 查找对应的完成记录
|
|
1085
|
+
const completeLog = taskCompleteLogs.find(log => {
|
|
1086
|
+
if (!log.apiResponse)
|
|
1087
|
+
return false;
|
|
1088
|
+
try {
|
|
1089
|
+
const completeResponse = JSON.parse(log.apiResponse);
|
|
1090
|
+
return completeResponse.alive_task_id === taskId || String(completeResponse.alive_task_id) === String(taskId);
|
|
1091
|
+
}
|
|
1092
|
+
catch {
|
|
1093
|
+
return false;
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
if (completeLog) {
|
|
1097
|
+
const submitTime = new Date(submitLog.createdAt).getTime();
|
|
1098
|
+
const completeTime = new Date(completeLog.createdAt).getTime();
|
|
1099
|
+
const duration = (completeTime - submitTime) / 1000; // 转换为秒
|
|
1100
|
+
if (duration > 0 && duration < 600) { // 排除异常数据(超过10分钟的)
|
|
1101
|
+
avgDuration += duration;
|
|
1102
|
+
durationCount++;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
catch {
|
|
1107
|
+
continue;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
// 计算平均时长
|
|
1111
|
+
if (durationCount > 0) {
|
|
1112
|
+
avgDuration = avgDuration / durationCount;
|
|
1113
|
+
}
|
|
1114
|
+
// 计算成功率
|
|
1115
|
+
const successRate = totalCompleted > 0 ? Math.round((successCount / totalCompleted) * 100) : 0;
|
|
1116
|
+
// 构建统计信息字符串
|
|
1117
|
+
let statsStr = '';
|
|
1118
|
+
if (avgDuration > 0) {
|
|
1119
|
+
statsStr += `平均处理用时 ${avgDuration.toFixed(2)} s`;
|
|
1120
|
+
}
|
|
1121
|
+
if (totalCompleted > 0) {
|
|
1122
|
+
if (statsStr)
|
|
1123
|
+
statsStr += ',';
|
|
1124
|
+
statsStr += `今日成功率 ${successRate}%`;
|
|
1125
|
+
}
|
|
1126
|
+
return statsStr;
|
|
1127
|
+
}
|
|
1128
|
+
catch (error) {
|
|
1129
|
+
logger.warn('获取上传统计信息失败:', error);
|
|
1130
|
+
return '';
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
/**
|
|
1134
|
+
* 获取错误帮助信息(如果配置了帮助URL)
|
|
1135
|
+
*/
|
|
1136
|
+
function getErrorHelpInfo() {
|
|
1137
|
+
if (!errorHelpUrl) {
|
|
1138
|
+
return '';
|
|
1139
|
+
}
|
|
1140
|
+
return `\n\n如有问题,请前往 ${errorHelpUrl} 提问`;
|
|
1141
|
+
}
|
|
971
1142
|
/**
|
|
972
1143
|
* 生成唯一的 ref_id
|
|
973
1144
|
*/
|
|
@@ -1269,7 +1440,7 @@ function apply(ctx, config) {
|
|
|
1269
1440
|
if (isDone || hasError) {
|
|
1270
1441
|
// 任务完成或出错,发送通知并停止
|
|
1271
1442
|
const statusText = hasError
|
|
1272
|
-
? `❌ 任务失败:${detail.error}`
|
|
1443
|
+
? `❌ 任务失败:${detail.error}${getErrorHelpInfo()}`
|
|
1273
1444
|
: '✅ 任务已完成';
|
|
1274
1445
|
const finishTime = detail.alive_task_end_time
|
|
1275
1446
|
? `\n完成时间: ${new Date((typeof detail.alive_task_end_time === 'number' ? detail.alive_task_end_time : parseInt(String(detail.alive_task_end_time))) * 1000).toLocaleString('zh-CN')}`
|
|
@@ -1299,7 +1470,7 @@ function apply(ctx, config) {
|
|
|
1299
1470
|
status: 'failure',
|
|
1300
1471
|
errorMessage: '任务轮询超时(10分钟)',
|
|
1301
1472
|
});
|
|
1302
|
-
let msg = `${mention} 水鱼B50任务 ${taskId}
|
|
1473
|
+
let msg = `${mention} 水鱼B50任务 ${taskId} 上传失败,请稍后再试一次。${getErrorHelpInfo()}`;
|
|
1303
1474
|
const maintenanceMsg = getMaintenanceMessage(maintenanceNotice);
|
|
1304
1475
|
if (maintenanceMsg) {
|
|
1305
1476
|
msg += `\n${maintenanceMsg}`;
|
|
@@ -1319,7 +1490,7 @@ function apply(ctx, config) {
|
|
|
1319
1490
|
status: 'error',
|
|
1320
1491
|
errorMessage: error instanceof Error ? error.message : '未知错误',
|
|
1321
1492
|
});
|
|
1322
|
-
let msg = `${mention} 水鱼B50任务 ${taskId}
|
|
1493
|
+
let msg = `${mention} 水鱼B50任务 ${taskId} 上传失败,请稍后再试一次。${getErrorHelpInfo()}`;
|
|
1323
1494
|
const maintenanceMsg = getMaintenanceMessage(maintenanceNotice);
|
|
1324
1495
|
if (maintenanceMsg) {
|
|
1325
1496
|
msg += `\n${maintenanceMsg}`;
|
|
@@ -1353,7 +1524,7 @@ function apply(ctx, config) {
|
|
|
1353
1524
|
if (isDone || hasError) {
|
|
1354
1525
|
// 任务完成或出错,发送通知并停止
|
|
1355
1526
|
const statusText = hasError
|
|
1356
|
-
? `❌ 任务失败:${detail.error}`
|
|
1527
|
+
? `❌ 任务失败:${detail.error}${getErrorHelpInfo()}`
|
|
1357
1528
|
: '✅ 任务已完成';
|
|
1358
1529
|
const finishTime = detail.alive_task_end_time
|
|
1359
1530
|
? `\n完成时间: ${new Date((typeof detail.alive_task_end_time === 'number' ? detail.alive_task_end_time : parseInt(String(detail.alive_task_end_time))) * 1000).toLocaleString('zh-CN')}`
|
|
@@ -1383,7 +1554,7 @@ function apply(ctx, config) {
|
|
|
1383
1554
|
status: 'failure',
|
|
1384
1555
|
errorMessage: '任务轮询超时(10分钟)',
|
|
1385
1556
|
});
|
|
1386
|
-
let msg = `${mention} 落雪B50任务 ${taskId}
|
|
1557
|
+
let msg = `${mention} 落雪B50任务 ${taskId} 上传失败,请稍后再试一次。${getErrorHelpInfo()}`;
|
|
1387
1558
|
const maintenanceMsg = getMaintenanceMessage(maintenanceNotice);
|
|
1388
1559
|
if (maintenanceMsg) {
|
|
1389
1560
|
msg += `\n${maintenanceMsg}`;
|
|
@@ -1403,7 +1574,7 @@ function apply(ctx, config) {
|
|
|
1403
1574
|
status: 'error',
|
|
1404
1575
|
errorMessage: error instanceof Error ? error.message : '未知错误',
|
|
1405
1576
|
});
|
|
1406
|
-
let msg = `${mention} 落雪B50任务 ${taskId}
|
|
1577
|
+
let msg = `${mention} 落雪B50任务 ${taskId} 上传失败,请稍后再试一次。${getErrorHelpInfo()}`;
|
|
1407
1578
|
const maintenanceMsg = getMaintenanceMessage(maintenanceNotice);
|
|
1408
1579
|
if (maintenanceMsg) {
|
|
1409
1580
|
msg += `\n${maintenanceMsg}`;
|
|
@@ -1689,10 +1860,13 @@ function apply(ctx, config) {
|
|
|
1689
1860
|
logger.debug(`收到用户输入: ${trimmed.substring(0, 50)}`);
|
|
1690
1861
|
qrCode = trimmed;
|
|
1691
1862
|
// 检查是否为公众号网页地址格式(https://wq.wahlap.net/qrcode/req/)
|
|
1692
|
-
const
|
|
1863
|
+
const isReqLink = trimmed.includes('https://wq.wahlap.net/qrcode/req/');
|
|
1864
|
+
// 检查是否为二维码图片链接格式(https://wq.wahlap.net/qrcode/img/)
|
|
1865
|
+
const isImgLink = trimmed.includes('https://wq.wahlap.net/qrcode/img/');
|
|
1866
|
+
const isLink = isReqLink || isImgLink;
|
|
1693
1867
|
const isSGID = trimmed.startsWith('SGWCMAID');
|
|
1694
1868
|
// 如果是网页地址,提取MAID并转换为SGWCMAID格式
|
|
1695
|
-
if (
|
|
1869
|
+
if (isReqLink) {
|
|
1696
1870
|
try {
|
|
1697
1871
|
// 从URL中提取MAID部分:https://wq.wahlap.net/qrcode/req/MAID2601...55.html?...
|
|
1698
1872
|
// 匹配 /qrcode/req/ 后面的 MAID 开头的内容(到 .html 或 ? 之前)
|
|
@@ -1704,30 +1878,52 @@ function apply(ctx, config) {
|
|
|
1704
1878
|
logger.info(`从网页地址提取MAID并转换: ${maid.substring(0, 20)}... -> ${qrCode.substring(0, 24)}...`);
|
|
1705
1879
|
}
|
|
1706
1880
|
else {
|
|
1707
|
-
await session.send('⚠️ 无法从网页地址中提取MAID,请发送SGID文本(SGWCMAID
|
|
1881
|
+
await session.send('⚠️ 无法从网页地址中提取MAID,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
1708
1882
|
throw new Error('无法从网页地址中提取MAID');
|
|
1709
1883
|
}
|
|
1710
1884
|
}
|
|
1711
1885
|
catch (error) {
|
|
1712
1886
|
logger.warn('解析网页地址失败:', error);
|
|
1713
|
-
await session.send('⚠️ 网页地址格式错误,请发送SGID文本(SGWCMAID
|
|
1887
|
+
await session.send('⚠️ 网页地址格式错误,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
1714
1888
|
throw new Error('网页地址格式错误');
|
|
1715
1889
|
}
|
|
1716
1890
|
}
|
|
1891
|
+
else if (isImgLink) {
|
|
1892
|
+
try {
|
|
1893
|
+
// 从图片URL中提取MAID部分:https://wq.wahlap.net/qrcode/img/MAID260128205107...png?v
|
|
1894
|
+
// 匹配 /qrcode/img/ 后面的 MAID 开头的内容(到 .png 或 ? 之前)
|
|
1895
|
+
const match = trimmed.match(/qrcode\/img\/(MAID[^?\.]+)/i);
|
|
1896
|
+
if (match && match[1]) {
|
|
1897
|
+
const maid = match[1];
|
|
1898
|
+
// 在前面加上 SGWC 变成 SGWCMAID...
|
|
1899
|
+
qrCode = 'SGWC' + maid;
|
|
1900
|
+
logger.info(`从图片地址提取MAID并转换: ${maid.substring(0, 20)}... -> ${qrCode.substring(0, 24)}...`);
|
|
1901
|
+
}
|
|
1902
|
+
else {
|
|
1903
|
+
await session.send('⚠️ 无法从图片地址中提取MAID,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
1904
|
+
throw new Error('无法从图片地址中提取MAID');
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
catch (error) {
|
|
1908
|
+
logger.warn('解析图片地址失败:', error);
|
|
1909
|
+
await session.send('⚠️ 图片地址格式错误,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
1910
|
+
throw new Error('图片地址格式错误');
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1717
1913
|
else if (!isSGID) {
|
|
1718
|
-
await session.send('⚠️ 未识别到有效的SGID格式或网页地址,请发送SGID文本(SGWCMAID
|
|
1719
|
-
throw new Error('无效的二维码格式,必须是SGID
|
|
1914
|
+
await session.send('⚠️ 未识别到有效的SGID格式或网页地址,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
1915
|
+
throw new Error('无效的二维码格式,必须是SGID文本或网页/图片地址');
|
|
1720
1916
|
}
|
|
1721
1917
|
// 验证SGID格式和长度
|
|
1722
1918
|
if (!qrCode.startsWith('SGWCMAID')) {
|
|
1723
|
-
await session.send('⚠️ 未识别到有效的SGID格式,请发送SGID文本(SGWCMAID
|
|
1919
|
+
await session.send('⚠️ 未识别到有效的SGID格式,请发送SGID文本(SGWCMAID开头)或公众号提供的网页/图片地址');
|
|
1724
1920
|
throw new Error('无效的二维码格式,必须以 SGWCMAID 开头');
|
|
1725
1921
|
}
|
|
1726
1922
|
if (qrCode.length < 48 || qrCode.length > 128) {
|
|
1727
1923
|
await session.send('❌ SGID长度错误,应在48-128字符之间');
|
|
1728
1924
|
throw new Error('二维码长度错误,应在48-128字符之间');
|
|
1729
1925
|
}
|
|
1730
|
-
logger.info(`✅ 接收到${isLink ? '
|
|
1926
|
+
logger.info(`✅ 接收到${isLink ? '链接地址(已转换)' : 'SGID'}: ${qrCode.substring(0, 50)}...`);
|
|
1731
1927
|
// 发送识别中反馈
|
|
1732
1928
|
await session.send('⏳ 正在处理,请稍候...');
|
|
1733
1929
|
}
|
|
@@ -2854,9 +3050,11 @@ function apply(ctx, config) {
|
|
|
2854
3050
|
return '⚠️ 当前账号已有未完成的水鱼B50任务,请稍后再试,无需重复上传。';
|
|
2855
3051
|
}
|
|
2856
3052
|
const taskIdInfo = result.task_id ? `\n任务ID: ${result.task_id}` : '';
|
|
2857
|
-
return `❌ 上传失败:${result.msg || '未知错误'}${taskIdInfo}`;
|
|
3053
|
+
return `❌ 上传失败:${result.msg || '未知错误'}${taskIdInfo}${getErrorHelpInfo()}`;
|
|
2858
3054
|
}
|
|
2859
|
-
const
|
|
3055
|
+
const statsInfo = await getUploadStats('mai上传B50');
|
|
3056
|
+
const statsStr = statsInfo ? `\n${statsInfo}` : '';
|
|
3057
|
+
const successMessage = `✅ B50上传任务已提交!${statsStr}\n任务ID: ${result.task_id}\n\n请耐心等待任务完成,预计1-10分钟`;
|
|
2860
3058
|
const refId = await logOperation({
|
|
2861
3059
|
command: 'mai上传B50',
|
|
2862
3060
|
session,
|
|
@@ -2939,13 +3137,15 @@ function apply(ctx, config) {
|
|
|
2939
3137
|
return `✅ 重新绑定成功!请重新执行上传操作。`;
|
|
2940
3138
|
}
|
|
2941
3139
|
const taskIdInfo = result.task_id ? `\n任务ID: ${result.task_id}` : '';
|
|
2942
|
-
return `❌ 上传失败:${result.msg || '未知错误'}\n重新绑定失败:${rebindResult.error || '未知错误'}${taskIdInfo}`;
|
|
3140
|
+
return `❌ 上传失败:${result.msg || '未知错误'}\n重新绑定失败:${rebindResult.error || '未知错误'}${taskIdInfo}${getErrorHelpInfo()}`;
|
|
2943
3141
|
}
|
|
2944
3142
|
const taskIdInfo = result.task_id ? `\n任务ID: ${result.task_id}` : '';
|
|
2945
|
-
return `❌ 上传失败:${result.msg || '未知错误'}${taskIdInfo}`;
|
|
3143
|
+
return `❌ 上传失败:${result.msg || '未知错误'}${taskIdInfo}${getErrorHelpInfo()}`;
|
|
2946
3144
|
}
|
|
2947
3145
|
}
|
|
2948
|
-
const
|
|
3146
|
+
const statsInfo = await getUploadStats('mai上传B50');
|
|
3147
|
+
const statsStr = statsInfo ? `\n${statsInfo}` : '';
|
|
3148
|
+
const successMessage = `✅ B50上传任务已提交!${statsStr}\n任务ID: ${result.task_id}\n\n请耐心等待任务完成,预计1-10分钟`;
|
|
2949
3149
|
const refId = await logOperation({
|
|
2950
3150
|
command: 'mai上传B50',
|
|
2951
3151
|
session,
|
|
@@ -2969,7 +3169,7 @@ function apply(ctx, config) {
|
|
|
2969
3169
|
if (maintenanceMsg) {
|
|
2970
3170
|
msg += `\n${maintenanceMsg}`;
|
|
2971
3171
|
}
|
|
2972
|
-
msg += `\n\n${maintenanceMessage}`;
|
|
3172
|
+
msg += `\n\n${maintenanceMessage}${getErrorHelpInfo()}`;
|
|
2973
3173
|
return msg;
|
|
2974
3174
|
}
|
|
2975
3175
|
if (error?.response) {
|
|
@@ -3909,9 +4109,11 @@ function apply(ctx, config) {
|
|
|
3909
4109
|
return '⚠️ 当前账号已有未完成的落雪B50任务,请稍后再试,无需重复上传。';
|
|
3910
4110
|
}
|
|
3911
4111
|
const taskIdInfo = result.task_id ? `\n任务ID: ${result.task_id}` : '';
|
|
3912
|
-
return `❌ 上传失败:${result.msg || '未知错误'}${taskIdInfo}`;
|
|
4112
|
+
return `❌ 上传失败:${result.msg || '未知错误'}${taskIdInfo}${getErrorHelpInfo()}`;
|
|
3913
4113
|
}
|
|
3914
|
-
const
|
|
4114
|
+
const statsInfo = await getUploadStats('mai上传落雪b50');
|
|
4115
|
+
const statsStr = statsInfo ? `\n${statsInfo}` : '';
|
|
4116
|
+
const successMessage = `✅ 落雪B50上传任务已提交!${statsStr}\n任务ID: ${result.task_id}\n\n请耐心等待任务完成,预计1-10分钟`;
|
|
3915
4117
|
const refId = await logOperation({
|
|
3916
4118
|
command: 'mai上传落雪b50',
|
|
3917
4119
|
session,
|
|
@@ -3923,7 +4125,7 @@ function apply(ctx, config) {
|
|
|
3923
4125
|
scheduleLxB50Notification(session, result.task_id, refId);
|
|
3924
4126
|
return appendRefId(successMessage, refId);
|
|
3925
4127
|
}
|
|
3926
|
-
return `❌ 获取二维码失败:${qrTextResult.error}`;
|
|
4128
|
+
return `❌ 获取二维码失败:${qrTextResult.error}${getErrorHelpInfo()}`;
|
|
3927
4129
|
}
|
|
3928
4130
|
// 在调用API前加入队列
|
|
3929
4131
|
await waitForQueue(session);
|
|
@@ -3994,13 +4196,15 @@ function apply(ctx, config) {
|
|
|
3994
4196
|
return `✅ 重新绑定成功!请重新执行上传操作。`;
|
|
3995
4197
|
}
|
|
3996
4198
|
const taskIdInfo = result.task_id ? `\n任务ID: ${result.task_id}` : '';
|
|
3997
|
-
return `❌ 上传失败:${result.msg || '未知错误'}\n重新绑定失败:${rebindResult.error || '未知错误'}${taskIdInfo}`;
|
|
4199
|
+
return `❌ 上传失败:${result.msg || '未知错误'}\n重新绑定失败:${rebindResult.error || '未知错误'}${taskIdInfo}${getErrorHelpInfo()}`;
|
|
3998
4200
|
}
|
|
3999
4201
|
const taskIdInfo = result.task_id ? `\n任务ID: ${result.task_id}` : '';
|
|
4000
|
-
return `❌ 上传失败:${result.msg || '未知错误'}${taskIdInfo}`;
|
|
4202
|
+
return `❌ 上传失败:${result.msg || '未知错误'}${taskIdInfo}${getErrorHelpInfo()}`;
|
|
4001
4203
|
}
|
|
4002
4204
|
}
|
|
4003
|
-
const
|
|
4205
|
+
const statsInfo = await getUploadStats('mai上传落雪b50');
|
|
4206
|
+
const statsStr = statsInfo ? `\n${statsInfo}` : '';
|
|
4207
|
+
const successMessage = `✅ 落雪B50上传任务已提交!${statsStr}\n任务ID: ${result.task_id}\n\n请耐心等待任务完成,预计1-10分钟`;
|
|
4004
4208
|
const refId = await logOperation({
|
|
4005
4209
|
command: 'mai上传落雪b50',
|
|
4006
4210
|
session,
|
|
@@ -4023,12 +4227,12 @@ function apply(ctx, config) {
|
|
|
4023
4227
|
if (maintenanceMsg) {
|
|
4024
4228
|
msg += `\n${maintenanceMsg}`;
|
|
4025
4229
|
}
|
|
4026
|
-
msg += `\n\n${maintenanceMessage}`;
|
|
4230
|
+
msg += `\n\n${maintenanceMessage}${getErrorHelpInfo()}`;
|
|
4027
4231
|
return msg;
|
|
4028
4232
|
})()
|
|
4029
4233
|
: (error?.response
|
|
4030
|
-
? `❌ API请求失败: ${error.response.status} ${error.response.statusText}\n\n${maintenanceMessage}`
|
|
4031
|
-
: `❌ 上传失败: ${error?.message || '未知错误'}\n\n${maintenanceMessage}`));
|
|
4234
|
+
? `❌ API请求失败: ${error.response.status} ${error.response.statusText}\n\n${maintenanceMessage}${getErrorHelpInfo()}`
|
|
4235
|
+
: `❌ 上传失败: ${error?.message || '未知错误'}\n\n${maintenanceMessage}${getErrorHelpInfo()}`));
|
|
4032
4236
|
const refId = await logOperation({
|
|
4033
4237
|
command: 'mai上传落雪b50',
|
|
4034
4238
|
session,
|