DingTalkController.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Jobs\ProcessDataJob;
  4. use App\Model\Record;
  5. use App\Service\DingCallbackCrypto;
  6. use App\Service\DingService;
  7. use Illuminate\Http\Request;
  8. use Illuminate\Support\Facades\Http;
  9. use Illuminate\Support\Facades\Log;
  10. class DingTalkController extends BaseController
  11. {
  12. public function getAccessToken(Request $request)
  13. {
  14. $service = new DingService();
  15. list($status,$data) = $service->getAccessToken();
  16. if($status){
  17. return $this->json_return(200,'',$data);
  18. }else{
  19. return $this->json_return(201,$data);
  20. }
  21. }
  22. public function getUserByCode(Request $request)
  23. {
  24. $service = new DingService();
  25. list($status,$data) = $service->getUserByCode($request->all());
  26. if($status){
  27. return $this->json_return(200,'',$data);
  28. }else{
  29. return $this->json_return(201,$data);
  30. }
  31. }
  32. public function createProcessInstance(Request $request)
  33. {
  34. $service = new DingService();
  35. $userData = $request->userData;
  36. list($status,$data) = $service->createProcessInstance($request->all(), $userData);
  37. if($status){
  38. return $this->json_return(200,'',$data);
  39. }else{
  40. return $this->json_return(201,$data);
  41. }
  42. }
  43. public function getTodoProcessList(Request $request)
  44. {
  45. $service = new DingService();
  46. $userData = $request->userData;
  47. list($status,$data) = $service->getTodoProcessList($request->all(), $userData);
  48. if($status){
  49. return $this->json_return(200,'',$data);
  50. }else{
  51. return $this->json_return(201,$data);
  52. }
  53. }
  54. public function executeApproval(Request $request)
  55. {
  56. $service = new DingService();
  57. $userData = $request->userData;
  58. list($status,$data) = $service->executeApproval($request->all(), $userData);
  59. if($status){
  60. return $this->json_return(200,'',$data);
  61. }else{
  62. return $this->json_return(201,$data);
  63. }
  64. }
  65. public function getTemplateFields(Request $request)
  66. {
  67. $service = new DingService();
  68. list($status,$data) = $service->getTemplateFields($request->all());
  69. if($status){
  70. return $this->json_return(200,'',$data);
  71. }else{
  72. return $this->json_return(201,$data);
  73. }
  74. }
  75. /**
  76. * 钉钉事件回调
  77. */
  78. public function dinCallback(Request $request)
  79. {
  80. $token = config('dingtalk.token'); // 钉钉事件订阅 token
  81. $aesKey = config('dingtalk.aes_key'); // 钉钉事件订阅 aes_key
  82. $corpid = config('dingtalk.app_key'); // 钉钉事件订阅 corpid
  83. $crypt = new DingCallbackCrypto($token, $aesKey, $corpid);
  84. try {
  85. $encrypt = $request->input('encrypt');
  86. $msgSignature = $request->get('msg_signature');
  87. $timeStamp = $request->get('timestamp');
  88. $nonce = $request->get('nonce');
  89. // 1️⃣ 解密
  90. $event = $crypt->getDecryptMsg($msgSignature, $timeStamp, $nonce, $encrypt);
  91. $event = json_decode($event, true);
  92. // Log::info('钉钉回调解密后的数据', $event);
  93. // 2️⃣ 处理事件
  94. if (isset($event['EventType'])) {
  95. switch ($event['EventType']) {
  96. case 'bpms_instance_change':
  97. $processInstanceId = $event['processInstanceId'] ?? null;
  98. $result = $event['result'] ?? null;
  99. $type = $event['type'] ?? null; // start/finish/terminate/delete
  100. $staffId = $event['staffId'] ?? "";
  101. // 动作导致流程成功 或 流程终止
  102. $this->settleData($type, $result, $processInstanceId, $staffId);
  103. // Log::info('审批实例变更', compact('processInstanceId','result'));
  104. // Log::info("最后一个节点审核通过,审批完成", compact('processInstanceId'));
  105. // Log::info("审批流程被驳回或终止", compact('processInstanceId','result'));
  106. break;
  107. case 'bpms_task_change':
  108. $processInstanceId = $event['processInstanceId'] ?? null;
  109. $taskId = $event['taskId'] ?? null;
  110. $result = $event['result'] ?? null;
  111. $approverUserId = $event['staffId'] ?? null;
  112. // 捕获节点被驳回
  113. if ($result === 'refuse') {
  114. // Log::info("节点被驳回", compact('processInstanceId','taskId','approverUserId'));
  115. }
  116. break;
  117. }
  118. }
  119. // 3️⃣ 返回加密 success
  120. $res = $crypt->getEncryptedMap('success');
  121. return response($res, 200)->header('Content-Type', 'application/json');
  122. } catch (\Exception $e) {
  123. Log::channel('apiLog')->info('钉钉回调解密异常', ['msg' => $e->getMessage()]);
  124. return response()->json(['errcode'=>1, 'errmsg'=>'解密失败']);
  125. }
  126. }
  127. private function settleData($type, $result, $processInstanceId, $staffId){
  128. try {
  129. // ProcessDataJob::dispatch(Record::where('id',71)->first()->toArray())->onQueue(Record::$job);dd(1);
  130. $record = Record::where("del_time",0)
  131. ->where('process_instance_id', $processInstanceId)
  132. ->first();
  133. if(empty($record)) return;
  134. $record->userid = $staffId;
  135. switch ($type) {
  136. // case 'start': // 审批实例开始
  137. // $record->del_time = 9; // 自定义标记,待审批
  138. // break;
  139. case 'finish': // 审批正常结束(同意 / 拒绝)
  140. if ($result === 'agree') {
  141. $record->del_time = 2; // 成功
  142. } elseif ($result === 'refuse') {
  143. $record->del_time = 1; // 驳回
  144. }
  145. break;
  146. case 'terminate': // 审批终止(发起人撤销)
  147. $record->del_time = 1; // 终止
  148. break;
  149. case 'delete': // 审批实例删除
  150. $record->del_time = 1; // 删除
  151. break;
  152. }
  153. $record->save();
  154. $record_array = $record->toArray();
  155. if($record_array['del_time'] == 2) ProcessDataJob::dispatch($record_array)->onQueue(Record::$job);
  156. } catch (\Throwable $exception) {
  157. Log::channel('apiLog')->info('钉钉回调处理数据保存异常', ['msg' => $exception->getMessage()]);
  158. }
  159. // try {
  160. // $record = Record::where("del_time",0)
  161. // ->where('process_instance_id', $processInstanceId)
  162. // ->first();
  163. // if(empty($record)) return;
  164. //
  165. // if ($result === 'agree') {
  166. // $record->del_time = 2; //成功
  167. // }elseif ($result == "refuse") {
  168. // $record->del_time = 1; //驳回
  169. // }
  170. // $record->save();
  171. // }catch (\Throwable $exception){
  172. // Log::channel('apiLog')->info('钉钉回调处理数据保存异常', ['msg' => $exception->getMessage()]);
  173. // }
  174. }
  175. }