WxTemplateMessageService.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <?php
  2. namespace App\Service\Weixin;
  3. use Exception;
  4. class WxTemplateMessageService extends WeixinService
  5. {
  6. /**
  7. * 发送微信模板消息
  8. *
  9. * @param string $templateKey 模板配置key(对应 config 中的 template_map)
  10. * @param array $dataData 模板参数(key 对应 config 中定义)
  11. * @param array $options [
  12. * 'pagepath' => '', // 小程序路径
  13. * 'url' => '', // 网页路径
  14. * 'openid' => '', // 可选,优先使用
  15. * ]
  16. * @return array [bool, string]
  17. */
  18. public function sendTemplateMessage(string $templateKey, array $dataData, array $options = []): array
  19. {
  20. try {
  21. $config = config("wx_msg.template_map.$templateKey");
  22. if (!$config) return [false, "微信消息模板键值不存在: {$templateKey}"];
  23. $openid = $options['openid'] ?? "";
  24. if (empty($openid)) return [false, "openid 不能为空"];
  25. list($tokenOk, $token) = $this->getTokenSTABLE();
  26. if (! $tokenOk) return [false, $token];
  27. $jumpType = $config['jump_type'] ?? '';
  28. $payload = [
  29. 'touser' => $openid,
  30. 'template_id' => $config['tmp_id'],
  31. 'data' => $this->buildTemplateData($config, $dataData, $options),
  32. ];
  33. // 动态跳转处理
  34. if ($jumpType === 'h5') {
  35. $payload['url'] = $options['url'] ?? '';
  36. } elseif ($jumpType === 'mp') {
  37. $payload['miniprogram'] = [
  38. 'appid' => config('wx_msg.default_appid'),
  39. 'pagepath' => $options['pagepath'] ?? '',
  40. ];
  41. }
  42. $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}";
  43. $res = $this->curlOpen($url, ['post' => json_encode($payload, JSON_UNESCAPED_UNICODE)]);
  44. $res = json_decode($res, true);
  45. if (isset($res['errcode']) && $res['errcode'] === 0) return [true, ''];
  46. return [false , $res['errmsg']];
  47. } catch (Exception $e) {
  48. return [false, $e->getMessage()];
  49. }
  50. }
  51. /**
  52. * 构建模板数据结构
  53. */
  54. protected function buildTemplateData(array $config, array $dataData, array $options = []): array
  55. {
  56. $result = [];
  57. $first = $options['first'] ?? $config['first'] ?? '';
  58. $remark = $options['remark'] ?? $config['remark'] ?? '';
  59. if ($first) {
  60. $result['first'] = ['value' => $first, 'color' => '#173177'];
  61. }
  62. foreach ($config['params'] as $key => $field) {
  63. $value = $dataData[$key] ?? '';
  64. $result[$field] = ['value' => (string)$value, 'color' => '#173177'];
  65. }
  66. if ($remark) {
  67. $result['remark'] = ['value' => $remark, 'color' => '#173177'];
  68. }
  69. return $result;
  70. }
  71. }