RuleKeywordService.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. namespace addons\Wechat\services;
  3. use Yii;
  4. use common\components\Service;
  5. use common\enums\StatusEnum;
  6. use common\helpers\AddonHelper;
  7. use common\helpers\ExecuteHelper;
  8. use common\helpers\ArrayHelper;
  9. use EasyWeChat\Kernel\Messages\Text;
  10. use EasyWeChat\Kernel\Messages\Image;
  11. use EasyWeChat\Kernel\Messages\Video;
  12. use EasyWeChat\Kernel\Messages\Voice;
  13. use EasyWeChat\Kernel\Messages\News;
  14. use EasyWeChat\Kernel\Messages\NewsItem;
  15. use addons\Wechat\common\models\Rule;
  16. use addons\Wechat\common\models\RuleKeyword;
  17. use addons\Wechat\common\enums\RuleModuleEnum;
  18. use addons\Wechat\common\enums\RuleKeywordTypeEnum;
  19. /**
  20. * Class RuleKeywordService
  21. * @package addons\Wechat\services
  22. * @author jianyan74 <751393839@qq.com>
  23. */
  24. class RuleKeywordService extends Service
  25. {
  26. /**
  27. * 关键字查询匹配
  28. *
  29. * @param $content
  30. * @return bool|mixed
  31. * @throws \yii\web\NotFoundHttpException
  32. */
  33. public function match($content)
  34. {
  35. $keyword = RuleKeyword::find()->where([
  36. 'or',
  37. ['and', '{{type}} = :typeMatch', '{{content}} = :content'], // 直接匹配关键字
  38. ['and', '{{type}} = :typeInclude', 'INSTR(:content, {{content}}) > 0'], // 包含关键字
  39. ['and', '{{type}} = :typeRegular', ' :content REGEXP {{content}}'], // 正则匹配关键字
  40. ])->addParams([
  41. ':content' => $content,
  42. ':typeMatch' => RuleKeywordTypeEnum::MATCH,
  43. ':typeInclude' => RuleKeywordTypeEnum::INCLUDE,
  44. ':typeRegular' => RuleKeywordTypeEnum::REGULAR
  45. ])
  46. ->andWhere(['status' => StatusEnum::ENABLED])
  47. ->orderBy('sort desc,id desc')
  48. ->one();
  49. if (!$keyword) {
  50. return false;
  51. }
  52. // 查询直接接管的
  53. $takeKeyword = RuleKeyword::find()
  54. ->where(['type' => RuleKeywordTypeEnum::TAKE, 'status' => StatusEnum::ENABLED])
  55. ->andFilterWhere(['>=', 'sort', $keyword->sort])
  56. ->orderBy('sort desc, id desc')
  57. ->one();
  58. $takeKeyword && $keyword = $takeKeyword;
  59. // 历史消息记录
  60. Yii::$app->params['messageHistory'] = ArrayHelper::merge(Yii::$app->params['messageHistory'], [
  61. 'keyword_id' => $keyword->id,
  62. 'rule_id' => $keyword->rule_id,
  63. 'module' => $keyword->module,
  64. ]);
  65. /* @var $model Rule */
  66. $model = Rule::find()
  67. ->where(['id' => $keyword->rule_id])
  68. ->one();
  69. switch ($keyword->module) {
  70. // 文字回复
  71. case RuleModuleEnum::TEXT :
  72. return new Text($model->data);
  73. break;
  74. // 图文回复
  75. case RuleModuleEnum::NEWS :
  76. $news = $model->news;
  77. $newsList = [];
  78. if (!$news) {
  79. return false;
  80. }
  81. foreach ($news as $vo) {
  82. $newsList[] = new NewsItem([
  83. 'title' => $vo['title'],
  84. 'description' => $vo['digest'],
  85. 'url' => $vo['media_url'],
  86. 'image' => $vo['thumb_url'],
  87. ]);
  88. }
  89. return new News($newsList);
  90. break;
  91. // 图片回复
  92. case RuleModuleEnum::IMAGE :
  93. return new Image($model->data);
  94. break;
  95. // 视频回复
  96. case RuleModuleEnum::VIDEO :
  97. return new Video($model->data, [
  98. 'title' => $model->attachment->title,
  99. 'description' => $model->attachment->description,
  100. ]);
  101. break;
  102. // 语音回复
  103. case RuleModuleEnum::VOICE :
  104. return new Voice($model->data);
  105. break;
  106. // 自定义接口回复
  107. case RuleModuleEnum::USER_API :
  108. if ($apiContent = Yii::$app->wechatService->rule->getApiData($model,
  109. Yii::$app->wechatService->message->getMessage())) {
  110. return $apiContent;
  111. }
  112. return $model->default;
  113. break;
  114. // 模块回复
  115. case RuleModuleEnum::ADDON :
  116. // Yii::$app->params['messageHistory']['addon_name'] = $model->data;
  117. // $class = AddonHelper::getAddonMessage($model->data);
  118. // return ExecuteHelper::map($class, 'run', Yii::$app->wechatService->message->getMessage());
  119. break;
  120. default :
  121. return false;
  122. break;
  123. }
  124. }
  125. /**
  126. * 验证是否有直接接管
  127. *
  128. * @param $ruleKeyword
  129. * @return bool
  130. */
  131. public function verifyTake($ruleKeyword)
  132. {
  133. foreach ($ruleKeyword as $item) {
  134. if ($item->type == RuleKeywordTypeEnum::TAKE) {
  135. return true;
  136. }
  137. }
  138. return false;
  139. }
  140. /**
  141. * 更新关键字
  142. *
  143. * @param $rule
  144. * @param $ruleKeywords
  145. * @param $defaultRuleKeywords
  146. * @throws \yii\db\Exception
  147. */
  148. public function update($rule, $ruleKeywords, $defaultRuleKeywords)
  149. {
  150. // 判断是否有直接接管
  151. if (!isset($ruleKeywords[RuleKeywordTypeEnum::TAKE])) {
  152. RuleKeyword::deleteAll(['rule_id' => $rule->id, 'type' => RuleKeywordTypeEnum::TAKE]);
  153. }
  154. // 给关键字赋值默认值
  155. foreach (RuleKeywordTypeEnum::getMap() as $key => $value) {
  156. !isset($ruleKeywords[$key]) && $ruleKeywords[$key] = [];
  157. }
  158. $rows = [];
  159. $merchant_id = Yii::$app->services->merchant->getNotNullId();
  160. $store_id = Yii::$app->services->store->getNotNullId();
  161. foreach ($ruleKeywords as $key => $vo) {
  162. // 去重
  163. $keyword = array_unique($vo);
  164. // 删除不存在的关键字
  165. if ($diff = array_diff($defaultRuleKeywords[$key], $keyword)) {
  166. RuleKeyword::deleteAll([
  167. 'and',
  168. ['rule_id' => $rule->id],
  169. ['type' => $key],
  170. ['in', 'content', array_values($diff)]
  171. ]);
  172. }
  173. // 判断是否有更改不更改直接不插入
  174. if (empty($keyword = array_diff($keyword, $defaultRuleKeywords[$key]))) {
  175. $keyword = [];
  176. }
  177. // 插入数据
  178. foreach ($keyword as $content) {
  179. $rows[] = [$rule->id, $rule->module, $content, $rule->sort, $rule->status, $key, $merchant_id, $store_id];
  180. }
  181. }
  182. // 插入数据
  183. $field = ['rule_id', 'module', 'content', 'sort', 'status', 'type', 'merchant_id', 'store_id'];
  184. !empty($rows) && Yii::$app->db->createCommand()->batchInsert(RuleKeyword::tableName(), $field, $rows)->execute();
  185. }
  186. /**
  187. * @param string $fields
  188. * @return array|\yii\db\ActiveRecord[]
  189. */
  190. public function getList($fields = 'id, content')
  191. {
  192. return RuleKeyword::find()
  193. ->where(['status' => StatusEnum::ENABLED])
  194. ->select($fields)
  195. ->asArray()
  196. ->all();
  197. }
  198. /**
  199. * 获取规则关键字类别
  200. *
  201. * @param array $ruleKeyword
  202. * @return array
  203. */
  204. public function getType($ruleKeyword)
  205. {
  206. !$ruleKeyword && $ruleKeyword = [];
  207. // 关键字列表
  208. $ruleKeywords = [
  209. RuleKeywordTypeEnum::MATCH => [],
  210. RuleKeywordTypeEnum::REGULAR => [],
  211. RuleKeywordTypeEnum::INCLUDE => [],
  212. RuleKeywordTypeEnum::TAKE => [],
  213. ];
  214. foreach ($ruleKeyword as $value) {
  215. $ruleKeywords[$value['type']][] = $value['content'];
  216. }
  217. return $ruleKeywords;
  218. }
  219. }
粤ICP备19079148号