WechatQrcodeRepository.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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\BaseDao;
  13. use app\common\dao\wechat\WechatQrcodeDao;
  14. use app\common\repositories\BaseRepository;
  15. use crmeb\services\WechatService;
  16. use think\db\exception\DataNotFoundException;
  17. use think\db\exception\DbException;
  18. use think\db\exception\ModelNotFoundException;
  19. use think\exception\ValidateException;
  20. use think\Model;
  21. /**
  22. * Class WechatQrcodeRepository
  23. * @package app\common\repositories\wechat
  24. * @author xaboy
  25. * @day 2020-04-28
  26. * @mixin WechatQrcodeDao
  27. */
  28. class WechatQrcodeRepository extends BaseRepository
  29. {
  30. /**
  31. * WechatQrcodeRepository constructor.
  32. * @param WechatQrcodeDao $dao
  33. */
  34. public function __construct(WechatQrcodeDao $dao)
  35. {
  36. $this->dao = $dao;
  37. }
  38. /**
  39. * 创建临时二维码
  40. *
  41. * 本函数用于生成微信公众号的临时二维码,并根据二维码ID($qtcode_id)决定是更新已有的二维码记录还是创建新的二维码记录。
  42. * 临时二维码具有固定的有效时长,且在过期后不能再次使用。
  43. *
  44. * @param int $id 二维码关联的ID,用于指定二维码的具体内容,如商品ID等。
  45. * @param string $type 二维码的类型,用于区分不同种类的二维码。
  46. * @param int|null $qtcode_id 二维码的ID,如果为null,则表示创建新的二维码记录;否则,表示更新已有的二维码记录。
  47. * @return int|bool 返回更新或创建的二维码记录ID,如果操作失败,则返回false。
  48. */
  49. public function createTemporaryQrcode($id, $type, $qtcode_id = null)
  50. {
  51. // 初始化微信服务,获取二维码对象
  52. $qrcode = WechatService::create()->getApplication()->qrcode;
  53. // 创建临时二维码,有效期为30天,转换为数组格式
  54. $data = $qrcode->temporary($id, 30 * 24 * 3600)->toArray();
  55. // 保存二维码的URL至$data数组
  56. $data['qrcode_url'] = $data['url'];
  57. // 计算二维码的过期时间,并保存至$data数组
  58. $data['expire_seconds'] = $data['expire_seconds'] + time();
  59. // 通过二维码的ticket获取二维码的URL,并保存至$data数组
  60. $data['url'] = $qrcode->url($data['ticket']);
  61. // 设置二维码的状态为可用
  62. $data['status'] = 1;
  63. // 保存关联的ID和类型至$data数组
  64. $data['third_id'] = $id;
  65. $data['third_type'] = $type;
  66. // 如果$qtcode_id不为空,则更新二维码记录,否则创建新的二维码记录
  67. if ($qtcode_id) {
  68. return $this->dao->update($qtcode_id, $data);
  69. } else {
  70. return $this->dao->create($data);
  71. }
  72. }
  73. /**
  74. * 创建永久二维码
  75. *
  76. * 本函数用于生成微信公众号的永久二维码,并将其相关数据存储到数据库中。
  77. * 永久二维码的特点是,扫描后不会失效,可以用于诸如会员卡绑定、商品链接等长期有效的场景。
  78. *
  79. * @param int $id 二维码的标识ID,用于关联具体的数据,如商品ID、会员卡ID等。
  80. * @param string $type 二维码的类型,用于区分不同种类的二维码,如商品类型、会员卡类型等。
  81. * @return static 返回创建的二维码记录实例。
  82. */
  83. public function createForeverQrcode($id, $type)
  84. {
  85. // 初始化微信服务,获取二维码对象
  86. $qrcode = WechatService::create()->getApplication()->qrcode;
  87. // 创建永久二维码,并获取其配置数据
  88. $data = $qrcode->forever($id)->toArray();
  89. // 将二维码的URL地址赋值给qrcode_url字段,便于后续展示或下载
  90. $data['qrcode_url'] = $data['url'];
  91. // 通过二维码的ticket获取实际的二维码URL,更新data中的URL字段
  92. $data['url'] = $qrcode->url($data['ticket']);
  93. // 永久二维码的有效期设置为0,表示永久有效
  94. $data['expire_seconds'] = 0;
  95. // 设置二维码的状态为可用(1)
  96. $data['status'] = 1;
  97. // 记录二维码的第三方标识ID和类型
  98. $data['third_id'] = $id;
  99. $data['third_type'] = $type;
  100. // 根据数据创建新的二维码记录,并返回该记录实例
  101. return self::create($data);
  102. }
  103. /**
  104. * 获取临时二维码
  105. *
  106. * 本函数用于根据类型和ID获取临时二维码的信息。如果二维码已过期或不存在,则重新创建一个。
  107. * 临时二维码用于一些需要时效性的场景,比如会议签到、活动报名等。
  108. *
  109. * @param string $type 二维码类型,用于区分不同场景的二维码。
  110. * @param int $id 与二维码相关的ID,用于唯一标识该二维码。
  111. * @return array 包含二维码信息的数组,包括ticket和expire_seconds等字段。
  112. * @throws ValidateException 如果无法获取到有效的临时二维码信息,则抛出异常。
  113. */
  114. public function getTemporaryQrcode($type, $id)
  115. {
  116. // 从数据库尝试获取临时二维码信息
  117. $qrInfo = $this->dao->getTemporaryQrcode($type, $id);
  118. // 检查二维码信息是否有效,如果无效则重新创建
  119. if (!$qrInfo || (!$qrInfo['expire_seconds'] || $qrInfo['expire_seconds'] < time())) {
  120. $qrInfo = $this->createTemporaryQrcode($type, $id);
  121. }
  122. // 确保二维码的ticket存在且不为空,否则抛出异常
  123. if (!isset($qrInfo['ticket']) || !$qrInfo['ticket']) {
  124. throw new ValidateException('临时二维码获取错误');
  125. }
  126. // 返回有效的二维码信息
  127. return $qrInfo;
  128. }
  129. /**
  130. * 获取永久二维码信息
  131. *
  132. * 本函数用于根据类型和ID获取永久二维码的信息。如果该二维码信息不存在,则通过调用
  133. * createForeverQrcode函数创建新的永久二维码信息。
  134. *
  135. * @param string $type 二维码类型
  136. * @param int $id 与二维码相关联的ID
  137. * @return array 二维码信息,包含ticket等关键信息
  138. * @throws ValidateException 如果二维码信息获取失败,则抛出异常
  139. */
  140. public function getForeverQrcode($type, $id)
  141. {
  142. // 尝试从数据库中获取永久二维码信息
  143. $qrInfo = $this->dao->getForeverQrcode($type, $id);
  144. // 如果二维码信息不存在,则创建新的永久二维码
  145. if (!$qrInfo) {
  146. $qrInfo = $this->createForeverQrcode($id, $type);
  147. }
  148. // 检查二维码信息是否包含有效的ticket,如果没有则抛出异常
  149. if (!isset($qrInfo['ticket']) || !$qrInfo['ticket']) {
  150. throw new ValidateException('二维码获取错误');
  151. }
  152. // 返回二维码信息
  153. return $qrInfo;
  154. }
  155. }