koishi-plugin-monetary-admin 1.0.3 → 1.2.0
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 +141 -74
- package/package.json +4 -1
package/lib/index.js
CHANGED
|
@@ -7,25 +7,15 @@ exports.name = 'monetary-admin';
|
|
|
7
7
|
exports.inject = ['monetary', 'database'];
|
|
8
8
|
exports.Config = koishi_1.Schema.object({});
|
|
9
9
|
function apply(ctx) {
|
|
10
|
-
|
|
11
|
-
.alias('开户')
|
|
12
|
-
.action(async ({ session }, target, currency, amount) => {
|
|
10
|
+
async function resolveUser(target) {
|
|
13
11
|
if (!target)
|
|
14
|
-
|
|
15
|
-
if (!currency)
|
|
16
|
-
return '请输入货币类型。';
|
|
17
|
-
if (!amount)
|
|
18
|
-
return '请输入金额。';
|
|
12
|
+
throw '请输入目标用户。';
|
|
19
13
|
const [platform, pid] = target.split(':');
|
|
20
14
|
if (!platform || !pid)
|
|
21
|
-
|
|
22
|
-
const bindings = await ctx.database.get('binding', {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}, ['aid']);
|
|
26
|
-
if (bindings.length === 0) {
|
|
27
|
-
return '未找到该用户。';
|
|
28
|
-
}
|
|
15
|
+
throw '目标用户格式错误。';
|
|
16
|
+
const bindings = await ctx.database.get('binding', { platform, pid }, ['aid']);
|
|
17
|
+
if (bindings.length === 0)
|
|
18
|
+
throw '未找到该用户。';
|
|
29
19
|
const uid = bindings[0].aid;
|
|
30
20
|
const [user] = await ctx.database.get('user', { id: uid }, ['name']);
|
|
31
21
|
let name = user?.name || target;
|
|
@@ -41,83 +31,127 @@ function apply(ctx) {
|
|
|
41
31
|
catch (e) { }
|
|
42
32
|
}
|
|
43
33
|
}
|
|
34
|
+
return { uid, name };
|
|
35
|
+
}
|
|
36
|
+
ctx.command('monetary.add [target:user] <currency:string> <amount:number>', '给目标用户添加货币', { authority: 5 })
|
|
37
|
+
.userFields(['id'])
|
|
38
|
+
.action(async ({ session }, target, currency, amount) => {
|
|
44
39
|
try {
|
|
40
|
+
let uid, name;
|
|
41
|
+
if (!target) {
|
|
42
|
+
// 如果没有指定目标,则给自己添加
|
|
43
|
+
if (!session?.user?.id)
|
|
44
|
+
return '无法获取您的用户信息。';
|
|
45
|
+
uid = session.user.id;
|
|
46
|
+
name = session.username || String(uid);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const resolved = await resolveUser(target);
|
|
50
|
+
uid = resolved.uid;
|
|
51
|
+
name = resolved.name;
|
|
52
|
+
}
|
|
53
|
+
if (!currency)
|
|
54
|
+
return '请输入货币类型。';
|
|
55
|
+
if (!amount)
|
|
56
|
+
return '请输入金额。';
|
|
57
|
+
if (amount <= 0)
|
|
58
|
+
return '金额必须为正数。';
|
|
45
59
|
await ctx.monetary.gain(uid, amount, currency);
|
|
46
60
|
return `成功给用户 ${name} (UID: ${uid}) 添加了 ${amount} ${currency}。`;
|
|
47
61
|
}
|
|
48
62
|
catch (e) {
|
|
49
|
-
return `添加失败: ${e.message}`;
|
|
63
|
+
return typeof e === 'string' ? e : `添加失败: ${e.message}`;
|
|
50
64
|
}
|
|
51
65
|
});
|
|
52
|
-
ctx.command('monetary.
|
|
53
|
-
.alias('
|
|
54
|
-
.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
ctx.command('monetary.reduce [target:user] <currency:string> <amount:number>', '扣除目标用户货币', { authority: 5 })
|
|
67
|
+
.alias('扣款')
|
|
68
|
+
.userFields(['id'])
|
|
69
|
+
.action(async ({ session }, target, currency, amount) => {
|
|
70
|
+
try {
|
|
71
|
+
let uid, name;
|
|
72
|
+
if (!target) {
|
|
73
|
+
if (!session?.user?.id)
|
|
74
|
+
return '无法获取您的用户信息。';
|
|
75
|
+
uid = session.user.id;
|
|
76
|
+
name = session.username || String(uid);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const resolved = await resolveUser(target);
|
|
80
|
+
uid = resolved.uid;
|
|
81
|
+
name = resolved.name;
|
|
82
|
+
}
|
|
83
|
+
if (!currency)
|
|
84
|
+
return '请输入货币类型。';
|
|
85
|
+
if (!amount)
|
|
86
|
+
return '请输入金额。';
|
|
87
|
+
if (amount <= 0)
|
|
88
|
+
return '金额必须为正数。';
|
|
89
|
+
await ctx.monetary.gain(uid, -amount, currency);
|
|
90
|
+
return `成功从用户 ${name} (UID: ${uid}) 扣除了 ${amount} ${currency}。`;
|
|
66
91
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
92
|
+
catch (e) {
|
|
93
|
+
return typeof e === 'string' ? e : `扣除失败: ${e.message}`;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
ctx.command('monetary.clear [target:user] <currency:string>', '清零目标用户指定货币', { authority: 5 })
|
|
97
|
+
.alias('清零')
|
|
98
|
+
.userFields(['id'])
|
|
99
|
+
.action(async ({ session }, target, currency) => {
|
|
100
|
+
try {
|
|
101
|
+
let uid, name;
|
|
102
|
+
if (!target) {
|
|
103
|
+
if (!session?.user?.id)
|
|
104
|
+
return '无法获取您的用户信息。';
|
|
105
|
+
uid = session.user.id;
|
|
106
|
+
name = session.username || String(uid);
|
|
80
107
|
}
|
|
108
|
+
else {
|
|
109
|
+
const resolved = await resolveUser(target);
|
|
110
|
+
uid = resolved.uid;
|
|
111
|
+
name = resolved.name;
|
|
112
|
+
}
|
|
113
|
+
if (!currency)
|
|
114
|
+
return '请输入货币类型。';
|
|
115
|
+
await ctx.database.set('monetary', { uid, currency }, { value: 0 });
|
|
116
|
+
return `成功将用户 ${name} (UID: ${uid}) 的 ${currency} 余额清零。`;
|
|
81
117
|
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
return typeof e === 'string' ? e : `清零失败: ${e.message}`;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
ctx.command('monetary.remove <target:user>', '删除目标用户的所有货币记录', { authority: 5 })
|
|
123
|
+
.alias('销户')
|
|
124
|
+
.option('force', '-f 强制删除')
|
|
125
|
+
.action(async ({ session, options }, target) => {
|
|
82
126
|
try {
|
|
127
|
+
const { uid, name } = await resolveUser(target);
|
|
128
|
+
if (!options.force) {
|
|
129
|
+
return '该操作将删除用户的所有货币记录,且不可恢复。请使用 --force 选项确认删除。';
|
|
130
|
+
}
|
|
83
131
|
await ctx.database.remove('monetary', { uid });
|
|
84
132
|
return `成功删除用户 ${name} (UID: ${uid}) 的所有货币记录。`;
|
|
85
133
|
}
|
|
86
134
|
catch (e) {
|
|
87
|
-
return `删除失败: ${e.message}`;
|
|
135
|
+
return typeof e === 'string' ? e : `删除失败: ${e.message}`;
|
|
88
136
|
}
|
|
89
137
|
});
|
|
90
|
-
ctx.command('monetary.balance
|
|
138
|
+
ctx.command('monetary.balance [target:user]', '查询目标用户的货币余额', { authority: 1 })
|
|
91
139
|
.alias('查询余额')
|
|
140
|
+
.userFields(['id'])
|
|
92
141
|
.action(async ({ session }, target) => {
|
|
93
|
-
if (!target)
|
|
94
|
-
return '请输入目标用户。';
|
|
95
|
-
const [platform, pid] = target.split(':');
|
|
96
|
-
if (!platform || !pid)
|
|
97
|
-
return '目标用户格式错误。';
|
|
98
|
-
const bindings = await ctx.database.get('binding', {
|
|
99
|
-
platform,
|
|
100
|
-
pid,
|
|
101
|
-
}, ['aid']);
|
|
102
|
-
if (bindings.length === 0) {
|
|
103
|
-
return '未找到该用户。';
|
|
104
|
-
}
|
|
105
|
-
const uid = bindings[0].aid;
|
|
106
|
-
const [user] = await ctx.database.get('user', { id: uid }, ['name']);
|
|
107
|
-
let name = user?.name || target;
|
|
108
|
-
if (!user?.name) {
|
|
109
|
-
const bot = ctx.bots.find(b => b.platform === platform);
|
|
110
|
-
if (bot) {
|
|
111
|
-
try {
|
|
112
|
-
const platformUser = await bot.getUser(pid);
|
|
113
|
-
if (platformUser?.name) {
|
|
114
|
-
name = platformUser.name;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
catch (e) { }
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
142
|
try {
|
|
143
|
+
let uid, name;
|
|
144
|
+
if (!target) {
|
|
145
|
+
if (!session?.user?.id)
|
|
146
|
+
return '无法获取您的用户信息。';
|
|
147
|
+
uid = session.user.id;
|
|
148
|
+
name = session.username || '您';
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const resolved = await resolveUser(target);
|
|
152
|
+
uid = resolved.uid;
|
|
153
|
+
name = resolved.name;
|
|
154
|
+
}
|
|
121
155
|
const monetaryRecords = await ctx.database.get('monetary', { uid });
|
|
122
156
|
if (monetaryRecords.length === 0) {
|
|
123
157
|
return `用户 ${name} (UID: ${uid}) 暂无任何货币记录。`;
|
|
@@ -129,7 +163,40 @@ function apply(ctx) {
|
|
|
129
163
|
return result.trim();
|
|
130
164
|
}
|
|
131
165
|
catch (e) {
|
|
132
|
-
return `查询失败: ${e.message}`;
|
|
166
|
+
return typeof e === 'string' ? e : `查询失败: ${e.message}`;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
ctx.command('monetary.transfer <target:user> <currency:string> <amount:number>', '转账给目标用户', { authority: 1 })
|
|
170
|
+
.alias('转账')
|
|
171
|
+
.userFields(['id'])
|
|
172
|
+
.action(async ({ session }, target, currency, amount) => {
|
|
173
|
+
try {
|
|
174
|
+
if (!session?.user?.id)
|
|
175
|
+
return '无法获取您的用户信息。';
|
|
176
|
+
if (!currency)
|
|
177
|
+
return '请输入货币类型。';
|
|
178
|
+
if (!amount)
|
|
179
|
+
return '请输入金额。';
|
|
180
|
+
if (amount <= 0)
|
|
181
|
+
return '转账金额必须为正数。';
|
|
182
|
+
const senderUid = session.user.id;
|
|
183
|
+
const { uid: targetUid, name: targetName } = await resolveUser(target);
|
|
184
|
+
if (senderUid === targetUid)
|
|
185
|
+
return '不能给自己转账。';
|
|
186
|
+
// 检查发送者余额
|
|
187
|
+
const senderRecords = await ctx.database.get('monetary', { uid: senderUid, currency });
|
|
188
|
+
if (senderRecords.length === 0 || senderRecords[0].value < amount) {
|
|
189
|
+
return `您的 ${currency} 余额不足。`;
|
|
190
|
+
}
|
|
191
|
+
// 执行转账
|
|
192
|
+
await ctx.monetary.gain(senderUid, -amount, currency);
|
|
193
|
+
await ctx.monetary.gain(targetUid, amount, currency);
|
|
194
|
+
const [senderUser] = await ctx.database.get('user', { id: senderUid }, ['name']);
|
|
195
|
+
const senderName = senderUser?.name || String(senderUid);
|
|
196
|
+
return `成功将 ${amount} ${currency} 从 ${senderName} 转账给 ${targetName}。`;
|
|
197
|
+
}
|
|
198
|
+
catch (e) {
|
|
199
|
+
return typeof e === 'string' ? e : `转账失败: ${e.message}`;
|
|
133
200
|
}
|
|
134
201
|
});
|
|
135
202
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-monetary-admin",
|
|
3
3
|
"description": "Admin commands for Koishi monetary system",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc"
|
|
14
|
+
},
|
|
12
15
|
"keywords": [
|
|
13
16
|
"koishi",
|
|
14
17
|
"plugin",
|