WechatReplyServices.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\services\wechat;
  13. use app\services\BaseServices;
  14. use app\dao\wechat\WechatReplyDao;
  15. use app\services\kefu\KefuServices;
  16. use crmeb\exceptions\AdminException;
  17. use crmeb\services\app\WechatService;
  18. /**
  19. * Class UserWechatuserServices
  20. * @package app\services\user
  21. * @method delete($id, ?string $key = null) 删除
  22. * @method update($id, array $data, ?string $key = null) 更新数据
  23. */
  24. class WechatReplyServices extends BaseServices
  25. {
  26. /**
  27. * UserWechatuserServices constructor.
  28. * @param WechatReplyDao $dao
  29. */
  30. public function __construct(WechatReplyDao $dao)
  31. {
  32. $this->dao = $dao;
  33. }
  34. /**
  35. * 消息类型
  36. * @return string[]
  37. */
  38. public function replyType()
  39. {
  40. return ['text', 'image', 'news', 'voice'];
  41. }
  42. /**
  43. * 自定义简单查询总数
  44. * @param array $where
  45. * @return int
  46. */
  47. public function getCount(array $where): int
  48. {
  49. return $this->dao->getCount($where);
  50. }
  51. /**
  52. * 复杂条件搜索列表
  53. * @param array $where
  54. * @param string $field
  55. * @return array
  56. */
  57. public function getWhereUserList(array $where, string $field): array
  58. {
  59. [$page, $limit] = $this->getPageValue();
  60. $list = $this->dao->getListByModel($where, $field, $page, $limit);
  61. $count = $this->dao->getCountByWhere($where);
  62. return [$list, $count];
  63. }
  64. /**
  65. * 关注回复
  66. * @param string $key
  67. * @return array|\think\Model|null
  68. * @throws \think\db\exception\DataNotFoundException
  69. * @throws \think\db\exception\DbException
  70. * @throws \think\db\exception\ModelNotFoundException
  71. */
  72. public function getDataByKey(string $key)
  73. {
  74. /** @var WechatKeyServices $services */
  75. $services = app()->make(WechatKeyServices::class);
  76. $data = $services->getOne(['keys' => $key]);
  77. $resdata = $this->dao->getOne(['id' => $data['reply_id'] ?? 0]);
  78. $resdata['data'] = isset($resdata['data']) ? json_decode($resdata['data'], true) : [];
  79. $resdata['key'] = $key;
  80. return $resdata;
  81. }
  82. /**
  83. * 保存关键字
  84. * @param $data
  85. * @param $id
  86. * @param $key
  87. * @param $type
  88. * @param int $status
  89. * @return bool
  90. */
  91. public function redact($data, $id, $key, $type, $status = 1)
  92. {
  93. $method = 'tidy' . ucfirst($type);
  94. if ($id == 'undefined') {
  95. $id = 0;
  96. }
  97. if (isset($data['content']) && $data['content'] == '' && isset($data['src']) && $data['src'] == '') $data = $data['list'][0] ?? [];
  98. try {
  99. $res = $this->{$method}($data, $id);
  100. } catch (\Throwable $e) {
  101. throw new AdminException($e->getMessage());
  102. }
  103. if (!$res) return false;
  104. $arr = [];
  105. /** @var WechatKeyServices $keyServices */
  106. $keyServices = app()->make(WechatKeyServices::class);
  107. $count = $this->dao->getCount(['id' => $id]);
  108. if ($count) {
  109. $keyServices->delete($id, 'reply_id');
  110. $insertData = explode(',', $key);
  111. foreach ($insertData as $k => $v) {
  112. $arr[$k]['keys'] = $v;
  113. $arr[$k]['reply_id'] = $id;
  114. }
  115. $res = $this->dao->update($id, ['type' => $type, 'data' => json_encode($res), 'status' => $status], 'id');
  116. $res1 = $keyServices->saveAll($arr);
  117. if (!$res || !$res1) {
  118. throw new AdminException(100006);
  119. }
  120. } else {
  121. $reply = $this->dao->save([
  122. 'type' => $type,
  123. 'data' => json_encode($res),
  124. 'status' => $status,
  125. ]);
  126. $insertData = explode(',', $key);
  127. foreach ($insertData as $k => $v) {
  128. $arr[$k]['keys'] = $v;
  129. $arr[$k]['reply_id'] = $reply->id;
  130. }
  131. $res = $keyServices->saveAll($arr);
  132. if (!$res) throw new AdminException(100006);
  133. }
  134. return true;
  135. }
  136. /**
  137. * 获取所有关键字
  138. * @param array $where
  139. * @return array
  140. */
  141. public function getKeyAll($where = array())
  142. {
  143. /** @var WechatReplyKeyServices $replyKeyServices */
  144. $replyKeyServices = app()->make(WechatReplyKeyServices::class);
  145. $data = $replyKeyServices->getReplyKeyAll($where);
  146. /** @var WechatKeyServices $keyServices */
  147. $keyServices = app()->make(WechatKeyServices::class);
  148. foreach ($data['list'] as &$item) {
  149. if ($item['data']) $item['data'] = json_decode($item['data'], true);
  150. switch ($item['type']) {
  151. case 'text':
  152. $item['typeName'] = '文字消息';
  153. break;
  154. case 'image':
  155. $item['typeName'] = '图片消息';
  156. break;
  157. case 'news':
  158. $item['typeName'] = '图文消息';
  159. break;
  160. case 'voice':
  161. $item['typeName'] = '声音消息';
  162. break;
  163. }
  164. $keys = $keyServices->getColumn(['reply_id' => $item['id']], 'keys');
  165. $item['key'] = implode(',', $keys);
  166. }
  167. return $data;
  168. }
  169. /**
  170. * 查询一条
  171. * @param $key
  172. * @return array|null|\think\Model
  173. * @throws \think\db\exception\DataNotFoundException
  174. * @throws \think\db\exception\ModelNotFoundException
  175. * @throws \think\exception\DbException
  176. */
  177. public function getKeyInfo(int $id)
  178. {
  179. $resdata = $this->dao->getOne(['id' => $id]);
  180. /** @var WechatKeyServices $keyServices */
  181. $keyServices = app()->make(WechatKeyServices::class);
  182. $keys = $keyServices->getColumn(['reply_id' => $resdata['id']], 'keys');
  183. $resdata['data'] = $resdata['data'] ? json_decode($resdata['data'], true) : [];
  184. $resdata['key'] = implode(',', $keys);
  185. return $resdata;
  186. }
  187. /**
  188. * 整理文本输入的消息
  189. * @param $data
  190. * @param $key
  191. * @return array|bool
  192. */
  193. public function tidyText($data, $id)
  194. {
  195. $res = [];
  196. if (!isset($data['content']) || $data['content'] == '') {
  197. throw new AdminException(400706);
  198. }
  199. $res['content'] = $data['content'];
  200. return $res;
  201. }
  202. /**
  203. * 整理图片资源
  204. * @param $data
  205. * @param $id
  206. * @return array|mixed
  207. * @throws \think\db\exception\DataNotFoundException
  208. * @throws \think\db\exception\DbException
  209. * @throws \think\db\exception\ModelNotFoundException
  210. */
  211. public function tidyImage($data, $id)
  212. {
  213. if (!isset($data['src']) || $data['src'] == '') {
  214. throw new AdminException(400707);
  215. }
  216. $reply = $this->dao->get((int)$id);
  217. if ($reply) $reply['data'] = json_decode($reply['data'], true);
  218. if ($reply && isset($reply['data']['src']) && $reply['data']['src'] == $data['src']) {
  219. $res = $reply['data'];
  220. } else {
  221. $res = [];
  222. //TODO 图片转media
  223. $res['src'] = $data['src'];
  224. try {
  225. $material = WechatService::materialService()->uploadImage(url_to_path($data['src']));
  226. } catch (\Throwable $e) {
  227. throw new AdminException(WechatService::getMessage($e->getMessage()));
  228. }
  229. $res['media_id'] = $material->media_id;
  230. $dataEvent = ['type' => 'image', 'media_id' => $material->media_id, 'path' => $res['src'], 'url' => $material->url];
  231. /** @var WechatMediaServices $mateServices */
  232. $mateServices = app()->make(WechatMediaServices::class);
  233. $mateServices->save($dataEvent);
  234. }
  235. return $res;
  236. }
  237. /**
  238. * 整理声音资源
  239. * @param $data
  240. * @param $id
  241. * @return array|mixed
  242. * @throws \think\db\exception\DataNotFoundException
  243. * @throws \think\db\exception\DbException
  244. * @throws \think\db\exception\ModelNotFoundException
  245. */
  246. public function tidyVoice($data, $id)
  247. {
  248. if (!isset($data['src']) || $data['src'] == '') {
  249. throw new AdminException(400708);
  250. }
  251. $reply = $this->dao->get((int)$id);
  252. if ($reply) $reply['data'] = json_decode($reply['data'], true);
  253. if ($reply && isset($reply['data']['src']) && $reply['data']['src'] == $data['src']) {
  254. $res = $reply['data'];
  255. } else {
  256. $res = [];
  257. //TODO 声音转media
  258. $res['src'] = $data['src'];
  259. try {
  260. $material = WechatService::materialService()->uploadVoice(url_to_path($data['src']));
  261. } catch (\Throwable $e) {
  262. throw new AdminException(WechatService::getMessage($e->getMessage()));
  263. }
  264. $res['media_id'] = $material->media_id;
  265. $dataEvent = ['media_id' => $material->media_id, 'path' => $res['src'], 'type' => 'voice'];
  266. /** @var WechatMediaServices $mateServices */
  267. $mateServices = app()->make(WechatMediaServices::class);
  268. $mateServices->save($dataEvent);
  269. }
  270. return $res;
  271. }
  272. /**
  273. * 整理图文资源
  274. * @param $data
  275. * @param $id
  276. * @return bool
  277. */
  278. public function tidyNews($data, $id = 0)
  279. {
  280. if ($id != 0) {
  281. $data = $data['list'][0];
  282. }
  283. if (!count($data)) {
  284. throw new AdminException(400709);
  285. }
  286. $siteUrl = sys_config('site_url');
  287. if (empty($data['url'])) $data['url'] = $siteUrl . '/pages/extension/news_details/index?id=' . $data['id'];
  288. if (count($data['image_input'])) $data['image'] = $data['image_input'][0];
  289. return $data;
  290. }
  291. /**
  292. * 获取关键字
  293. * @param $key
  294. * @param string $openId
  295. * @return array|\EasyWeChat\Message\Image|\EasyWeChat\Message\News|\EasyWeChat\Message\Text|\EasyWeChat\Message\Transfer|\EasyWeChat\Message\Voice
  296. * @throws \think\db\exception\DataNotFoundException
  297. * @throws \think\db\exception\DbException
  298. * @throws \think\db\exception\ModelNotFoundException
  299. */
  300. public function reply($key, string $openId = '')
  301. {
  302. $res = $this->dao->getKey($key);
  303. if (empty($res)) {
  304. /** @var KefuServices $services */
  305. $services = app()->make(KefuServices::class);
  306. $services->replyTransferService($key, $openId);
  307. return WechatService::transfer();
  308. }
  309. return $this->replyDataByMessage($res->toArray());
  310. }
  311. /**
  312. * 根据关键字内容返回对应的内容
  313. * @param array $res
  314. * @return array|\EasyWeChat\Message\Image|\EasyWeChat\Message\News|\EasyWeChat\Message\Text|\EasyWeChat\Message\Voice
  315. */
  316. public function replyDataByMessage(array $res)
  317. {
  318. $res['data'] = json_decode($res['data'], true);
  319. if ($res['type'] == 'text') {
  320. return WechatService::textMessage($res['data']['content']);
  321. } else if ($res['type'] == 'image') {
  322. return WechatService::imageMessage($res['data']['media_id']);
  323. } else if ($res['type'] == 'news') {
  324. $title = $res['data']['title'] ?? '';
  325. $image = $res['data']['image'] ?? '';
  326. $description = $res['data']['synopsis'] ?? '';
  327. $url = $res['data']['url'] ?? '';
  328. return WechatService::newsMessage($title, $description, $url, $image);
  329. } else if ($res['type'] == 'voice') {
  330. return WechatService::voiceMessage($res['data']['media_id']);
  331. }
  332. }
  333. }