QrcodeServices.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\services\other;
  13. use app\services\BaseServices;
  14. use app\dao\other\QrcodeDao;
  15. use app\services\system\attachment\SystemAttachmentServices;
  16. use crmeb\exceptions\AdminException;
  17. use crmeb\services\MiniProgramService;
  18. use crmeb\services\UploadService;
  19. use crmeb\services\UtilService;
  20. use crmeb\services\WechatService;
  21. use Guzzle\Http\EntityBody;
  22. use think\exception\ValidateException;
  23. /**
  24. *
  25. * Class QrcodeServices
  26. * @package app\services\other
  27. * @method getQrcode($id, $type)
  28. * @method scanQrcode($id, $type)
  29. */
  30. class QrcodeServices extends BaseServices
  31. {
  32. /**
  33. * QrcodeServices constructor.
  34. * @param QrcodeDao $dao
  35. */
  36. public function __construct(QrcodeDao $dao)
  37. {
  38. $this->dao = $dao;
  39. }
  40. /**
  41. * 获取临时二维码
  42. * @param $type
  43. * @param $id
  44. * @throws \think\db\exception\DataNotFoundException
  45. * @throws \think\db\exception\DbException
  46. * @throws \think\db\exception\ModelNotFoundException
  47. */
  48. public function getTemporaryQrcode($type, $id)
  49. {
  50. $where['third_id'] = $id;
  51. $where['third_type'] = $type;
  52. $res = $this->dao->getOne($where);
  53. if ($res) {
  54. $this->createTemporaryQrcode($id, $type);
  55. $res = $this->getTemporaryQrcode($type, $id);
  56. } else if (empty($res['expire_seconds']) || $res['expire_seconds'] < time()) {
  57. $this->createTemporaryQrcode($id, $type, $res['id']);
  58. $res = $this->getTemporaryQrcode($type, $id);
  59. }
  60. if (!$res['ticket']) throw new AdminException('临时二维码获取错误');
  61. return $res;
  62. }
  63. /**
  64. * 临时二维码生成
  65. * @param $id
  66. * @param $type
  67. * @param string $qrcode_id
  68. */
  69. public function createTemporaryQrcode($id, $type, $qrcode_id = '')
  70. {
  71. $qrcode = WechatService::qrcodeService();
  72. $data = $qrcode->temporary($id, 30 * 24 * 3600)->toArray();
  73. $data['qrcode_url'] = $data['url'];
  74. $data['expire_seconds'] = $data['expire_seconds'] + time();
  75. $data['url'] = $qrcode->url($data['ticket']);
  76. $data['status'] = 1;
  77. $data['third_id'] = $id;
  78. $data['third_type'] = $type;
  79. if ($qrcode_id) {
  80. $this->dao->update($qrcode_id, $data);
  81. } else {
  82. $data['add_time'] = time();
  83. $this->dao->save($data);
  84. }
  85. }
  86. /**
  87. * 获取永久二维码
  88. * @param $type
  89. * @param $id
  90. * @return array|mixed|\think\Model
  91. * @throws \think\db\exception\DataNotFoundException
  92. * @throws \think\db\exception\DbException
  93. * @throws \think\db\exception\ModelNotFoundException
  94. */
  95. public function getForeverQrcode($type, $id)
  96. {
  97. $where['third_id'] = $id;
  98. $where['third_type'] = $type;
  99. $res = $this->dao->getOne($where);
  100. if (!$res) {
  101. $this->createForeverQrcode($id, $type);
  102. $res = $this->getForeverQrcode($type, $id);
  103. }
  104. if (!$res['ticket']) throw new AdminException('永久二维码获取错误');
  105. return $res;
  106. }
  107. /**
  108. * 永久二维码生成
  109. * @param $id
  110. * @param $type
  111. */
  112. public function createForeverQrcode($id, $type)
  113. {
  114. $qrcode = WechatService::qrcodeService();
  115. $data = $qrcode->forever($id)->toArray();
  116. $data['qrcode_url'] = $data['url'];
  117. $data['url'] = $qrcode->url($data['ticket']);
  118. $data['expire_seconds'] = 0;
  119. $data['status'] = 1;
  120. $data['third_id'] = $id;
  121. $data['third_type'] = $type;
  122. $data['add_time'] = time();
  123. $this->dao->save($data);
  124. }
  125. /**
  126. * 获取二维码完整路径,不存在则自动生成
  127. * @param string $name
  128. * @param string $link
  129. * @param bool $force
  130. * @return bool|mixed|string
  131. */
  132. public function getWechatQrcodePath(string $name, string $link, bool $force = false, bool $isSaveAttach = true)
  133. {
  134. /** @var SystemAttachmentServices $systemAttachmentService */
  135. $systemAttachmentService = app()->make(SystemAttachmentServices::class);
  136. try {
  137. if (!$isSaveAttach) {
  138. $imageInfo = "";
  139. } else {
  140. $imageInfo = $systemAttachmentService->getOne(['name' => $name]);
  141. }
  142. $siteUrl = sys_config('site_url');
  143. if (!$imageInfo) {
  144. $codeUrl = UtilService::setHttpType($siteUrl . $link, request()->isSsl() ? 0 : 1);//二维码链接
  145. $imageInfo = UtilService::getQRCodePath($codeUrl, $name);
  146. if (is_string($imageInfo) && $force)
  147. return false;
  148. if (is_array($imageInfo)) {
  149. if ($isSaveAttach) {
  150. $systemAttachmentService->save([
  151. 'name' => $imageInfo['name'],
  152. 'att_dir' => $imageInfo['dir'],
  153. 'satt_dir' => $imageInfo['thumb_path'],
  154. 'att_size' => $imageInfo['size'],
  155. 'att_type' => $imageInfo['type'],
  156. 'image_type' => $imageInfo['image_type'],
  157. 'module_type' => 2,
  158. 'time' => time(),
  159. 'pid' => 1,
  160. 'type' => 1
  161. ]);
  162. }
  163. $url = $imageInfo['dir'];
  164. } else {
  165. $url = '';
  166. $imageInfo = ['image_type' => 0];
  167. }
  168. } else $url = $imageInfo['att_dir'];
  169. if ($imageInfo['image_type'] == 1 && $url) $url = $siteUrl . $url;
  170. return $url;
  171. } catch (\Throwable $e) {
  172. if ($force)
  173. return false;
  174. else
  175. return '';
  176. }
  177. }
  178. /**
  179. * 获取小程序分享二维码
  180. * @param int $id
  181. * @param int $uid
  182. * @param int $type 1 = 拼团,2 = 秒杀
  183. * @return bool|string
  184. */
  185. public function getRoutineQrcodePath(int $id, int $uid, int $type, array $parame = [], bool $isSaveAttach = true)
  186. {
  187. /** @var SystemAttachmentServices $systemAttachmentService */
  188. $systemAttachmentService = app()->make(SystemAttachmentServices::class);
  189. $page = '';
  190. $namePath = '';
  191. $data = 'id=' . $id . '&pid=' . $uid;
  192. switch ($type) {
  193. case 0:
  194. $page = 'pages/goods_details/index';
  195. $namePath = $id . '_' . $uid . '_' . $parame['is_promoter'] . '_product.jpg';
  196. break;
  197. case 1:
  198. $page = 'pages/activity/goods_combination_details/index';
  199. $namePath = 'combination_' . $id . '_' . $uid . '.jpg';
  200. break;
  201. case 2:
  202. $page = 'pages/activity/goods_seckill_details/index';
  203. $namePath = 'seckill_' . $id . '_' . $uid . '.jpg';
  204. if (isset($parame['stop_time']) && $parame['stop_time']) {
  205. $data .= '&time=' . $parame['stop_time'];
  206. $namePath = $parame['stop_time'] . $namePath;
  207. }
  208. break;
  209. case 3:
  210. $page = 'pages/annex/offline_pay/index';
  211. $namePath = 'routine_offline_scan.jpg';
  212. break;
  213. case 4:
  214. $page = 'pages/annex/vip_active/index';
  215. $namePath = 'routine_member_card.jpg';
  216. break;
  217. case 5:
  218. $page = 'pages/annex/vip_paid/index';
  219. $namePath = 'routine_pay_vip_code.jpg';
  220. break;
  221. case 6:
  222. $page = 'pages/annex/special/index';
  223. $namePath = $id . 'routine_index_code.jpg';
  224. break;
  225. }
  226. if (!$page || !$namePath) {
  227. return false;
  228. }
  229. try {
  230. if (!$isSaveAttach) {
  231. $imageInfo = "";
  232. } else {
  233. $imageInfo = $systemAttachmentService->getOne(['name' => $namePath]);
  234. }
  235. $siteUrl = sys_config('site_url');
  236. if (!$imageInfo) {
  237. $res = MiniProgramService::qrcodeService()->appCodeUnlimit($data, $page, 280);
  238. if (!$res) return false;
  239. $uploadType = (int)sys_config('upload_type', 1);
  240. $upload = UploadService::init();
  241. $res = (string)EntityBody::factory($res);
  242. $res = $upload->to('routine/product')->validate()->setAuthThumb(false)->stream($res, $namePath);
  243. if ($res === false) {
  244. return false;
  245. }
  246. $imageInfo = $upload->getUploadInfo();
  247. $imageInfo['image_type'] = $uploadType;
  248. if ($imageInfo['image_type'] == 1) $remoteImage = UtilService::remoteImage($siteUrl . $imageInfo['dir']);
  249. else $remoteImage = UtilService::remoteImage($imageInfo['dir']);
  250. if (!$remoteImage['status']) return false;
  251. if ($isSaveAttach) {
  252. $systemAttachmentService->save([
  253. 'name' => $imageInfo['name'],
  254. 'att_dir' => $imageInfo['dir'],
  255. 'satt_dir' => $imageInfo['thumb_path'],
  256. 'att_size' => $imageInfo['size'],
  257. 'att_type' => $imageInfo['type'],
  258. 'image_type' => $imageInfo['image_type'],
  259. 'module_type' => 2,
  260. 'time' => time(),
  261. 'pid' => 1,
  262. 'type' => 2
  263. ]);
  264. }
  265. $url = $imageInfo['dir'];
  266. } else $url = $imageInfo['att_dir'];
  267. if ($imageInfo['image_type'] == 1) $url = $siteUrl . $url;
  268. return $url;
  269. } catch (\Throwable $e) {
  270. return false;
  271. }
  272. }
  273. /**
  274. * TODO 添加二维码 存在直接获取
  275. * @param int $thirdId
  276. * @param string $thirdType
  277. * @param string $page
  278. * @param string $qrCodeLink
  279. * @return array|false|object|\PDOStatement|string|\think\Model
  280. * @throws \think\Exception
  281. * @throws \think\db\exception\DataNotFoundException
  282. * @throws \think\db\exception\ModelNotFoundException
  283. * @throws \think\exception\DbException
  284. */
  285. public function qrCodeForever($thirdId = 0, $thirdType = 'spread', $page = '', $qrCodeLink = '')
  286. {
  287. $qrcode = $this->dao->getOne(['third_id' => $thirdId, 'third_type' => $thirdType]);
  288. if ($qrcode) {
  289. return $qrcode;
  290. }
  291. return $this->setQrcodeForever($thirdId, $thirdType, $page, $qrCodeLink);
  292. }
  293. /**
  294. * 添加二维码记录
  295. * @param string $thirdType
  296. * @param int $thirdId
  297. * @return object
  298. */
  299. public function setQrcodeForever($thirdId = 0, $thirdType = 'spread', $page = '', $qrCodeLink = '')
  300. {
  301. $data['third_type'] = $thirdType;
  302. $data['third_id'] = $thirdId;
  303. $data['status'] = 1;
  304. $data['add_time'] = time();
  305. $data['page'] = $page;
  306. $data['url_time'] = '';
  307. $data['qrcode_url'] = $qrCodeLink;
  308. if (!$re = $this->dao->save($data)) {
  309. throw new ValidateException('生成失败');
  310. }
  311. return $re;
  312. }
  313. /**
  314. * 修改二维码地址
  315. * @param int $id
  316. * @param array $data
  317. * @return bool
  318. */
  319. public function setQrcodeFind($id = 0, $data = array())
  320. {
  321. if (!$id) return false;
  322. if (!$this->dao->get((int)$id)) {
  323. throw new ValidateException('数据不存在');
  324. }
  325. if (!$re = $this->dao->update($id, $data, 'id')) {
  326. throw new ValidateException('修改数据失败');
  327. }
  328. return $re;
  329. }
  330. /**
  331. * 检测是否存在
  332. * @param int $thirdId
  333. * @param string $thirdType
  334. * @return bool
  335. */
  336. public function qrCodeExist($thirdId = 0, $thirdType = 'spread')
  337. {
  338. return !!$this->dao->getCount(['third_id' => $thirdId, 'third_type' => $thirdType]);
  339. }
  340. }