AlertSettings.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. <?php
  2. declare(strict_types=1);
  3. namespace plugin\saiadmin\app\service\alerts;
  4. use plugin\saiadmin\app\model\water\{WaterAlertSetting, WaterModel, WaterLedger};
  5. use plugin\saiadmin\exception\ApiException;
  6. final class AlertSettings
  7. {
  8. public function current(): array
  9. {
  10. $row=WaterAlertSetting::query()->find(1);
  11. if (!$row) throw new ApiException('请先初始化平台预警策略');
  12. return $this->present($row->toArray());
  13. }
  14. private function present(array $row): array
  15. {
  16. return ['alert_qty'=>(int)$row['alert_qty'],'days_per_barrel'=>(int)$row['days_per_barrel'],
  17. 'urgent_qty'=>(int)$row['urgent_qty'],'revision'=>(int)$row['revision'],
  18. 'updated_at'=>$row['updated_at'],'comparison'=>'lt','accuracy_available'=>false];
  19. }
  20. public function save(array $input, int $actor): array
  21. {
  22. foreach (['id','threshold_qty','enterprise_id','account_id'] as $key) {
  23. if (array_key_exists($key,$input)) throw new ApiException('此入口仅保存平台统一策略,不支持企业账户阈值');
  24. }
  25. $values=[];
  26. foreach (['alert_qty'=>[1,10000000],'days_per_barrel'=>[1,365],'urgent_qty'=>[0,9999999],'revision'=>[1,2147483646]] as $key=>[$min,$max]) {
  27. $v=$input[$key]??null;
  28. if ((!is_int($v)&&!is_string($v)) || filter_var($v,FILTER_VALIDATE_INT)===false || (int)$v<$min || (int)$v>$max) {
  29. throw new ApiException('策略参数必须为范围内整数:'.$key);
  30. }
  31. $values[$key]=(int)$v;
  32. }
  33. if ($values['urgent_qty'] >= $values['alert_qty']) throw new ApiException('紧急预警桶数必须小于补货预警桶数');
  34. return WaterModel::transaction(function () use ($values,$actor) {
  35. $row=WaterAlertSetting::query()->lockForUpdate()->find(1);
  36. if (!$row) throw new ApiException('请先初始化平台预警策略');
  37. if ((int)$row->revision!==$values['revision']) throw new ApiException('策略已被其他操作员修改,请重新打开后编辑');
  38. $before=$this->present($row->toArray());
  39. $row->fill($values+['updated_by'=>$actor,'updated_at'=>date('Y-m-d H:i:s')]);
  40. $row->revision=$values['revision']+1;
  41. $row->save();
  42. $after=$this->present($row->toArray());
  43. WaterLedger::query()->insert(['kind'=>'alert_policy','created_by'=>$actor,'sku_id'=>0,'enterprise_id'=>0,
  44. 'quantity'=>0,'reference'=>'platform:alerts','note'=>'平台预警:桶数'.$before['alert_qty'].'→'.$after['alert_qty']
  45. .';每桶天数'.$before['days_per_barrel'].'→'.$after['days_per_barrel'].';紧急桶数'.$before['urgent_qty'].'→'.$after['urgent_qty'],
  46. 'created_at'=>date('Y-m-d H:i:s')]);
  47. return $after;
  48. });
  49. }
  50. }