package com.craftbank.commands; import com.craftbank.CraftBank; import com.craftbank.economy.EconomyManager; import com.craftbank.util.Amounts; import com.craftbank.util.Msg; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * /bankadmin <reload|give|take|set|setinterest> —— 管理员指令。 */ public final class BankAdminCommand implements TabExecutor { private final CraftBank plugin; private final Msg msg; public BankAdminCommand(CraftBank plugin) { this.plugin = plugin; this.msg = new Msg(plugin); } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (!sender.hasPermission("craftbank.admin")) { msg.key(sender, "no-permission", "&c你没有权限执行该操作。"); return true; } if (args.length == 0) { sendHelp(sender); return true; } switch (args[0].toLowerCase()) { case "reload" -> { plugin.reloadConfig(); plugin.getEconomyManager().reload(); msg.key(sender, "reload-success", "&a配置文件已重载。"); } case "give" -> modify(sender, args, ModifyType.GIVE); 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; } private enum ModifyType { GIVE, TAKE, SET } private void modify(CommandSender sender, String[] args, ModifyType type) { if (args.length < 3) { msg.raw(sender, "&c用法: /bankadmin " + type.name().toLowerCase() + " <玩家> <金额>"); return; } double amount = Amounts.parse(args[2]); if (amount < 0 || (type != ModifyType.SET && amount <= 0)) { msg.key(sender, "invalid-amount", "&c请输入一个有效的正数金额。"); return; } String targetName = args[1]; EconomyManager econ = plugin.getEconomyManager(); 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; } econ.loadBlocking(uuid, target.getName(), true); boolean ok; switch (type) { case GIVE -> ok = econ.deposit(uuid, amount); case TAKE -> ok = econ.withdraw(uuid, amount); case SET -> ok = econ.set(uuid, amount); default -> ok = false; } if (!ok) { 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)) + ")"); }); } private String label(ModifyType type) { return switch (type) { case GIVE -> "给予"; case TAKE -> "扣除"; case SET -> "设置"; }; } private void setInterest(CommandSender sender, String[] args) { if (args.length < 3) { msg.raw(sender, "&c用法: /bankadmin setinterest <利率>"); return; } String key = args[1].toLowerCase(); List valid = List.of("savings", "term_7d", "term_15d", "term_30d"); if (!valid.contains(key)) { msg.raw(sender, "&c利率类型无效, 可选: " + String.join(", ", valid)); return; } double rate; try { rate = Double.parseDouble(args[2]); } catch (NumberFormatException ex) { msg.raw(sender, "&c请输入一个有效的利率 (例如 0.005)。"); return; } if (!Double.isFinite(rate) || rate < 0) { msg.raw(sender, "&c利率必须为非负数。"); return; } plugin.getConfig().set("Interest_Rates." + key, rate); plugin.saveConfig(); 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")); sender.sendMessage(com.craftbank.util.Text.color("&7/bankadmin give <玩家> <金额>")); 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 public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { if (!sender.hasPermission("craftbank.admin")) { return List.of(); } if (args.length == 1) { List 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", "log").contains(args[0].toLowerCase())) { return null; // 在线玩家名 } return List.of(); } }