Poster.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace addon\pinfan\model;
  11. use addon\postertemplate\model\PosterTemplate as PosterTemplateModel;
  12. use app\model\BaseModel;
  13. use app\model\system\Site;
  14. use app\model\upload\Upload;
  15. use extend\Poster as PosterExtend;
  16. /**
  17. * 海报生成类
  18. */
  19. class Poster extends BaseModel
  20. {
  21. /**
  22. * 商品海报
  23. */
  24. public function goods($app_type, $page, $qrcode_param, $promotion_type, $site_id)
  25. {
  26. try {
  27. $goods_info = $this->getGoodsInfo($qrcode_param[ 'id' ]);
  28. if (empty($goods_info)) return $this->error('未获取到商品信息');
  29. $qrcode_info = $this->getGoodsQrcode($app_type, $page, $qrcode_param, $promotion_type, $site_id);
  30. if ($qrcode_info[ 'code' ] < 0) return $qrcode_info;
  31. //判断海报是否存在或停用
  32. $template_info = $this->getTemplateInfo($goods_info[ 'template_id' ]);
  33. $site_model = new Site();
  34. $condition = array (
  35. [ "site_id", "=", $site_id ]
  36. );
  37. $site_info = $site_model->getSiteInfo($condition);
  38. if (!empty($qrcode_param[ 'source_member' ])) {
  39. $member_info = $this->getMemberInfo($qrcode_param[ 'source_member' ]);
  40. }
  41. $pinfan_model = new Pinfan();
  42. $pintuan_info = $pinfan_model->getPinfanInfo([ [ 'pintuan_id', '=', $goods_info[ 'pintuan_id' ] ] ])[ 'data' ];
  43. #活动剩余时长
  44. $residue_time = $pintuan_info[ 'end_time' ] - time();
  45. if ($residue_time < 86400) {//如果不到一天
  46. $time = explode(' ', gmstrftime('%H %M %S', $residue_time));
  47. $format_time = $time[ 0 ] . ' : ' . $time[ 1 ] . ' : ' . $time[ 2 ];
  48. } else {
  49. $time = explode(' ', gmstrftime('%j %H %M %S', $residue_time));
  50. $format_time = ( $time[ 0 ] - 1 ) . ' 天 ' . $time[ 1 ] . ' : ' . $time[ 2 ] . ' : ' . $time[ 3 ];
  51. }
  52. if (empty($goods_info[ 'template_id' ]) || empty($template_info) || $template_info[ 'template_status' ] == 0) {
  53. $poster_width = 720;
  54. $poster_height = 1280;
  55. $poster = new PosterExtend($poster_width, $poster_height);
  56. $option = [
  57. [
  58. 'action' => 'imageCopy', // 背景图
  59. 'data' => [
  60. img('upload/poster/bg/promotion_3.png'),
  61. 0,
  62. 0,
  63. 720,
  64. 1280,
  65. 'square',
  66. 0,
  67. 1
  68. ]
  69. ],
  70. [
  71. 'action' => 'imageCopy', // 商品图
  72. 'data' => [
  73. $goods_info[ 'sku_image' ],
  74. 81,
  75. 168,
  76. 560,
  77. 558,
  78. 'square',
  79. 0,
  80. 1
  81. ]
  82. ],
  83. // [
  84. // 'action' => 'imageCopy', // 条幅
  85. // 'data' => [
  86. // getUrl().'upload/poster/bg/pinfan.png',
  87. // 90,
  88. // 708,
  89. // 539,
  90. // 55,
  91. // 'square',
  92. // 0,
  93. // 1
  94. // ]
  95. // ],
  96. [
  97. 'action' => 'imageCopy', // 二维码
  98. 'data' => [
  99. $qrcode_info[ 'data' ][ 'path' ],
  100. 310,
  101. 1050,
  102. 100,
  103. 100,
  104. 'square',
  105. 0,
  106. 1
  107. ]
  108. ],
  109. [
  110. 'action' => 'imageText', // 写入商品价格
  111. 'data' => [
  112. '¥' . $goods_info[ 'pintuan_price' ],
  113. 25,
  114. [ 255, 95, 75 ],
  115. 110,
  116. 853,
  117. 500,
  118. 2,
  119. true,
  120. 1
  121. ]
  122. ],
  123. [
  124. 'action' => 'imageText', // 写入商品名称
  125. 'data' => [
  126. $goods_info[ 'sku_name' ],
  127. 18,
  128. [ 89, 89, 89 ],
  129. 110,
  130. 890,
  131. 500,
  132. 1,
  133. true,
  134. 1
  135. ]
  136. ],
  137. [
  138. 'action' => 'imageText', // 写入活动倒计时
  139. 'data' => [
  140. '距离结束 ' . $format_time,
  141. 21,
  142. [ 255, 95, 75 ],
  143. 295,
  144. 780,
  145. 500,
  146. 1,
  147. true,
  148. 1
  149. ]
  150. ],
  151. ];
  152. if (!empty($member_info)) {
  153. $member_option = [
  154. [
  155. 'action' => 'imageCircularCopy', // 写入用户头像
  156. 'data' => [
  157. !empty($member_info[ 'headimg' ]) ? $member_info[ 'headimg' ] : 'public/static/img/default_img/head.png',
  158. 100,
  159. 35,
  160. 80,
  161. 80
  162. ]
  163. ],
  164. [
  165. 'action' => 'imageText', // 写入分享人昵称
  166. 'data' => [
  167. $member_info[ 'nickname' ],
  168. 22,
  169. [ 255, 255, 255 ],
  170. 200,
  171. 75,
  172. 440,
  173. 1,
  174. 0,
  175. 1
  176. ]
  177. ],
  178. [
  179. 'action' => 'imageText', // 写入分享语
  180. 'data' => [
  181. '拼不中得返利 快来一起参与~',
  182. 18,
  183. [ 255, 255, 255 ],
  184. 200,
  185. 102,
  186. 440,
  187. 1,
  188. 0,
  189. 1
  190. ]
  191. ]
  192. ];
  193. $option = array_merge($option, $member_option);
  194. }
  195. } else {
  196. $condition = [
  197. [ 'template_id', '=', $goods_info[ 'template_id' ] ],
  198. [ 'site_id', '=', $site_id ]
  199. ];
  200. $poster_template_model = new PosterTemplateModel();
  201. $poster_data = $poster_template_model->getPosterTemplateInfo($condition);
  202. $poster_data[ 'data' ][ 'template_json' ] = json_decode($poster_data[ 'data' ][ 'template_json' ], true);
  203. $poster_width = 720;
  204. $poster_height = 1280;
  205. $poster = new PosterExtend($poster_width, $poster_height);
  206. $fontRate = 0.725; // 20px 等于 14.5磅,换算比率 1px = 0.725磅
  207. $option = [
  208. [
  209. 'action' => 'imageText', // 写入店铺名称
  210. 'data' => [
  211. $site_info[ 'data' ][ 'site_name' ],
  212. $poster_data[ 'data' ][ 'template_json' ][ 'store_name_font_size' ] * $fontRate,
  213. hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'store_name_color' ]),
  214. $poster_data[ 'data' ][ 'template_json' ][ 'store_name_left' ] * 2,
  215. ( $poster_data[ 'data' ][ 'template_json' ][ 'store_name_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'store_name_font_size' ] ) * 2,
  216. $poster_data[ 'data' ][ 'template_json' ][ 'store_name_width' ] * 2,
  217. $poster_data[ 'data' ][ 'template_json' ][ 'store_name_height' ] * 2,
  218. true,
  219. $poster_data[ 'data' ][ 'template_json' ][ 'store_name_is_show' ]
  220. ]
  221. ],
  222. [
  223. 'action' => 'imageCopy', // 店铺logo
  224. 'data' => [
  225. !empty($site_info[ 'data' ][ 'logo_square' ]) ? $site_info[ 'data' ][ 'logo_square' ] : getUrl() . '/app/shop/view/public/img/shop_logo.png',
  226. $poster_data[ 'data' ][ 'template_json' ][ 'store_logo_left' ] * 2,
  227. $poster_data[ 'data' ][ 'template_json' ][ 'store_logo_top' ] * 2,
  228. $poster_data[ 'data' ][ 'template_json' ][ 'store_logo_width' ] * 2,
  229. $poster_data[ 'data' ][ 'template_json' ][ 'store_logo_height' ] * 2,
  230. 'square',
  231. 1,
  232. $poster_data[ 'data' ][ 'template_json' ][ 'store_logo_is_show' ]
  233. ]
  234. ],
  235. [
  236. 'action' => 'imageCopy', // 写入商品图
  237. 'data' => [
  238. $goods_info[ 'sku_image' ],
  239. $poster_data[ 'data' ][ 'template_json' ][ 'goods_img_left' ] * 2,
  240. $poster_data[ 'data' ][ 'template_json' ][ 'goods_img_top' ] * 2,
  241. $poster_data[ 'data' ][ 'template_json' ][ 'goods_img_width' ] * 2,
  242. $poster_data[ 'data' ][ 'template_json' ][ 'goods_img_height' ] * 2,
  243. !empty($poster_data[ 'data' ][ 'template_json' ][ 'goods_img_shape' ]) ? $poster_data[ 'data' ][ 'template_json' ][ 'goods_img_shape' ] : 'square',
  244. 0,
  245. $poster_data[ 'data' ][ 'template_json' ][ 'goods_img_is_show' ]
  246. ]
  247. ],
  248. [
  249. 'action' => 'imageText', // 写入商品名称
  250. 'data' => [
  251. $goods_info[ 'sku_name' ],
  252. $poster_data[ 'data' ][ 'template_json' ][ 'goods_name_font_size' ] * $fontRate,
  253. hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'goods_name_color' ]),
  254. $poster_data[ 'data' ][ 'template_json' ][ 'goods_name_left' ] * 2,
  255. ( $poster_data[ 'data' ][ 'template_json' ][ 'goods_name_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'goods_name_font_size' ] ) * 2,
  256. $poster_data[ 'data' ][ 'template_json' ][ 'goods_name_width' ] * 2,
  257. 1,//文本行数 $poster_data['data']['template_json']['goods_name_height']*2,
  258. true,
  259. $poster_data[ 'data' ][ 'template_json' ][ 'goods_name_is_show' ]
  260. ]
  261. ],
  262. [
  263. 'action' => 'imageCopy', // 写入商品二维码
  264. 'data' => [
  265. $qrcode_info[ 'data' ][ 'path' ],
  266. $poster_data[ 'data' ][ 'qrcode_left' ] * 2,
  267. $poster_data[ 'data' ][ 'qrcode_top' ] * 2,
  268. $poster_data[ 'data' ][ 'qrcode_width' ] * 2,
  269. $poster_data[ 'data' ][ 'qrcode_height' ] * 2,
  270. 'square',
  271. 0,
  272. 1
  273. ]
  274. ],
  275. [
  276. 'action' => 'imageText', // 写入商品价格
  277. 'data' => [
  278. '¥' . $goods_info[ 'pintuan_price' ],
  279. $poster_data[ 'data' ][ 'template_json' ][ 'goods_price_font_size' ] * $fontRate,
  280. hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'goods_price_color' ]),
  281. $poster_data[ 'data' ][ 'template_json' ][ 'goods_price_left' ] * 2,
  282. ( $poster_data[ 'data' ][ 'template_json' ][ 'goods_price_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'goods_price_font_size' ] ) * 2,
  283. $poster_data[ 'data' ][ 'template_json' ][ 'goods_price_width' ] * 2,
  284. $poster_data[ 'data' ][ 'template_json' ][ 'goods_price_height' ] * 2,
  285. true,
  286. $poster_data[ 'data' ][ 'template_json' ][ 'goods_price_is_show' ]
  287. ]
  288. ],
  289. [
  290. 'action' => 'imageText', // 写入商品划线价格
  291. 'data' => [
  292. '¥' . $goods_info[ 'price' ],
  293. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_font_size' ] * $fontRate,
  294. hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_color' ]),
  295. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_left' ] * 2,
  296. ( $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_font_size' ] ) * 2,
  297. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_width' ] * 2,
  298. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_height' ] * 2,
  299. true,
  300. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_is_show' ] ?? 0
  301. ]
  302. ],
  303. [
  304. 'action' => 'imageText', // 写入活动倒计时
  305. 'data' => [
  306. '距离结束 ' . $format_time,
  307. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_font_size' ] * $fontRate,
  308. hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_color' ]),
  309. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_left' ] * 2,
  310. ( $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_font_size' ] ) * 2,
  311. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_width' ] * 2,
  312. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_height' ] * 2,
  313. true,
  314. $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_is_show' ] ?? 0
  315. ]
  316. ],
  317. ];
  318. if (!empty($member_info)) {
  319. $member_option = [
  320. [
  321. 'action' => 'imageCopy', // 写入用户头像
  322. 'data' => [
  323. !empty($member_info[ 'headimg' ]) ? $member_info[ 'headimg' ] : 'public/static/img/default_img/head.png',
  324. $poster_data[ 'data' ][ 'template_json' ][ 'headimg_left' ] * 2,
  325. $poster_data[ 'data' ][ 'template_json' ][ 'headimg_top' ] * 2,
  326. $poster_data[ 'data' ][ 'template_json' ][ 'headimg_width' ] * 2,
  327. $poster_data[ 'data' ][ 'template_json' ][ 'headimg_height' ] * 2,
  328. !empty($poster_data[ 'data' ][ 'template_json' ][ 'headimg_shape' ]) ? $poster_data[ 'data' ][ 'template_json' ][ 'headimg_shape' ] : 'square',
  329. 0,
  330. $poster_data[ 'data' ][ 'template_json' ][ 'headimg_is_show' ]
  331. ]
  332. ],
  333. [
  334. 'action' => 'imageText', // 写入分享人昵称
  335. 'data' => [
  336. $member_info[ 'nickname' ],
  337. $poster_data[ 'data' ][ 'template_json' ][ 'nickname_font_size' ] * $fontRate,
  338. hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'nickname_color' ]),
  339. $poster_data[ 'data' ][ 'template_json' ][ 'nickname_left' ] * 2,
  340. ( $poster_data[ 'data' ][ 'template_json' ][ 'nickname_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'nickname_font_size' ] ) * 2,
  341. $poster_data[ 'data' ][ 'template_json' ][ 'nickname_width' ] * 2,
  342. $poster_data[ 'data' ][ 'template_json' ][ 'nickname_height' ] * 2,
  343. 0,
  344. $poster_data[ 'data' ][ 'template_json' ][ 'nickname_is_show' ]
  345. ]
  346. ],
  347. ];
  348. if (!empty($poster_data[ 'data' ][ 'background' ])) {
  349. list($width, $height, $type, $attr) = getimagesize(img($poster_data[ 'data' ][ 'background' ]));
  350. $back_ground = [
  351. [
  352. 'action' => 'imageCopy', // 写入背景图
  353. 'data' => [
  354. img($poster_data[ 'data' ][ 'background' ]),
  355. 0,
  356. 0,
  357. $poster_width,
  358. $poster_height,
  359. 'square',
  360. 0,
  361. 1
  362. ]
  363. ],
  364. ];
  365. } else {
  366. $back_ground = [
  367. [
  368. 'action' => 'setBackground', // 设背景色
  369. 'data' => [ 255, 255, 255 ]
  370. ],
  371. ];
  372. }
  373. $ground = [
  374. [
  375. 'action' => 'setBackground',
  376. 'data' => [ 255, 255, 255 ]
  377. ]
  378. ];
  379. $option = array_merge($ground, $back_ground, $option, $member_option);
  380. }
  381. }
  382. $option_res = $poster->create($option);
  383. if (is_array($option_res)) return $option_res;
  384. $res = $option_res->jpeg('upload/poster/goods', 'goods_' . $promotion_type . '_' . $goods_info[ 'pintuan_id' ] . '_' . $qrcode_param[ 'source_member' ] . '_' . time() . '_' . $app_type);
  385. if ($res[ 'code' ] == 0) {
  386. $upload = new Upload($site_id);
  387. $cloud_res = $upload->fileCloud($res[ 'data' ][ 'path' ]);
  388. if ($cloud_res[ 'code' ] >= 0) {
  389. return $this->success([ "path" => $cloud_res[ 'data' ] ]);
  390. } else {
  391. return $this->error();
  392. }
  393. }
  394. return $res;
  395. } catch (\Exception $e) {
  396. return $this->error($e->getMessage() . $e->getFile() . $e->getLine());
  397. }
  398. }
  399. /**
  400. * 获取用户信息
  401. * @param unknown $member_id
  402. */
  403. private function getMemberInfo($member_id)
  404. {
  405. $info = model('member')->getInfo([ 'member_id' => $member_id ], 'nickname,headimg');
  406. return $info;
  407. }
  408. /**
  409. * 获取商品信息
  410. * @param unknown
  411. */
  412. private function getGoodsInfo($id)
  413. {
  414. $alias = 'nppg';
  415. $join = [
  416. [ 'goods_sku ngs', 'nppg.sku_id = ngs.sku_id', 'inner' ]
  417. ];
  418. $field = 'ngs.sku_name,ngs.introduction,ngs.sku_image,ngs.sku_id,nppg.pintuan_price,nppg.pintuan_id,ngs.template_id,ngs.price';
  419. $info = model('promotion_pinfan_goods')->getInfo([ 'nppg.id' => $id ], $field, $alias, $join);
  420. return $info;
  421. }
  422. /**
  423. * 获取商品二维码
  424. * @param unknown $app_type 请求类型
  425. * @param unknown $page uniapp页面路径
  426. * @param unknown $qrcode_param 二维码携带参数
  427. * @param string $promotion_type 活动类型 null为无活动
  428. */
  429. private function getGoodsQrcode($app_type, $page, $qrcode_param, $promotion_type, $site_id)
  430. {
  431. $res = event('Qrcode', [
  432. 'site_id' => $site_id,
  433. 'app_type' => $app_type,
  434. 'type' => 'create',
  435. 'data' => $qrcode_param,
  436. 'page' => $page,
  437. 'qrcode_path' => 'upload/qrcode/goods',
  438. 'qrcode_name' => 'goods_' . $promotion_type . '_' . $qrcode_param[ 'id' ] . '_' . $qrcode_param[ 'source_member' ] . '_' . $site_id,
  439. ], true);
  440. return $res;
  441. }
  442. /**
  443. * 获取海报信息
  444. * @param unknown $template_id
  445. */
  446. private function getTemplateInfo($template_id)
  447. {
  448. $info = model('poster_template')->getInfo([ 'template_id' => $template_id ], 'template_id,template_status');
  449. return $info;
  450. }
  451. }