package com.yami.trading.common.util;
|
|
import java.util.HashMap;
|
import java.util.Map;
|
import java.util.regex.Pattern;
|
|
/**
|
* Translates API error/success messages to English for the user client (H5).
|
* <p>User API controllers ({@code com.yami.trading.api}) should throw English messages directly.
|
* This translator only applies to {@code /api/} and {@code *.action} requests, mainly for
|
* shared service-layer exceptions; admin endpoints are not translated.
|
*/
|
public final class ApiMessageTranslator {
|
|
private static final Pattern CHINESE = Pattern.compile("[\u4e00-\u9fff]");
|
|
private static final Map<String, String> ZH_TO_EN = new HashMap<>();
|
|
static {
|
// Common
|
ZH_TO_EN.put("参数错误", "Invalid parameters");
|
ZH_TO_EN.put("参数错误!", "Invalid parameters");
|
ZH_TO_EN.put("系统错误,请稍后重试", "System error, please try again later");
|
ZH_TO_EN.put("请稍后再试", "Please try again later");
|
ZH_TO_EN.put("操作失败,请稍后再试", "Operation failed, please try again later");
|
ZH_TO_EN.put("无权限", "Permission denied");
|
ZH_TO_EN.put("无网络", "Network unavailable");
|
ZH_TO_EN.put("请先登录", "Please log in first");
|
ZH_TO_EN.put("请登录!", "Please log in");
|
ZH_TO_EN.put("请重新登录", "Please log in again");
|
ZH_TO_EN.put("用户已禁用", "User account is disabled");
|
ZH_TO_EN.put("用户已禁用!", "User account is disabled");
|
|
// Auth / user
|
ZH_TO_EN.put("校验IP不合法", "Invalid IP address");
|
ZH_TO_EN.put("账号或密码不正确", "Incorrect username or password");
|
ZH_TO_EN.put("用户名不能为空", "Username is required");
|
ZH_TO_EN.put("用户名不存在", "Username does not exist");
|
ZH_TO_EN.put("用户名参数为空", "Username is required");
|
ZH_TO_EN.put("用户名重复", "Username already exists");
|
ZH_TO_EN.put("用户名不合法!", "Invalid username");
|
ZH_TO_EN.put("密码不能为空", "Password is required");
|
ZH_TO_EN.put("密码必须6-12位", "Password must be 6-12 characters");
|
ZH_TO_EN.put("密码不正确", "Incorrect password");
|
ZH_TO_EN.put("密码不正确!", "Incorrect password");
|
ZH_TO_EN.put("旧密码不能为空", "Old password is required");
|
ZH_TO_EN.put("新密码不能为空", "New password is required");
|
ZH_TO_EN.put("新密码确认不能为空", "Password confirmation is required");
|
ZH_TO_EN.put("旧密码不正确!", "Incorrect old password");
|
ZH_TO_EN.put("新密码不一致", "New passwords do not match");
|
ZH_TO_EN.put("登录失败", "Login failed");
|
ZH_TO_EN.put("注册失败!", "Registration failed");
|
ZH_TO_EN.put("用户不存在", "User does not exist");
|
ZH_TO_EN.put("用户不存在!", "User does not exist");
|
ZH_TO_EN.put("账号不存在", "Account does not exist");
|
ZH_TO_EN.put("当前登录账号不存在!", "Current account does not exist");
|
ZH_TO_EN.put("账号已存在!", "Account already exists");
|
|
// Fund password / verification
|
ZH_TO_EN.put("资金密码不能为空", "Fund password is required");
|
ZH_TO_EN.put("资金密码不符合设定", "Fund password does not meet requirements");
|
ZH_TO_EN.put("资金密码必须6-12位", "Fund password must be 6-12 characters");
|
ZH_TO_EN.put("资金密码错误", "Incorrect fund password");
|
ZH_TO_EN.put("资金密码不正确!", "Incorrect fund password");
|
ZH_TO_EN.put("旧资金密码不能为空", "Old fund password is required");
|
ZH_TO_EN.put("新资金密码不能为空", "New fund password is required");
|
ZH_TO_EN.put("新资金密码确认不能为空", "Fund password confirmation is required");
|
ZH_TO_EN.put("验证类型不能为空", "Verification type is required");
|
ZH_TO_EN.put("验证码不能为空", "Verification code is required");
|
ZH_TO_EN.put("验证码不正确", "Incorrect verification code");
|
ZH_TO_EN.put("请填写正确的验证码", "Please enter a valid verification code");
|
ZH_TO_EN.put("谷歌验证码错误!", "Incorrect Google Authenticator code");
|
ZH_TO_EN.put("用户谷歌验证码未绑定!", "Google Authenticator is not bound");
|
|
// Phone / email
|
ZH_TO_EN.put("请填写正确的电话号码", "Please enter a valid phone number");
|
ZH_TO_EN.put("电话号码已绑定", "Phone number is already bound");
|
ZH_TO_EN.put("电话号码已绑定其他用户", "Phone number is bound to another user");
|
ZH_TO_EN.put("请输入正确的手机号码", "Please enter a valid phone number");
|
ZH_TO_EN.put("手机号格式不正常!", "Invalid phone number format");
|
ZH_TO_EN.put("手机号已存在!", "Phone number already exists");
|
ZH_TO_EN.put("请填写正确的邮箱地址", "Please enter a valid email address");
|
ZH_TO_EN.put("邮箱已绑定", "Email is already bound");
|
ZH_TO_EN.put("邮箱已绑定其他用户", "Email is bound to another user");
|
ZH_TO_EN.put("邮箱已存在!", "Email already exists");
|
ZH_TO_EN.put("邮箱已重复", "Email already exists");
|
ZH_TO_EN.put("请输入正确的邮箱地址", "Please enter a valid email address");
|
|
// Referral
|
ZH_TO_EN.put("请输入推荐码", "Please enter referral code");
|
ZH_TO_EN.put("请输入正确的推荐码", "Please enter a valid referral code");
|
ZH_TO_EN.put("推荐码不正确", "Incorrect referral code");
|
ZH_TO_EN.put("推荐人无权限推荐", "Referrer is not authorized to refer");
|
|
// Trading
|
ZH_TO_EN.put("不在交易时段", "Outside trading hours");
|
ZH_TO_EN.put("当前已经休市", "Market is closed");
|
ZH_TO_EN.put("未开放合约交易", "Contract trading is not available");
|
ZH_TO_EN.put("停牌禁止交易", "Trading suspended for this symbol");
|
ZH_TO_EN.put("余额不足", "Insufficient balance");
|
ZH_TO_EN.put("仓位不足", "Insufficient position");
|
ZH_TO_EN.put("可平仓合约数量不足", "Insufficient closable contract quantity");
|
ZH_TO_EN.put("杠杠倍数不存在", "Leverage multiplier does not exist");
|
ZH_TO_EN.put("当前币对不存在", "Trading pair does not exist");
|
ZH_TO_EN.put("您已存在订单", "You already have an open order");
|
ZH_TO_EN.put("订单不存在", "Order does not exist");
|
ZH_TO_EN.put("订单不存在!", "Order does not exist");
|
ZH_TO_EN.put("委托单不存在", "Order does not exist");
|
ZH_TO_EN.put("平仓失败", "Failed to close position");
|
ZH_TO_EN.put("一键平仓失败", "Failed to close all positions");
|
ZH_TO_EN.put("追加保证金异常", "Failed to add margin");
|
ZH_TO_EN.put("执行撤单异常", "Failed to cancel order");
|
|
// Futures / delivery
|
ZH_TO_EN.put("k线图获取失败", "Failed to load chart data");
|
ZH_TO_EN.put("生成实时数据失败", "Failed to generate market data");
|
|
// Exchange / wallet
|
ZH_TO_EN.put("请输入正确的货币数量", "Please enter a valid amount");
|
ZH_TO_EN.put("请输入正确的兑换数量", "Please enter a valid exchange amount");
|
ZH_TO_EN.put("请选择正确的币种", "Please select a valid currency");
|
ZH_TO_EN.put("操作钱包失败!", "Wallet operation failed");
|
ZH_TO_EN.put("操作钱包失败!", "Wallet operation failed");
|
|
// Withdraw / recharge
|
ZH_TO_EN.put("未基础认证", "Basic verification required");
|
ZH_TO_EN.put("未安全认证,无提现权限", "Security verification required for withdrawal");
|
ZH_TO_EN.put("请先通过高级认证", "Advanced verification required");
|
ZH_TO_EN.put("无提现权限", "Withdrawal not permitted");
|
ZH_TO_EN.put("提现不得大于限额", "Withdrawal amount exceeds limit");
|
ZH_TO_EN.put("用户资金账户不存在!", "User fund account does not exist");
|
ZH_TO_EN.put("订单已操作,请不要重复操作!", "Order already processed");
|
ZH_TO_EN.put("请上传图片", "Please upload an image");
|
ZH_TO_EN.put("提交失败,当前有未处理银行卡订单", "Submission failed, pending bank order exists");
|
ZH_TO_EN.put("请求第三方失败", "Third-party request failed");
|
|
// C2C
|
ZH_TO_EN.put("支付币种不正确", "Invalid payment currency");
|
ZH_TO_EN.put("提交失败,当前有未处理订单", "Submission failed, pending order exists");
|
ZH_TO_EN.put("用户未结束订单数量已达上限", "Too many open orders");
|
ZH_TO_EN.put("今日取消订单次数太多了,请明日再试", "Too many cancellations today, try again tomorrow");
|
ZH_TO_EN.put("广告不存在", "Advertisement does not exist");
|
ZH_TO_EN.put("支付方式不存在", "Payment method does not exist");
|
ZH_TO_EN.put("订单类型不正确", "Invalid order type");
|
ZH_TO_EN.put("支付金额不正确", "Invalid payment amount");
|
ZH_TO_EN.put("币种数量不正确", "Invalid currency amount");
|
ZH_TO_EN.put("承兑商不存在", "Merchant does not exist");
|
ZH_TO_EN.put("承兑商的用户信息不存在", "Merchant user info does not exist");
|
ZH_TO_EN.put("流水小于限额", "Transaction volume below minimum limit");
|
ZH_TO_EN.put("用户不能取消提现", "Withdrawal cannot be cancelled");
|
ZH_TO_EN.put("充值或提现不正确", "Invalid deposit or withdrawal type");
|
ZH_TO_EN.put("订单状态不正确", "Invalid order status");
|
|
// Appeal / chat
|
ZH_TO_EN.put("申诉订单号不正确", "Invalid appeal order number");
|
ZH_TO_EN.put("请输入申诉原因", "Please enter appeal reason");
|
ZH_TO_EN.put("请上传申诉凭证", "Please upload appeal evidence");
|
ZH_TO_EN.put("该订单已提交申诉", "Appeal already submitted for this order");
|
ZH_TO_EN.put("申诉不存在", "Appeal does not exist");
|
ZH_TO_EN.put("订单号不能未空", "Order number is required");
|
ZH_TO_EN.put("发送消息为空", "Message cannot be empty");
|
|
// KYC
|
ZH_TO_EN.put("实名认证未通过,无法进行高级认证", "Real-name verification required before advanced verification");
|
ZH_TO_EN.put("证件号码长度超过50", "ID number exceeds 50 characters");
|
ZH_TO_EN.put("实名姓名长度超过50", "Real name exceeds 50 characters");
|
ZH_TO_EN.put("工作地址长度超过245", "Work address exceeds 245 characters");
|
ZH_TO_EN.put("家庭地址长度超过245", "Home address exceeds 245 characters");
|
|
// Upload / pagination
|
ZH_TO_EN.put("图片大小不能超过4M", "Image size cannot exceed 4MB");
|
ZH_TO_EN.put("图片大小不能超过30M", "Image size cannot exceed 30MB");
|
ZH_TO_EN.put("文件上传失败", "File upload failed");
|
ZH_TO_EN.put("页码不是整数", "Page number must be an integer");
|
ZH_TO_EN.put("页码不能小于等于0", "Page number must be greater than 0");
|
ZH_TO_EN.put("状态不是整数", "Status must be an integer");
|
ZH_TO_EN.put("状态不能小于0", "Status cannot be negative");
|
|
// Misc API responses
|
ZH_TO_EN.put("重复提交", "Duplicate submission");
|
ZH_TO_EN.put("失败", "Failed");
|
ZH_TO_EN.put("删除自选币种成功", "Removed from favorites");
|
ZH_TO_EN.put("该自选组名称已经使用", "Watchlist name already in use");
|
ZH_TO_EN.put("已经添加过该分组了", "Group already added");
|
ZH_TO_EN.put("当前支付方式有未处理完成的订单!", "Pending orders exist for this payment method");
|
ZH_TO_EN.put("广告id不正确", "Invalid advertisement ID");
|
ZH_TO_EN.put("承兑商支付方式未配置", "Merchant payment method not configured");
|
ZH_TO_EN.put("承兑商广告支付方式未配置", "Merchant ad payment method not configured");
|
|
// Operation type / remark
|
ZH_TO_EN.put("操作类型为空", "Operation type is required");
|
ZH_TO_EN.put("操作类型不是整数", "Operation type must be an integer");
|
ZH_TO_EN.put("操作类型不能小于0", "Operation type cannot be negative");
|
ZH_TO_EN.put("备注长度超过250", "Remark exceeds 250 characters");
|
ZH_TO_EN.put("请填入有效数字", "Please enter a valid number");
|
ZH_TO_EN.put("修改后金额不能小于0", "Amount cannot be negative after adjustment");
|
ZH_TO_EN.put("请选择转移类型", "Please select transfer type");
|
|
// Bean validation (API DTOs)
|
ZH_TO_EN.put("请输入正确的方向", "Please enter a valid direction");
|
ZH_TO_EN.put("委托数量(张)必填", "Order quantity (lots) is required");
|
ZH_TO_EN.put("委托数量(张)不能小于0", "Order quantity cannot be less than 0");
|
ZH_TO_EN.put("交易价格必填", "Price is required");
|
ZH_TO_EN.put("交易价格不能小于0", "Price cannot be less than 0");
|
ZH_TO_EN.put("请输入订单报价类型", "Please enter a valid order price type");
|
ZH_TO_EN.put("金额", "Amount is required");
|
ZH_TO_EN.put("金额小于0", "Amount cannot be less than 0");
|
ZH_TO_EN.put("交割参数不能为空", "Delivery parameter is required");
|
ZH_TO_EN.put("资金密码最小6位", "Fund password must be at least 6 characters");
|
}
|
|
private ApiMessageTranslator() {
|
}
|
|
public static boolean isUserApiRequest(String requestUri) {
|
if (requestUri == null) {
|
return false;
|
}
|
return requestUri.contains("/api/") || requestUri.endsWith(".action");
|
}
|
|
public static boolean containsChinese(String text) {
|
return text != null && CHINESE.matcher(text).find();
|
}
|
|
public static String toEnglish(String message) {
|
if (message == null || message.isEmpty()) {
|
return message;
|
}
|
String trimmed = message.trim();
|
String mapped = ZH_TO_EN.get(trimmed);
|
if (mapped != null) {
|
return mapped;
|
}
|
if (trimmed.startsWith("最低下单金额:")) {
|
return "Minimum order amount: " + trimmed.substring("最低下单金额:".length());
|
}
|
if (trimmed.startsWith("最低下单金额:")) {
|
return "Minimum order amount: " + trimmed.substring("最低下单金额:".length());
|
}
|
if (containsChinese(trimmed)) {
|
return "Operation failed, please try again later";
|
}
|
return message;
|
}
|
}
|