koishi-plugin-prism-neo 0.0.25 → 0.0.27
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.js +616 -199
- package/lib/model.d.ts +14 -0
- package/lib/service.d.ts +60 -31
- package/lib/types.d.ts +3 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -28,154 +28,218 @@ module.exports = __toCommonJS(src_exports);
|
|
|
28
28
|
var import_koishi = require("koishi");
|
|
29
29
|
|
|
30
30
|
// src/service.ts
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
var PrismService = class {
|
|
32
|
+
constructor(ctx, config) {
|
|
33
|
+
this.ctx = ctx;
|
|
34
|
+
this.config = config;
|
|
35
|
+
this.apiBase = `${config.url.trimEnd().replace(/\/+$/, "")}/api`;
|
|
36
|
+
}
|
|
37
|
+
static {
|
|
38
|
+
__name(this, "PrismService");
|
|
39
|
+
}
|
|
40
|
+
apiBase;
|
|
41
|
+
url(endpoint) {
|
|
42
|
+
return `${this.apiBase}/${endpoint.trimStart().replace(/^\/+/, "")}`;
|
|
43
|
+
}
|
|
44
|
+
async register(userId) {
|
|
45
|
+
return await this.ctx.http.post(
|
|
46
|
+
this.url("/users"),
|
|
47
|
+
[
|
|
48
|
+
{
|
|
49
|
+
"binds": [
|
|
50
|
+
{
|
|
51
|
+
"type": "QQ",
|
|
52
|
+
"bid": userId
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
async login(userId) {
|
|
60
|
+
return await this.ctx.http.post(
|
|
61
|
+
this.url(`/users/QQ:${userId}/login`)
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
async history(userId, limit) {
|
|
65
|
+
return await this.ctx.http.get(
|
|
66
|
+
this.url(`/users/QQ:${userId}/sortedsessions?limit=${limit}`)
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
async logout(userId) {
|
|
70
|
+
return await this.ctx.http.post(
|
|
71
|
+
this.url(`/users/QQ:${userId}/logout`)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
async billing(userId) {
|
|
75
|
+
return await this.ctx.http.get(
|
|
76
|
+
this.url(`/users/QQ:${userId}/billing`)
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
async list() {
|
|
80
|
+
return await this.ctx.http.get(
|
|
81
|
+
this.url(`/users/logined?binds=true&sessions=true`)
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
async wallet(userId) {
|
|
85
|
+
return await this.ctx.http.get(
|
|
86
|
+
this.url(`/users/QQ:${userId}/wallet?details=true`)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
async assets(userId) {
|
|
90
|
+
return await this.ctx.http.get(
|
|
91
|
+
this.url(`/users/QQ:${userId}/assets?details=true`)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
async upsertUserAssets(userId, assets) {
|
|
95
|
+
return await this.ctx.http.post(
|
|
96
|
+
this.url(`/users/QQ:${userId}/assets`),
|
|
97
|
+
assets
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
async deleteUserAsset(userId, userAssetId) {
|
|
101
|
+
return await this.ctx.http.delete(
|
|
102
|
+
this.url(`/users/QQ:${userId}/assets/${userAssetId}`)
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
async updateUserAsset(userId, userAssetId, amount) {
|
|
106
|
+
return await this.ctx.http.patch(
|
|
107
|
+
this.url(`/users/QQ:${userId}/assets/${userAssetId}`),
|
|
108
|
+
{ amount }
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
async getLock(userId) {
|
|
112
|
+
return await this.ctx.http.get(
|
|
113
|
+
this.url(`/users/QQ:${userId}/door-password`)
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
async machinePowerOn(machineName, userId, needLogin = true) {
|
|
117
|
+
return await this.ctx.http.post(
|
|
118
|
+
this.url(`/machine/power`),
|
|
39
119
|
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
]
|
|
120
|
+
machineName,
|
|
121
|
+
powerState: true,
|
|
122
|
+
userId: `QQ:${userId}`,
|
|
123
|
+
needLogin
|
|
46
124
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
__name(redeem, "redeem");
|
|
169
|
-
async function insertCoin({ ctx, config }, alias, userId, force = false) {
|
|
170
|
-
return await ctx.http.post(
|
|
171
|
-
makeUrl(config.url, `/remote/${alias}/coin`),
|
|
172
|
-
{
|
|
173
|
-
userId: `QQ:${userId}`,
|
|
174
|
-
force
|
|
175
|
-
}
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
__name(insertCoin, "insertCoin");
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
async machinePowerOff(machineName, userId, needLogin = true) {
|
|
128
|
+
return await this.ctx.http.post(
|
|
129
|
+
this.url(`/machine/power`),
|
|
130
|
+
{
|
|
131
|
+
machineName,
|
|
132
|
+
powerState: false,
|
|
133
|
+
userId: `QQ:${userId}`,
|
|
134
|
+
needLogin
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
async getAllMachinePower() {
|
|
139
|
+
return await this.ctx.http.get(
|
|
140
|
+
this.url(`/machine/power`)
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
async getMachinePower(machineName) {
|
|
144
|
+
return await this.ctx.http.get(
|
|
145
|
+
this.url(`/machine/power?name=${machineName}`)
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
async walletAdd(amount, userId) {
|
|
149
|
+
return await this.ctx.http.post(
|
|
150
|
+
this.url(`/users/QQ:${userId}/wallet`),
|
|
151
|
+
{
|
|
152
|
+
type: "free",
|
|
153
|
+
action: amount,
|
|
154
|
+
comment: "管理员添加"
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
async walletDel(amount, userId) {
|
|
159
|
+
return await this.ctx.http.post(
|
|
160
|
+
this.url(`/users/QQ:${userId}/wallet`),
|
|
161
|
+
{
|
|
162
|
+
type: "free",
|
|
163
|
+
action: -amount,
|
|
164
|
+
comment: "管理员扣除"
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
async costOverwrite(amount, userId) {
|
|
169
|
+
return await this.ctx.http.post(
|
|
170
|
+
this.url(`/users/QQ:${userId}/billing-overwrite`),
|
|
171
|
+
{
|
|
172
|
+
cost: parseInt(amount)
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
async redeem(code, userId) {
|
|
177
|
+
return await this.ctx.http.post(
|
|
178
|
+
this.url(`/users/QQ:${userId}/redeem`),
|
|
179
|
+
{
|
|
180
|
+
code
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
async insertCoin(alias, userId, force = false) {
|
|
185
|
+
return await this.ctx.http.post(
|
|
186
|
+
this.url(`/remote/${alias}/coin`),
|
|
187
|
+
{
|
|
188
|
+
userId: `QQ:${userId}`,
|
|
189
|
+
force
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
// --- Admin API ---
|
|
194
|
+
async adminListAssets() {
|
|
195
|
+
return await this.ctx.http.get(this.url("/admin/assets"));
|
|
196
|
+
}
|
|
197
|
+
async adminCreateAsset(data) {
|
|
198
|
+
return await this.ctx.http.post(this.url("/admin/assets"), data);
|
|
199
|
+
}
|
|
200
|
+
async adminDeleteAsset(id) {
|
|
201
|
+
return await this.ctx.http.delete(this.url(`/admin/assets/${id}`));
|
|
202
|
+
}
|
|
203
|
+
async adminListCoupons() {
|
|
204
|
+
return await this.ctx.http.get(this.url("/admin/coupons"));
|
|
205
|
+
}
|
|
206
|
+
async adminCreateCoupon(data) {
|
|
207
|
+
return await this.ctx.http.post(this.url("/admin/coupons"), data);
|
|
208
|
+
}
|
|
209
|
+
async adminListGifts() {
|
|
210
|
+
return await this.ctx.http.get(this.url("/admin/gifts"));
|
|
211
|
+
}
|
|
212
|
+
async adminCreateGift(data) {
|
|
213
|
+
return await this.ctx.http.post(this.url("/admin/gifts"), data);
|
|
214
|
+
}
|
|
215
|
+
async adminDeleteGift(id) {
|
|
216
|
+
return await this.ctx.http.delete(this.url(`/admin/gifts/${id}`));
|
|
217
|
+
}
|
|
218
|
+
async adminGenerateGiftCodes(id, count) {
|
|
219
|
+
return await this.ctx.http.post(this.url(`/admin/gifts/${id}/codes`), { count });
|
|
220
|
+
}
|
|
221
|
+
async adminListRules() {
|
|
222
|
+
return await this.ctx.http.get(this.url("/admin/rules"));
|
|
223
|
+
}
|
|
224
|
+
async adminCreateRule(data) {
|
|
225
|
+
return await this.ctx.http.post(this.url("/admin/rules"), data);
|
|
226
|
+
}
|
|
227
|
+
async adminDeleteRule(id) {
|
|
228
|
+
return await this.ctx.http.delete(this.url(`/admin/rules/${id}`));
|
|
229
|
+
}
|
|
230
|
+
async adminUpdateRuleStatus(id, available) {
|
|
231
|
+
return await this.ctx.http(this.url(`/admin/rules/${id}`), {
|
|
232
|
+
method: "PATCH",
|
|
233
|
+
data: { available }
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
async adminAddUserAsset(userId, id, count) {
|
|
237
|
+
return await this.ctx.http.post(this.url(`/users/QQ:${userId}/assets`), {
|
|
238
|
+
id,
|
|
239
|
+
count
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
};
|
|
179
243
|
|
|
180
244
|
// src/index.ts
|
|
181
245
|
var name = "prism-neo";
|
|
@@ -214,15 +278,22 @@ var handleAction = /* @__PURE__ */ __name((action) => {
|
|
|
214
278
|
if (apiMessage) {
|
|
215
279
|
message = apiMessage;
|
|
216
280
|
} else {
|
|
217
|
-
message =
|
|
281
|
+
message = e.message;
|
|
218
282
|
}
|
|
219
283
|
}
|
|
284
|
+
if (!message) return;
|
|
220
285
|
if (argv.session?.messageId) {
|
|
221
286
|
message = (0, import_koishi.h)("quote", { id: argv.session.messageId }) + message;
|
|
222
287
|
}
|
|
223
288
|
return message;
|
|
224
289
|
};
|
|
225
290
|
}, "handleAction");
|
|
291
|
+
async function checkAdmin(context) {
|
|
292
|
+
if (!await context.ctx.permissions.check(context.config.admin, context.session)) {
|
|
293
|
+
throw new Error("权限不足");
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
__name(checkAdmin, "checkAdmin");
|
|
226
297
|
var formatDateTime = /* @__PURE__ */ __name((dateStr) => {
|
|
227
298
|
if (!dateStr) return "永不过期";
|
|
228
299
|
const date = new Date(dateStr);
|
|
@@ -311,7 +382,7 @@ var formatBilling = /* @__PURE__ */ __name((res, currency) => {
|
|
|
311
382
|
}
|
|
312
383
|
return message.join("\n");
|
|
313
384
|
}, "formatBilling");
|
|
314
|
-
async function executeWithAutoRegister(context, userArg,
|
|
385
|
+
async function executeWithAutoRegister(context, userArg, action, formatter) {
|
|
315
386
|
try {
|
|
316
387
|
const res = await action();
|
|
317
388
|
return await formatter(res);
|
|
@@ -344,7 +415,7 @@ async function getTargetUserId(context, user) {
|
|
|
344
415
|
if (!await context.ctx.permissions.check(context.config.admin, context.session)) {
|
|
345
416
|
return { error: "权限不足" };
|
|
346
417
|
}
|
|
347
|
-
return { userId: user.split(":")[1] };
|
|
418
|
+
return { userId: user.split(":")[1] ?? user };
|
|
348
419
|
}
|
|
349
420
|
return { userId: context.session.userId };
|
|
350
421
|
}
|
|
@@ -352,27 +423,33 @@ __name(getTargetUserId, "getTargetUserId");
|
|
|
352
423
|
async function handleRegisterCmd(context, user) {
|
|
353
424
|
const { error, userId } = await getTargetUserId(context, user);
|
|
354
425
|
if (error) return error;
|
|
355
|
-
await register(
|
|
426
|
+
await context.prism.register(userId);
|
|
356
427
|
return user ? `为用户 ${userId} 注册成功` : "注册成功";
|
|
357
428
|
}
|
|
358
429
|
__name(handleRegisterCmd, "handleRegisterCmd");
|
|
359
430
|
async function handleLoginCmd(context, user) {
|
|
360
431
|
const { error, userId } = await getTargetUserId(context, user);
|
|
361
432
|
if (error) return error;
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
433
|
+
return executeWithAutoRegister(
|
|
434
|
+
context,
|
|
435
|
+
user,
|
|
436
|
+
() => context.prism.login(userId),
|
|
437
|
+
async (res) => {
|
|
438
|
+
let message = "✅ 入场成功";
|
|
439
|
+
if (context.config.autoLockOnLogin) {
|
|
440
|
+
let lockMessage = await handleLockCmd(context);
|
|
441
|
+
message += "\n\n" + lockMessage;
|
|
442
|
+
}
|
|
443
|
+
return message;
|
|
444
|
+
}
|
|
445
|
+
);
|
|
369
446
|
}
|
|
370
447
|
__name(handleLoginCmd, "handleLoginCmd");
|
|
371
448
|
async function handleLogoutCmd(context, user) {
|
|
372
449
|
const { error, userId: targetUserId } = await getTargetUserId(context, user);
|
|
373
450
|
if (error) return error;
|
|
374
451
|
if (!context.config.logoutConfirmation) {
|
|
375
|
-
const res = await logout(
|
|
452
|
+
const res = await context.prism.logout(targetUserId);
|
|
376
453
|
let name2 = await getUserName(context.session, targetUserId);
|
|
377
454
|
let message = user ? `✅ 已为用户 ${name2} 退场` : "✅ 退场成功";
|
|
378
455
|
message += "\n";
|
|
@@ -385,7 +462,7 @@ ${message}`);
|
|
|
385
462
|
const now = Date.now();
|
|
386
463
|
if (pendingLogout && now - pendingLogout < 60 * 1e3) {
|
|
387
464
|
kv.delete(targetUserId);
|
|
388
|
-
const res = await logout(
|
|
465
|
+
const res = await context.prism.logout(targetUserId);
|
|
389
466
|
const messagePrefix = user ? `✅ 已为用户 ${await getUserName(context.session, targetUserId)} 退场` : "✅ 退场成功";
|
|
390
467
|
return [
|
|
391
468
|
messagePrefix,
|
|
@@ -394,7 +471,7 @@ ${message}`);
|
|
|
394
471
|
`消费: ${res.session.finalCost} ${context.config.currency}`
|
|
395
472
|
].join("\n");
|
|
396
473
|
} else {
|
|
397
|
-
const billingRes = await billing(
|
|
474
|
+
const billingRes = await context.prism.billing(targetUserId);
|
|
398
475
|
const billingMessage = formatBilling(billingRes, context.config.currency);
|
|
399
476
|
kv.set(targetUserId, now);
|
|
400
477
|
if (user) {
|
|
@@ -413,9 +490,9 @@ ${billingMessage}
|
|
|
413
490
|
}
|
|
414
491
|
__name(handleLogoutCmd, "handleLogoutCmd");
|
|
415
492
|
async function handleListCmd(context, user) {
|
|
416
|
-
const users = await list(
|
|
493
|
+
const users = await context.prism.list();
|
|
417
494
|
if (!users || users.length === 0) {
|
|
418
|
-
return "窝里目前没有玩家呢";
|
|
495
|
+
return "🫥 窝里目前没有玩家呢";
|
|
419
496
|
}
|
|
420
497
|
const tasks = users.map((user2) => {
|
|
421
498
|
const entryDate = formatDateTime(user2.sessions[0].createdAt);
|
|
@@ -428,7 +505,7 @@ async function handleListCmd(context, user) {
|
|
|
428
505
|
return `玩家: ${u}
|
|
429
506
|
入场时间: ${tasks[idx].entryDate}`;
|
|
430
507
|
});
|
|
431
|
-
return
|
|
508
|
+
return `👥 窝里目前共有 ${users.length} 人
|
|
432
509
|
|
|
433
510
|
${userReports.join("\n\n")}`;
|
|
434
511
|
}
|
|
@@ -436,10 +513,10 @@ __name(handleListCmd, "handleListCmd");
|
|
|
436
513
|
async function handleWalletCmd(context, user) {
|
|
437
514
|
const { error, userId } = await getTargetUserId(context, user);
|
|
438
515
|
if (error) return error;
|
|
439
|
-
const res = await wallet(
|
|
516
|
+
const res = await context.prism.wallet(userId);
|
|
440
517
|
const message = [];
|
|
441
518
|
const targetUserId = user ? userId : void 0;
|
|
442
|
-
message.push(targetUserId ?
|
|
519
|
+
message.push(targetUserId ? `💰 --- 用户 ${await getUserName(context.session, targetUserId)} 的钱包余额 ---` : "💰 --- 钱包余额 ---");
|
|
443
520
|
message.push(
|
|
444
521
|
`可用: ${res.total.available} ${context.config.currency} (共 ${res.total.all})`,
|
|
445
522
|
` - 付费: ${res.paid.available}`,
|
|
@@ -478,10 +555,48 @@ async function handleWalletCmd(context, user) {
|
|
|
478
555
|
return message.join("\n");
|
|
479
556
|
}
|
|
480
557
|
__name(handleWalletCmd, "handleWalletCmd");
|
|
558
|
+
async function handleHistoriesCmd(context, arg1, arg2) {
|
|
559
|
+
let limit = 10;
|
|
560
|
+
let userArg;
|
|
561
|
+
if (arg1) {
|
|
562
|
+
if (arg1.startsWith("@")) {
|
|
563
|
+
userArg = arg1.replace("@", "");
|
|
564
|
+
if (!userArg.includes(":")) {
|
|
565
|
+
userArg = `onebot:${userArg}`;
|
|
566
|
+
}
|
|
567
|
+
if (arg2 && /^\d+$/.test(String(arg2))) {
|
|
568
|
+
limit = parseInt(String(arg2));
|
|
569
|
+
}
|
|
570
|
+
} else if (/^\d+$/.test(arg1)) {
|
|
571
|
+
limit = parseInt(arg1);
|
|
572
|
+
} else {
|
|
573
|
+
userArg = arg1;
|
|
574
|
+
if (arg2 && /^\d+$/.test(String(arg2))) {
|
|
575
|
+
limit = parseInt(String(arg2));
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
const { error, userId } = await getTargetUserId(context, userArg);
|
|
580
|
+
if (error) return error;
|
|
581
|
+
console.log(userId);
|
|
582
|
+
const res = await context.prism.history(userId, limit);
|
|
583
|
+
if (!res || !res.sessions || res.sessions.length === 0) {
|
|
584
|
+
return "暂无历史记录";
|
|
585
|
+
}
|
|
586
|
+
const message = [`📜 最近 ${res.sessions.length} 条记录:`];
|
|
587
|
+
res.sessions.forEach((s) => {
|
|
588
|
+
const start = formatDateTime(s.createdAt);
|
|
589
|
+
const end = s.closedAt ? formatDateTime(s.closedAt) : "进行中";
|
|
590
|
+
const cost = s.finalCost !== null ? `${s.finalCost} ${context.config.currency}` : "未结算";
|
|
591
|
+
message.push(`- [${s.id}] ${start} -> ${end} (${cost})`);
|
|
592
|
+
});
|
|
593
|
+
return message.join("\n");
|
|
594
|
+
}
|
|
595
|
+
__name(handleHistoriesCmd, "handleHistoriesCmd");
|
|
481
596
|
async function handleBillingCmd(context, user) {
|
|
482
597
|
const { error, userId } = await getTargetUserId(context, user);
|
|
483
598
|
if (error) return error;
|
|
484
|
-
const res = await billing(
|
|
599
|
+
const res = await context.prism.billing(userId);
|
|
485
600
|
const billingMessage = formatBilling(res, context.config.currency);
|
|
486
601
|
if (user) {
|
|
487
602
|
return `用户 ${await getUserName(context.session, userId)} 的账单:
|
|
@@ -492,9 +607,9 @@ ${billingMessage}`;
|
|
|
492
607
|
}
|
|
493
608
|
__name(handleBillingCmd, "handleBillingCmd");
|
|
494
609
|
async function handleLockCmd(context) {
|
|
495
|
-
const res = await getLock(context
|
|
610
|
+
const res = await context.prism.getLock(context.session.userId);
|
|
496
611
|
return [
|
|
497
|
-
"获取密码成功",
|
|
612
|
+
"🔑 获取密码成功",
|
|
498
613
|
`你的门锁密码是: ${res.password}`,
|
|
499
614
|
`输入完成后按 # 结束`,
|
|
500
615
|
"注意! 门锁密码有效期为三分钟"
|
|
@@ -504,11 +619,11 @@ __name(handleLockCmd, "handleLockCmd");
|
|
|
504
619
|
async function handleItemsCmd(context, user) {
|
|
505
620
|
const { error, userId } = await getTargetUserId(context, user);
|
|
506
621
|
if (error) return error;
|
|
507
|
-
const userAssets = await assets(
|
|
622
|
+
const userAssets = await context.prism.assets(userId);
|
|
508
623
|
if (!userAssets || userAssets.length === 0) {
|
|
509
624
|
return user ? `用户 ${await getUserName(context.session, userId)} 没有任何物品。` : "您当前没有任何物品。";
|
|
510
625
|
}
|
|
511
|
-
const header = user ?
|
|
626
|
+
const header = user ? `🎒 --- 用户 ${await getUserName(context.session, userId)} 拥有的物品 ---` : "🎒 --- 您拥有的物品 ---";
|
|
512
627
|
const itemsList = userAssets.map((asset) => {
|
|
513
628
|
let line = `- ${asset.asset.name} (x${asset.count})`;
|
|
514
629
|
if (asset.expireAt) {
|
|
@@ -524,26 +639,32 @@ async function handleItemsCmd(context, user) {
|
|
|
524
639
|
}
|
|
525
640
|
__name(handleItemsCmd, "handleItemsCmd");
|
|
526
641
|
async function handleMachineOn(context, alias) {
|
|
527
|
-
if (!alias)
|
|
642
|
+
if (!alias) {
|
|
643
|
+
await context.session.execute("help on");
|
|
644
|
+
return "";
|
|
645
|
+
}
|
|
528
646
|
let isAdmin = await context.ctx.permissions.check(context.config.admin, context.session);
|
|
529
|
-
const res = await machinePowerOn(
|
|
530
|
-
return
|
|
647
|
+
const res = await context.prism.machinePowerOn(alias, context.session.userId, !isAdmin);
|
|
648
|
+
return `✅ ${res.machine} 启动成功`;
|
|
531
649
|
}
|
|
532
650
|
__name(handleMachineOn, "handleMachineOn");
|
|
533
651
|
async function handleMachineOff(context, alias) {
|
|
534
|
-
if (!alias)
|
|
652
|
+
if (!alias) {
|
|
653
|
+
await context.session.execute("help off");
|
|
654
|
+
return "";
|
|
655
|
+
}
|
|
535
656
|
let isAdmin = await context.ctx.permissions.check(context.config.admin, context.session);
|
|
536
|
-
const res = await machinePowerOff(
|
|
537
|
-
if (alias === "all") return
|
|
538
|
-
return
|
|
657
|
+
const res = await context.prism.machinePowerOff(alias, context.session.userId, !isAdmin);
|
|
658
|
+
if (alias === "all") return `🛑 全部机器关闭成功`;
|
|
659
|
+
return `🛑 ${res.machine} 关闭成功`;
|
|
539
660
|
}
|
|
540
661
|
__name(handleMachineOff, "handleMachineOff");
|
|
541
662
|
async function handleMachineShow(context, alias) {
|
|
542
663
|
if (alias) {
|
|
543
|
-
const res = await getMachinePower(
|
|
664
|
+
const res = await context.prism.getMachinePower(alias);
|
|
544
665
|
return `${res.machine}: ${res.state.state}`;
|
|
545
666
|
} else {
|
|
546
|
-
const res = await getAllMachinePower(
|
|
667
|
+
const res = await context.prism.getAllMachinePower();
|
|
547
668
|
return res.map(
|
|
548
669
|
(e) => {
|
|
549
670
|
return `${e.machine}: ${e.state.state}`;
|
|
@@ -553,14 +674,16 @@ async function handleMachineShow(context, alias) {
|
|
|
553
674
|
}
|
|
554
675
|
__name(handleMachineShow, "handleMachineShow");
|
|
555
676
|
async function handleWalletAdd(context, user, amount) {
|
|
677
|
+
if (!user || !amount) {
|
|
678
|
+
await context.session.execute("help add");
|
|
679
|
+
return "";
|
|
680
|
+
}
|
|
556
681
|
const { error, userId } = await getTargetUserId(context, user);
|
|
557
682
|
if (error) return error;
|
|
558
|
-
if (!amount) return "请输入数量";
|
|
559
683
|
return executeWithAutoRegister(
|
|
560
684
|
context,
|
|
561
685
|
user,
|
|
562
|
-
userId,
|
|
563
|
-
() => walletAdd(context, parseInt(amount), userId),
|
|
686
|
+
() => context.prism.walletAdd(parseFloat(amount), userId),
|
|
564
687
|
async (res) => {
|
|
565
688
|
return [
|
|
566
689
|
`为用户 ${await getUserName(context.session, userId)} 增加${context.config.currency}成功`,
|
|
@@ -572,14 +695,16 @@ async function handleWalletAdd(context, user, amount) {
|
|
|
572
695
|
}
|
|
573
696
|
__name(handleWalletAdd, "handleWalletAdd");
|
|
574
697
|
async function handleWalletDeduct(context, user, amount) {
|
|
698
|
+
if (!user || !amount) {
|
|
699
|
+
await context.session.execute("help del");
|
|
700
|
+
return "";
|
|
701
|
+
}
|
|
575
702
|
const { error, userId } = await getTargetUserId(context, user);
|
|
576
703
|
if (error) return error;
|
|
577
|
-
if (!amount) return "请输入数量";
|
|
578
704
|
return executeWithAutoRegister(
|
|
579
705
|
context,
|
|
580
706
|
user,
|
|
581
|
-
userId,
|
|
582
|
-
() => walletDel(context, parseInt(amount), userId),
|
|
707
|
+
() => context.prism.walletDel(parseInt(amount), userId),
|
|
583
708
|
(res) => {
|
|
584
709
|
return [
|
|
585
710
|
`为用户 ${userId} 扣除${context.config.currency}成功`,
|
|
@@ -591,27 +716,31 @@ async function handleWalletDeduct(context, user, amount) {
|
|
|
591
716
|
}
|
|
592
717
|
__name(handleWalletDeduct, "handleWalletDeduct");
|
|
593
718
|
async function handleCostOverwrite(context, user, amount) {
|
|
719
|
+
if (!user || !amount) {
|
|
720
|
+
await context.session.execute("help overwrite");
|
|
721
|
+
return "";
|
|
722
|
+
}
|
|
594
723
|
const { error, userId } = await getTargetUserId(context, user);
|
|
595
724
|
if (error) return error;
|
|
596
|
-
if (!amount) return "请输入数量";
|
|
597
725
|
return executeWithAutoRegister(
|
|
598
726
|
context,
|
|
599
727
|
user,
|
|
600
|
-
userId,
|
|
601
|
-
() => costOverwrite(context, amount, userId),
|
|
728
|
+
() => context.prism.costOverwrite(amount, userId),
|
|
602
729
|
() => `为用户 ${userId} 调价成功`
|
|
603
730
|
);
|
|
604
731
|
}
|
|
605
732
|
__name(handleCostOverwrite, "handleCostOverwrite");
|
|
606
733
|
async function handleRedeem(context, code) {
|
|
734
|
+
if (!code) {
|
|
735
|
+
await context.session.execute("help redeem");
|
|
736
|
+
return "";
|
|
737
|
+
}
|
|
607
738
|
const { error, userId } = await getTargetUserId(context, null);
|
|
608
739
|
if (error) return error;
|
|
609
|
-
if (!code) return "请输入兑换码";
|
|
610
740
|
return executeWithAutoRegister(
|
|
611
741
|
context,
|
|
612
742
|
void 0,
|
|
613
|
-
userId,
|
|
614
|
-
() => redeem(context, code, userId),
|
|
743
|
+
() => context.prism.redeem(code, userId),
|
|
615
744
|
(res) => {
|
|
616
745
|
const items = res;
|
|
617
746
|
if (!items || items.length === 0) {
|
|
@@ -632,19 +761,290 @@ async function handleRedeem(context, code) {
|
|
|
632
761
|
}
|
|
633
762
|
__name(handleRedeem, "handleRedeem");
|
|
634
763
|
async function handleCoin(context, alias) {
|
|
635
|
-
if (!alias)
|
|
764
|
+
if (!alias) {
|
|
765
|
+
await context.session.execute("help coin");
|
|
766
|
+
return "";
|
|
767
|
+
}
|
|
636
768
|
let isAdmin = await context.ctx.permissions.check(context.config.admin, context.session);
|
|
637
|
-
const res = await insertCoin(
|
|
638
|
-
return
|
|
769
|
+
const res = await context.prism.insertCoin(alias, context.session.userId, isAdmin);
|
|
770
|
+
return `🪙 已为 ${res.machineName} 投入 ${res.count} 个币`;
|
|
639
771
|
}
|
|
640
772
|
__name(handleCoin, "handleCoin");
|
|
773
|
+
async function handleAdminListAssets(context) {
|
|
774
|
+
await checkAdmin(context);
|
|
775
|
+
const res = await context.prism.adminListAssets();
|
|
776
|
+
if (!res || res.length === 0) return "暂无资产";
|
|
777
|
+
return res.map((a) => {
|
|
778
|
+
const status = a.valid ? "[有效]" : "[无效]";
|
|
779
|
+
const typeInfo = `${a.type} (ID:${a.assetId})`;
|
|
780
|
+
let timeInfo = "";
|
|
781
|
+
if (a.activeAt || a.expireAt) {
|
|
782
|
+
const start = a.activeAt ? formatDateTime(a.activeAt) : "不限";
|
|
783
|
+
const end = a.expireAt ? formatDateTime(a.expireAt) : "不限";
|
|
784
|
+
timeInfo = `
|
|
785
|
+
有效期: ${start} -> ${end}`;
|
|
786
|
+
}
|
|
787
|
+
const desc = a.description ? `
|
|
788
|
+
描述: ${a.description}` : "";
|
|
789
|
+
return `${status} [${a.id}] ${a.name}
|
|
790
|
+
类型: ${typeInfo}${timeInfo}${desc}`;
|
|
791
|
+
}).join("\n\n");
|
|
792
|
+
}
|
|
793
|
+
__name(handleAdminListAssets, "handleAdminListAssets");
|
|
794
|
+
async function handleAdminAddAsset(context, type, assetId, name2, desc) {
|
|
795
|
+
await checkAdmin(context);
|
|
796
|
+
const opts = context.options || {};
|
|
797
|
+
if (!type || assetId === void 0 || !name2) {
|
|
798
|
+
await context.session.execute("help admin.asset.add");
|
|
799
|
+
return "";
|
|
800
|
+
}
|
|
801
|
+
await context.prism.adminCreateAsset({
|
|
802
|
+
type,
|
|
803
|
+
assetId,
|
|
804
|
+
name: name2,
|
|
805
|
+
description: desc,
|
|
806
|
+
valid: opts.valid,
|
|
807
|
+
activeAt: opts.active,
|
|
808
|
+
expireAt: opts.expire
|
|
809
|
+
});
|
|
810
|
+
return `资产 ${name2} [${type}-${assetId}] 创建成功`;
|
|
811
|
+
}
|
|
812
|
+
__name(handleAdminAddAsset, "handleAdminAddAsset");
|
|
813
|
+
async function handleAdminDelAsset(context, id) {
|
|
814
|
+
await checkAdmin(context);
|
|
815
|
+
if (!id) {
|
|
816
|
+
await context.session.execute("help admin.asset.del");
|
|
817
|
+
return "";
|
|
818
|
+
}
|
|
819
|
+
await context.prism.adminDeleteAsset(parseInt(id));
|
|
820
|
+
return `资产 ${id} 删除成功`;
|
|
821
|
+
}
|
|
822
|
+
__name(handleAdminDelAsset, "handleAdminDelAsset");
|
|
823
|
+
async function handleAdminDelCoupon(context, id) {
|
|
824
|
+
await checkAdmin(context);
|
|
825
|
+
if (!id) {
|
|
826
|
+
await context.session.execute("help admin.coupon.del");
|
|
827
|
+
return "";
|
|
828
|
+
}
|
|
829
|
+
await context.prism.adminDeleteAsset(parseInt(id));
|
|
830
|
+
return `优惠券 ${id} 删除成功`;
|
|
831
|
+
}
|
|
832
|
+
__name(handleAdminDelCoupon, "handleAdminDelCoupon");
|
|
833
|
+
async function handleAdminListCoupons(context) {
|
|
834
|
+
await checkAdmin(context);
|
|
835
|
+
const res = await context.prism.adminListCoupons();
|
|
836
|
+
if (!res || res.length === 0) return "暂无优惠券";
|
|
837
|
+
return res.map((c) => {
|
|
838
|
+
const ef = c.billingEffect;
|
|
839
|
+
if (!ef) return `[${c.id}] ${c.name} (无特效)`;
|
|
840
|
+
const typeStr = ef.type === "RATE" ? `折扣 ${(ef.value * 10).toFixed(1)}折` : `减免 ${ef.value}元`;
|
|
841
|
+
const p = `P${ef.priority}`;
|
|
842
|
+
const flags = [];
|
|
843
|
+
if (ef.consume) flags.push("一次性");
|
|
844
|
+
if (ef.stackable) flags.push("可叠加");
|
|
845
|
+
const limits = [];
|
|
846
|
+
if (ef.maxDiscountAmount) limits.push(`封顶${ef.maxDiscountAmount}元`);
|
|
847
|
+
if (ef.condition?.minCost) limits.push(`满${ef.condition.minCost}元`);
|
|
848
|
+
if (ef.condition?.matchRuleIds?.length) limits.push(`限规则[${ef.condition.matchRuleIds.join(",")}]`);
|
|
849
|
+
return `🎫 [${c.id}] ${c.name}
|
|
850
|
+
效果: ${typeStr}
|
|
851
|
+
属性: ${p} | ${flags.join(", ") || "无特殊属性"}
|
|
852
|
+
限制: ${limits.join(", ") || "无限制"}`;
|
|
853
|
+
}).join("\n\n");
|
|
854
|
+
}
|
|
855
|
+
__name(handleAdminListCoupons, "handleAdminListCoupons");
|
|
856
|
+
async function handleAdminAddCoupon(context, name2, assetId, type, value) {
|
|
857
|
+
await checkAdmin(context);
|
|
858
|
+
const opts = context.options || {};
|
|
859
|
+
if (!name2 || assetId === void 0 || !type || value === void 0) {
|
|
860
|
+
await context.session.execute("help admin.coupon.add");
|
|
861
|
+
return "";
|
|
862
|
+
}
|
|
863
|
+
let t = type.toUpperCase();
|
|
864
|
+
if (t === "FIXED") t = "FIXED_OFF";
|
|
865
|
+
if (t !== "RATE" && t !== "FIXED_OFF") {
|
|
866
|
+
return "类型错误: type 必须是 RATE (折扣) 或 FIXED (减免)";
|
|
867
|
+
}
|
|
868
|
+
await context.prism.adminCreateCoupon({
|
|
869
|
+
name: name2,
|
|
870
|
+
assetId,
|
|
871
|
+
billingEffect: {
|
|
872
|
+
type: t,
|
|
873
|
+
value,
|
|
874
|
+
priority: opts.priority || 0,
|
|
875
|
+
consume: !!opts.consume,
|
|
876
|
+
stackable: !!opts.stackable,
|
|
877
|
+
maxDiscountAmount: opts.max,
|
|
878
|
+
condition: {
|
|
879
|
+
minCost: opts.min,
|
|
880
|
+
matchRuleIds: opts.rules ? String(opts.rules).split(",").map(Number) : void 0
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
});
|
|
884
|
+
return `优惠券 ${name2} 创建成功`;
|
|
885
|
+
}
|
|
886
|
+
__name(handleAdminAddCoupon, "handleAdminAddCoupon");
|
|
887
|
+
async function handleAdminListGifts(context) {
|
|
888
|
+
await checkAdmin(context);
|
|
889
|
+
const res = await context.prism.adminListGifts();
|
|
890
|
+
if (!res || res.length === 0) return "暂无礼包";
|
|
891
|
+
return res.map((g) => {
|
|
892
|
+
const limit = g.oncePerUser ? "🔴 每人限领一次" : "🟢 可重复领取";
|
|
893
|
+
const items = (g.body || []).map((i) => {
|
|
894
|
+
let detail = `${i.name} x${i.count}`;
|
|
895
|
+
if (i.durationMs) {
|
|
896
|
+
const days = (i.durationMs / (1e3 * 60 * 60 * 24)).toFixed(1);
|
|
897
|
+
detail += ` (${days}天)`;
|
|
898
|
+
}
|
|
899
|
+
if (i.mergeStrategy === "EXTEND_TIME") detail += " [续期]";
|
|
900
|
+
if (i.mergeStrategy === "REPLACE") detail += " [覆盖]";
|
|
901
|
+
return detail;
|
|
902
|
+
}).join("\n - ");
|
|
903
|
+
return `[${g.id}] ${g.name}
|
|
904
|
+
限制: ${limit}
|
|
905
|
+
内容:
|
|
906
|
+
- ${items}`;
|
|
907
|
+
}).join("\n\n");
|
|
908
|
+
}
|
|
909
|
+
__name(handleAdminListGifts, "handleAdminListGifts");
|
|
910
|
+
async function handleAdminAddGift(context, name2, content) {
|
|
911
|
+
await checkAdmin(context);
|
|
912
|
+
if (!name2 || !content) {
|
|
913
|
+
await context.session.execute("help admin.gift.add");
|
|
914
|
+
return "";
|
|
915
|
+
}
|
|
916
|
+
try {
|
|
917
|
+
const allAssets = await context.prism.adminListAssets();
|
|
918
|
+
const assetMap = new Map(allAssets.map((a) => [a.assetId, a]));
|
|
919
|
+
const items = content.split(/[,,]/).map((item) => {
|
|
920
|
+
const parts = item.trim().split(/[::]/);
|
|
921
|
+
if (parts.length < 2) throw new Error(`项 "${item}" 格式错误,应为 id:count`);
|
|
922
|
+
const [idStr, countStr] = parts;
|
|
923
|
+
const assetId = parseInt(idStr);
|
|
924
|
+
const count = parseInt(countStr);
|
|
925
|
+
if (isNaN(assetId)) throw new Error(`资产ID "${idStr}" 无效`);
|
|
926
|
+
if (isNaN(count) || count <= 0) throw new Error(`数量 "${countStr}" 无效`);
|
|
927
|
+
const asset = assetMap.get(assetId);
|
|
928
|
+
if (!asset) throw new Error(`Asset ID ${assetId} not found`);
|
|
929
|
+
return { assetId, assetType: asset.type, name: asset.name, mergeStrategy: "STACK", oncePerUser: false, count };
|
|
930
|
+
});
|
|
931
|
+
await context.prism.adminCreateGift({
|
|
932
|
+
name: name2,
|
|
933
|
+
oncePerUser: false,
|
|
934
|
+
body: items
|
|
935
|
+
});
|
|
936
|
+
return `礼包 ${name2} 创建成功`;
|
|
937
|
+
} catch (e) {
|
|
938
|
+
return `创建失败: ${e.message}`;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
__name(handleAdminAddGift, "handleAdminAddGift");
|
|
942
|
+
async function handleAdminDelGift(context, id) {
|
|
943
|
+
await checkAdmin(context);
|
|
944
|
+
if (!id) {
|
|
945
|
+
await context.session.execute("help admin.gift.del");
|
|
946
|
+
return "";
|
|
947
|
+
}
|
|
948
|
+
await context.prism.adminDeleteGift(parseInt(id));
|
|
949
|
+
return `礼包 ${id} 删除成功`;
|
|
950
|
+
}
|
|
951
|
+
__name(handleAdminDelGift, "handleAdminDelGift");
|
|
952
|
+
async function handleAdminGiftCodes(context, id, count) {
|
|
953
|
+
await checkAdmin(context);
|
|
954
|
+
if (!id || !count) {
|
|
955
|
+
await context.session.execute("help admin.gift.codes");
|
|
956
|
+
return "";
|
|
957
|
+
}
|
|
958
|
+
const res = await context.prism.adminGenerateGiftCodes(parseInt(id), parseInt(count));
|
|
959
|
+
return `成功生成 ${res.count} 个兑换码:
|
|
960
|
+
${res.codes.join("\n")}`;
|
|
961
|
+
}
|
|
962
|
+
__name(handleAdminGiftCodes, "handleAdminGiftCodes");
|
|
963
|
+
async function handleAdminListRules(context) {
|
|
964
|
+
await checkAdmin(context);
|
|
965
|
+
const res = await context.prism.adminListRules();
|
|
966
|
+
if (!res || res.length === 0) return "暂无规则";
|
|
967
|
+
return res.map((r) => {
|
|
968
|
+
const tr = r.timeRange;
|
|
969
|
+
const pr = r.pricing;
|
|
970
|
+
const md = r.matchDate || {};
|
|
971
|
+
let dateStr = "每天";
|
|
972
|
+
if (md.specificDates?.length) dateStr = `指定日期(${md.specificDates.length}天)`;
|
|
973
|
+
if (md.weekdays?.length) {
|
|
974
|
+
const days = md.weekdays.map((d) => ["日", "一", "二", "三", "四", "五", "六"][d]).join("");
|
|
975
|
+
dateStr = `每周[${days}]`;
|
|
976
|
+
}
|
|
977
|
+
const status = r.available ? "[✅]" : "[❌]";
|
|
978
|
+
return `${status} [${r.id}] ${r.name} (P${r.priority})
|
|
979
|
+
时间: ${dateStr} ${tr.start}-${tr.end}
|
|
980
|
+
价格: ${pr.unitPrice}元 / ${pr.unitMinutes}分钟
|
|
981
|
+
封顶: ${pr.priceCap}元 (宽限${pr.roundGraceMinutes}分)`;
|
|
982
|
+
}).join("\n\n");
|
|
983
|
+
}
|
|
984
|
+
__name(handleAdminListRules, "handleAdminListRules");
|
|
985
|
+
async function handleAdminDelRule(context, id) {
|
|
986
|
+
await checkAdmin(context);
|
|
987
|
+
if (!id) {
|
|
988
|
+
await context.session.execute("help admin.rule.del");
|
|
989
|
+
return "";
|
|
990
|
+
}
|
|
991
|
+
await context.prism.adminDeleteRule(parseInt(id));
|
|
992
|
+
return `规则 ${id} 删除成功`;
|
|
993
|
+
}
|
|
994
|
+
__name(handleAdminDelRule, "handleAdminDelRule");
|
|
995
|
+
async function handleAdminRuleStatus(context, id, state) {
|
|
996
|
+
await checkAdmin(context);
|
|
997
|
+
if (!id || !state) {
|
|
998
|
+
await context.session.execute("help admin.rule.set");
|
|
999
|
+
return "";
|
|
1000
|
+
}
|
|
1001
|
+
const available = ["on", "true", "enable", "1", "yes"].includes(state.toLowerCase());
|
|
1002
|
+
await context.prism.adminUpdateRuleStatus(parseInt(id), available);
|
|
1003
|
+
return `规则 ${id} 已${available ? "启用" : "禁用"}`;
|
|
1004
|
+
}
|
|
1005
|
+
__name(handleAdminRuleStatus, "handleAdminRuleStatus");
|
|
1006
|
+
async function handleAdminUserAssetAdd(context, user, assetId, count) {
|
|
1007
|
+
await checkAdmin(context);
|
|
1008
|
+
if (!user || !assetId) {
|
|
1009
|
+
await context.session.execute("help admin.user.asset.add");
|
|
1010
|
+
return "";
|
|
1011
|
+
}
|
|
1012
|
+
const { error, userId } = await getTargetUserId(context, user);
|
|
1013
|
+
if (error) return error;
|
|
1014
|
+
let res = await context.prism.upsertUserAssets(userId, [{
|
|
1015
|
+
id: assetId,
|
|
1016
|
+
count
|
|
1017
|
+
}]);
|
|
1018
|
+
return `已为用户 ${userId} 添加资产 ${JSON.stringify(res)}`;
|
|
1019
|
+
}
|
|
1020
|
+
__name(handleAdminUserAssetAdd, "handleAdminUserAssetAdd");
|
|
1021
|
+
async function handleAdminUserAssetDel(context, user, userAssetId, count) {
|
|
1022
|
+
await checkAdmin(context);
|
|
1023
|
+
if (!user || !userAssetId) {
|
|
1024
|
+
await context.session.execute("help admin.user.asset.del");
|
|
1025
|
+
return "";
|
|
1026
|
+
}
|
|
1027
|
+
const { error, userId } = await getTargetUserId(context, user);
|
|
1028
|
+
if (error) return error;
|
|
1029
|
+
if (count) {
|
|
1030
|
+
await context.prism.updateUserAsset(userId, userAssetId, -count);
|
|
1031
|
+
return `已为用户 ${userId} 扣除资产(ID:${userAssetId}) 数量 ${count}`;
|
|
1032
|
+
} else {
|
|
1033
|
+
await context.prism.deleteUserAsset(userId, userAssetId);
|
|
1034
|
+
return `已为用户 ${userId} 删除资产(ID:${userAssetId})`;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
__name(handleAdminUserAssetDel, "handleAdminUserAssetDel");
|
|
641
1038
|
function apply(ctx, config) {
|
|
1039
|
+
const prism = new PrismService(ctx, config);
|
|
642
1040
|
const createAction = /* @__PURE__ */ __name((handler) => {
|
|
643
1041
|
const actionFn = /* @__PURE__ */ __name((argv, ...args) => {
|
|
644
1042
|
const context = {
|
|
645
1043
|
ctx,
|
|
646
1044
|
config,
|
|
647
|
-
session: argv.session
|
|
1045
|
+
session: argv.session,
|
|
1046
|
+
options: argv.options,
|
|
1047
|
+
prism
|
|
648
1048
|
};
|
|
649
1049
|
return handler(context, ...args);
|
|
650
1050
|
}, "actionFn");
|
|
@@ -655,6 +1055,7 @@ function apply(ctx, config) {
|
|
|
655
1055
|
ctx.command("logout [user:user]").action(createAction(handleLogoutCmd));
|
|
656
1056
|
ctx.command("list").action(createAction(handleListCmd));
|
|
657
1057
|
ctx.command("wallet [user:user]").action(createAction(handleWalletCmd));
|
|
1058
|
+
ctx.command("history [arg1] [arg2]").action(createAction(handleHistoriesCmd));
|
|
658
1059
|
ctx.command("billing [user:user]").action(createAction(handleBillingCmd));
|
|
659
1060
|
ctx.command("lock").action(createAction(handleLockCmd));
|
|
660
1061
|
ctx.command("items [user:user]").action(createAction(handleItemsCmd));
|
|
@@ -666,11 +1067,27 @@ function apply(ctx, config) {
|
|
|
666
1067
|
ctx.command("add <user:user> <amount>").action(createAction(handleWalletAdd));
|
|
667
1068
|
ctx.command("del <user:user> <amount>").action(createAction(handleWalletDeduct));
|
|
668
1069
|
ctx.command("overwrite <user:user> <amount>").action(createAction(handleCostOverwrite));
|
|
1070
|
+
ctx.command("admin.asset.list", "列出资产").action(createAction(handleAdminListAssets));
|
|
1071
|
+
ctx.command("admin.asset.add <type> <id:number> <name> [desc]", "添加资产").option("valid", "-v [val:boolean]", { fallback: true }).option("active", "--active <date:string>").option("expire", "--expire <date:string>").action(createAction(handleAdminAddAsset));
|
|
1072
|
+
ctx.command("admin.asset.del <id>", "删除资产").action(createAction(handleAdminDelAsset));
|
|
1073
|
+
ctx.command("admin.coupon.list", "列出优惠券").action(createAction(handleAdminListCoupons));
|
|
1074
|
+
ctx.command("admin.user.asset.add <user:user> <assetId:number> [count:number]", "发放资产").action(createAction(handleAdminUserAssetAdd));
|
|
1075
|
+
ctx.command("admin.user.asset.del <user:user> <userAssetId:number> [count:number]", "删除资产(指定数量则扣除)").action(createAction(handleAdminUserAssetDel));
|
|
1076
|
+
ctx.command("admin.coupon.add <name> <assetId:number> <type> <value:number>", "添加优惠券").option("priority", "-p <val:number>", { fallback: 0 }).option("consume", "-c", { fallback: false }).option("stackable", "-s", { fallback: false }).option("min", "--min <val:number>").option("max", "--max <val:number>").option("rules", "--rules <ids:string>").action(createAction(handleAdminAddCoupon));
|
|
1077
|
+
ctx.command("admin.coupon.del <id>", "删除优惠券").action(createAction(handleAdminDelCoupon));
|
|
1078
|
+
ctx.command("admin.gift.list", "列出礼包").action(createAction(handleAdminListGifts));
|
|
1079
|
+
ctx.command("admin.gift.add <name> <content:text>", "添加礼包 (格式: id:count,id:count)").action(createAction(handleAdminAddGift));
|
|
1080
|
+
ctx.command("admin.gift.del <id>", "删除礼包").action(createAction(handleAdminDelGift));
|
|
1081
|
+
ctx.command("admin.gift.codes <id> <count>", "生成礼包码").action(createAction(handleAdminGiftCodes));
|
|
1082
|
+
ctx.command("admin.rule.list", "列出规则").action(createAction(handleAdminListRules));
|
|
1083
|
+
ctx.command("admin.rule.del <id>", "删除规则").action(createAction(handleAdminDelRule));
|
|
1084
|
+
ctx.command("admin.rule.set <id> <state>", "设置规则状态").action(createAction(handleAdminRuleStatus));
|
|
1085
|
+
ctx.command("echo <message>").action((_, message) => message);
|
|
669
1086
|
ctx.setInterval(
|
|
670
1087
|
async () => {
|
|
671
|
-
let
|
|
672
|
-
if (
|
|
673
|
-
let machines = await getAllMachinePower(
|
|
1088
|
+
let list = await prism.list();
|
|
1089
|
+
if (list.length < 1) {
|
|
1090
|
+
let machines = await prism.getAllMachinePower();
|
|
674
1091
|
let turnOff = false;
|
|
675
1092
|
machines.forEach((m) => {
|
|
676
1093
|
if (m.state.state !== "off") {
|
|
@@ -678,7 +1095,7 @@ function apply(ctx, config) {
|
|
|
678
1095
|
}
|
|
679
1096
|
});
|
|
680
1097
|
if (turnOff) {
|
|
681
|
-
let res = await machinePowerOff(
|
|
1098
|
+
let res = await prism.machinePowerOff("all", "system", false);
|
|
682
1099
|
ctx.broadcast(config.broadcasts, "窝里目前有 0 人,自动关闭所有机器");
|
|
683
1100
|
}
|
|
684
1101
|
return;
|
package/lib/model.d.ts
CHANGED
|
@@ -88,6 +88,19 @@ export interface UserAsset {
|
|
|
88
88
|
comment: string;
|
|
89
89
|
count: number;
|
|
90
90
|
}
|
|
91
|
+
export type DiscountType = 'RATE' | 'FIXED_OFF';
|
|
92
|
+
export interface BillingEffectConfig {
|
|
93
|
+
type: DiscountType;
|
|
94
|
+
value: number;
|
|
95
|
+
priority: number;
|
|
96
|
+
consume: boolean;
|
|
97
|
+
stackable: boolean;
|
|
98
|
+
maxDiscountAmount?: number;
|
|
99
|
+
condition?: {
|
|
100
|
+
matchRuleIds?: number[];
|
|
101
|
+
minCost?: number;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
91
104
|
export interface Asset {
|
|
92
105
|
type: string;
|
|
93
106
|
id: number;
|
|
@@ -97,6 +110,7 @@ export interface Asset {
|
|
|
97
110
|
activeAt: Date | null;
|
|
98
111
|
description: string | null;
|
|
99
112
|
valid: boolean;
|
|
113
|
+
billingEffect?: BillingEffectConfig;
|
|
100
114
|
}
|
|
101
115
|
export type UserAssetWithDef = UserAsset & {
|
|
102
116
|
asset: Asset;
|
package/lib/service.d.ts
CHANGED
|
@@ -1,32 +1,61 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koishi";
|
|
2
|
+
import { Config } from "./index";
|
|
2
3
|
import { BillingResponse, ListResponse, UserAsset, Wallet } from "./model";
|
|
3
|
-
export declare
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
4
|
+
export declare class PrismService {
|
|
5
|
+
private ctx;
|
|
6
|
+
private config;
|
|
7
|
+
private apiBase;
|
|
8
|
+
constructor(ctx: Context, config: Config);
|
|
9
|
+
private url;
|
|
10
|
+
register(userId: string): Promise<unknown>;
|
|
11
|
+
login(userId: string): Promise<unknown>;
|
|
12
|
+
history(userId: string, limit: number): Promise<any>;
|
|
13
|
+
logout(userId: string): Promise<BillingResponse>;
|
|
14
|
+
billing(userId: string): Promise<BillingResponse>;
|
|
15
|
+
list(): Promise<ListResponse>;
|
|
16
|
+
wallet(userId: string): Promise<Wallet>;
|
|
17
|
+
assets(userId: string): Promise<UserAsset[]>;
|
|
18
|
+
upsertUserAssets(userId: string, assets: {
|
|
19
|
+
id: number;
|
|
20
|
+
count: number;
|
|
21
|
+
}[]): Promise<any>;
|
|
22
|
+
deleteUserAsset(userId: string, userAssetId: number): Promise<any>;
|
|
23
|
+
updateUserAsset(userId: string, userAssetId: number, amount: number): Promise<any>;
|
|
24
|
+
getLock(userId: string): Promise<{
|
|
25
|
+
password: string;
|
|
26
|
+
id: any;
|
|
27
|
+
}>;
|
|
28
|
+
machinePowerOn(machineName: string, userId: string, needLogin?: boolean): Promise<any>;
|
|
29
|
+
machinePowerOff(machineName: string, userId: string, needLogin?: boolean): Promise<any>;
|
|
30
|
+
getAllMachinePower(): Promise<{
|
|
31
|
+
machine: string;
|
|
32
|
+
state: {
|
|
33
|
+
state: string;
|
|
34
|
+
};
|
|
35
|
+
}[]>;
|
|
36
|
+
getMachinePower(machineName: string): Promise<{
|
|
37
|
+
machine: string;
|
|
38
|
+
state: {
|
|
39
|
+
state: string;
|
|
40
|
+
};
|
|
41
|
+
}>;
|
|
42
|
+
walletAdd(amount: number, userId: string): Promise<any>;
|
|
43
|
+
walletDel(amount: number, userId: string): Promise<any>;
|
|
44
|
+
costOverwrite(amount: string, userId: string): Promise<any>;
|
|
45
|
+
redeem(code: string, userId: string): Promise<any>;
|
|
46
|
+
insertCoin(alias: string, userId: string, force?: boolean): Promise<any>;
|
|
47
|
+
adminListAssets(): Promise<any>;
|
|
48
|
+
adminCreateAsset(data: any): Promise<any>;
|
|
49
|
+
adminDeleteAsset(id: number): Promise<any>;
|
|
50
|
+
adminListCoupons(): Promise<any>;
|
|
51
|
+
adminCreateCoupon(data: any): Promise<any>;
|
|
52
|
+
adminListGifts(): Promise<any>;
|
|
53
|
+
adminCreateGift(data: any): Promise<any>;
|
|
54
|
+
adminDeleteGift(id: number): Promise<any>;
|
|
55
|
+
adminGenerateGiftCodes(id: number, count: number): Promise<any>;
|
|
56
|
+
adminListRules(): Promise<any>;
|
|
57
|
+
adminCreateRule(data: any): Promise<any>;
|
|
58
|
+
adminDeleteRule(id: number): Promise<any>;
|
|
59
|
+
adminUpdateRuleStatus(id: number, available: boolean): Promise<import("koishi").HTTP.Response<any>>;
|
|
60
|
+
adminAddUserAsset(userId: string, id: number, count: number): Promise<any>;
|
|
61
|
+
}
|
package/lib/types.d.ts
CHANGED