123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- <?php
- declare (strict_types = 1);
- namespace app\model;
- use think\Model;
- class MedicalCalculator extends Model
- {
- protected $name = 'medical_calculators';
- protected $autoWriteTimestamp = false;
- protected $schema = [
- 'id' => '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;
- }
- }
|