Salary.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. <?php
  2. namespace app\common\util;
  3. use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
  4. /**
  5. * 表达式操作类
  6. */
  7. class Salary
  8. {
  9. /**
  10. * 计算
  11. * @param string $expression
  12. * @return array
  13. */
  14. public function evaluate(string $expression)
  15. {
  16. $language = new ExpressionLanguage();
  17. try {
  18. $result = $language->evaluate($expression);
  19. return ['code' => 0, 'msg' => '计算成功','data'=>$result];
  20. } catch (\Exception $exception) {
  21. return ['code' => 999, 'msg' => '公式格式不正确,请检查'];
  22. }
  23. }
  24. /**
  25. * @return void
  26. */
  27. public function compile(): void
  28. {
  29. $language = new ExpressionLanguage();
  30. var_dump($language->compile('1 + 2')); // displ
  31. }
  32. /**
  33. * @param $value
  34. * @param $num
  35. * @return array
  36. */
  37. function checkSalaryItem($value, $num): array
  38. {
  39. $bj_num = substr_count($value, '#');
  40. if ($bj_num % 2 == 0) {
  41. if ($bj_num == 0 && $num > 0) {
  42. return \app\facade\Salary::evaluate($value);
  43. }
  44. if (!str_contains($value, '#')) {
  45. return \app\facade\Salary::evaluate($value);
  46. }
  47. $var = $this->getBetweenAB($value);
  48. $res2 = (new SalaryItemModel)->detail(['variable' => $var]);
  49. if (!$res2) {
  50. return ['code' => 999, 'msg' => '公式错误,变量' . $var . '未找到'];
  51. }
  52. $value = str_replace('#' . $var . '#', $res2->value, $value);
  53. $num += 1;
  54. return $this->checkSalaryItem($value, $num);
  55. } else {
  56. return ['code' => 999, 'msg' => '公式错误,请检查变量#符号数量是否准确'];
  57. }
  58. }
  59. /**
  60. * @param $str
  61. * @param string $begin
  62. * @param string $end
  63. * @return string
  64. */
  65. private function getBetweenAB($str, string $begin = "#", string $end = "#"): string
  66. {
  67. if ($begin == '') return '';
  68. $beginPos = mb_strpos($str, $begin);
  69. if ($beginPos === false) return ''; // 起始字符不存在,直接返回空。合理
  70. $start = $beginPos + mb_strlen($begin); // 1.1、开始截取下标
  71. if ($end == '') $endPos = mb_strlen($str);// 结束字符不存在,默认截取到字符串末尾。合理
  72. else $endPos = mb_strpos($str, $end, $start); // 1.2、从开始下标之后查找
  73. if ($endPos === false) $endPos = mb_strlen($str);
  74. $length = $endPos - $start; // 2、截取字符的长度
  75. return mb_substr($str, $start, $length);
  76. }
  77. }