WechatTemplateJob.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\jobs\notice\template;
  12. use app\services\message\TemplateMessageServices;
  13. use crmeb\basic\BaseJobs;
  14. use crmeb\services\wechat\OfficialAccount;
  15. use crmeb\traits\QueueTrait;
  16. use crmeb\services\template\Template;
  17. use think\facade\Log;
  18. use think\facade\Route;
  19. /**
  20. * 公众号模版消息
  21. * Class WechatTemplateJob
  22. * @package app\jobs
  23. */
  24. class WechatTemplateJob extends BaseJobs
  25. {
  26. use QueueTrait;
  27. /**
  28. * 同步模版消息
  29. * @return bool
  30. */
  31. public function doJob(array $template)
  32. {
  33. if ($template) {
  34. try {
  35. /*
  36. * 删除所有模版ID
  37. */
  38. //获取微信平台已经添加的模版
  39. $list = OfficialAccount::getPrivateTemplates();//获取所有模版
  40. foreach ($list['template_list'] as $v) {
  41. //删除已有模版
  42. OfficialAccount::deleleTemplate($v['template_id']);
  43. }
  44. /** @var TemplateMessageServices $templateMessageServices */
  45. $templateMessageServices = app()->make(TemplateMessageServices::class);
  46. foreach ($template as $temp) {
  47. $keywordList = [];
  48. $content = is_array($temp['content']) ? $temp['content'] : explode("\n", $temp['content']);
  49. foreach ($content as $c) {
  50. $name = explode('{{', $c)[0] ?? '';
  51. if ($name) {
  52. $keywordList[] = $name;
  53. }
  54. }
  55. if(!$keywordList) continue;
  56. //添加模版消息
  57. $res = OfficialAccount::addTemplateId($temp['tempkey'], $keywordList);
  58. if (!$res['errcode'] && $res['template_id']) {
  59. $templateMessageServices->update($temp['id'], ['tempid' => $res['template_id']]);
  60. }
  61. }
  62. } catch (\Throwable $e) {
  63. Log::error('同步订阅消息失败,原因:' . $e->getMessage());
  64. }
  65. }
  66. return true;
  67. }
  68. /**
  69. * 支付成功发送模板消息
  70. * @param $order
  71. * @return bool
  72. */
  73. public function sendOrderPaySuccess($openid, $order)
  74. {
  75. return $this->sendTemplate('ORDER_PAY_SUCCESS', $openid, [
  76. 'first' => '亲,您购买的商品已支付成功',
  77. 'keyword1' => $order['order_id'],
  78. 'keyword2' => $order['pay_price'],
  79. 'remark' => '点击查看订单详情'
  80. ], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix('')->domain(false)->build());
  81. }
  82. /**
  83. * 购买会员成功
  84. * @param $openid
  85. * @param $order
  86. * @return bool|mixed
  87. */
  88. public function sendMemberOrderPaySuccess($openid, $order)
  89. {
  90. return $this->sendTemplate('ORDER_PAY_SUCCESS', $openid, [
  91. 'first' => '亲,购买会员成功,恭喜您成为本平台尊贵会员!',
  92. 'keyword1' => $order['order_id'],
  93. 'keyword2' => $order['pay_price'],
  94. 'remark' => '点击查看订单详情'
  95. ], sys_config('site_url') . Route::buildUrl('/pages/annex/vip_paid/index')->suffix('')->domain(false)->build());
  96. }
  97. /**
  98. * 服务消息(新)
  99. * @param $openid
  100. * @param $data
  101. * @param $url
  102. * @return bool|mixed
  103. */
  104. public function sendServiceNoticeNew($openid, $data, $url)
  105. {
  106. return $this->sendTemplate('SERVICE_NOTICE_NEW', $openid, [
  107. 'first' => $data['first'],
  108. 'keyword1' => $data['keyword1'],
  109. 'keyword2' => $data['keyword2'],
  110. 'keyword3' => $data['keyword3'],
  111. 'remark' => $data['remark']
  112. ], $url);
  113. }
  114. /**
  115. * 订单发货
  116. * @param $order
  117. * @param array $data
  118. * @return bool|mixed
  119. */
  120. public function sendOrderDeliver($openid, string $goodsName, $order, array $data)
  121. {
  122. return $this->sendTemplate('ORDER_DELIVER_SUCCESS', $openid, [
  123. 'keyword1' => $goodsName,
  124. 'keyword2' => $order['pay_type'] == 'offline' ? '线下支付' : date('Y/m/d H:i', $order['pay_time']),
  125. 'keyword3' => $order['user_address'],
  126. 'keyword4' => $data['delivery_name'],
  127. 'keyword5' => $data['delivery_id'],
  128. 'first' => '亲,您的订单已发货,请注意查收',
  129. 'remark' => '点击查看订单详情'
  130. ], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix(false)->domain(false)->build());
  131. }
  132. /**
  133. * 订单发货
  134. * @param $order
  135. * @param array $data
  136. * @return bool|mixed
  137. */
  138. public function sendOrderPostage($openid, $order, array $data)
  139. {
  140. return $this->sendTemplate('ORDER_POSTAGE_SUCCESS', $openid, [
  141. 'keyword1' => $order['order_id'],
  142. 'keyword2' => $data['delivery_name'],
  143. 'keyword3' => $data['delivery_id'],
  144. 'first' => '亲,您的订单已发货,请注意查收',
  145. 'remark' => '点击查看订单详情'
  146. ], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix(false)->domain(false)->build());
  147. }
  148. /**
  149. * 发送客服消息
  150. * @param $order
  151. * @param string|null $link
  152. * @return bool
  153. */
  154. public function sendServiceNotice($openid, $data, ?string $link = null)
  155. {
  156. return $this->sendTemplate('ADMIN_NOTICE', $openid, $data, $link);
  157. }
  158. /**
  159. * 退款发送客服消息
  160. * @param $order
  161. * @param string|null $link
  162. * @return bool
  163. */
  164. public function sendRefundServiceNotice($openid, $data, ?string $link = null)
  165. {
  166. return $this->sendTemplate('ADMIN_NOTICE', $openid, $data, $link);
  167. }
  168. /**
  169. * 确认收货发送模板消息
  170. * @param $order
  171. * @return bool|mixed
  172. */
  173. public function sendOrderTakeSuccess($openid, $order, $title)
  174. {
  175. return $this->sendTemplate('ORDER_TAKE_SUCCESS', $openid, [
  176. 'first' => '亲,您的订单已收货',
  177. 'keyword1' => $order['order_id'],
  178. 'keyword2' => '已收货',
  179. 'keyword3' => date('Y-m-d H:i:s', time()),
  180. 'keyword4' => $title,
  181. 'remark' => '感谢您的光临!'
  182. ]);
  183. }
  184. /**
  185. * 发送退款申请模板消息
  186. * @param array $data
  187. * @param $order
  188. * @return bool|mixed
  189. */
  190. public function sendOrderApplyRefund($openid, $order)
  191. {
  192. return $this->sendTemplate('ORDER_REFUND_STATUS', $openid, [
  193. 'amount2' => bcadd((string)$order['pay_price'],'0',2),
  194. 'time4' => date('Y-m-d H:i:s', $order['add_time']),
  195. 'character_string5' => $order['order_id']
  196. ], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix('')->domain(false)->build());
  197. }
  198. /**
  199. * 发送退款模板消息
  200. * @param array $data
  201. * @param $order
  202. * @return bool|mixed
  203. */
  204. public function sendOrderRefundSuccess($openid, array $data, $order)
  205. {
  206. return $this->sendTemplate('ORDER_REFUND_STATUS', $openid, [
  207. 'first' => '亲,您购买的商品已退款,本次退款' . $data['refund_price'] . '金额',
  208. 'keyword1' => $order['order_id'],
  209. 'keyword2' => $order['pay_price'],
  210. 'keyword3' => date('Y-m-d H:i:s', $order['add_time']),
  211. 'remark' => '点击查看订单详情'
  212. ], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'] . '&isReturen=1')->suffix('')->domain(false)->build());
  213. }
  214. /**
  215. * 发送退款模板消息
  216. * @param array $data
  217. * @param $order
  218. * @return bool|mixed
  219. */
  220. public function sendOrderRefundNoStatus($openid, $order)
  221. {
  222. return $this->sendTemplate('ORDER_REFUND_STATUS', $openid, [
  223. 'first' => '亲,您的退款申请未申请通过',
  224. 'keyword1' => $order['order_id'],
  225. 'keyword2' => $order['pay_price'],
  226. 'keyword3' => date('Y-m-d H:i:s', $order['add_time']),
  227. 'remark' => '点击查看订单详情'
  228. ], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix('')->domain(false)->build());
  229. }
  230. /**
  231. * 发送用户充值退款模板消息
  232. * @param array $data
  233. * @param $userRecharge
  234. * @return bool|mixed
  235. */
  236. public function sendRechargeRefundStatus($openid, array $data, $userRecharge)
  237. {
  238. return $this->sendTemplate('ORDER_REFUND_STATUS', $openid, [
  239. 'first' => '亲,您充值的金额已退款,本次退款' .
  240. $data['refund_price'] . '金额',
  241. 'keyword1' => $userRecharge['order_id'],
  242. 'keyword2' => $userRecharge['price'],
  243. 'keyword3' => date('Y-m-d H:i:s', $userRecharge['add_time']),
  244. 'remark' => '点击查看订单详情'
  245. ], sys_config('site_url') . Route::buildUrl('/pages/users/user_bill/index')->domain(false)->suffix(false)->build());
  246. }
  247. /**
  248. * 佣金提现失败发送模板消息
  249. * @param $uid
  250. * @param $extract_number
  251. * @param $fail_msg
  252. * @return bool|mixed
  253. */
  254. public function sendUserBalanceChangeFial($openid, $extract_number, $fail_msg)
  255. {
  256. return $this->sendTemplate('USER_BALANCE_CHANGE', $openid, [
  257. 'first' => '提现失败,退回佣金' . $extract_number . '元',
  258. 'keyword1' => '佣金提现',
  259. 'keyword2' => date('Y-m-d H:i:s', time()),
  260. 'keyword3' => $extract_number,
  261. 'remark' => '错误原因:' . $fail_msg
  262. ], sys_config('site_url') . Route::buildUrl('/pages/users/user_spread_money/index?type=1')->suffix(false)->domain(false)->build());
  263. }
  264. /**
  265. * 佣金提现成功发送模板消息
  266. * @param $uid
  267. * @param $extractNumber
  268. * @return bool|mixed
  269. */
  270. public function sendUserBalanceChangeSuccess($openid, $extractNumber)
  271. {
  272. return $this->sendTemplate('USER_BALANCE_CHANGE', $openid, [
  273. 'first' => '成功提现佣金' . $extractNumber . '元',
  274. 'keyword1' => '佣金提现',
  275. 'keyword2' => date('Y-m-d H:i:s', time()),
  276. 'keyword3' => $extractNumber,
  277. 'remark' => '点击查看我的佣金明细'
  278. ], sys_config('site_url') . Route::buildUrl('/pages/users/user_spread_money/index?type=1')->suffix(false)->domain(false)->build());
  279. }
  280. /**
  281. * 拼团成功发送模板消息
  282. * @param $uid
  283. * @param $order_id
  284. * @param $title
  285. * @return bool|mixed
  286. */
  287. public function sendOrderPinkSuccess($openid, $order_id, $pinkId, $title)
  288. {
  289. return $this->sendTemplate('ORDER_USER_GROUPS_SUCCESS', $openid, [
  290. 'first' => '亲,您的拼团已经完成了',
  291. 'keyword1' => $order_id,
  292. 'keyword2' => $title,
  293. 'remark' => '点击查看订单详情'
  294. ], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pinkId)->suffix(false)->domain(false)->build());
  295. }
  296. /**
  297. * 参团成功发送模板消息
  298. * @param $uid
  299. * @param $order_id
  300. * @param $title
  301. * @return bool|mixed
  302. */
  303. public function sendOrderPinkUseSuccess($openid, string $order_id, string $title, int $pink_id)
  304. {
  305. return $this->sendTemplate('ORDER_USER_GROUPS_SUCCESS', $openid, [
  306. 'first' => '亲,您已成功参与拼团',
  307. 'keyword1' => $order_id,
  308. 'keyword2' => $title,
  309. 'remark' => '点击查看订单详情'
  310. ], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pink_id)->suffix(false)->domain(false)->build());
  311. }
  312. /**
  313. * 取消拼团发送模板消息
  314. * @param $uid
  315. * @param StorePink $order_id
  316. * @param $price
  317. * @param string $title
  318. * @return bool|mixed
  319. */
  320. public function sendOrderPinkClone($openid, $pink, $title)
  321. {
  322. return $this->sendTemplate('ORDER_USER_GROUPS_LOSE', $openid, [
  323. 'first' => '亲,您的拼团取消',
  324. 'keyword1' => $title,
  325. 'keyword2' => $pink->price,
  326. 'keyword3' => $pink->price,
  327. 'remark' => '点击查看订单详情'
  328. ], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pink->id)->suffix(false)->domain(false)->build());
  329. }
  330. /**
  331. * 拼团失败发送模板消息
  332. * @param $uid
  333. * @param StorePink $pink
  334. * @param $title
  335. * @return bool|mixed
  336. */
  337. public function sendOrderPinkFial($openid, $pink, $title)
  338. {
  339. return $this->sendTemplate('ORDER_USER_GROUPS_LOSE', $openid, [
  340. 'first' => '亲,您的拼团失败',
  341. 'keyword1' => $title,
  342. 'keyword2' => $pink->price,
  343. 'keyword3' => $pink->price,
  344. 'remark' => '点击查看订单详情'
  345. ], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pink->id)->suffix(false)->domain(false)->build());
  346. }
  347. /**
  348. * 开团成功发送模板消息
  349. * @param $uid
  350. * @param StorePink $pink
  351. * @param $title
  352. * @return bool|mixed
  353. */
  354. public function sendOrderPinkOpenSuccess($openid, $pink, $title)
  355. {
  356. return $this->sendTemplate('OPEN_PINK_SUCCESS', $openid, [
  357. 'first' => '您好,您已成功开团!赶紧与小伙伴们分享吧!!!',
  358. 'keyword1' => $title,
  359. 'keyword2' => $pink['total_price'],
  360. 'keyword3' => $pink['people'],
  361. 'remark' => '点击查看订单详情'
  362. ], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pink['id'])->suffix(false)->domain(false)->build());
  363. }
  364. /**
  365. * 砍价成功发送模板消息
  366. * @param $uid
  367. * @param StoreBargain $bargain
  368. * @return bool|mixed
  369. */
  370. public function sendBargainSuccess($openid, $bargain, $bargainUser = [], $bargainUserId = 0)
  371. {
  372. return $this->sendTemplate('BARGAIN_SUCCESS', $openid, [
  373. 'first' => '好腻害!你的朋友们已经帮你砍到底价了!',
  374. 'keyword1' => $bargain['title'],
  375. 'keyword2' => $bargain['min_price'],
  376. 'remark' => '点击查看订单详情'
  377. ], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_bargain_details/index?id=' . $bargain['id'] . '&bargain=' . $bargainUserId)->suffix(false)->domain(false)->build());
  378. }
  379. /**
  380. * 发送模板消息
  381. * @param string $tempCode 模板消息常量名称
  382. * @param $uid 用户uid
  383. * @param array $data 模板内容
  384. * @param string $link 跳转链接
  385. * @param string|null $color 文字颜色
  386. * @return bool|mixed
  387. */
  388. public function sendTemplate(string $tempCode, $openid, array $data, string $link = null, string $color = null)
  389. {
  390. try {
  391. if (!$openid) return true;
  392. $template = new Template('wechat');
  393. $template->to($openid)->color($color);
  394. if ($link) $template->url($link);
  395. return $template->send($tempCode, $data);
  396. } catch (\Exception $e) {
  397. Log::error('发送模版消息失败,原因:' . $e->getMessage());
  398. return true;
  399. }
  400. }
  401. /**
  402. * 佣金到账发送模板消息
  403. * @param $order
  404. * @return bool
  405. */
  406. public function sendOrderBrokerageSuccess(string $openid, string $brokeragePrice, string $goodsName, string $goodsPrice, $orderTime)
  407. {
  408. return $this->sendTemplate('ORDER_BROKERAGE', $openid, [
  409. 'first' => '亲,您有一笔佣金入账!',
  410. 'keyword1' => $goodsName,
  411. 'keyword2' => $goodsPrice . "元",
  412. 'keyword3' => $brokeragePrice . "元",
  413. 'keyword4' => date('Y-m-d H:i:s', $orderTime),
  414. 'remark' => '点击查看订单详情'
  415. ], sys_config('site_url') . Route::buildUrl('/pages/users/user_spread_user/index')->suffix('')->domain(false)->build());
  416. }
  417. }