Poster.php 21 KB

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