WxTemplateMessageService.php 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. * 'first' => '', // 可选,覆盖默认
  16. * 'remark' => '', // 可选,覆盖默认
  17. * ]
  18. * @return array [bool, string]
  19. */
  20. public function sendTemplateMessage(string $templateKey, array $dataData, array $options = []): array
  21. {
  22. try {
  23. $config = config("wx_msg.template_map.$templateKey");
  24. if (!$config) return [false, "微信消息模板键值不存在: {$templateKey}"];
  25. $openid = $options['openid'] ?? "";
  26. if (empty($openid)) return [false, "openid 不能为空"];
  27. list($tokenOk, $token) = $this->getTokenSTABLE();
  28. if (! $tokenOk) return [false, $token];
  29. $jumpType = $config['jump_type'] ?? '';
  30. $payload = [
  31. 'touser' => $openid,
  32. 'template_id' => $config['tmp_id'],
  33. 'data' => $this->buildTemplateData($config, $dataData, $options),
  34. ];
  35. // 动态跳转处理
  36. if ($jumpType === 'h5') {
  37. $payload['url'] = $options['url'] ?? '';
  38. } elseif ($jumpType === 'mp') {
  39. $payload['miniprogram'] = [
  40. 'appid' => config('wx_msg.default_appid'),
  41. 'pagepath' => $options['pagepath'] ?? '',
  42. ];
  43. }
  44. $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}";
  45. $res = $this->curlOpen($url, ['post' => json_encode($payload, JSON_UNESCAPED_UNICODE)]);
  46. $res = json_decode($res, true);
  47. if (isset($res['errcode']) && $res['errcode'] === 0) return [true, ''];
  48. return [false , $res['errmsg']];
  49. } catch (Exception $e) {
  50. return [false, $e->getMessage()];
  51. }
  52. }
  53. /**
  54. * 构建模板数据结构
  55. */
  56. protected function buildTemplateData(array $config, array $dataData, array $options = []): array
  57. {
  58. $result = [];
  59. $first = $options['first'] ?? $config['first'] ?? '';
  60. $remark = $options['remark'] ?? $config['remark'] ?? '';
  61. if ($first) {
  62. $result['first'] = ['value' => $first, 'color' => '#173177'];
  63. }
  64. foreach ($config['params'] as $key => $field) {
  65. $value = $dataData[$key] ?? '';
  66. $result[$field] = ['value' => (string)$value, 'color' => '#173177'];
  67. }
  68. if ($remark) {
  69. $result['remark'] = ['value' => $remark, 'color' => '#173177'];
  70. }
  71. return $result;
  72. }
  73. }