koishi-plugin-subscription 0.0.2 → 0.0.4

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.
Files changed (2) hide show
  1. package/lib/index.js +277 -13
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -257,7 +257,7 @@ var SubscriptionService = class extends import_koishi.Service {
257
257
  return `${channel.platform}:${channel.id}`;
258
258
  }
259
259
  registerCommands(ctx, config) {
260
- const sub = ctx.command("subscription.add <app:string> [...accounts]", "添加订阅").alias("订阅").alias("添加订阅").userFields(["authority"]).action(async ({ session, options }, app, ...accounts) => {
260
+ const sub = ctx.command("subscription <app:string> [...accounts]", "添加订阅").alias("订阅").alias("添加订阅").userFields(["authority"]).action(async ({ session, options }, app, ...accounts) => {
261
261
  if (!await this.authCheck(session, config)) {
262
262
  return "权限不足";
263
263
  }
@@ -332,25 +332,289 @@ var SubscriptionService = class extends import_koishi.Service {
332
332
  alias: account.alias ? account.alias.split(",") : []
333
333
  }));
334
334
  }
335
- let result = `群组 ${groupId} 的订阅状态:
335
+ if (!ctx.puppeteer) {
336
+ let result = `群组 ${groupId} 的订阅状态:
336
337
 
337
338
  `;
338
- for (const app in availableAccounts) {
339
- result += `【${app}】
339
+ for (const app in availableAccounts) {
340
+ result += `【${app}】
340
341
  `;
341
- const subscribed = subscribedByApp[app] || /* @__PURE__ */ new Set();
342
- availableAccounts[app].forEach((account) => {
343
- const isSubscribed = subscribed.has(account.id);
344
- const status = isSubscribed ? "✅ 已订阅" : "❌ 未订阅";
345
- const aliases = account.alias.length > 0 ? ` (${account.alias.join(", ")})` : "";
346
- result += `${status} ${account.name} id:${account.id}
342
+ const subscribed = subscribedByApp[app] || /* @__PURE__ */ new Set();
343
+ availableAccounts[app].forEach((account) => {
344
+ const isSubscribed = subscribed.has(account.id);
345
+ const status = isSubscribed ? "✅ 已订阅" : "❌ 未订阅";
346
+ const aliases = account.alias.length > 0 ? ` (${account.alias.join(", ")})` : "";
347
+ result += `${status} ${account.name} id:${account.id}
347
348
  ${aliases}
348
349
  `;
349
- });
350
- result += "\n";
350
+ });
351
+ result += "\n";
352
+ }
353
+ return result;
351
354
  }
352
- return result;
355
+ const html = generateSubscriptionHTML(groupId, availableAccounts, subscribedByApp);
356
+ return await ctx.puppeteer.render(html);
353
357
  });
358
+ function generateSubscriptionHTML(groupId, availableAccounts, subscribedByApp) {
359
+ return `
360
+ <!DOCTYPE html>
361
+ <html>
362
+ <head>
363
+ <meta charset="UTF-8">
364
+ <style>
365
+ * {
366
+ margin: 0;
367
+ padding: 0;
368
+ box-sizing: border-box;
369
+ }
370
+ body {
371
+ font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
372
+ background: #f5f7fa;
373
+ min-height: 100vh;
374
+ padding: 20px;
375
+ }
376
+ .container {
377
+ max-width: 1200px;
378
+ margin: 0 auto;
379
+ }
380
+ .header {
381
+ text-align: center;
382
+ margin-bottom: 20px;
383
+ color: #2c3e50;
384
+ }
385
+ .header h1 {
386
+ font-size: 24px;
387
+ margin-bottom: 8px;
388
+ font-weight: 600;
389
+ }
390
+ .header .subtitle {
391
+ font-size: 14px;
392
+ color: #7f8c8d;
393
+ }
394
+ .apps-container {
395
+ background: white;
396
+ border-radius: 8px;
397
+ box-shadow: 0 2px 12px rgba(0,0,0,0.08);
398
+ overflow: hidden;
399
+ }
400
+ .app-section {
401
+ border-bottom: 1px solid #eaeaea;
402
+ }
403
+ .app-section:last-child {
404
+ border-bottom: none;
405
+ }
406
+ .app-title {
407
+ font-size: 16px;
408
+ font-weight: 600;
409
+ color: #34495e;
410
+ padding: 12px 16px;
411
+ background: #f8f9fa;
412
+ border-bottom: 1px solid #eaeaea;
413
+ display: flex;
414
+ align-items: center;
415
+ gap: 8px;
416
+ }
417
+ .app-title::before {
418
+ content: "▸";
419
+ font-size: 14px;
420
+ color: #3498db;
421
+ }
422
+ .grid {
423
+ display: grid;
424
+ grid-template-columns: repeat(3, 1fr);
425
+ gap: 0;
426
+ }
427
+ .account-card {
428
+ padding: 14px;
429
+ border-right: 1px solid #f0f0f0;
430
+ border-bottom: 1px solid #f0f0f0;
431
+ transition: all 0.2s ease;
432
+ position: relative;
433
+ min-height: 80px;
434
+ display: flex;
435
+ flex-direction: column;
436
+ }
437
+ .account-card:nth-child(odd) {
438
+ background: #f8f9fa;
439
+ }
440
+ .account-card:nth-child(even) {
441
+ background: #f0f2f5;
442
+ }
443
+ .account-card:hover {
444
+ background: #e6f3ff !important;
445
+ }
446
+ .account-card:nth-child(3n) {
447
+ border-right: none;
448
+ }
449
+ .account-card:last-child {
450
+ border-right: none;
451
+ }
452
+ .name-id-container {
453
+ display: flex;
454
+ justify-content: space-between;
455
+ align-items: center;
456
+ margin-bottom: 8px;
457
+ flex-wrap: wrap;
458
+ }
459
+ .name {
460
+ font-size: 14px;
461
+ font-weight: 600;
462
+ color: #2c3e50;
463
+ line-height: 1.3;
464
+ max-width: 60%;
465
+ overflow: hidden;
466
+ text-overflow: ellipsis;
467
+ white-space: nowrap;
468
+ }
469
+ .id {
470
+ font-size: 12px;
471
+ color: #5a6c7d;
472
+ font-family: 'Courier New', monospace;
473
+ background: #f8f9fa;
474
+ padding: 3px 6px;
475
+ border-radius: 3px;
476
+ line-height: 1.3;
477
+ max-width: 35%;
478
+ overflow: hidden;
479
+ text-overflow: ellipsis;
480
+ white-space: nowrap;
481
+ }
482
+ .name-id-container.vertical {
483
+ flex-direction: column;
484
+ align-items: flex-start;
485
+ }
486
+ .name-id-container.vertical .name {
487
+ max-width: 100%;
488
+ margin-bottom: 4px;
489
+ }
490
+ .name-id-container.vertical .id {
491
+ max-width: 100%;
492
+ align-self: flex-end;
493
+ }
494
+ .alias-status-container {
495
+ display: flex;
496
+ justify-content: space-between;
497
+ margin-top: 8px;
498
+ flex-grow: 1;
499
+ }
500
+ .alias-container {
501
+ flex: 1;
502
+ max-width: calc(100% - 70px);
503
+ align-self: flex-start;
504
+ }
505
+ .alias {
506
+ font-size: 11px;
507
+ color: #6c757d;
508
+ display: flex;
509
+ flex-wrap: wrap;
510
+ gap: 4px;
511
+ align-items: flex-start;
512
+ }
513
+ .alias-tag {
514
+ background: #e8f4fd;
515
+ color: #1971c2;
516
+ padding: 2px 6px;
517
+ border-radius: 10px;
518
+ border: 1px solid #a5d8ff;
519
+ white-space: nowrap;
520
+ margin-bottom: 2px;
521
+ }
522
+ .no-alias {
523
+ font-size: 11px;
524
+ color: #adb5bd;
525
+ font-style: italic;
526
+ }
527
+ .status-container {
528
+ display: flex;
529
+ align-items: flex-end;
530
+ margin-left: 8px;
531
+ }
532
+ .status {
533
+ display: inline-flex;
534
+ align-items: center;
535
+ gap: 6px;
536
+ padding: 3px 10px;
537
+ border-radius: 16px;
538
+ font-size: 11px;
539
+ font-weight: 600;
540
+ white-space: nowrap;
541
+ flex-shrink: 0;
542
+ }
543
+ .subscribed {
544
+ background: #d4edda;
545
+ color: #155724;
546
+ border: 1px solid #c3e6cb;
547
+ }
548
+ .unsubscribed {
549
+ background: #f8d7da;
550
+ color: #721c24;
551
+ border: 1px solid #f5c6cb;
552
+ }
553
+ .empty-state {
554
+ text-align: center;
555
+ color: #6c757d;
556
+ font-style: italic;
557
+ padding: 30px;
558
+ background: #f8f9fa;
559
+ grid-column: 1 / -1;
560
+ }
561
+ </style>
562
+ </head>
563
+ <body>
564
+ <div class="container">
565
+ <div class="header">
566
+ <h1>订阅状态总览</h1>
567
+ <div class="subtitle">群组 ID: ${groupId}</div>
568
+ </div>
569
+
570
+ <div class="apps-container">
571
+ ${Object.entries(availableAccounts).map(([app, accounts]) => {
572
+ const subscribed = subscribedByApp[app] || /* @__PURE__ */ new Set();
573
+ return `
574
+ <div class="app-section">
575
+ <div class="app-title">${app}</div>
576
+ <div class="grid">
577
+ ${accounts.length > 0 ? accounts.map((account) => {
578
+ const isSubscribed = subscribed.has(account.id);
579
+ const needsVerticalLayout = account.name.length > 15 || account.id.length > 20;
580
+ return `
581
+ <div class="account-card">
582
+ <div class="name-id-container ${needsVerticalLayout ? "vertical" : ""}">
583
+ <div class="name">${account.name}</div>
584
+ <div class="id">${account.id}</div>
585
+ </div>
586
+ <div class="alias-status-container">
587
+ <div class="alias-container">
588
+ ${account.alias.length > 0 ? `
589
+ <div class="alias">
590
+ ${account.alias.map((alias) => `<span class="alias-tag">${alias}</span>`).join("")}
591
+ </div>
592
+ ` : `<div class="no-alias">无别名</div>`}
593
+ </div>
594
+ <div class="status-container">
595
+ <div class="status ${isSubscribed ? "subscribed" : "unsubscribed"}">
596
+ ${isSubscribed ? "✅ 已订阅" : "❌ 未订阅"}
597
+ </div>
598
+ </div>
599
+ </div>
600
+ </div>
601
+ `;
602
+ }).join("") : `
603
+ <div class="empty-state">
604
+ 暂无可用账号
605
+ </div>
606
+ `}
607
+ </div>
608
+ </div>
609
+ `;
610
+ }).join("")}
611
+ </div>
612
+ </div>
613
+ </body>
614
+ </html>
615
+ `;
616
+ }
617
+ __name(generateSubscriptionHTML, "generateSubscriptionHTML");
354
618
  ctx.command("subscription.clear", "删除群组的所有订阅").alias("清空订阅").userFields(["authority"]).action(async ({ session }) => {
355
619
  if (!await this.authCheck(session, config)) {
356
620
  return "权限不足";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-subscription",
3
3
  "description": "给多个应用提供订阅群组管理",
4
- "version": "0.0.2",
4
+ "version": "0.0.4",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [