DingTalkController.php 6.3 KB

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