'int', 'name' => 'string', 'disease_name'=> 'string', 'formula' => 'string', 'instructions'=> 'string', 'results' => 'string' ]; protected $json = ['results']; public function questions() { return $this->hasMany(MedicalQuestion::class, 'medical_calculator_id', 'id'); } public function calculateResult(array $inputs) { $formula = $this->formula; // 检查公式中 `=` 的数量 $equalsCount = substr_count($formula, '='); if ($equalsCount > 0) { // 分割公式,使用换行符作为分隔符 $formulas = preg_split('/\r\n|\r|\n/', $formula); foreach ($formulas as $f) { // 提取等号右边的表达式 if (strpos($f, '=') !== false) { list($label, $expr) = explode('=', $f); // 检查公式中的变量是否都在输入中 preg_match_all('/\b([a-zA-Z_]\w*)\b/', $expr, $matches); $formulaVariables = array_unique($matches[1]); $allVariablesExist = true; foreach ($formulaVariables as $variable) { if (!isset($inputs[$variable])) { $allVariablesExist = false; break; } } if ($allVariablesExist) { $formula = $expr; break; } } } } else { // 如果没有等号,直接使用整个公式 preg_match_all('/\b([a-zA-Z_]\w*)\b/', $formula, $matches); $formulaVariables = array_unique($matches[1]); } // 将百分比转换为小数 $formula = str_replace('%', '/100', $formula); foreach ($formulaVariables as $variable) { if (!isset($inputs[$variable])) { throw new \Exception("缺少变量: {$variable}"); } if (!is_numeric($inputs[$variable])) { throw new \Exception("变量不是数字: {$variable}"); } // 使用正则表达式确保只替换完整的变量名,并用括号包裹数值避免运算优先级问题 $formula = preg_replace('/\b' . preg_quote($variable, '/') . '\b/', '(' . floatval($inputs[$variable]) . ')', $formula ); } // 输出替换后的公式以便调试 trace('Processed formula: ' . $formula); try { // 计算结果 $result = eval('return ' . $formula . ';'); if ($result === false || !is_numeric($result)) { throw new \Exception("计算公式错误"); } return floatval($result); } catch (\ParseError $e) { throw new \Exception("计算公式语法错误: " . $e->getMessage()); } } public function getResultInterpretation($value) { $results = $this->results; if (!is_array($results)) { return null; } foreach ($results as $result) { if (isset($result['min']) && isset($result['max'])) { if ($value >= $result['min'] && $value <= $result['max']) { return $result; } } } return null; } }