QrcodeServices.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2022 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 1 = 拼团,2 = 秒杀
  217. * @return bool|string
  218. */
  219. public function getRoutineQrcodePath(int $id, int $uid, int $type, array $parame = [], bool $isSaveAttach = true)
  220. {
  221. /** @var SystemAttachmentServices $systemAttachmentService */
  222. $systemAttachmentService = app()->make(SystemAttachmentServices::class);
  223. $page = '';
  224. $namePath = '';
  225. $data = 'id=' . $id . '&pid=' . $uid;
  226. switch ($type) {
  227. case 0:
  228. $page = 'pages/goods_details/index';
  229. $namePath = $id . '_' . $uid . '_' . $parame['is_promoter'] . '_product.jpg';
  230. break;
  231. case 1:
  232. $page = 'pages/activity/goods_combination_details/index';
  233. $namePath = 'combination_' . $id . '_' . $uid . '.jpg';
  234. break;
  235. case 2:
  236. $page = 'pages/activity/goods_seckill_details/index';
  237. $namePath = 'seckill_' . $id . '_' . $uid . '.jpg';
  238. if (isset($parame['stop_time']) && $parame['stop_time']) {
  239. $data .= '&time=' . $parame['stop_time'];
  240. $namePath = $parame['stop_time'] . $namePath;
  241. }
  242. break;
  243. case 3:
  244. $page = 'pages/annex/offline_pay/index';
  245. $namePath = 'routine_offline_scan.jpg';
  246. break;
  247. case 4:
  248. $page = 'pages/annex/vip_active/index';
  249. $namePath = 'routine_member_card.jpg';
  250. break;
  251. case 5:
  252. $page = 'pages/annex/vip_paid/index';
  253. $namePath = 'routine_pay_vip_code.jpg';
  254. break;
  255. case 6:
  256. $page = 'pages/annex/special/index';
  257. $namePath = $id . 'routine_index_code.jpg';
  258. break;
  259. }
  260. if (!$page || !$namePath) {
  261. return false;
  262. }
  263. try {
  264. if (!$isSaveAttach) {
  265. $imageInfo = "";
  266. } else {
  267. $imageInfo = $systemAttachmentService->getOne(['name' => $namePath]);
  268. }
  269. $siteUrl = sys_config('site_url');
  270. if (!$imageInfo) {
  271. $res = MiniProgramService::appCodeUnlimitService($data, $page, 280);
  272. if (!$res) return false;
  273. if ($res->getSize() < 100) return 'unpublished';
  274. $uploadType = (int)sys_config('upload_type', 1);
  275. $upload = UploadService::init();
  276. $res = (string)EntityBody::factory($res);
  277. $res = $upload->to('routine/product')->validate()->setAuthThumb(false)->stream($res, $namePath);
  278. if ($res === false) {
  279. return false;
  280. }
  281. $imageInfo = $upload->getUploadInfo();
  282. $imageInfo['image_type'] = $uploadType;
  283. if ($imageInfo['image_type'] == 1) $remoteImage = PosterServices::remoteImage($siteUrl . $imageInfo['dir']);
  284. else $remoteImage = PosterServices::remoteImage($imageInfo['dir']);
  285. if (!$remoteImage['status']) return false;
  286. if ($isSaveAttach) {
  287. $systemAttachmentService->save([
  288. 'name' => $imageInfo['name'],
  289. 'att_dir' => $imageInfo['dir'],
  290. 'satt_dir' => $imageInfo['thumb_path'],
  291. 'att_size' => $imageInfo['size'],
  292. 'att_type' => $imageInfo['type'],
  293. 'image_type' => $imageInfo['image_type'],
  294. 'module_type' => 2,
  295. 'time' => time(),
  296. 'pid' => 1,
  297. 'type' => 2
  298. ]);
  299. }
  300. $url = $imageInfo['dir'];
  301. } else $url = $imageInfo['att_dir'];
  302. if ($imageInfo['image_type'] == 1) $url = $siteUrl . $url;
  303. return $url;
  304. } catch (\Throwable $e) {
  305. return false;
  306. }
  307. }
  308. /**
  309. * TODO 添加二维码 存在直接获取
  310. * @param int $thirdId
  311. * @param string $thirdType
  312. * @param string $page
  313. * @param string $qrCodeLink
  314. * @return array|false|object|\PDOStatement|string|\think\Model
  315. * @throws \think\Exception
  316. * @throws \think\db\exception\DataNotFoundException
  317. * @throws \think\db\exception\ModelNotFoundException
  318. * @throws \think\exception\DbException
  319. */
  320. public function qrCodeForever($thirdId = 0, $thirdType = 'spread', $page = '', $qrCodeLink = '')
  321. {
  322. $qrcode = $this->dao->getOne(['third_id' => $thirdId, 'third_type' => $thirdType]);
  323. if ($qrcode) {
  324. return $qrcode;
  325. }
  326. return $this->setQrcodeForever($thirdId, $thirdType, $page, $qrCodeLink);
  327. }
  328. /**
  329. * 添加二维码记录
  330. * @param string $thirdType
  331. * @param int $thirdId
  332. * @return object
  333. */
  334. public function setQrcodeForever($thirdId = 0, $thirdType = 'spread', $page = '', $qrCodeLink = '')
  335. {
  336. $data['third_type'] = $thirdType;
  337. $data['third_id'] = $thirdId;
  338. $data['status'] = 1;
  339. $data['add_time'] = time();
  340. $data['page'] = $page;
  341. $data['url_time'] = '';
  342. $data['qrcode_url'] = $qrCodeLink;
  343. if (!$re = $this->dao->save($data)) {
  344. throw new AdminException(400237);
  345. }
  346. return $re;
  347. }
  348. /**
  349. * 修改二维码地址
  350. * @param int $id
  351. * @param array $data
  352. * @return bool
  353. */
  354. public function setQrcodeFind($id = 0, $data = array())
  355. {
  356. if (!$id) return false;
  357. if (!$this->dao->get((int)$id)) {
  358. throw new AdminException(100026);
  359. }
  360. if (!$re = $this->dao->update($id, $data, 'id')) {
  361. throw new AdminException(100007);
  362. }
  363. return $re;
  364. }
  365. /**
  366. * 检测是否存在
  367. * @param int $thirdId
  368. * @param string $thirdType
  369. * @return bool
  370. */
  371. public function qrCodeExist($thirdId = 0, $thirdType = 'spread')
  372. {
  373. return !!$this->dao->getCount(['third_id' => $thirdId, 'third_type' => $thirdType]);
  374. }
  375. }