OfficialAccountReplyLogic.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | likeadmin快速开发前后端分离管理后台(PHP版)
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | 开源版本可自由商用,可去除界面版权logo
  7. // | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
  8. // | github下载:https://github.com/likeshop-github/likeadmin
  9. // | 访问官网:https://www.likeadmin.cn
  10. // | likeadmin团队 版权所有 拥有最终解释权
  11. // +----------------------------------------------------------------------
  12. // | author: likeadminTeam
  13. // +----------------------------------------------------------------------
  14. namespace app\adminapi\logic\channel;
  15. use app\common\enum\OfficialAccountEnum;
  16. use app\common\enum\YesNoEnum;
  17. use app\common\logic\BaseLogic;
  18. use app\common\model\channel\OfficialAccountReply;
  19. use app\common\service\wechat\WeChatConfigService;
  20. use app\common\service\wechat\WeChatOaService;
  21. /**
  22. * 微信公众号回复逻辑层
  23. * Class OfficialAccountReplyLogic
  24. * @package app\adminapi\logic\channel
  25. */
  26. class OfficialAccountReplyLogic extends BaseLogic
  27. {
  28. /**
  29. * @notes 添加回复(关注/关键词/默认)
  30. * @param $params
  31. * @return bool
  32. * @author 段誉
  33. * @date 2022/3/29 10:57
  34. */
  35. public static function add($params)
  36. {
  37. try {
  38. // 关键字回复排序值须大于0
  39. if ($params['reply_type'] == OfficialAccountEnum::REPLY_TYPE_KEYWORD && $params['sort'] < 0) {
  40. throw new \Exception('排序值须大于或等于0');
  41. }
  42. if ($params['reply_type'] != OfficialAccountEnum::REPLY_TYPE_KEYWORD && $params['status']) {
  43. // 非关键词回复只能有一条记录处于启用状态,所以将该回复类型下的已有记录置为禁用状态
  44. OfficialAccountReply::where(['reply_type' => $params['reply_type']])->update(['status' => YesNoEnum::NO]);
  45. }
  46. OfficialAccountReply::create($params);
  47. return true;
  48. } catch (\Exception $e) {
  49. self::setError($e->getMessage());
  50. return false;
  51. }
  52. }
  53. /**
  54. * @notes 查看回复详情
  55. * @param $params
  56. * @return array
  57. * @author 段誉
  58. * @date 2022/3/29 11:00
  59. */
  60. public static function detail($params)
  61. {
  62. $field = 'id,name,keyword,reply_type,matching_type,content_type,content,status,sort';
  63. $field .= ',reply_type as reply_type_desc, matching_type as matching_type_desc, content_type as content_type_desc, status as status_desc';
  64. return OfficialAccountReply::field($field)->findOrEmpty($params['id'])->toArray();
  65. }
  66. /**
  67. * @notes 编辑回复(关注/关键词/默认)
  68. * @param $params
  69. * @return bool
  70. * @author 段誉
  71. * @date 2022/3/29 11:01
  72. */
  73. public static function edit($params)
  74. {
  75. try {
  76. // 关键字回复排序值须大于0
  77. if ($params['reply_type'] == OfficialAccountEnum::REPLY_TYPE_KEYWORD && $params['sort'] < 0) {
  78. throw new \Exception('排序值须大于或等于0');
  79. }
  80. if ($params['reply_type'] != OfficialAccountEnum::REPLY_TYPE_KEYWORD && $params['status']) {
  81. // 非关键词回复只能有一条记录处于启用状态,所以将该回复类型下的已有记录置为禁用状态
  82. OfficialAccountReply::where(['reply_type' => $params['reply_type']])->update(['status' => YesNoEnum::NO]);
  83. }
  84. OfficialAccountReply::update($params);
  85. return true;
  86. } catch (\Exception $e) {
  87. self::setError($e->getMessage());
  88. return false;
  89. }
  90. }
  91. /**
  92. * @notes 删除回复(关注/关键词/默认)
  93. * @param $params
  94. * @author 段誉
  95. * @date 2022/3/29 11:01
  96. */
  97. public static function delete($params)
  98. {
  99. OfficialAccountReply::destroy($params['id']);
  100. }
  101. /**
  102. * @notes 更新排序
  103. * @param $params
  104. * @author 段誉
  105. * @date 2022/3/29 11:01
  106. */
  107. public static function sort($params)
  108. {
  109. $params['sort'] = $params['new_sort'];
  110. OfficialAccountReply::update($params);
  111. }
  112. /**
  113. * @notes 更新状态
  114. * @param $params
  115. * @author 段誉
  116. * @date 2022/3/29 11:01
  117. */
  118. public static function status($params)
  119. {
  120. $reply = OfficialAccountReply::findOrEmpty($params['id']);
  121. $reply->status = !$reply->status;
  122. $reply->save();
  123. }
  124. /**
  125. * @notes 微信公众号回调
  126. * @return \Psr\Http\Message\ResponseInterface|void
  127. * @throws \EasyWeChat\Kernel\Exceptions\BadRequestException
  128. * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
  129. * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
  130. * @throws \ReflectionException
  131. * @throws \Throwable
  132. * @author 段誉
  133. * @date 2023/2/27 14:38\
  134. */
  135. public static function index()
  136. {
  137. $server = (new WeChatOaService())->getServer();
  138. // 事件
  139. $server->addMessageListener(OfficialAccountEnum::MSG_TYPE_EVENT, function ($message, \Closure $next) {
  140. switch ($message['Event']) {
  141. case OfficialAccountEnum::EVENT_SUBSCRIBE: // 关注事件
  142. $replyContent = OfficialAccountReply::where([
  143. 'reply_type' => OfficialAccountEnum::REPLY_TYPE_FOLLOW,
  144. 'status' => YesNoEnum::YES
  145. ])
  146. ->value('content');
  147. if ($replyContent) {
  148. return $replyContent;
  149. }
  150. break;
  151. }
  152. return $next($message);
  153. });
  154. // 文本
  155. $server->addMessageListener(OfficialAccountEnum::MSG_TYPE_TEXT, function ($message, \Closure $next) {
  156. $replyList = OfficialAccountReply::where([
  157. 'reply_type' => OfficialAccountEnum::REPLY_TYPE_KEYWORD,
  158. 'status' => YesNoEnum::YES
  159. ])
  160. ->order('sort asc')
  161. ->select();
  162. $replyContent = '';
  163. foreach ($replyList as $reply) {
  164. switch ($reply['matching_type']) {
  165. case OfficialAccountEnum::MATCHING_TYPE_FULL:
  166. $reply['keyword'] === $message['Content'] && $replyContent = $reply['content'];
  167. break;
  168. case OfficialAccountEnum::MATCHING_TYPE_FUZZY:
  169. stripos($message['Content'], $reply['keyword']) !== false && $replyContent = $reply['content'];
  170. break;
  171. }
  172. if ($replyContent) {
  173. break; // 得到回复文本,中止循环
  174. }
  175. }
  176. //消息回复为空的话,找默认回复
  177. if (empty($replyContent)) {
  178. $replyContent = static::getDefaultReply();
  179. }
  180. if ($replyContent) {
  181. return $replyContent;
  182. }
  183. return $next($message);
  184. });
  185. return $server->serve();
  186. }
  187. /**
  188. * @notes 默认回复信息
  189. * @return mixed
  190. * @author 段誉
  191. * @date 2023/2/27 14:36
  192. */
  193. public static function getDefaultReply()
  194. {
  195. return OfficialAccountReply::where([
  196. 'reply_type' => OfficialAccountEnum::REPLY_TYPE_DEFAULT,
  197. 'status' => YesNoEnum::YES
  198. ])
  199. ->value('content');
  200. }
  201. }