WechatTemplate.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <?php
  2. namespace addons\DepositPresale\common\helpers\wechat;
  3. use addons\DepositPresale\common\enums\DepositPresaleEnum;
  4. use common\models\user\UserExtra;
  5. use common\models\user\UserInfo;
  6. use EasyWeChat\Factory;
  7. use common\models\common\MallSetting;
  8. use Yii;
  9. class WechatTemplate
  10. {
  11. private $wechat = null;
  12. private $mall_id;
  13. private $openid;
  14. private $notice_wechat; //['order_create'=>['tem_key' => 'OPENTM401424715', 'name' => '订单生成通知', 'tempid'=>'Fpjmfna8511']];
  15. const PLATFORM_MP_MX = 'mp-wx'; //小程序
  16. const PLATFORM_WECHAT = 'wechat'; //公众号
  17. const ERRCODE_INVALID_TEMPLATE_ID = 40037; //微信公众号没有该模板id
  18. const ORDER_CREATE = 'order_create'; //订单创建
  19. const ORDER_PAY_SUCCESS = 'order_pay_success'; //订单支付成功
  20. const ORDER_CANCEL = 'order_cancel'; //订单取消通知
  21. const ORDER_SENT = 'order_sent'; //订单发货提现
  22. const ORDER_CONFIRMED = 'order_confirmed'; //订单确认收货
  23. const GROUP_BY_SUCCESS = 'group_buy_success'; //拼团成功通知
  24. const GROUP_BY_FAILED = 'group_buy_failed'; //拼团失败通知
  25. const BALANCE_CHANE = 'balance_change'; //账户余额通知
  26. const INCOME_CHANGE = 'income_change'; //账户余额通知
  27. const SCORE_CHANGE = 'score_change'; //积分交易提醒
  28. const ORDER_REFUND_AGREE = 'order_refund_agree'; //退货申请通过提醒
  29. const ORDER_REFUND_REFUSE = 'order_refund_refuse'; //售后申请审核通知
  30. const ORDER_REFUND_MONEY = 'order_refund_money'; //退款成功通知
  31. const USER_REGISTER = 'userRegister'; //下线加入通知
  32. const UP_LEVEL = 'upLevel'; //会员等级变更通知
  33. const E_COUPON_SEND = 'e_coupon_send'; //电子券通知
  34. const ACHIEVEMENT_GRANT_PUSH = 'achievement_grant_push'; //定期业绩通知
  35. const ORDER_DEPOSIT = 'order_deposit'; //订单支付定金后通知
  36. const ORDER_FINAL_PAYMENT = 'order_final_payment'; //订单支付尾款后通知
  37. public function __construct($mall_id)
  38. {
  39. try {
  40. $this->mall_id = $mall_id;
  41. $config = Yii::$app->services->setting->addons->get($this->mall_id, DepositPresaleEnum::ADDONS_NAME, 'basic.notice_wechat');
  42. if (empty($config)) {
  43. $this->notice_wechat = false;
  44. return false;
  45. }
  46. if (is_string($config)) {
  47. $data = json_decode($config, true);
  48. } else {
  49. if(is_array($config)) {
  50. $data = $config;
  51. }else{
  52. $this->notice_wechat = false;
  53. return false;
  54. }
  55. }
  56. if (empty($data['is_logging'])) {
  57. $this->notice_wechat = false;
  58. return false;
  59. }
  60. $template_message = $data['template_message']['value'];
  61. if (empty($template_message)) {
  62. $this->notice_wechat = false;
  63. return false;
  64. }
  65. $data = array_merge($data, $template_message);
  66. $this->notice_wechat = $data;
  67. //获取accsee_token app_id等信息
  68. $wechat = MallSetting::getConfByGroup($this->mall_id, 'wechat', true);
  69. if (empty($wechat)) {
  70. $this->notice_wechat = false;
  71. } else {
  72. unset($wechat['name']);
  73. unset($wechat['qrcode']);
  74. $wechat_config = [];
  75. foreach ($wechat as $name => $setting) {
  76. $wechat_config[$name] = $setting['value'];
  77. }
  78. $this->wechat = Factory::officialAccount($wechat_config);
  79. }
  80. } catch (\Exception $e) {
  81. Yii::error('插件DepositPresale:微信模板配置出现问题--'.$e->getMessage);
  82. }
  83. }
  84. /**
  85. * 获取商城是否打开推送
  86. */
  87. public function is_logging()
  88. {
  89. if ($this->wechat === null) return false;
  90. return empty($this->notice_wechat) ? false : ($this->notice_wechat['is_logging'] == 1 ? true : false);
  91. }
  92. /**
  93. * 用户是否开启推送
  94. */
  95. public function is_notice($user_id)
  96. {
  97. $user_extra = UserExtra::find()->where(['user_id' => $user_id])->one();
  98. return empty($user_extra) ? false : ($user_extra['is_wechat_notice'] == 1 ? true : false);
  99. }
  100. /**
  101. * 用户是否公众号用户
  102. */
  103. public function is_platform_wechat($user_id)
  104. {
  105. $user_info = UserInfo::find()->where(['status' => 1, 'user_id' => $user_id, 'platform' => self::PLATFORM_WECHAT])->one();
  106. return !empty($user_info) && $this->openid = $user_info->openid;
  107. }
  108. /**
  109. * 发送模板消息
  110. * @param $user_id 用户ID
  111. * @param $template_key 模板key
  112. * @param $url 跳转链接
  113. * @param $data 发生的数据
  114. * @param $platform 平台
  115. */
  116. public function sendTemplate($user_id, $template_key, $url, $data, $platform = "wechat", $miniapp_page = null)
  117. {
  118. if ($this->wechat == null) {
  119. return;
  120. }
  121. try {
  122. $template_id = $this->checkTemplate($template_key);
  123. if ($template_id == false) {
  124. return;
  125. }
  126. //公众号
  127. if ($platform == self::PLATFORM_WECHAT) {
  128. $result = $this->sendWechat($this->openid, $template_id, $url, $data);
  129. }
  130. //小程序
  131. if ($platform == self::PLATFORM_MP_MX) {
  132. $result = $this->sendMiniApp($this->openid, $template_id, $url, $data, $miniapp_page);
  133. }
  134. //微信公众号数据没有该模板,删除本地数据库中的数据
  135. if ($result['errcode'] != 0) {
  136. if ($result['errcode'] == self::ERRCODE_INVALID_TEMPLATE_ID) {
  137. $this->wechat->template_message->deletePrivateTemplate($template_id);
  138. }
  139. \Yii::error('发送模板消息失败, error_code=' . $result['errcode'] . ',error_message=' . $result['errmsg']);
  140. }
  141. } catch (\Exception $e) {
  142. \Yii::error('发送模板消息失败,失败原因:' . $e->getMessage() . ',错误行数:' . $e->getLine());
  143. }
  144. }
  145. /**
  146. * 有模板返回模板,没有模板消息通过template_id_short获取
  147. * @param string $template_type 触发发送模板消息的事件类型
  148. * @return void
  149. */
  150. public function checkTemplate($template_type)
  151. {
  152. try {
  153. $template_massage = $this->notice_wechat;
  154. if (!isset($this->notice_wechat[$template_type])) {
  155. \Yii::error('发送模板消息失败,触发事件不存在');
  156. return false;
  157. }
  158. //获取
  159. if (!isset($this->notice_wechat[$template_type]['tem_key'])) {
  160. $data = $this->wechat->template_message->addTemplate($this->notice_wechat[$template_type]['tem_key']);
  161. /*
  162. * $data=[
  163. * 'errcode'=>0,
  164. * 'errmsg'=>"ok",
  165. * "template_id"=>"2O0LuGyxows93Y6D6LMKrF09P5tpfoNift3n7AjwT5o",
  166. * ];
  167. */
  168. if ($data['errcode'] == 0) {
  169. $template_massage[$template_type]['tempid'] = $data['template_id'];
  170. $setting = ['notice_wechat' => ['template_message' => json_encode($template_massage, JSON_UNESCAPED_UNICODE)]];
  171. \Yii::$app->services->setting->mall->set($this->mall_id, $setting);
  172. return $data['template_id'];
  173. } else {
  174. \Yii::error('发送模板消息失败,获取template_id失败,失败原因:' . $data['errmsg']);
  175. return false;
  176. }
  177. }
  178. return $this->notice_wechat[$template_type]['tem_key'];
  179. } catch (\Exception $e) {
  180. \Yii::error('发送模板消息失败,获取template_id失败,失败原因:' . $e->getMessage() . ',错误行数:' . $e->getLine());
  181. return false;
  182. }
  183. }
  184. /**
  185. * 跳转平台
  186. */
  187. public function getPlatForm()
  188. {
  189. return $this->notice_wechat['is_miniapp_priority'] == 1 ? 'mp-wx' : 'wechat';
  190. }
  191. /**
  192. * @param $touser
  193. * @param $template_id
  194. * @param $url
  195. * @param $data
  196. * [
  197. * 'touser' => 'owdRztxk_XOtVZ0xglXuGv_MsRbA',
  198. * 'template_id' => '7rTBQadzdA4qn2RSR0_6lYUJxBlR6HloEMl03AuPRK4',
  199. * 'url' => 'http://jxmall.com',
  200. * 'data' => [
  201. * 'productType' => '商品名称',
  202. * 'name' => '小米手机',
  203. * 'number' => 12,
  204. * 'expDate' => '永久有效',
  205. * 'remark' => '恭喜你,购买成功'
  206. * ],
  207. * ]
  208. *
  209. * @return array
  210. * {
  211. * "errcode": 0,
  212. * "errmsg": "ok",
  213. * "msgid": 1552413574407520257
  214. * }
  215. */
  216. public function sendWechat($touser, $template_id, $url, $data)
  217. {
  218. return $this->wechat->template_message->send([
  219. 'touser' => $touser,
  220. 'template_id' => $template_id,
  221. 'url' => $url,
  222. 'data' => $data
  223. ]);
  224. }
  225. /**
  226. * @param $touser
  227. * @param $template_id
  228. * @param $url
  229. * @param $data
  230. * [
  231. * 'touser' => 'user-openid',
  232. * 'template_id' => 'template-id',
  233. * 'url' => 'https://abc.org',
  234. * 'miniprogram' => [
  235. * 'appid' => 'xxxxxxx',
  236. * 'pagepath' => 'pages/xxx',
  237. * ],
  238. * 'data' => [
  239. * 'key1' => 'VALUE',
  240. * 'key2' => 'VALUE2',
  241. * ...
  242. * ],
  243. * ]
  244. * @param $pagepath
  245. */
  246. public function sendMiniApp($touser, $template_id, $url, $data, $pagepath)
  247. {
  248. $app_id = isset(\Yii::$app->params['wechatMiniProgramConfig']['app_id']) ? \Yii::$app->params['wechatMiniProgramConfig']['app_id'] : "";
  249. return $this->wechat->template_message->send([
  250. 'touser' => $touser,
  251. 'template_id' => $template_id,
  252. 'url' => $url,
  253. 'miniprogram' => [
  254. 'appid' => $app_id,
  255. 'pagepath' => $pagepath,
  256. ],
  257. 'data' => $data
  258. ]);
  259. }
  260. }