addError('金额必须为数字'); return false; } $amount = (float)$value; // 检查金额是否为正数 if ($amount <= 0) { $this->addError('金额必须大于0'); return false; } // 获取钻石币种的精度 $precision = FUND_CURRENCY_TYPE::ZUANSHI->getPrecision(); // 验证金额精度 if (!$this->validatePrecision($amount, $precision)) { $this->addError("金额精度不能超过{$precision}位小数"); return false; } // 检查金额范围(最大值) $maxAmount = 999999999.9999999999; // 10位小数的最大合理值 if ($amount > $maxAmount) { $this->addError("金额不能超过{$maxAmount}"); return false; } // 格式化金额到正确的精度 $formattedAmount = $this->formatAmountToPrecision($amount, $precision); // 将格式化后的金额设置到验证对象中 if (isset($this->args['formattedAmount'])) { $this->validation->formattedAmount = $formattedAmount; } return true; } /** * 验证金额精度 * * @param float $amount 金额 * @param int $precision 允许的小数位数 * @return bool */ private function validatePrecision(float $amount, int $precision): bool { // 将金额转换为字符串以检查小数位数 $amountStr = (string)$amount; // 如果包含小数点 if (strpos($amountStr, '.') !== false) { $parts = explode('.', $amountStr); $decimalPart = $parts[1]; // 移除末尾的0 $decimalPart = rtrim($decimalPart, '0'); // 检查小数位数 if (strlen($decimalPart) > $precision) { return false; } } return true; } /** * 格式化金额到指定精度 * * @param float $amount 原始金额 * @param int $precision 精度 * @return float */ private function formatAmountToPrecision(float $amount, int $precision): float { // 使用 bcmath 进行高精度计算 if (function_exists('bcadd')) { return (float)bcadd((string)$amount, '0', $precision); } // 如果没有 bcmath,使用 number_format return (float)number_format($amount, $precision, '.', ''); } /** * 获取验证器描述 * * @return string */ public function getDescription(): string { return '验证钻石金额的格式和精度,确保符合系统要求'; } }