QrcodeServices.php 14 KB

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