feat: add transaction logs and custom bank inputs
Adds configurable fees, transaction history, chat amount input, and v1.1.0 release documentation.
This commit is contained in:
@@ -48,6 +48,7 @@ public final class BankAdminCommand implements TabExecutor {
|
||||
case "take" -> modify(sender, args, ModifyType.TAKE);
|
||||
case "set" -> modify(sender, args, ModifyType.SET);
|
||||
case "setinterest" -> setInterest(sender, args);
|
||||
case "log" -> queryLog(sender, args);
|
||||
default -> sendHelp(sender);
|
||||
}
|
||||
return true;
|
||||
@@ -90,6 +91,13 @@ public final class BankAdminCommand implements TabExecutor {
|
||||
msg.raw(sender, "&c操作失败 (可能是余额不足)。");
|
||||
return;
|
||||
}
|
||||
com.craftbank.model.Transaction.Type txType = switch (type) {
|
||||
case GIVE -> com.craftbank.model.Transaction.Type.ADMIN_GIVE;
|
||||
case TAKE -> com.craftbank.model.Transaction.Type.ADMIN_TAKE;
|
||||
case SET -> com.craftbank.model.Transaction.Type.ADMIN_SET;
|
||||
};
|
||||
plugin.getTransactionLog().record(uuid, txType, amount,
|
||||
"管理员 " + sender.getName() + " 操作");
|
||||
msg.raw(sender, "&a已" + label(type) + " &f" + targetName + " &a现金 " + econ.format(amount)
|
||||
+ " &7(当前: " + econ.format(econ.getCash(uuid)) + ")");
|
||||
});
|
||||
@@ -130,6 +138,66 @@ public final class BankAdminCommand implements TabExecutor {
|
||||
msg.raw(sender, "&a已将 &f" + key + " &a的日利率设置为 &e" + rate + " &7(" + (rate * 100) + "%)");
|
||||
}
|
||||
|
||||
private void queryLog(CommandSender sender, String[] args) {
|
||||
if (args.length < 2) {
|
||||
msg.raw(sender, "&c用法: /bankadmin log <玩家> [页码]");
|
||||
return;
|
||||
}
|
||||
String targetName = args[1];
|
||||
int page = 1;
|
||||
if (args.length >= 3) {
|
||||
try {
|
||||
page = Math.max(1, Integer.parseInt(args[2]));
|
||||
} catch (NumberFormatException ignored) {
|
||||
page = 1;
|
||||
}
|
||||
}
|
||||
final int finalPage = page;
|
||||
final int pageSize = 10;
|
||||
|
||||
plugin.runAsync(() -> {
|
||||
@SuppressWarnings("deprecation")
|
||||
OfflinePlayer target = Bukkit.getOfflinePlayer(targetName);
|
||||
UUID uuid = target.getUniqueId();
|
||||
if (uuid == null || (!target.hasPlayedBefore() && !target.isOnline())) {
|
||||
msg.key(sender, "player-not-found", "&c找不到目标玩家。");
|
||||
return;
|
||||
}
|
||||
var list = plugin.getTransactionLog().query(uuid, finalPage, pageSize);
|
||||
if (list.isEmpty()) {
|
||||
msg.raw(sender, "&7" + targetName + " 在第 " + finalPage + " 页没有交易记录。");
|
||||
return;
|
||||
}
|
||||
EconomyManager econ = plugin.getEconomyManager();
|
||||
java.text.SimpleDateFormat fmt = new java.text.SimpleDateFormat("MM-dd HH:mm");
|
||||
msg.raw(sender, "&b&l" + targetName + " 的交易流水 &7- 第 " + finalPage + " 页");
|
||||
for (var tx : list) {
|
||||
String feePart = tx.getFee() > 0 ? " &8(费 " + econ.format(tx.getFee()) + ")" : "";
|
||||
sender.sendMessage(com.craftbank.util.Text.color(
|
||||
"&7[" + fmt.format(new java.util.Date(tx.getTimestamp())) + "] &f"
|
||||
+ typeLabel(tx.getType()) + " &a" + econ.format(tx.getAmount())
|
||||
+ feePart + " &8" + (tx.getDescription() == null ? "" : tx.getDescription())));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String typeLabel(com.craftbank.model.Transaction.Type type) {
|
||||
return switch (type) {
|
||||
case PAY_OUT -> "转出";
|
||||
case PAY_IN -> "转入";
|
||||
case DEPOSIT -> "存活期";
|
||||
case WITHDRAW -> "取活期";
|
||||
case CHEQUE_ISSUE -> "开支票";
|
||||
case CHEQUE_REDEEM -> "兑支票";
|
||||
case TERM_CREATE -> "存定期";
|
||||
case TERM_CLAIM -> "领定期";
|
||||
case INTEREST -> "利息";
|
||||
case ADMIN_GIVE -> "管理给予";
|
||||
case ADMIN_TAKE -> "管理扣除";
|
||||
case ADMIN_SET -> "管理设置";
|
||||
};
|
||||
}
|
||||
|
||||
private void sendHelp(CommandSender sender) {
|
||||
msg.raw(sender, "&b&l工艺银行管理 &7指令帮助:");
|
||||
sender.sendMessage(com.craftbank.util.Text.color("&7/bankadmin reload"));
|
||||
@@ -137,6 +205,7 @@ public final class BankAdminCommand implements TabExecutor {
|
||||
sender.sendMessage(com.craftbank.util.Text.color("&7/bankadmin take <玩家> <金额>"));
|
||||
sender.sendMessage(com.craftbank.util.Text.color("&7/bankadmin set <玩家> <金额>"));
|
||||
sender.sendMessage(com.craftbank.util.Text.color("&7/bankadmin setinterest <类型> <利率>"));
|
||||
sender.sendMessage(com.craftbank.util.Text.color("&7/bankadmin log <玩家> [页码]"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,14 +214,14 @@ public final class BankAdminCommand implements TabExecutor {
|
||||
return List.of();
|
||||
}
|
||||
if (args.length == 1) {
|
||||
List<String> base = new ArrayList<>(List.of("reload", "give", "take", "set", "setinterest"));
|
||||
List<String> base = new ArrayList<>(List.of("reload", "give", "take", "set", "setinterest", "log"));
|
||||
base.removeIf(s -> !s.startsWith(args[0].toLowerCase()));
|
||||
return base;
|
||||
}
|
||||
if (args.length == 2 && args[0].equalsIgnoreCase("setinterest")) {
|
||||
return new ArrayList<>(List.of("savings", "term_7d", "term_15d", "term_30d"));
|
||||
}
|
||||
if (args.length == 2 && List.of("give", "take", "set").contains(args[0].toLowerCase())) {
|
||||
if (args.length == 2 && List.of("give", "take", "set", "log").contains(args[0].toLowerCase())) {
|
||||
return null; // 在线玩家名
|
||||
}
|
||||
return List.of();
|
||||
|
||||
@@ -67,6 +67,8 @@ public final class ChequeCommand implements TabExecutor {
|
||||
});
|
||||
return;
|
||||
}
|
||||
plugin.getTransactionLog().record(player.getUniqueId(),
|
||||
com.craftbank.model.Transaction.Type.CHEQUE_ISSUE, amount, "开具支票");
|
||||
msg.raw(player, "&a已开具一张面额 &f" + econ.format(amount) + " &a的支票。");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -71,16 +71,34 @@ public final class PayCommand implements TabExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!econ.has(player.getUniqueId(), amount)) {
|
||||
msg.key(sender, "insufficient-funds", "&c余额不足。");
|
||||
// 手续费由付款方承担:需同时覆盖转账金额与手续费。
|
||||
double fee = plugin.getFeeCalculator().calculate("pay", amount);
|
||||
if (!econ.has(player.getUniqueId(), amount + fee)) {
|
||||
if (fee > 0) {
|
||||
msg.raw(sender, "&c余额不足 (需 " + econ.format(amount) + " + 手续费 " + econ.format(fee) + ")。");
|
||||
} else {
|
||||
msg.key(sender, "insufficient-funds", "&c余额不足。");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (econ.transfer(player.getUniqueId(), targetUuid, amount)) {
|
||||
msg.raw(sender, "&a成功向 &f" + targetName + " &a转账 " + econ.format(amount));
|
||||
// 转账成功后再扣手续费(金额已校验充足)。
|
||||
if (fee > 0) {
|
||||
econ.withdraw(player.getUniqueId(), fee);
|
||||
}
|
||||
String feeNote = fee > 0 ? " &7(手续费 " + econ.format(fee) + ")" : "";
|
||||
msg.raw(sender, "&a成功向 &f" + targetName + " &a转账 " + econ.format(amount) + feeNote);
|
||||
Player onlineTarget = Bukkit.getPlayer(targetUuid);
|
||||
if (onlineTarget != null) {
|
||||
msg.raw(onlineTarget, "&a你收到来自 &f" + player.getName() + " &a的转账 " + econ.format(amount));
|
||||
}
|
||||
// 记录双方流水。
|
||||
plugin.getTransactionLog().record(player.getUniqueId(),
|
||||
com.craftbank.model.Transaction.Type.PAY_OUT, amount, fee, targetUuid,
|
||||
"转账给 " + targetName);
|
||||
plugin.getTransactionLog().record(targetUuid,
|
||||
com.craftbank.model.Transaction.Type.PAY_IN, amount, 0, player.getUniqueId(),
|
||||
"收到 " + player.getName() + " 的转账");
|
||||
} else {
|
||||
msg.key(sender, "insufficient-funds", "&c余额不足。");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user