WorkMomentServices.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. namespace app\services\work;
  3. use app\dao\work\WorkMomentDao;
  4. use app\jobs\work\WorkMomentJob;
  5. use app\services\BaseServices;
  6. use crmeb\services\wechat\Work;
  7. use crmeb\traits\service\ContactWayQrCode;
  8. use crmeb\traits\ServicesTrait;
  9. use think\exception\ValidateException;
  10. use think\facade\Log;
  11. /**
  12. * 创建发布朋友圈
  13. * Class WorkMomentServices
  14. * @package app\services\work
  15. * @mixin WorkMomentDao
  16. */
  17. class WorkMomentServices extends BaseServices
  18. {
  19. use ServicesTrait, ContactWayQrCode;
  20. /**
  21. * WorkMomentServices constructor.
  22. * @param WorkMomentDao $dao
  23. */
  24. public function __construct(WorkMomentDao $dao)
  25. {
  26. $this->dao = $dao;
  27. }
  28. /**
  29. * @param array $where
  30. * @return array
  31. */
  32. public function getList(array $where)
  33. {
  34. [$page, $limit] = $this->getPageValue();
  35. $list = $this->dao->getDataList($where, ['*'], $page, $limit, 'create_time', [
  36. 'sendResult' => function ($query) {
  37. $query->field(['status', 'moment_id']);
  38. }
  39. ]);
  40. $userIds = $userList = [];
  41. foreach ($list as $v) {
  42. $userIds = array_merge($userIds, $v['user_ids']);
  43. }
  44. if ($userIds) {
  45. $userIds = array_merge(array_unique(array_filter($userIds)));
  46. /** @var WorkMemberServices $service */
  47. $service = app()->make(WorkMemberServices::class);
  48. $userList = $service->getColumn([
  49. ['userid', 'in', $userIds]
  50. ], 'name', 'userid');
  51. }
  52. foreach ($list as &$item) {
  53. $item['user_count'] = $item['unuser_count'] = $userCount = $unuserCount = 0;
  54. if (!empty($item['sendResult'])) {
  55. foreach ($item['sendResult'] as $value) {
  56. if ($value['status']) {
  57. $userCount++;
  58. } else {
  59. $unuserCount++;
  60. }
  61. }
  62. }
  63. $item['user_count'] = $userCount;
  64. $item['unuser_count'] = $unuserCount;
  65. $item['user_list'] = [];
  66. foreach ($userList as $k => $v) {
  67. if (in_array($k, $item['user_ids'])) {
  68. $item['user_list'][] = $v;
  69. }
  70. }
  71. }
  72. $count = $this->dao->count($where);
  73. return compact('list', 'count');
  74. }
  75. /**
  76. * 添加发送朋友圈任务
  77. * @param array $data
  78. * @return mixed
  79. */
  80. public function createMomentTask(array $data)
  81. {
  82. $this->checkWelcome($data['welcome_words'], 0);
  83. return $this->transaction(function () use ($data) {
  84. $res = $this->dao->save($data);
  85. //立即发送或者过了发送时间直接发送
  86. if (!$data['send_type'] || ($data['send_type'] == 1 && $data['send_time'] < time())) {
  87. $this->sendMomentTask($res->id, $data['welcome_words'], $data['type'] ? $data['user_ids'] : [], $data['type'] ? $data['client_tag_list'] : []);
  88. }
  89. return $res;
  90. });
  91. }
  92. /**
  93. * 发送
  94. * @param int $id
  95. * @param array $content
  96. * @param array $userIds
  97. * @param array $tags
  98. */
  99. public function sendMomentTask(int $id, array $content, array $userIds, array $tags = [])
  100. {
  101. $resTask = $this->addMomentTask($content, $userIds, $tags);
  102. $this->dao->update($id, ['jobid' => $resTask['jobid']]);
  103. WorkMomentJob::dispatchSece(60 * 3, 'task', [$resTask['jobid']]);
  104. }
  105. /**
  106. * 获取异步任务执行结果
  107. * @param string $jobId
  108. * @return bool
  109. */
  110. public function getTaskInfo(string $jobId)
  111. {
  112. try {
  113. $res = Work::getMomentTask($jobId);
  114. if ($res['status'] !== 3) {
  115. WorkMomentJob::dispatchSece(60 * 3, 'task', [$jobId]);
  116. return true;
  117. }
  118. $this->dao->update(['jobid' => $jobId], [
  119. 'moment_id' => $res['result']['moment_id'],
  120. 'invalid_sender_list' => isset($res['result']['invalid_sender_list']) ? json_encode($res['result']['invalid_sender_list']) : null,
  121. 'invalid_external_contact_list' => isset($res['result']['invalid_external_contact_list']) ? json_encode($res['result']['invalid_external_contact_list']) : null,
  122. ]);
  123. //执行获取任务详情
  124. WorkMomentJob::dispatchDo('getTaskPage', [$res['result']['moment_id'], '']);
  125. return true;
  126. } catch (\Throwable $e) {
  127. Log::error([
  128. 'message' => '获取异步任务结果失败:' . $e->getMessage(),
  129. 'file' => $e->getFile(),
  130. 'line' => $e->getLine()
  131. ]);
  132. return false;
  133. }
  134. }
  135. /**
  136. * 获取发送朋友圈详情
  137. * @param int $id
  138. * @return array
  139. */
  140. public function getMomentInfo(int $id)
  141. {
  142. $info = $this->dao->get($id);
  143. if (!$info) {
  144. throw new ValidateException('没有查询到此朋友圈信息');
  145. }
  146. $userCount = $sendUserCount = $unSendUserCount = $externalUserCount = 0;
  147. if ($info->moment_id) {
  148. /** @var WorkMomentSendResultServices $service */
  149. $service = app()->make(WorkMomentSendResultServices::class);
  150. $userCount = $service->count(['moment_id' => $info->moment_id]);
  151. $sendUserCount = $service->count(['moment_id' => $info->moment_id, 'status' => 1]);
  152. $unSendUserCount = $service->count(['moment_id' => $info->moment_id, 'status' => 0]);
  153. $list = $service->getMomentList(['moment_id' => $info->moment_id, 'status' => 1], ['external_userid']);
  154. $externalUserid = [];
  155. foreach ($list as $item) {
  156. $externalUserid = array_merge($externalUserid, $item['external_userid']);
  157. }
  158. $externalUserCount = count($externalUserid);
  159. }
  160. $info = $info->toArray();
  161. $info['info'] = compact('userCount', 'sendUserCount', 'unSendUserCount', 'externalUserCount');
  162. return $info;
  163. }
  164. /**
  165. * @param int $id
  166. * @return mixed
  167. * @throws \think\db\exception\DataNotFoundException
  168. * @throws \think\db\exception\DbException
  169. * @throws \think\db\exception\ModelNotFoundException
  170. */
  171. public function deleteMoment(int $id)
  172. {
  173. $info = $this->dao->get($id);
  174. if (!$info) {
  175. throw new ValidateException('没有查询到此朋友圈信息');
  176. }
  177. /** @var WorkMomentSendResultServices $service */
  178. $service = app()->make(WorkMomentSendResultServices::class);
  179. return $this->transaction(function () use ($info, $id, $service) {
  180. if ($info->moment_id) {
  181. $service->delete(['moment_id' => $info->moment_id]);
  182. }
  183. return $info->delete();
  184. });
  185. }
  186. /**
  187. * 执行定时任务发送朋友圈
  188. */
  189. public function cronHandle()
  190. {
  191. $time = time();
  192. $list = $this->dao->getDataList(['send_time' => $time, 'send_type' => 1, 'jobid_null' => true]);
  193. foreach ($list as $item) {
  194. $this->sendMomentTask($item['id'], $item['welcome_words'], $item['type'] ? $item['user_ids'] : [], $item['type'] ? $item['client_tag_list'] : []);
  195. }
  196. return true;
  197. }
  198. }