koishi-plugin-rocom 1.0.5 → 1.0.6

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.
@@ -103,11 +103,16 @@ function parseMerchantSubscriptionArgs(args, defaultItems) {
103
103
  if (parts[0] === '1' || parts[0] === '0') {
104
104
  mentionAll = parts.shift() === '1';
105
105
  }
106
- const items = parts.length ? parts : defaultItems;
106
+ const matchAll = parts.length === 1 && parts[0] === '全部';
107
+ if (matchAll)
108
+ parts.shift();
109
+ const items = matchAll ? [] : (parts.length ? parts : defaultItems);
110
+ const source = matchAll ? '全部商品' : (parts.length ? TEXT.customSource : TEXT.defaultSource);
107
111
  return {
108
112
  mention_all: mentionAll,
113
+ match_all: matchAll,
109
114
  items,
110
- source: parts.length ? TEXT.customSource : TEXT.defaultSource,
115
+ source,
111
116
  };
112
117
  }
113
118
  function getSubscriptionTarget(session) {
@@ -158,13 +163,26 @@ async function checkMerchantSubscriptions(deps) {
158
163
  let matchedCount = 0;
159
164
  let pushedCount = 0;
160
165
  for (const [key, sub] of Object.entries(subs)) {
161
- const matched = sub.items.filter((item) => productNames.some(n => n.includes(item)));
162
- if (!matched.length)
166
+ const matchAll = !!sub.match_all;
167
+ const matched = matchAll
168
+ ? productNames
169
+ : sub.items.filter((item) => productNames.some(n => n.includes(item)));
170
+ if (!matchAll && !matched.length)
163
171
  continue;
164
- matchedCount++;
165
- if (sub.last_push_round === roundInfo.round_id && sameStringArray(matched, sub.last_matched_items || []))
172
+ if (matchAll && !products.length)
166
173
  continue;
167
- const msg = `\ud83d\udd14 \u8fdc\u884c\u5546\u4eba\u5237\u65b0\u63d0\u9192\n\u5f53\u524d\u5546\u54c1\uff1a${productNames.join('\u3001')}\n\u5339\u914d\u8ba2\u9605\uff1a${matched.join('\u3001')}`;
174
+ matchedCount++;
175
+ if (matchAll) {
176
+ if (sub.last_push_round === roundInfo.round_id)
177
+ continue;
178
+ }
179
+ else {
180
+ if (sub.last_push_round === roundInfo.round_id && sameStringArray(matched, sub.last_matched_items || []))
181
+ continue;
182
+ }
183
+ const msg = matchAll
184
+ ? `\ud83d\udd14 \u8fdc\u884c\u5546\u4eba\u5237\u65b0\u63d0\u9192\n\u5f53\u524d\u5546\u54c1\uff1a${productNames.join('\u3001')}`
185
+ : `\ud83d\udd14 \u8fdc\u884c\u5546\u4eba\u5237\u65b0\u63d0\u9192\n\u5f53\u524d\u5546\u54c1\uff1a${productNames.join('\u3001')}\n\u5339\u914d\u8ba2\u9605\uff1a${matched.join('\u3001')}`;
168
186
  const platform = sub.platform || ctx.bots[0]?.platform;
169
187
  const channelId = sub.channel_id || sub.group_id || sub.user_id || key;
170
188
  if (!platform || !channelId) {
@@ -216,12 +234,13 @@ function register(deps) {
216
234
  channel_id: target.channelId,
217
235
  platform: target.platform,
218
236
  items: parsed.items,
237
+ match_all: parsed.match_all,
219
238
  mention_all: target.privateChat ? false : parsed.mention_all,
220
239
  last_push_round: existing?.last_push_round ?? null,
221
240
  last_matched_items: existing?.last_matched_items ?? [],
222
241
  updated_by: session.userId,
223
242
  });
224
- return `\u2705 \u5df2\u8ba2\u9605\u8fdc\u884c\u5546\u4eba\u5546\u54c1\uff1a${parsed.items.join('\u3001')}\uff08${parsed.source}\uff09\uff1b${target.privateChat ? '个人订阅' : (parsed.mention_all ? '\u547d\u4e2d\u540e\u4f1a @\u5168\u4f53' : '\u547d\u4e2d\u540e\u4e0d @\u5168\u4f53')}`;
243
+ return `\u2705 \u5df2\u8ba2\u9605\u8fdc\u884c\u5546\u4eba\u5546\u54c1\uff1a${parsed.match_all ? '\u5168\u90e8\u5546\u54c1\uff08\u6bcf\u8f6e\u63a8\u9001\uff09' : parsed.items.join('\u3001')}\uff08${parsed.source}\uff09\uff1b${target.privateChat ? '个人订阅' : (parsed.mention_all ? '\u547d\u4e2d\u540e\u4f1a @\u5168\u4f53' : '\u547d\u4e2d\u540e\u4e0d @\u5168\u4f53')}`;
225
244
  });
226
245
  ctx.command(TEXT.viewSubscribe, '\u67e5\u770b\u5f53\u524d\u4f1a\u8bdd\u7684\u8fdc\u884c\u5546\u4eba\u8ba2\u9605')
227
246
  .action(async ({ session }) => {
@@ -231,8 +250,9 @@ function register(deps) {
231
250
  const sub = merchantSubMgr.get(target.key);
232
251
  const scopeName = target.privateChat ? '你' : '当前群组';
233
252
  if (!sub)
234
- return `${scopeName}未订阅远行商人。\n用法:${TEXT.subscribe} [1/0] [商品名1] [商品名2] ...`;
235
- return `${scopeName}订阅商品:${sub.items.join('、')}\n提醒方式:${target.privateChat ? '私聊提醒' : (sub.mention_all ? '@全体' : '普通提醒')}`;
253
+ return `${scopeName}未订阅远行商人。\n用法:${TEXT.subscribe} [1/0] [商品名1] [商品名2] ...\n或:${TEXT.subscribe} 全部(每轮直接推送整张商人图)`;
254
+ const itemsText = sub.match_all ? '全部商品(每轮推送)' : sub.items.join('');
255
+ return `${scopeName}订阅商品:${itemsText}\n提醒方式:${target.privateChat ? '私聊提醒' : (sub.mention_all ? '@全体' : '普通提醒')}`;
236
256
  });
237
257
  ctx.command(TEXT.unsubscribe, '\u53d6\u6d88\u8fdc\u884c\u5546\u4eba\u8ba2\u9605')
238
258
  .action(async ({ session }) => {
package/lib/user.d.ts CHANGED
@@ -13,6 +13,7 @@ export interface MerchantSubscription {
13
13
  user_id?: string;
14
14
  type?: string;
15
15
  mention_all: boolean;
16
+ match_all?: boolean;
16
17
  items: string[];
17
18
  last_push_round: string | null;
18
19
  last_matched_items: string[];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-rocom",
3
3
  "description": "洛克王国查询与订阅插件",
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "homepage": "https://github.com/staytomorrow/koishi-plugin-rocom",
package/readme.md CHANGED
@@ -16,7 +16,7 @@ Koishi 版洛克王国数据查询插件。插件基于 WeGame / 后端接口提
16
16
  | --- | --- |
17
17
  | 账号管理 | QQ 扫码登录、微信扫码登录、凭证导入、绑定列表、切换账号、解绑、刷新凭证 |
18
18
  | 数据查询 | 档案、战绩、背包、阵容推荐、阵容详情、交换大厅 |
19
- | 商人提醒 | 远行商人查询、远行商人商品订阅、取消订阅 |
19
+ | 商人提醒 | 远行商人查询、商品关键词订阅、全部订阅(每轮直推整图)、查看订阅、取消订阅 |
20
20
  | 百科查询 | 精灵 Wiki、技能 Wiki |
21
21
  | 查蛋配种 | 精灵查蛋、尺寸反查、候选结果、目标配种方案、配种判定 |
22
22
  | 管理维护 | 刷新所有凭证、删除失效绑定、自动刷新凭证 |
@@ -275,23 +275,34 @@ Koishi 版洛克王国数据查询插件。插件基于 WeGame / 后端接口提
275
275
 
276
276
  > 图片位置:远行商人商品截图。建议插入 `docs/images/merchant-current.png`。
277
277
 
278
- ### `订阅远行商人 [商品名...]`
278
+ ### `订阅远行商人 [1/0] [商品名... | 全部]`
279
279
 
280
- 在群聊中订阅远行商人商品提醒。群内操作仅 `adminUserIds` 中配置的 Bot 管理员可设置;私聊场景支持个人自行订阅(需开启 `merchantPrivateSubscriptionEnabled`)。
280
+ 在群聊中订阅远行商人提醒。群内操作仅 `adminUserIds` 中配置的 Bot 管理员可设置;私聊场景支持个人自行订阅(需开启 `merchantPrivateSubscriptionEnabled`)。
281
281
 
282
- 查看当前订阅:
282
+ 参数说明:
283
+
284
+ - 第一个可选参数 `1` / `0`:仅群聊生效。`1` 表示命中后 @全体成员,`0` 表示不 @全体。省略时默认 `0`。私聊订阅强制为不 @。
285
+ - 后续参数为订阅商品名,按"包含关系"与当前商品名做模糊匹配(例如订阅 `国王球` 会命中 `国王球(大)`)。
286
+ - 若只传一个特殊关键字 `全部`,则进入 **全部订阅模式**:忽略商品匹配,只要远行商人本轮有在售商品,就把整张远行商人渲染图直接推送给订阅方。每轮(`08:00 / 12:00 / 16:00 / 20:00`)只推一次。
287
+ - 不传任何商品名时,使用配置里的 `merchantSubscriptionItems` 作为默认关键词。
288
+
289
+ 查看当前会话的订阅:
283
290
 
284
291
  ```text
285
- 订阅远行商人
292
+ 查看远行商人订阅
286
293
  ```
287
294
 
288
- 设置订阅商品:
295
+ 常见用法:
289
296
 
290
297
  ```text
291
- 订阅远行商人 国王球 棱镜球 炫彩精灵蛋
298
+ 订阅远行商人 # 使用配置中的默认关键词
299
+ 订阅远行商人 国王球 棱镜球 炫彩精灵蛋 # 按关键词匹配
300
+ 订阅远行商人 1 国王球 # 命中后 @全体
301
+ 订阅远行商人 全部 # 每轮直接推送整张商人图
302
+ 订阅远行商人 1 全部 # 每轮推送并 @全体
292
303
  ```
293
304
 
294
- 插件会定时检查远行商人商品,当当前商品命中订阅关键词时推送提醒。
305
+ 按关键词订阅时,去重规则是"同一轮次 + 同一匹配商品集合"只推一次;全部订阅模式下仅按轮次去重,本轮推过就不再重复。
295
306
 
296
307
  > 图片位置:订阅远行商人结果截图。建议插入 `docs/images/merchant-subscribe.png`。
297
308
 
@@ -537,8 +548,9 @@ autoRefreshTime:
537
548
  请检查:
538
549
 
539
550
  - `merchantSubscriptionEnabled` 是否开启。
540
- - 群聊是否已经使用 `订阅远行商人 <商品名>` 设置订阅。
541
- - 商品名称是否能匹配当前远行商人商品。
551
+ - 会话是否已经使用 `订阅远行商人` 设置订阅,可用 `查看远行商人订阅` 确认当前订阅内容。
552
+ - 按关键词订阅时,商品名称是否能命中当前远行商人商品(按包含关系匹配)。
553
+ - 全部订阅模式(`订阅远行商人 全部`)在本轮商品为空时不会推送;每轮 `08:00 / 12:00 / 16:00 / 20:00` 只推一次,已推过的轮次不会重复。
542
554
  - Bot 是否有向目标群聊发送消息的权限。
543
555
 
544
556
  > 图片位置:远行商人订阅排查截图。建议插入 `docs/images/faq-merchant-subscription.png`。