TemplateMessageRepository.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\common\repositories\wechat;
  12. use app\common\dao\wechat\TemplateMessageDao;
  13. use app\common\repositories\BaseRepository;
  14. use app\common\repositories\system\notice\SystemNoticeConfigRepository;
  15. use crmeb\exceptions\WechatException;
  16. use crmeb\services\MiniProgramService;
  17. use crmeb\services\WechatService;
  18. use FormBuilder\Factory\Elm;
  19. use think\exception\ValidateException;
  20. use think\facade\Config;
  21. use think\facade\Log;
  22. use think\facade\Route;
  23. /**
  24. * Class TemplateMessageRepository
  25. * @package app\common\repositories\wechat
  26. * @mixin TemplateMessageDao
  27. */
  28. class TemplateMessageRepository extends BaseRepository
  29. {
  30. /**
  31. * @var TemplateMessageDao
  32. */
  33. public $dao;
  34. /**
  35. * TemplateMessageRepository constructor.
  36. * @param TemplateMessageDao $dao
  37. */
  38. public function __construct(TemplateMessageDao $dao)
  39. {
  40. $this->dao = $dao;
  41. }
  42. /**
  43. * 获取列表
  44. * @param $wereh
  45. * @param $page
  46. * @param $limit
  47. * @return array
  48. * @author wuhaotian
  49. * @email 442384644@qq.com
  50. * @date 2024/7/25
  51. */
  52. public function getList($wereh,$page,$limit)
  53. {
  54. $query = $this->dao->search($wereh);
  55. $count = $query->count();
  56. $list = $query->page($page,$limit)->order('template_id DESC')->select();
  57. return compact('count','list');
  58. }
  59. /**
  60. * 添加表单
  61. * @param int|null $id
  62. * @param int $type
  63. * @return \FormBuilder\Form
  64. * @author Qinii
  65. * @day 2020-06-19
  66. */
  67. public function form(?int $id = null,$type = 0)
  68. {
  69. $form = Elm::createForm(Route::buildUrl('systemTemplateMessageCreate')->build());
  70. $form->setRule([
  71. Elm::hidden('type',$type),
  72. Elm::input('tempkey','模板编号:')->placeholder('请输入模板编号'),
  73. Elm::input('name','模板名:')->placeholder('请输入模板名'),
  74. Elm::input('tempid','模板ID:')->placeholder('请输入模板ID'),
  75. Elm::textarea('content','回复内容:')->placeholder('请输入回复内容'),
  76. Elm::switches('status','状态:',1)->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开'),
  77. ]);
  78. return $form->setTitle(is_null($id) ? '添加' : '编辑');
  79. }
  80. /**
  81. * 修改表表单
  82. * @param $id
  83. * @return \FormBuilder\Form
  84. * @author Qinii
  85. * @day 2020-06-19
  86. */
  87. public function updateForm($id)
  88. {
  89. $tem = $this->dao->get($id);
  90. $form = Elm::createForm(Route::buildUrl('systemTemplateMessageUpdate',['id' => $id])->build());
  91. $form->setRule([
  92. Elm::hidden('type',$tem['type']),
  93. Elm::input('tempkey','模板编号:',$tem['tempkey'])->disabled(1)->placeholder('请输入模板编号'),
  94. Elm::input('name','模板名:',$tem['name'])->disabled(1)->placeholder('请输入模板名'),
  95. Elm::input('tempid','模板ID:',$tem['tempid'])->placeholder('请输入模板ID'),
  96. Elm::switches('status','状态:',$tem['status'])->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开'),
  97. ]);
  98. return $form->setTitle('编辑');
  99. }
  100. /**
  101. * 获取同步信息
  102. * @return array
  103. * @author wuhaotian
  104. * @email 442384644@qq.com
  105. * @date 2024/7/25
  106. */
  107. public function getSubscribe()
  108. {
  109. $res = [];
  110. $data = $this->dao->search(['type' => 0])->column('tempid','tempkey');
  111. $arr = Config::get('template.stores.subscribe.template_id');
  112. foreach ($arr as $k => $v){
  113. $res[$k] = $data[$v] ?? '';
  114. }
  115. return $res;
  116. }
  117. /**
  118. * 获取模板列表
  119. * @param array $where
  120. * @return array
  121. * @author wuhaotian
  122. * @email 442384644@qq.com
  123. * @date 2024/7/25
  124. */
  125. public function getTemplateList(array $where)
  126. {
  127. $query = $this->dao->search($where);
  128. $count = $query->count();
  129. $list = $query->select();
  130. foreach ($list as &$item) {
  131. if ($item['content']) $item['content'] = explode("\n", $item['content']);
  132. }
  133. return compact('list', 'count');
  134. }
  135. /**
  136. * 同步订阅消息
  137. * @return string
  138. * @author Qinii
  139. * @day 11/24/21
  140. */
  141. public function syncMinSubscribe()
  142. {
  143. if (!systemConfig('routine_appId') || !systemConfig('routine_appsecret')) {
  144. throw new ValidateException('请先配置小程序appid、appSecret等参数');
  145. }
  146. $systemNoticeConfigRepository = app()->make(SystemNoticeConfigRepository::class);
  147. $all = $systemNoticeConfigRepository->getTemplateList(0);
  148. $errData = [];
  149. $errMessage = [
  150. '-1' => '系统繁忙,此时请稍候再试',
  151. '40001' => 'AppSecret错误或者AppSecret不属于这个小程序,请确认AppSecret 的正确性',
  152. '40002' => '请确保grant_type字段值为client_credential',
  153. '40013' => '不合法的AppID,请检查AppID的正确性,避免异常字符,注意大小写',
  154. '40125' => '小程序配置无效,请检查配置',
  155. '41002' => '缺少appid参数',
  156. '41004' => '缺少secret参数',
  157. '43104' => 'appid与openid不匹配',
  158. '45009' => '达到微信api每日限额上限',
  159. '200011' => '此账号已被封禁,无法操作',
  160. '200012' => '个人模版数已达上限,上限25个',
  161. ];
  162. if ($all['list']) {
  163. $time = time();
  164. foreach ($all['list'] as $k => $template) {
  165. if ($template['tempkey']) {
  166. if (!isset($template['kid'])) {
  167. throw new ValidateException('缺少字段:kid');
  168. }
  169. if (isset($template['kid']) && $template['kid']) {
  170. continue;
  171. }
  172. $works = [];
  173. try {
  174. $works = MiniProgramService::create()->getSubscribeTemplateKeyWords($template['tempkey']);
  175. } catch (\Throwable $e) {
  176. $wechatErr = $e->getMessage();
  177. if (is_string($wechatErr))
  178. throw new WechatException('模板ID:'.$template['tempkey'].',错误信息'.$wechatErr);
  179. if (in_array($e->getCode(), array_keys($errMessage))) {
  180. throw new WechatException($errMessage[$wechatErr->getCode()]);
  181. }
  182. $errData[$k][] = '获取关键词列表失败:' . $wechatErr->getMessage(). ',微信错误代码:' . $e->getCode();
  183. }
  184. $kid = [];
  185. if ($works) {
  186. $works = array_combine(array_column($works, 'name'), $works);
  187. $content = is_array($template['content']) ? $template['content'] : explode("\n", $template['content']);
  188. foreach ($content as $c) {
  189. $name = trim(explode('{{', $c)[0] ?? '');
  190. if ($name && isset($works[$name])) {
  191. $kid[] = $works[$name]['kid'];
  192. }
  193. }
  194. }
  195. if ($kid && isset($template['kid']) && !$template['kid']) {
  196. $tempid = '';
  197. try {
  198. $tempid = MiniProgramService::create()->addSubscribeTemplate($template['tempkey'], $kid, $template['notice_title']);
  199. } catch (\Throwable $e) {
  200. $wechatErr = $e->getMessage();
  201. if ($e->getCode() == 200022) continue;
  202. if (is_string($wechatErr)) throw new WechatException($wechatErr);
  203. if (in_array($wechatErr->getCode(), array_keys($errMessage))) {
  204. throw new WechatException($errMessage[$wechatErr->getCode()]);
  205. }
  206. $errData[$k][] = '模板ID:'.$template['tempkey'].',添加订阅消息模版失败:'.$wechatErr->getMessage().',微信错误代码:'.$wechatErr->getCode();
  207. }
  208. if ($tempid != $template['tempid'] && $tempid) {
  209. $systemNoticeConfigRepository->update($template['notice_config_id'], ['routine_tempid' => $tempid, 'kid' => json_encode($kid)]);
  210. }
  211. }
  212. }
  213. }
  214. }
  215. if ($errData) Log::error('同步消息失败:'.var_export($errData,1));
  216. return $errData ? '同步存在错误,请在日志查看:/runtime/log/' : '同步成功';
  217. }
  218. /**
  219. * 同步模板消息
  220. * @return mixed
  221. * @throws \think\db\exception\DataNotFoundException
  222. * @throws \think\db\exception\DbException
  223. * @throws \think\db\exception\ModelNotFoundException
  224. */
  225. public function syncWechatSubscribe()
  226. {
  227. if (!systemConfig('wechat_appid') || !systemConfig('wechat_appsecret')) {
  228. throw new WechatException('请先配置微信公众号appid、appSecret等参数');
  229. }
  230. $systemNoticeConfigRepository = app()->make(SystemNoticeConfigRepository::class);
  231. $tempall = $systemNoticeConfigRepository->getTemplateList(1);
  232. /*
  233. * 删除所有模版ID
  234. */
  235. //获取微信平台已经添加的模版
  236. $list = WechatService::create()->getPrivateTemplates();//获取所有模版
  237. foreach ($list->template_list as $v) {
  238. //删除已有模版
  239. WechatService::create()->deleleTemplate($v['template_id']);
  240. }
  241. foreach ($tempall['list'] as $temp) {
  242. $content = is_array($temp['content']) ? $temp['content'] : explode("\n", $temp['content']);
  243. $name = [];
  244. foreach ($content as $c) {
  245. $name[] = trim(explode('{{', $c)[0] ?? '');
  246. }
  247. //添加模版消息
  248. try{
  249. $res = WechatService::create()->addTemplateId($temp['tempkey'],$name);
  250. }catch (\Exception $exception) {
  251. return $temp['notice_title'].$exception->getMessage();
  252. }
  253. if (!$res->errcode && $res->template_id) {
  254. $systemNoticeConfigRepository->update($temp['notice_config_id'], ['wechat_tempid' => $res->template_id]);
  255. }
  256. }
  257. return '模版消息一键设置成功';
  258. }
  259. }