TemplateMsg.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php
  2. namespace app\common\model;
  3. use think\Model;
  4. use app\common\model\Order;
  5. use app\common\model\SubscribeLog;
  6. use app\common\library\message\Service;
  7. use think\Queue;
  8. class TemplateMsg extends Model
  9. {
  10. // 表名
  11. protected $name = 'shop_template_msg';
  12. // 自动写入时间戳字段
  13. protected $autoWriteTimestamp = 'int';
  14. // 定义时间戳字段名
  15. protected $createTime = 'createtime';
  16. protected $updateTime = 'updatetime';
  17. protected $deleteTime = false;
  18. // 追加属性
  19. protected $append = [];
  20. public static function getTplIds()
  21. {
  22. return self::where('switch', 1)->where('type', 2)->column('tpl_id');
  23. }
  24. //获取发送模板消息的数据【付款成功】【商城发货通知】【退款通知】【售后回复】
  25. public static function sendTempMsg($event, $order_sn)
  26. {
  27. try {
  28. $config = get_addon_config('shop');
  29. if ($config['sendnoticemode'] == 'queue') {
  30. if (extension_loaded('redis') && class_exists('\think\Queue') && config('queue.connector') == 'redis') {
  31. //使用队列发送
  32. Queue::push('addons\shop\controller\queue\Subscribe', ['event' => $event, 'order_sn' => $order_sn], 'shopSubscribeQueue');
  33. }
  34. } elseif ($config['sendnoticemode'] == 'async') {
  35. //异步并发发送
  36. self::getSendOrderData($event, $order_sn);
  37. }
  38. } catch (\Exception $e) {
  39. }
  40. return true;
  41. }
  42. /**
  43. * @ 获取数据发送
  44. * @param $event
  45. * @param $order_sn
  46. * @return bool
  47. */
  48. public static function getSendOrderData($event, $order_sn)
  49. {
  50. try {
  51. //type 1=公众号,2=小程序,3=邮箱,4=短信
  52. $temps = self::where('event', $event)->where('switch', 1)->order('id asc')->column('*', 'type');
  53. //找订单
  54. $order = Order::field('o.*,u.mobile,u.email,u.nickname')
  55. ->alias('o')
  56. ->join('user u', 'u.id=o.user_id')
  57. ->where('order_sn', $order_sn)
  58. ->find();
  59. self::toSend($order, $temps);
  60. } catch (\Exception $e) {
  61. if (config('app_debug')) {
  62. \think\Log::write("Line:" . $e->getLine() . " Code:" . $e->getCode() . " Message:" . $e->getMessage() . " File:" . $e->getFile());
  63. }
  64. return false;
  65. }
  66. return true;
  67. }
  68. //去发送
  69. protected static function toSend($order, $temps)
  70. {
  71. $result = false;
  72. foreach ($temps as $tp) {
  73. switch ($tp['type']) {
  74. case 1:
  75. //是否有openID
  76. if (!empty($order['openid'])) {
  77. $result = self::assembleMpData($order, $tp);
  78. }
  79. break;
  80. case 2:
  81. //是否有openID
  82. if (!empty($order['openid'])) {
  83. //是否订阅有
  84. $subscribe = SubscribeLog::where('order_sn', $order['order_sn'])->where('tpl_id', $tp['tpl_id'])->where('status', 0)->find();
  85. if (!empty($subscribe)) {
  86. $result = self::assembleMiniData($order, $tp);
  87. $subscribe->status = 1;
  88. $subscribe->save();
  89. }
  90. }
  91. break;
  92. case 3:
  93. if (!empty($order['email'])) {
  94. $result = self::assembleMEData($order, $tp);
  95. }
  96. break;
  97. case 4:
  98. if (!empty($order['mobile'])) {
  99. $result = self::assembleMEData($order, $tp);
  100. }
  101. break;
  102. }
  103. \think\Log::record($result);
  104. $result && Service::send($tp['type'], $result);
  105. }
  106. }
  107. //组装公众号模板数据
  108. protected static function assembleMpData($param, $temp)
  109. {
  110. $data = self::prepareData($param, $temp);
  111. $templateData = [
  112. 'touser' => $param['openid'],
  113. 'template_id' => $temp['tpl_id'],
  114. 'data' => $data
  115. ];
  116. if (strpos($temp['page'], 'http') !== false) {
  117. $templateData['url'] = $temp['page'];
  118. } else {
  119. $config = get_addon_config('shop');
  120. $templateData['miniprogram'] = [
  121. "appid" => $config['wx_appid'],
  122. "pagepath" => $temp['page']
  123. ];
  124. }
  125. return $templateData;
  126. }
  127. //组装小程序模板数据
  128. protected static function assembleMiniData($param, $temp)
  129. {
  130. $data = self::prepareData($param, $temp);
  131. return [
  132. 'touser' => $param['openid'],
  133. 'template_id' => $temp['tpl_id'],
  134. 'page' => $temp['page'],
  135. 'data' => $data
  136. ];
  137. }
  138. //组装邮箱,短信模板数据
  139. protected static function assembleMEData($param, $temp)
  140. {
  141. $data = self::prepareData($param, $temp);
  142. $msg = $temp['extend'];
  143. //替换内容中的变量 ${变量名}
  144. $msg = preg_replace_callback('/\$\{(.*?)\}/i', function ($matches) use ($data) {
  145. return $data[$matches[1]] ?? '';
  146. }, $msg);
  147. return [
  148. 'template_id' => $temp['tpl_id'],
  149. 'mobile' => $param['mobile'],
  150. 'email' => $param['email'],
  151. 'nickname' => $param['nickname'],
  152. 'title' => $temp['title'],
  153. 'message' => $msg,
  154. 'data' => $data,
  155. ];
  156. }
  157. //准备数据
  158. protected static function prepareData($param, $temp)
  159. {
  160. $msg = $temp['extend'];
  161. $temp['content'] = is_array($temp['content']) ? $temp['content'] : (array)json_decode($temp['content'], true);
  162. $data = [];
  163. foreach ($temp['content'] as $res) {
  164. $value = $res['value'];
  165. $value = str_replace('.DATA}}', '', str_replace('{{', '', $value));
  166. if ($value) {
  167. $data[$value] = $res['key'] != 'diy_text' && isset($param[$res['key']]) ? $param[$res['key']] : $res['def_val'];
  168. //如果为时间字段且为数字则做转换
  169. if (is_numeric($data[$value]) && $data[$value] && preg_match("/([a-z]+)time\$/", $res['key'])) {
  170. $data[$value] = date("Y-m-d H:i:s", $data[$value]);
  171. }
  172. }
  173. }
  174. return $data;
  175. }
  176. }