Process.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: shenyang
  5. * Date: 2018/6/6
  6. * Time: 下午4:11
  7. */
  8. namespace app\common\models;
  9. use app\common\exceptions\AppException;
  10. use app\common\modules\process\events\AfterProcessStateChangedEvent;
  11. use app\common\modules\process\events\AfterProcessStatusChangedEvent;
  12. use app\common\traits\HasProcessTrait;
  13. use app\common\traits\CanPendingTrait;
  14. use Illuminate\Database\Eloquent\SoftDeletes;
  15. /**
  16. * 进程
  17. * Class ModelHasFlow
  18. * @package app\common\models\flow
  19. * @property Flow flow
  20. * @property Status status
  21. * @property int id
  22. * @property int model_id
  23. * @property int status_id
  24. * @property int is_pending
  25. * @property string name
  26. * @property string code
  27. * @property \Illuminate\Support\Collection allState
  28. * @property string state
  29. * @property string model_type
  30. * @property string status_name
  31. * @property string state_name
  32. * @property string note
  33. */
  34. class Process extends BaseModel
  35. {
  36. use HasProcessTrait, SoftDeletes;
  37. public $table = 'yz_process';
  38. protected $guarded = ['id'];
  39. protected $dates = ['created_at', 'updated_at'];
  40. protected $appends = ['name', 'status_name'];
  41. protected $hidden = ['flow', 'model_type'];
  42. const STATUS_PROCESSING = 'processing';
  43. const STATUS_COMPLETED = 'completed';
  44. const STATUS_CANCELED = 'canceled';
  45. /**
  46. * 进程的主体
  47. * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
  48. */
  49. public function model()
  50. {
  51. return $this->belongsTo($this->model_type, 'model_id');
  52. }
  53. /**
  54. * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
  55. */
  56. public function status()
  57. {
  58. return $this->belongsTo(Status::class);
  59. }
  60. /**
  61. * 所属流程类型
  62. * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
  63. */
  64. public function flow()
  65. {
  66. return $this->belongsTo(Flow::class);
  67. }
  68. public function member()
  69. {
  70. return $this->belongsTo(Member::class, 'uid');
  71. }
  72. /**
  73. * 初始化状态
  74. * @throws \Exception
  75. */
  76. public function initStatus()
  77. {
  78. // 流程的第一个情况
  79. $firstStatus = $this->flow->getFirstStatus();
  80. $this->setStatus($firstStatus);
  81. }
  82. /**
  83. * 进入下一个状态
  84. * @throws \Exception
  85. */
  86. public function toNextStatus()
  87. {
  88. // 流程的下一个情况
  89. $nextStatus = $this->flow->getNextStatus($this->status);
  90. // 根据情况生成新状态
  91. $this->setStatus($nextStatus);
  92. }
  93. /**
  94. * @throws AppException
  95. */
  96. private function operationValidate()
  97. {
  98. // todo 是否可以考虑继续提取一个操作类
  99. if (isset($this->state) && $this->state != self::STATUS_PROCESSING) {
  100. throw new AppException("{$this->name}状态为{$this->status->name},无法继续操作");
  101. }
  102. if ($this->isPending() == true) {
  103. throw new AppException("{$this->name}已挂起,无法继续操作");
  104. }
  105. }
  106. /**
  107. * @param $value
  108. */
  109. public function setStateAttribute($value){
  110. $this->attributes['state'] = $value;
  111. event(new AfterProcessStateChangedEvent($this));
  112. }
  113. /**
  114. * @param Status $status
  115. * @throws AppException
  116. */
  117. private function setStatus($status)
  118. {
  119. $this->operationValidate();
  120. if ($status->is($this->flow->getFinalStatus())) {
  121. // 流程执行完
  122. $this->state = self::STATUS_COMPLETED;
  123. }
  124. if ($status->is($this->flow->getCancelStatus()) || $status->is($this->flow->getCloseStatus())) {
  125. // 流程执行完
  126. $this->state = self::STATUS_CANCELED;
  127. }
  128. $this->setRelation('status',$status);
  129. $this->status_id = $status->id;
  130. $this->save();
  131. event(new AfterProcessStatusChangedEvent($this));
  132. }
  133. /**
  134. * @throws \Exception
  135. */
  136. public function toCloseStatus()
  137. {
  138. $closeStatus = $this->flow->getCloseStatus();
  139. $this->setStatus($closeStatus);
  140. }
  141. /**
  142. * @throws \Exception
  143. */
  144. public function toCancelStatus()
  145. {
  146. $cancelStatus = $this->flow->getCancelStatus();
  147. $this->setStatus($cancelStatus);
  148. }
  149. /**
  150. * @return string
  151. */
  152. public function getNameAttribute()
  153. {
  154. return $this->flow->name;
  155. }
  156. /**
  157. * @return string
  158. */
  159. public function getStateNameAttribute()
  160. {
  161. return $this->allState[$this->state];
  162. }
  163. /**
  164. * @return string
  165. */
  166. public function getStatusNameAttribute()
  167. {
  168. return $this->status->name;
  169. }
  170. /**
  171. * @return int
  172. */
  173. public function isPending()
  174. {
  175. return $this->is_pending;
  176. }
  177. /**
  178. * @return string
  179. */
  180. public function getCodeAttribute()
  181. {
  182. return $this->flow->code;
  183. }
  184. /**
  185. * @return \Illuminate\Support\Collection
  186. */
  187. public function getAllStateAttribute()
  188. {
  189. return collect([
  190. self::STATUS_PROCESSING => '处理中',
  191. self::STATUS_COMPLETED => '已完成',
  192. self::STATUS_CANCELED => '已取消',
  193. ]);
  194. }
  195. }