ShareQrcodeForm.php 106 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\client\models\v1;
  8. use app\constants\OptionSetting;
  9. use app\models\common\InviteCode;
  10. use app\models\material\Material;
  11. use app\models\material\MaterialResource;
  12. use app\models\Md;
  13. use app\models\Qrcode;
  14. use app\models\SaasUser;
  15. use app\models\Topic;
  16. use app\models\User;
  17. use app\models\VideoGoodsList;
  18. use app\modules\admin\models\UserCenterForm;
  19. use app\modules\client\models\ApiModel;
  20. use app\utils\CurlHelper;
  21. use claviska\SimpleImage;
  22. use yii\base\Model;
  23. use app\utils\ShareQrcode;
  24. use app\models\Goods;
  25. use app\models\Option;
  26. use yii\helpers\ArrayHelper;
  27. use yii\helpers\Json;
  28. use app\models\Mch;
  29. use app\modules\admin\models\StorageForm;
  30. use app\models\LiveRoom;
  31. use app\models\LiveAnchor;
  32. class ShareQrcodeForm extends ApiModel
  33. {
  34. public $store_id;
  35. public $user;
  36. public $user_id;
  37. public $goods_id;
  38. public $is_pt = false;
  39. public $is_seckill = false;
  40. public $vl_id;
  41. public $num;
  42. public $type; //0--商城海报 1--秒杀海报 2--拼团海报 3--预约海报 4--分销海报 5--砍价海报 6--专题海报 7--抽奖海报 8--布数宝海报 11--门店海报 12--入驻商海报 15--素材海报
  43. public $md_id;
  44. public $mch_id;
  45. public $id;
  46. public function rules()
  47. {
  48. return [
  49. [['type'], 'required'],
  50. [['type'], 'in', 'range' => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, Qrcode::TYPE_GROUP_PURCHASE,Qrcode::TYPE_MATERIAL, Qrcode::TYPE_SUPER_SALES]],
  51. [['goods_id', 'num', 'vl_id'], 'integer'],
  52. [['mch_id'], 'safe'],
  53. [['is_pt', 'is_seckill'], 'safe'],
  54. [['id'], 'safe'],
  55. ];
  56. }
  57. public function beforeValidate() {
  58. if(parent::beforeValidate()){
  59. if($this->is_pt === 'false'){
  60. $this->is_pt = false;
  61. }
  62. return true;
  63. }
  64. return false;
  65. }
  66. public function search()
  67. {
  68. if (!$this->validate()) {
  69. return [
  70. 'code' => 1,
  71. 'msg' => $this->getErrorSummary(false)[0],
  72. ];
  73. }
  74. if ($this->type == 0) {
  75. return $this->goods_qrcode();
  76. } elseif ($this->type == 1) {
  77. // return $this->ms_goods_qrcode();
  78. } elseif ($this->type == 2) {
  79. // return $this->pt_goods_qrcode();
  80. } elseif ($this->type == 3) {
  81. // return $this->yy_goods_qrcode();
  82. } elseif ($this->type == 4) {
  83. return $this->share_qrcode();
  84. } elseif ($this->type == 5) {
  85. // return $this->bargain_qrcode();
  86. } elseif ($this->type == 6) {
  87. return $this->topic_qrcode();
  88. } elseif ($this->type == 7) {
  89. // return $this->lottery_qrcode();
  90. } elseif ($this->type == 8) {
  91. // return $this->step_qrcode();
  92. } elseif ($this->type == 9) {
  93. return $this->new_share_qrcode();
  94. } elseif ($this->type == 10) {
  95. return $this->video_goods_qrcode();
  96. } elseif ($this->type == 11) {
  97. return $this->md_qrcode();
  98. } elseif ($this->type == Qrcode::TYPE_LIVE) {
  99. return $this->live_qrcode();
  100. } elseif ($this->type == Qrcode::TYPE_MCH) {
  101. return $this->mch_qrcode();
  102. } elseif ($this->type == Qrcode::TYPE_GROUP_PURCHASE) {
  103. return $this->group_purchase_qrcode();
  104. } elseif ($this->type == Qrcode::TYPE_MATERIAL) {
  105. return $this->material_qrcode();
  106. } elseif ($this->type == Qrcode::TYPE_SUPER_SALES) {
  107. return $this->super_sales_qrcode();
  108. } else {
  109. return [
  110. 'code' => 1,
  111. 'msg' => 'error'
  112. ];
  113. }
  114. }
  115. public function goods_qrcode($qrcode = '')
  116. {
  117. if (!$this->goods_id) {
  118. return [
  119. 'code' => 1,
  120. 'msg' => '未知的商品'
  121. ];
  122. }
  123. $goods = Goods::findOne($this->goods_id);
  124. if (!$goods) {
  125. return [
  126. 'code' => 1,
  127. 'msg' => '商品不存在',
  128. ];
  129. }
  130. $store_name = Option::get('name', $this->store_id, 'store');
  131. $store_name = $store_name ? $store_name['value'] : '';
  132. $goods_pic_obj = $goods->getGoodsPic(0);
  133. if ($goods_pic_obj) {
  134. $goods_pic_url = $goods->getGoodsPic(0)->pic_url;
  135. } else {
  136. return [
  137. 'code' => 1,
  138. 'msg' => '获取商品图片失败',
  139. ];
  140. }
  141. $goods_pic_save_path = \Yii::$app->basePath . '/web/temp/';
  142. $is_pt = $this->is_pt;
  143. $is_seckill = $this->is_seckill;
  144. $version = cyy_version();
  145. $goods_pic_save_name = md5("v={$version}&goods_id={$goods->id}&goods_name={$goods->name}&store_name={$store_name}&user_id={$this->user_id}&goods_pic_url={$goods_pic_url}&type=0&is_pt={$is_pt}&qrcode={$qrcode}") . '.jpg';
  146. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $goods_pic_save_name);
  147. if (file_exists($goods_pic_save_path . $goods_pic_save_name)) {
  148. return [
  149. 'code' => 0,
  150. 'data' => [
  151. 'goods_name' => $goods->name,
  152. 'pic_url' => (new StorageForm())->local2cloudLink($goods_pic_save_path . $goods_pic_save_name) ?? $pic_url . '?v=' . time(),
  153. ],
  154. ];
  155. }
  156. $goods_pic_path = $this->saveTempImage($goods_pic_url);
  157. if (!$goods_pic_path) {
  158. return [
  159. 'code' => 1,
  160. 'msg' => '获取商品海报失败:商品图片丢失',
  161. ];
  162. }
  163. $goods_qrcode_dst = \Yii::$app->basePath . '/web/v1/statics/images/goods-qrcode-dst.jpg';
  164. $font_path = \Yii::$app->basePath . '/web/v1/statics/font/AaBanSong.ttf';
  165. $goods_qrcode = @(new \claviska\SimpleImage($goods_qrcode_dst));
  166. $goods_pic = @(new \claviska\SimpleImage($goods_pic_path));
  167. //获取小程序码图片
  168. $scene = "gid:{$goods->id},uid:{$this->user_id},store:{$this->store_id}";
  169. if ($is_pt) {
  170. $scene = "id:{$goods->id},u:{$this->user_id},s:{$this->store_id},p:1";
  171. }
  172. if ($is_seckill) {
  173. $scene = "id:{$goods->id},u:{$this->user_id},s:{$this->store_id},m:1";
  174. }
  175. if (is_h5() || (!is_alipay_platform() && !is_wechat_platform())) {
  176. $is_login = 0;
  177. if (!is_alipay_platform() && !is_wechat_platform() && !is_h5()) {
  178. $is_login = 1;
  179. }
  180. // 如果是h5环境,就生成普通二维码
  181. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/goods/goods/goods?scene=' . $scene . '&is_login=' . $is_login);
  182. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  183. } else {
  184. if ($goods->product_type == Goods::GOODS_TYPE_ADOPT) {
  185. $scene = "id:{$goods->id},u:{$this->user_id},s:{$this->store_id}";
  186. $wxapp_qrcode_file_res = $this->getQrcode($scene, 240, "livestockAdoption/adopt_detail/adopt_detail");
  187. } else {
  188. if ($goods->product_type === 4) {
  189. $page = 'integral/integralStore/goods';
  190. } else {
  191. $page = 'goods/goods/goods';
  192. }
  193. $wxapp_qrcode_file_res = $this->getQrcode($scene, 240, $page);
  194. }
  195. }
  196. if (!isset($wxapp_qrcode_file_res['root_path'])) {
  197. unlink($goods_pic_path);
  198. return [
  199. 'code' => 1,
  200. 'msg' => '获取商品海报失败:获取小程序码失败',
  201. ];
  202. }
  203. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  204. $wxapp_qrcode = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  205. if($qrcode){
  206. $qrcode_path = $this->saveTempImage($qrcode);
  207. if (!$qrcode_path) {
  208. return [
  209. 'code' => 1,
  210. 'msg' => '获取分享商品海报失败:商品图片丢失',
  211. ];
  212. }
  213. $wxapp_qrcode = @(new \claviska\SimpleImage($qrcode_path));
  214. }
  215. $name_size = 30;
  216. $name_width = 900;
  217. //商品名称处理换行
  218. $name = $this->autowrap($name_size, 0, $font_path, $goods->name, $name_width, 2);
  219. //加商品名称
  220. $search = ['“', '”', ':', '’', '‘'];
  221. $name = str_replace($search, '', $name);
  222. $goods_qrcode->text($name, [
  223. 'fontFile' => $font_path,
  224. 'size' => $name_size,
  225. 'color' => '#333333',
  226. 'anchor' => 'top left',
  227. 'xOffset' => 40,
  228. 'yOffset' => 750,
  229. ]);
  230. // 加载图片
  231. // 获取原始图片的宽度和高度
  232. $original_width = $goods_pic->getWidth();
  233. $original_height = $goods_pic->getHeight();
  234. // 设置目标宽度(保持不变)
  235. $targetWidth = 670; // 例如,宽度保持为 670 像素
  236. // 计算新的高度以保持宽高比
  237. $targetHeight = round(($targetWidth / $original_width) * $original_height);
  238. //裁剪商品图片
  239. $goods_pic->resize($targetWidth, $targetHeight);
  240. // 获取调整后的图像宽度和高度
  241. $resizedWidth = $goods_pic->getWidth();
  242. $resizedHeight = $goods_pic->getHeight();
  243. // 设置最终的目标高度
  244. $finalHeight = 900; // 例如,最终高度为 600 像素
  245. // 计算剪裁的起始位置
  246. $cropX = 0; // 宽度不变,不需要剪裁
  247. $cropY = max(0, ($resizedHeight - $finalHeight) / 2); // 居中剪裁
  248. // 剪裁图像
  249. $goods_pic->crop($cropX, $cropY, $targetWidth, $finalHeight);
  250. //附加商品图片
  251. $goods_qrcode->overlay($goods_pic, 'top left', 1, 40, 40);
  252. //加商品价格
  253. if ($goods->is_negotiable) {
  254. $goods_qrcode->text('价格面议', [
  255. 'fontFile' => $font_path,
  256. 'size' => 45,
  257. 'color' => '#ff4544',
  258. 'anchor' => 'top left',
  259. 'xOffset' => 30,
  260. 'yOffset' => 910,
  261. ]);
  262. } else {
  263. $goods_qrcode->text('¥' . $goods->price, [
  264. 'fontFile' => $font_path,
  265. 'size' => 45,
  266. 'color' => '#ff4544',
  267. 'anchor' => 'top left',
  268. 'xOffset' => 30,
  269. 'yOffset' => 910,
  270. ]);
  271. if (intval($goods->product_type) === 4) {
  272. $goods_qrcode->text('¥' . $goods->price . ' + ' . $goods->integral_price . '积分', [
  273. 'fontFile' => $font_path,
  274. 'size' => 45,
  275. 'color' => '#ff4544',
  276. 'anchor' => 'top left',
  277. 'xOffset' => 30,
  278. 'yOffset' => 910,
  279. ]);
  280. }
  281. }
  282. //加商城名称
  283. $goods_qrcode->text($store_name, [
  284. 'fontFile' => $font_path,
  285. 'size' => 20,
  286. 'color' => '#888888',
  287. 'anchor' => 'top left',
  288. 'xOffset' => 40,
  289. 'yOffset' => 1170,
  290. ]);
  291. //调整小程序码图片
  292. $wxapp_qrcode->resize(240, 240);
  293. //附加小程序码图片
  294. $goods_qrcode->overlay($wxapp_qrcode, 'top left', 1, 470, 1040);
  295. //保存图片
  296. $goods_qrcode->toFile($goods_pic_save_path . $goods_pic_save_name, 'image/jpeg', 85);
  297. //删除临时图片
  298. unlink($goods_pic_path);
  299. unlink($wxapp_qrcode_file_path);
  300. return [
  301. 'code' => 0,
  302. 'data' => [
  303. 'goods_name' => $goods->name,
  304. 'pic_url' => (new StorageForm())->local2cloudLink($goods_pic_save_path . $goods_pic_save_name) ?? $pic_url . '?v=' . time(),
  305. ],
  306. ];
  307. }
  308. //分销海报
  309. public function share_qrcode()
  310. {
  311. $save_root = \Yii::$app->basePath . '/web/temp/';
  312. if (!is_dir($save_root)) {
  313. mkdir($save_root);
  314. file_put_contents($save_root . '.gitignore', "*\r\n!.gitignore");
  315. }
  316. $version = cyy_version();
  317. if (is_alipay_platform()) {
  318. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id={$this->user->id}&alipay") . '.jpg';
  319. } else {
  320. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id={$this->user->id}") . '.jpg';
  321. if (is_wechat_platform()) {
  322. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id={$this->user->id}&wechat") . '.jpg';
  323. }
  324. }
  325. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $save_name);
  326. if (file_exists($save_root . $save_name)) {
  327. return [
  328. 'code' => 0,
  329. 'msg' => 'success',
  330. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  331. ];
  332. }
  333. $store_qrcode = Qrcode::findOne(['store_id' => $this->store_id, 'is_delete' => 0, 'type' => Qrcode::TYPE_SHARE]);
  334. if (!$store_qrcode) {
  335. return [
  336. 'code' => 1,
  337. 'msg' => '请先在后台设置分销海报'
  338. ];
  339. }
  340. //昵称位置
  341. $font_position = json_decode($store_qrcode->font_position, true);
  342. //小程序码位置
  343. $qrcode_position = json_decode($store_qrcode->qrcode_position, true);
  344. //头像位置
  345. $avatar_position = json_decode($store_qrcode->avatar_position, true);
  346. //头像大小
  347. $avatar_size = json_decode($store_qrcode->avatar_size, true);
  348. //小程序码大小
  349. $qrcode_size = json_decode($store_qrcode->qrcode_size, true);
  350. //昵称大小
  351. $font_size = json_decode($store_qrcode->font, true);
  352. //背景图下载到临时目录
  353. $qrcode_bg = $this->saveTempImage($store_qrcode->qrcode_bg);
  354. //邀请码位置
  355. $invite_position = json_decode($store_qrcode->invite_position, true);
  356. if (!$qrcode_bg) {
  357. return [
  358. 'code' => 1,
  359. 'msg' => '获取背景图片失败'
  360. ];
  361. }
  362. if ((!is_h5() && !is_alipay_platform() && !is_wechat_platform())) {
  363. $qrcode_size['c'] = 'false';
  364. }
  365. //用户头像下载到临时目录
  366. $user_avatar = $this->saveTempImage(get_saas_user()->avatar);
  367. if (!$user_avatar) {
  368. return [
  369. 'code' => 1,
  370. 'msg' => '获取用户头像失败'
  371. ];
  372. }
  373. $img_src_user_avatar = @(new \claviska\SimpleImage($user_avatar));
  374. $img_src_user_avatar->resize(200, 200);
  375. $img_src_user_avatar->toFile($user_avatar);
  376. //背景图宽高
  377. [$qrcode_bg_w, $qrcode_bg_h] = getimagesize($qrcode_bg);
  378. if ($qrcode_bg_w == 0) {
  379. return [
  380. 'code' => 1,
  381. 'msg' => '获取背景图片失败'
  382. ];
  383. }
  384. //文字字体
  385. $font_path = \Yii::$app->basePath . '/web/statics/font/AaBanSong.ttf';
  386. //比例尺
  387. $percent = 750 / 300;
  388. $width = doubleval($qrcode_size['w'] * $percent);
  389. //获取小程序码图片
  390. if (is_h5()) {
  391. // 如果是h5环境,就生成普通二维码
  392. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/?store_id=' . get_store_id() . '&user_id=' . get_user_id() . '&page_type=2');
  393. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  394. } elseif (is_app_platform()) {
  395. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/?store_id=' . get_store_id() . '&user_id=' . get_user_id() . '&is_login=1&page_type=2');
  396. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  397. } else {
  398. $scene = "uid:{$this->user_id},store:{$this->store_id}";//page_type=2,
  399. $wxapp_qrcode_file_res = $this->getQrcode($scene);
  400. }
  401. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  402. if (! file_exists($wxapp_qrcode_file_path)) {
  403. return [
  404. 'code' => 1,
  405. 'msg' => '获取分享海报失败:获取二维码失败',
  406. ];
  407. }
  408. //获取背景图
  409. $qrcode_bg_dst = @(new \claviska\SimpleImage($qrcode_bg));
  410. $qrcode_bg_dst->resize(750, 1200);
  411. //获取小程序码
  412. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true') {
  413. $wxapp_qrcode_file_path2 = $wxapp_qrcode_file_path . '2.jpg';
  414. $c = copy($wxapp_qrcode_file_path, $wxapp_qrcode_file_path2);
  415. [$w, $h] = getimagesize($wxapp_qrcode_file_path);
  416. $wxapp_qrcode_file_path = $this->test($wxapp_qrcode_file_path, $save_root, $w, $w);
  417. }
  418. $wxapp_qrcode_dst = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  419. $wxapp_qrcode_dst->resize($width, $width);
  420. //将小程序码添加到背景图
  421. $qrcode_x = $qrcode_position['x'] * $percent;
  422. $qrcode_y = $qrcode_position['y'] * $percent;
  423. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  424. $qrcode_bg_dst->overlay($wxapp_qrcode_dst, 'top left', 1, $qrcode_x, $qrcode_y);
  425. }
  426. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true' && is_h5()) {
  427. $c = 0.7;
  428. $width = $width * $c - 15;
  429. $w2 = (1 - $c) * $width / 2 + 30;
  430. $wxapp_qrcode_dst2 = @(new \claviska\SimpleImage($wxapp_qrcode_file_path2));
  431. $wxapp_qrcode_dst2->resize($width, $width);
  432. //将小程序码添加到背景图
  433. $qrcode_x = $qrcode_position['x'] * $percent;
  434. $qrcode_y = $qrcode_position['y'] * $percent;
  435. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  436. $qrcode_bg_dst->overlay($wxapp_qrcode_dst2, 'top left', 1, $qrcode_x + $w2, $qrcode_y + $w2);
  437. }
  438. @unlink($wxapp_qrcode_file_path2);
  439. }
  440. if ($avatar_size['w'] > 0) {
  441. //获取头像
  442. $avatar_w = $avatar_size['w'] * $percent;
  443. $avatar_h = $avatar_size['h'] * $percent;
  444. $avatar_x = $avatar_position['x'] * $percent;
  445. $avatar_y = $avatar_position['y'] * $percent;
  446. if ($avatar_x >= 0 && $avatar_x <= 750 && $avatar_y >= 0 && $avatar_y <= 1200) {
  447. [$w, $h] = getimagesize($user_avatar);
  448. $user_avatar = $this->test($user_avatar, $save_root, $w, $h);
  449. $avatar_dst = @(new \claviska\SimpleImage($user_avatar));
  450. //裁剪头像
  451. $avatar_dst->resize($avatar_w, $avatar_h);
  452. //将头像添加到背景图
  453. $qrcode_bg_dst->overlay($avatar_dst, 'top left', 1, $avatar_x, $avatar_y);
  454. }
  455. }
  456. if ($font_size['size'] > 0) {
  457. // $color = \app\models\Color::find()->andWhere(['color' => (int)$font_size['color']])->asArray()->one();
  458. //附加用户昵称
  459. $font = $font_size['size'] * $percent * 0.74;
  460. $font_x = $font_position['x'] * $percent;
  461. $font_y = $font_position['y'] * $percent + 1;
  462. if ($font_x >= 0 && $font_x <= 750 && $font_y >= 0 && $font_y <= 1200) {
  463. $qrcode_bg_dst->text(get_saas_user()->name, [
  464. 'fontFile' => $font_path,
  465. 'size' => $font,
  466. 'color' => $font_size['color'],
  467. 'anchor' => 'top left',
  468. 'xOffset' => $font_x,
  469. 'yOffset' => $font_y,
  470. ]);
  471. }
  472. }
  473. //附加邀请码
  474. if($invite_position){
  475. $uid = get_user_id();
  476. if($uid){
  477. //转化成邀请码
  478. $inviteCode = InviteCode::id2Code($uid);
  479. $font = $font_size['size'] * $percent * 0.74;
  480. $invite_x = $invite_position['x'] * $percent;
  481. $invite_y = $invite_position['y'] * $percent + 1;
  482. if ($invite_x >= 0 && $invite_x <= 750 && $invite_y >= 0 && $invite_y <= 1200) {
  483. $qrcode_bg_dst->text($inviteCode, [
  484. 'fontFile' => $font_path,
  485. 'size' => $font,
  486. 'color' => $font_size['color'],
  487. 'anchor' => 'top left',
  488. 'xOffset' => $invite_x,
  489. 'yOffset' => $invite_y,
  490. ]);
  491. }
  492. }
  493. }
  494. //保存图片
  495. $qrcode_bg_dst->toFile($save_root . $save_name, 'image/jpeg', 85);
  496. //删除临时图片
  497. unlink($qrcode_bg);
  498. unlink($user_avatar);
  499. unlink($wxapp_qrcode_file_path);
  500. return [
  501. 'code' => 0,
  502. 'msg' => 'success',
  503. 'page' => $page ?? $scene,
  504. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  505. ];
  506. }
  507. public function material_qrcode():array
  508. {
  509. if(empty($this->id)){
  510. return [
  511. 'code' => 1,
  512. 'msg' => '缺少参数',
  513. ];
  514. }
  515. $save_root = \Yii::$app->basePath . '/web/temp/';
  516. if (!is_dir($save_root)) {
  517. mkdir($save_root);
  518. file_put_contents($save_root . '.gitignore', "*\r\n!.gitignore");
  519. }
  520. $version = cyy_version();
  521. if (is_alipay_platform()) {
  522. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id={$this->user->id}&m_id=".$this->id."&alipay") . '.jpg';
  523. } else {
  524. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id={$this->user->id}&m_id=".$this->id) . '.jpg';
  525. if (is_wechat_platform()) {
  526. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id={$this->user->id}&m_id=".$this->id."&wechat") . '.jpg';
  527. }
  528. }
  529. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $save_name);
  530. if (file_exists($save_root . $save_name)) {
  531. return [
  532. 'code' => 0,
  533. 'msg' => 'success',
  534. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  535. ];
  536. }
  537. $store_qrcode = Qrcode::findOne(['store_id' => $this->store_id, 'is_delete' => 0, 'type' => Qrcode::TYPE_MATERIAL]);
  538. if (!$store_qrcode) {
  539. return [
  540. 'code' => 1,
  541. 'msg' => '请先在后台设置素材海报'
  542. ];
  543. }
  544. //推广文案位置
  545. $font_position = json_decode($store_qrcode->font_position, true);
  546. //小程序码位置
  547. $qrcode_position = json_decode($store_qrcode->qrcode_position, true);
  548. //素材位置
  549. $avatar_position = json_decode($store_qrcode->avatar_position, true);
  550. //素材大小
  551. $avatar_size = json_decode($store_qrcode->avatar_size, true);
  552. //小程序码大小
  553. $qrcode_size = json_decode($store_qrcode->qrcode_size, true);
  554. //推广文案大小
  555. $font_size = json_decode($store_qrcode->font, true);
  556. //背景图下载到临时目录
  557. $qrcode_bg = $this->saveTempImage($store_qrcode->qrcode_bg);
  558. if (!$qrcode_bg) {
  559. return [
  560. 'code' => 1,
  561. 'msg' => '获取背景图片失败'
  562. ];
  563. }
  564. if ((!is_h5() && !is_alipay_platform() && !is_wechat_platform())) {
  565. $qrcode_size['c'] = 'false';
  566. }
  567. // todo 素材第一张下载到临时目录
  568. $material = Material::find()->where(['id' => $this->id,'status'=>1])->andWhere(['OR', ['delete_time'=>0], ['IS', 'delete_time', NULL]])->one();
  569. if(empty($material)){
  570. return [
  571. 'code' => 1,
  572. 'msg' => '素材未设置推广图'
  573. ];
  574. }
  575. $user_avatar = $this->saveTempImage($material->promotion_image);
  576. if (!$user_avatar) {
  577. return [
  578. 'code' => 1,
  579. 'msg' => '获取推广图失败'
  580. ];
  581. }
  582. $img_src_user_avatar = @(new \claviska\SimpleImage($user_avatar));
  583. $img_src_user_avatar->resize(200, 200);
  584. $img_src_user_avatar->toFile($user_avatar);
  585. //背景图宽高
  586. [$qrcode_bg_w, $qrcode_bg_h] = getimagesize($qrcode_bg);
  587. if ($qrcode_bg_w == 0) {
  588. return [
  589. 'code' => 1,
  590. 'msg' => '获取背景图片失败'
  591. ];
  592. }
  593. //文字字体
  594. $font_path = \Yii::$app->basePath . '/web/statics/font/AaBanSong.ttf';
  595. //比例尺
  596. $percent = 750 / 300;
  597. $width = doubleval($qrcode_size['w'] * $percent);
  598. //获取小程序码图片
  599. if (is_h5()) {
  600. // 如果是h5环境,就生成普通二维码
  601. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/tools/quickPost/item/index?store_id=' . get_store_id() . '&user_id=' . get_user_id() . '&m_id='.$this->id.'&page_type=2');
  602. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  603. } elseif (is_app_platform()) {
  604. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/tools/quickPost/item/index?store_id=' . get_store_id() . '&user_id=' . get_user_id() . '&m_id='.$this->id.'&is_login=1&page_type=2');
  605. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  606. } else {
  607. $page = 'tools/quickPost/item/index';
  608. $scene = "uid:{$this->user_id},store:{$this->store_id},m_id:{$this->id}";//page_type=2,
  609. $wxapp_qrcode_file_res = $this->getQrcode($scene, $qrcode_size['w'], $page);
  610. }
  611. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  612. if (! file_exists($wxapp_qrcode_file_path)) {
  613. return [
  614. 'code' => 1,
  615. 'msg' => '获取分享海报失败:获取二维码失败',
  616. ];
  617. }
  618. //获取背景图
  619. $qrcode_bg_dst = @(new \claviska\SimpleImage($qrcode_bg));
  620. $qrcode_bg_dst->resize(750, 1200);
  621. //获取小程序码
  622. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true') {
  623. $wxapp_qrcode_file_path2 = $wxapp_qrcode_file_path . '2.jpg';
  624. $c = copy($wxapp_qrcode_file_path, $wxapp_qrcode_file_path2);
  625. [$w, $h] = getimagesize($wxapp_qrcode_file_path);
  626. $wxapp_qrcode_file_path = $this->test($wxapp_qrcode_file_path, $save_root, $w, $w);
  627. }
  628. $wxapp_qrcode_dst = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  629. $wxapp_qrcode_dst->resize($width, $width);
  630. //将小程序码添加到背景图
  631. $qrcode_x = $qrcode_position['x'] * $percent;
  632. $qrcode_y = $qrcode_position['y'] * $percent;
  633. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  634. $qrcode_bg_dst->overlay($wxapp_qrcode_dst, 'top left', 1, $qrcode_x, $qrcode_y);
  635. }
  636. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true' && is_h5()) {
  637. $c = 0.7;
  638. $width = $width * $c - 15;
  639. $w2 = (1 - $c) * $width / 2 + 30;
  640. $wxapp_qrcode_dst2 = @(new \claviska\SimpleImage($wxapp_qrcode_file_path2));
  641. $wxapp_qrcode_dst2->resize($width, $width);
  642. //将小程序码添加到背景图
  643. $qrcode_x = $qrcode_position['x'] * $percent;
  644. $qrcode_y = $qrcode_position['y'] * $percent;
  645. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  646. $qrcode_bg_dst->overlay($wxapp_qrcode_dst2, 'top left', 1, $qrcode_x + $w2, $qrcode_y + $w2);
  647. }
  648. @unlink($wxapp_qrcode_file_path2);
  649. }
  650. if ($avatar_size['w'] > 0) {
  651. //获取头像
  652. $avatar_w = $avatar_size['w'] * $percent;
  653. $avatar_h = $avatar_size['h'] * $percent;
  654. $avatar_x = $avatar_position['x'] * $percent;
  655. $avatar_y = $avatar_position['y'] * $percent;
  656. if ($avatar_x >= 0 && $avatar_x <= 750 && $avatar_y >= 0 && $avatar_y <= 1200) {
  657. [$w, $h] = getimagesize($user_avatar);
  658. // $user_avatar = $this->test($user_avatar, $save_root, $w, $h);
  659. $avatar_dst = @(new \claviska\SimpleImage($user_avatar));
  660. //裁剪头像
  661. $avatar_dst->resize($avatar_w, $avatar_h);
  662. //将头像添加到背景图
  663. $qrcode_bg_dst->overlay($avatar_dst, 'top left', 1, $avatar_x, $avatar_y);
  664. }
  665. }
  666. if ($font_size['size'] > 0) {
  667. // $color = \app\models\Color::find()->andWhere(['color' => (int)$font_size['color']])->asArray()->one();
  668. //附加用户昵称
  669. $font = $font_size['size'] * $percent * 0.74;
  670. $font_x = $font_position['x'] * $percent;
  671. $font_y = $font_position['y'] * $percent + 1;
  672. if ($font_x >= 0 && $font_x <= 750 && $font_y >= 0 && $font_y <= 1200) {
  673. // 超多多少个文字的推广文案 截取前面的文字并将后面的文字替换为...
  674. $promotion = $material->promotion;
  675. if (mb_strlen($promotion) > 15) {
  676. $promotion = mb_substr($promotion, 0, 15) . '...';
  677. }
  678. $qrcode_bg_dst->text($promotion, [
  679. 'fontFile' => $font_path,
  680. 'size' => $font,
  681. 'color' => $font_size['color'],
  682. 'anchor' => 'top left',
  683. 'xOffset' => $font_x,
  684. 'yOffset' => $font_y,
  685. ]);
  686. }
  687. }
  688. //保存图片
  689. $qrcode_bg_dst->toFile($save_root . $save_name, 'image/jpeg', 85);
  690. //删除临时图片
  691. unlink($qrcode_bg);
  692. unlink($user_avatar);
  693. unlink($wxapp_qrcode_file_path);
  694. return [
  695. 'code' => 0,
  696. 'msg' => 'success',
  697. 'page' => $page ?? $scene,
  698. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  699. ];
  700. }
  701. /**
  702. * 门店海报
  703. * @return array
  704. * @throws \Exception
  705. * @author: hankaige
  706. * @Time: 2024/3/20 14:19
  707. */
  708. public function md_qrcode() {
  709. if(empty($this->md_id)){
  710. return [
  711. 'code' => 1,
  712. 'msg' => '门店信息错误'
  713. ];
  714. }
  715. $md = Md::findOne($this->md_id);
  716. $save_root = \Yii::$app->basePath . '/web/temp/';
  717. if (!is_dir($save_root)) {
  718. mkdir($save_root);
  719. file_put_contents($save_root . '.gitignore', "*\r\n!.gitignore");
  720. }
  721. $version = cyy_version();
  722. if (is_alipay_platform()) {
  723. $save_name = md5("v={$version}&store_id={$this->store_id}&md_id={$md->id}&user_id{$md->user_id}&alipay") . '.jpg';
  724. } else {
  725. $save_name = md5("v={$version}&store_id={$this->store_id}&md_id={$md->id}&user_id{$md->user_id}") . '.jpg';
  726. if (is_wechat_platform()) {
  727. $save_name = md5("v={$version}&store_id={$this->store_id}&md_id={$md->id}&user_id{$md->user_id}&wechat") . '.jpg';
  728. }
  729. }
  730. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $save_name);
  731. if (file_exists($save_root . $save_name)) {
  732. return [
  733. 'code' => 0,
  734. 'msg' => 'success',
  735. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  736. ];
  737. }
  738. $store_qrcode = Qrcode::findOne(['store_id' => $this->store_id, 'is_delete' => 0, 'type' => Qrcode::TYPE_MD]);
  739. if (!$store_qrcode) {
  740. return [
  741. 'code' => 1,
  742. 'msg' => '请先在后台设置分销海报'
  743. ];
  744. }
  745. //昵称位置
  746. $font_position = json_decode($store_qrcode->font_position, true);
  747. //小程序码位置
  748. $qrcode_position = json_decode($store_qrcode->qrcode_position, true);
  749. //头像位置
  750. $avatar_position = json_decode($store_qrcode->avatar_position, true);
  751. //头像大小
  752. $avatar_size = json_decode($store_qrcode->avatar_size, true);
  753. //小程序码大小
  754. $qrcode_size = json_decode($store_qrcode->qrcode_size, true);
  755. //昵称大小
  756. $font_size = json_decode($store_qrcode->font, true);
  757. //背景图下载到临时目录
  758. $qrcode_bg = $this->saveTempImage($store_qrcode->qrcode_bg);
  759. if (!$qrcode_bg) {
  760. return [
  761. 'code' => 1,
  762. 'msg' => '获取背景图片失败'
  763. ];
  764. }
  765. if ((!is_h5() && !is_alipay_platform() && !is_wechat_platform())) {
  766. $qrcode_size['c'] = 'false';
  767. }
  768. //门店的logo下载到临时目录
  769. $user_avatar = $this->saveTempImage($md->cover_url);
  770. if (!$user_avatar) {
  771. return [
  772. 'code' => 1,
  773. 'msg' => '获取门店LOGO失败'
  774. ];
  775. }
  776. $img_src_user_avatar = @(new \claviska\SimpleImage($user_avatar));
  777. $img_src_user_avatar->resize(200, 200);
  778. $img_src_user_avatar->toFile($user_avatar);
  779. //背景图宽高
  780. [$qrcode_bg_w, $qrcode_bg_h] = getimagesize($qrcode_bg);
  781. if ($qrcode_bg_w == 0) {
  782. return [
  783. 'code' => 1,
  784. 'msg' => '获取背景图片失败'
  785. ];
  786. }
  787. //文字字体
  788. $font_path = \Yii::$app->basePath . '/web/statics/font/AaBanSong.ttf';
  789. //比例尺
  790. $percent = 750 / 300;
  791. $width = doubleval($qrcode_size['w'] * $percent);
  792. //获取小程序码图片
  793. if (is_h5()) {
  794. // 如果是h5环境,就生成普通二维码
  795. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/?store_id=' . get_store_id() . '&user_id=' . $md->user_id . '&md_id='. $md->id .'&page_type=2');
  796. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  797. } elseif (is_app_platform()) {
  798. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/?store_id=' . get_store_id() . '&user_id=' . $md->user_id. '&md_id='. $md->id . '&is_login=1&page_type=2');
  799. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  800. } else {
  801. $scene = "uid:{$md->user_id},store:{$this->store_id},mid:{$md->id}";//page_type=2,
  802. $wxapp_qrcode_file_res = $this->getQrcode($scene,240,'pages/home/home');
  803. }
  804. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  805. if (! file_exists($wxapp_qrcode_file_path)) {
  806. return [
  807. 'code' => 1,
  808. 'msg' => '获取门店海报失败:获取二维码失败',
  809. ];
  810. }
  811. //获取背景图
  812. $qrcode_bg_dst = @(new \claviska\SimpleImage($qrcode_bg));
  813. $qrcode_bg_dst->resize(750, 1200);
  814. //获取小程序码
  815. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true') {
  816. $wxapp_qrcode_file_path2 = $wxapp_qrcode_file_path . '2.jpg';
  817. $c = copy($wxapp_qrcode_file_path, $wxapp_qrcode_file_path2);
  818. [$w, $h] = getimagesize($wxapp_qrcode_file_path);
  819. $wxapp_qrcode_file_path = $this->test($wxapp_qrcode_file_path, $save_root, $w, $w);
  820. }
  821. $wxapp_qrcode_dst = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  822. $wxapp_qrcode_dst->resize($width, $width);
  823. //将小程序码添加到背景图
  824. $qrcode_x = $qrcode_position['x'] * $percent;
  825. $qrcode_y = $qrcode_position['y'] * $percent;
  826. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  827. $qrcode_bg_dst->overlay($wxapp_qrcode_dst, 'top left', 1, $qrcode_x, $qrcode_y);
  828. }
  829. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true' && is_h5()) {
  830. $c = 0.7;
  831. $width = $width * $c - 15;
  832. $w2 = (1 - $c) * $width / 2 + 30;
  833. $wxapp_qrcode_dst2 = @(new \claviska\SimpleImage($wxapp_qrcode_file_path2));
  834. $wxapp_qrcode_dst2->resize($width, $width);
  835. //将小程序码添加到背景图
  836. $qrcode_x = $qrcode_position['x'] * $percent;
  837. $qrcode_y = $qrcode_position['y'] * $percent;
  838. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  839. $qrcode_bg_dst->overlay($wxapp_qrcode_dst2, 'top left', 1, $qrcode_x + $w2, $qrcode_y + $w2);
  840. }
  841. @unlink($wxapp_qrcode_file_path2);
  842. }
  843. if ($avatar_size['w'] > 0) {
  844. //获取头像
  845. $avatar_w = $avatar_size['w'] * $percent;
  846. $avatar_h = $avatar_size['h'] * $percent;
  847. $avatar_x = $avatar_position['x'] * $percent;
  848. $avatar_y = $avatar_position['y'] * $percent;
  849. if ($avatar_x >= 0 && $avatar_x <= 750 && $avatar_y >= 0 && $avatar_y <= 1200) {
  850. [$w, $h] = getimagesize($user_avatar);
  851. $user_avatar = $this->test($user_avatar, $save_root, $w, $h);
  852. $avatar_dst = @(new \claviska\SimpleImage($user_avatar));
  853. //裁剪头像
  854. $avatar_dst->resize($avatar_w, $avatar_h);
  855. //将头像添加到背景图
  856. $qrcode_bg_dst->overlay($avatar_dst, 'top left', 1, $avatar_x, $avatar_y);
  857. }
  858. }
  859. if ($font_size['size'] > 0) {
  860. // $color = \app\models\Color::find()->andWhere(['color' => (int)$font_size['color']])->asArray()->one();
  861. //附加门店名称
  862. $font = $font_size['size'] * $percent * 0.74;
  863. $font_x = $font_position['x'] * $percent;
  864. $font_y = $font_position['y'] * $percent + 1;
  865. if ($font_x >= 0 && $font_x <= 750 && $font_y >= 0 && $font_y <= 1200) {
  866. $qrcode_bg_dst->text($md->name, [
  867. 'fontFile' => $font_path,
  868. 'size' => $font,
  869. 'color' => $font_size['color'],
  870. 'anchor' => 'top left',
  871. 'xOffset' => $font_x,
  872. 'yOffset' => $font_y,
  873. ]);
  874. }
  875. }
  876. //保存图片
  877. $qrcode_bg_dst->toFile($save_root . $save_name, 'image/jpeg', 85);
  878. //删除临时图片
  879. unlink($qrcode_bg);
  880. unlink($user_avatar);
  881. unlink($wxapp_qrcode_file_path);
  882. return [
  883. 'code' => 0,
  884. 'msg' => 'success',
  885. 'page' => $page ?? $scene,
  886. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  887. ];
  888. }
  889. /**
  890. * 入驻商海报
  891. */
  892. public function mch_qrcode() {
  893. if(empty($this->mch_id)){
  894. return [
  895. 'code' => 1,
  896. 'msg' => '入驻商信息错误'
  897. ];
  898. }
  899. $mch = Mch::findOne($this->mch_id);
  900. $save_root = \Yii::$app->basePath . '/web/temp/';
  901. if (!is_dir($save_root)) {
  902. mkdir($save_root);
  903. file_put_contents($save_root . '.gitignore', "*\r\n!.gitignore");
  904. }
  905. $version = cyy_version();
  906. if (is_alipay_platform()) {
  907. $save_name = md5("v={$version}&store_id={$this->store_id}&mch_id={$mch->id}&user_id{$mch->user_id}&alipay") . '.jpg';
  908. } else {
  909. $save_name = md5("v={$version}&store_id={$this->store_id}&mch_id={$mch->id}&user_id{$mch->user_id}") . '.jpg';
  910. if (is_wechat_platform()) {
  911. $save_name = md5("v={$version}&store_id={$this->store_id}&mch_id={$mch->id}&user_id{$mch->user_id}&wechat") . '.jpg';
  912. }
  913. }
  914. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $save_name);
  915. if (file_exists($save_root . $save_name)) {
  916. return [
  917. 'code' => 0,
  918. 'msg' => 'success',
  919. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  920. ];
  921. }
  922. // $store_qrcode = Qrcode::findOne(['store_id' => $this->store_id, 'is_delete' => 0, 'type' => Qrcode::TYPE_MCH]);
  923. // if (!$store_qrcode) {
  924. // return [
  925. // 'code' => 1,
  926. // 'msg' => '请先在后台设置分销海报'
  927. // ];
  928. // }
  929. $qrcode_bg = \Yii::$app->basePath . '/web/v1/statics/images/mch-home/qr_bg.png';
  930. //昵称位置
  931. $font_position = ['x' => '110', 'y' => '40'];
  932. //小程序码位置
  933. $qrcode_position = ['x' => '65', 'y' => '180'];
  934. //头像位置
  935. $avatar_position = ['x' => '20', 'y' => '20'];
  936. //头像大小
  937. $avatar_size = ['w' => '80', 'h' => '80'];
  938. //小程序码大小
  939. $qrcode_size = ['w' => '170', 'h' => '170', 'c' => false];
  940. //昵称大小
  941. $font_size = ['size' => '21', 'color' => '#333333'];
  942. //背景图下载到临时目录
  943. // $qrcode_bg = $this->saveTempImage($store_qrcode->qrcode_bg);
  944. // if (!$qrcode_bg) {
  945. // return [
  946. // 'code' => 1,
  947. // 'msg' => '获取背景图片失败'
  948. // ];
  949. // }
  950. if ((!is_h5() && !is_alipay_platform() && !is_wechat_platform())) {
  951. $qrcode_size['c'] = 'false';
  952. }
  953. //门店的logo下载到临时目录
  954. if(empty($mch->logo)){
  955. return [
  956. 'code' => 1,
  957. 'msg' => '请先设置入驻商LOGO'
  958. ];
  959. }
  960. $user_avatar = $this->saveTempImage($mch->logo);
  961. if (!$user_avatar) {
  962. return [
  963. 'code' => 1,
  964. 'msg' => '获取LOGO失败'
  965. ];
  966. }
  967. $img_src_user_avatar = @(new \claviska\SimpleImage($user_avatar));
  968. $img_src_user_avatar->resize(200, 200);
  969. $img_src_user_avatar->toFile($user_avatar);
  970. //背景图宽高
  971. [$qrcode_bg_w, $qrcode_bg_h] = getimagesize($qrcode_bg);
  972. if ($qrcode_bg_w == 0) {
  973. return [
  974. 'code' => 1,
  975. 'msg' => '获取背景图片失败'
  976. ];
  977. }
  978. //文字字体
  979. $font_path = \Yii::$app->basePath . '/web/statics/font/AaBanSong.ttf';
  980. //比例尺
  981. $percent = 750 / 300;
  982. $width = doubleval($qrcode_size['w'] * $percent);
  983. $link = 'mch_store/mchCommodity/mchCommodity';
  984. //获取小程序码图片
  985. if (is_h5()) {
  986. // 如果是h5环境,就生成普通二维码
  987. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/' . $link . '?store_id=' . get_store_id() . '&user_id=' . $mch->user_id . '&mch_id='. $mch->id .'&page_type=2');
  988. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  989. } elseif (is_app_platform()) {
  990. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/' . $link . '?store_id=' . get_store_id() . '&user_id=' . $mch->user_id. '&mch_id='. $mch->id . '&is_login=1&page_type=2');
  991. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  992. } else {
  993. $scene = "u:{$mch->user_id},s:{$this->store_id},mch_id:{$mch->id}";
  994. $wxapp_qrcode_file_res = $this->getQrcode($scene,240,$link);
  995. }
  996. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  997. if (! file_exists($wxapp_qrcode_file_path)) {
  998. \Yii::error([$wxapp_qrcode_file_res, $link, $scene]);
  999. return [
  1000. 'code' => 1,
  1001. 'msg' => '获取二维码失败.' . json_encode($wxapp_qrcode_file_res),
  1002. ];
  1003. }
  1004. //获取背景图
  1005. $qrcode_bg_dst = @(new \claviska\SimpleImage($qrcode_bg));
  1006. $qrcode_bg_dst->resize(750, 1200);
  1007. //获取小程序码
  1008. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true') {
  1009. $wxapp_qrcode_file_path2 = $wxapp_qrcode_file_path . '2.jpg';
  1010. $c = copy($wxapp_qrcode_file_path, $wxapp_qrcode_file_path2);
  1011. [$w, $h] = getimagesize($wxapp_qrcode_file_path);
  1012. $wxapp_qrcode_file_path = $this->test($wxapp_qrcode_file_path, $save_root, $w, $w);
  1013. }
  1014. $wxapp_qrcode_dst = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  1015. $wxapp_qrcode_dst->resize($width, $width);
  1016. //将小程序码添加到背景图
  1017. $qrcode_x = $qrcode_position['x'] * $percent;
  1018. $qrcode_y = $qrcode_position['y'] * $percent;
  1019. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  1020. $qrcode_bg_dst->overlay($wxapp_qrcode_dst, 'top left', 1, $qrcode_x, $qrcode_y);
  1021. }
  1022. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true' && is_h5()) {
  1023. $c = 0.7;
  1024. $width = $width * $c - 15;
  1025. $w2 = (1 - $c) * $width / 2 + 30;
  1026. $wxapp_qrcode_dst2 = @(new \claviska\SimpleImage($wxapp_qrcode_file_path2));
  1027. $wxapp_qrcode_dst2->resize($width, $width);
  1028. //将小程序码添加到背景图
  1029. $qrcode_x = $qrcode_position['x'] * $percent;
  1030. $qrcode_y = $qrcode_position['y'] * $percent;
  1031. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  1032. $qrcode_bg_dst->overlay($wxapp_qrcode_dst2, 'top left', 1, $qrcode_x + $w2, $qrcode_y + $w2);
  1033. }
  1034. @unlink($wxapp_qrcode_file_path2);
  1035. }
  1036. if ($avatar_size['w'] > 0) {
  1037. //获取头像
  1038. $avatar_w = $avatar_size['w'] * $percent;
  1039. $avatar_h = $avatar_size['h'] * $percent;
  1040. $avatar_x = $avatar_position['x'] * $percent;
  1041. $avatar_y = $avatar_position['y'] * $percent;
  1042. if ($avatar_x >= 0 && $avatar_x <= 750 && $avatar_y >= 0 && $avatar_y <= 1200) {
  1043. [$w, $h] = getimagesize($user_avatar);
  1044. $user_avatar = $this->test($user_avatar, $save_root, $w, $h);
  1045. $avatar_dst = @(new \claviska\SimpleImage($user_avatar));
  1046. //裁剪头像
  1047. $avatar_dst->resize($avatar_w, $avatar_h);
  1048. //将头像添加到背景图
  1049. $qrcode_bg_dst->overlay($avatar_dst, 'top left', 1, $avatar_x, $avatar_y);
  1050. }
  1051. }
  1052. if ($font_size['size'] > 0) {
  1053. // $color = \app\models\Color::find()->andWhere(['color' => (int)$font_size['color']])->asArray()->one();
  1054. //附加门店名称
  1055. $font = $font_size['size'] * $percent * 0.74;
  1056. $font_x = $font_position['x'] * $percent;
  1057. $font_y = $font_position['y'] * $percent + 1;
  1058. if ($font_x >= 0 && $font_x <= 750 && $font_y >= 0 && $font_y <= 1200) {
  1059. $qrcode_bg_dst->text($mch->name, [
  1060. 'fontFile' => $font_path,
  1061. 'size' => $font,
  1062. 'color' => $font_size['color'],
  1063. 'anchor' => 'top left',
  1064. 'xOffset' => $font_x,
  1065. 'yOffset' => $font_y,
  1066. ]);
  1067. $qrcode_bg_dst->text($mch->realname, [
  1068. 'fontFile' => $font_path,
  1069. 'size' => $font * 0.65,
  1070. 'color' => '#999999',
  1071. 'anchor' => 'top left',
  1072. 'xOffset' => $font_x,
  1073. 'yOffset' => $font_y + $font * 1.5,
  1074. ]);
  1075. $qrcode_bg_dst->text('打开手机扫一扫查看店铺首页', [
  1076. 'fontFile' => $font_path,
  1077. 'size' => $font * 0.65,
  1078. 'color' => '#999999',
  1079. 'anchor' => 'top left',
  1080. 'xOffset' => 215,
  1081. 'yOffset' => 1000,
  1082. ]);
  1083. }
  1084. }
  1085. //保存图片
  1086. $qrcode_bg_dst->toFile($save_root . $save_name, 'image/png', 85);
  1087. //删除临时图片
  1088. // unlink($qrcode_bg);
  1089. unlink($user_avatar);
  1090. unlink($wxapp_qrcode_file_path);
  1091. return [
  1092. 'code' => 0,
  1093. 'msg' => 'success',
  1094. 'page' => $page ?? $scene,
  1095. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  1096. ];
  1097. }
  1098. /**
  1099. * 直播间海报
  1100. */
  1101. public function live_qrcode() {
  1102. if(empty($this->id)){
  1103. return [
  1104. 'code' => 1,
  1105. 'msg' => '直播间信息错误'
  1106. ];
  1107. }
  1108. $room = LiveRoom::findOne($this->id);
  1109. if(empty($room)){
  1110. return [
  1111. 'code' => 1,
  1112. 'msg' => '直播间信息错误'
  1113. ];
  1114. }
  1115. $anchor = \app\models\LiveAnchor::findOne($room->anchor_id);
  1116. $anchor_user = User::findOne($anchor['user_id']);
  1117. $anchor_saasUser = SaasUser::findOne(['mobile' => $anchor_user['binding']]);
  1118. $save_root = \Yii::$app->basePath . '/web/temp/';
  1119. if (!is_dir($save_root)) {
  1120. mkdir($save_root);
  1121. file_put_contents($save_root . '.gitignore', "*\r\n!.gitignore");
  1122. }
  1123. $version = cyy_version();
  1124. if (is_alipay_platform()) {
  1125. $save_name = md5("v={$version}&store_id={$this->store_id}&room_id={$room->id}&user_id{$this->user_id}&alipay") . '.jpg';
  1126. } else {
  1127. $save_name = md5("v={$version}&store_id={$this->store_id}&room_id={$room->id}&user_id{$this->user_id}") . '.jpg';
  1128. if (is_wechat_platform()) {
  1129. $save_name = md5("v={$version}&store_id={$this->store_id}&room_id={$room->id}&user_id{$this->user_id}&wechat") . '.jpg';
  1130. }
  1131. }
  1132. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $save_name);
  1133. if (file_exists($save_root . $save_name)) {
  1134. return [
  1135. 'code' => 0,
  1136. 'msg' => 'success',
  1137. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  1138. ];
  1139. }
  1140. // $store_qrcode = Qrcode::findOne(['store_id' => $this->store_id, 'is_delete' => 0, 'type' => Qrcode::TYPE_MCH]);
  1141. // if (!$store_qrcode) {
  1142. // return [
  1143. // 'code' => 1,
  1144. // 'msg' => '请先在后台设置分销海报'
  1145. // ];
  1146. // }
  1147. $qrcode_bg = \Yii::$app->basePath . '/web/v1/statics/images/live/qr_bg.png';
  1148. //昵称位置
  1149. $font_position = ['x' => '25', 'y' => '310'];
  1150. //小程序码位置
  1151. $qrcode_position = ['x' => '190', 'y' => '370'];
  1152. //头像位置
  1153. $avatar_position = ['x' => '20', 'y' => '380'];
  1154. //头像大小
  1155. $avatar_size = ['w' => '20', 'h' => '20'];
  1156. //头像位置
  1157. $room_position = ['x' => '0', 'y' => '0'];
  1158. //头像大小
  1159. $room_size = ['w' => '300', 'h' => '292'];
  1160. //小程序码大小
  1161. $qrcode_size = ['w' => '90', 'h' => '90', 'c' => false];
  1162. //昵称大小
  1163. $font_size = ['size' => '21', 'color' => '#333333'];
  1164. //背景图下载到临时目录
  1165. // $qrcode_bg = $this->saveTempImage($store_qrcode->qrcode_bg);
  1166. // if (!$qrcode_bg) {
  1167. // return [
  1168. // 'code' => 1,
  1169. // 'msg' => '获取背景图片失败'
  1170. // ];
  1171. // }
  1172. if ((!is_h5() && !is_alipay_platform() && !is_wechat_platform())) {
  1173. $qrcode_size['c'] = 'false';
  1174. }
  1175. if (!empty(trim($room->pic_url))) {
  1176. $room_pic = $this->saveTempImage($room->pic_url);
  1177. if (!$room_pic) {
  1178. return [
  1179. 'code' => 1,
  1180. 'msg' => '获取直播间图片失败'
  1181. ];
  1182. }
  1183. $img_src_room_pic = @(new \claviska\SimpleImage($room_pic));
  1184. $img_src_room_pic->resize(500, 400);
  1185. $img_src_room_pic->toFile($room_pic);
  1186. }
  1187. //门店的logo下载到临时目录
  1188. $user_avatar = $this->saveTempImage($anchor_saasUser->avatar);
  1189. if (!$user_avatar) {
  1190. return [
  1191. 'code' => 1,
  1192. 'msg' => '获取LOGO失败'
  1193. ];
  1194. }
  1195. $img_src_user_avatar = @(new \claviska\SimpleImage($user_avatar));
  1196. $img_src_user_avatar->resize(200, 200);
  1197. $img_src_user_avatar->toFile($user_avatar);
  1198. //背景图宽高
  1199. [$qrcode_bg_w, $qrcode_bg_h] = getimagesize($qrcode_bg);
  1200. if ($qrcode_bg_w == 0) {
  1201. return [
  1202. 'code' => 1,
  1203. 'msg' => '获取背景图片失败'
  1204. ];
  1205. }
  1206. //文字字体
  1207. $font_path = \Yii::$app->basePath . '/web/statics/font/AaBanSong.ttf';
  1208. //比例尺
  1209. $percent = 750 / 300;
  1210. $width = doubleval($qrcode_size['w'] * $percent);
  1211. $link = 'tools/live/player/index';
  1212. //获取小程序码图片
  1213. if (is_h5()) {
  1214. // 如果是h5环境,就生成普通二维码
  1215. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/' . $link . '?store_id=' . get_store_id() . '&user_id=' . $this->user_id . '&id='. $room->id .'&page_type=2');
  1216. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  1217. } elseif (is_app_platform()) {
  1218. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/' . $link . '?store_id=' . get_store_id() . '&user_id=' . $this->user_id. '&id='. $room->id . '&is_login=1&page_type=2');
  1219. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  1220. } else {
  1221. $scene = "u:{$this->user_id},s:{$this->store_id},id:{$room->id}";
  1222. $wxapp_qrcode_file_res = $this->getQrcode($scene,240,$link);
  1223. }
  1224. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  1225. if (! file_exists($wxapp_qrcode_file_path)) {
  1226. \Yii::error([$wxapp_qrcode_file_res, $link, $scene]);
  1227. return [
  1228. 'code' => 1,
  1229. 'msg' => '获取二维码失败.' . json_encode($wxapp_qrcode_file_res),
  1230. ];
  1231. }
  1232. //获取背景图
  1233. $qrcode_bg_dst = @(new \claviska\SimpleImage($qrcode_bg));
  1234. $qrcode_bg_dst->resize(750, 1200);
  1235. //获取小程序码
  1236. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true') {
  1237. $wxapp_qrcode_file_path2 = $wxapp_qrcode_file_path . '2.jpg';
  1238. $c = copy($wxapp_qrcode_file_path, $wxapp_qrcode_file_path2);
  1239. [$w, $h] = getimagesize($wxapp_qrcode_file_path);
  1240. $wxapp_qrcode_file_path = $this->test($wxapp_qrcode_file_path, $save_root, $w, $w);
  1241. }
  1242. $wxapp_qrcode_dst = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  1243. $wxapp_qrcode_dst->resize($width, $width);
  1244. //将小程序码添加到背景图
  1245. $qrcode_x = $qrcode_position['x'] * $percent;
  1246. $qrcode_y = $qrcode_position['y'] * $percent;
  1247. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  1248. $qrcode_bg_dst->overlay($wxapp_qrcode_dst, 'top left', 1, $qrcode_x, $qrcode_y);
  1249. }
  1250. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true' && is_h5()) {
  1251. $c = 0.7;
  1252. $width = $width * $c - 15;
  1253. $w2 = (1 - $c) * $width / 2 + 30;
  1254. $wxapp_qrcode_dst2 = @(new \claviska\SimpleImage($wxapp_qrcode_file_path2));
  1255. $wxapp_qrcode_dst2->resize($width, $width);
  1256. //将小程序码添加到背景图
  1257. $qrcode_x = $qrcode_position['x'] * $percent;
  1258. $qrcode_y = $qrcode_position['y'] * $percent;
  1259. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  1260. $qrcode_bg_dst->overlay($wxapp_qrcode_dst2, 'top left', 1, $qrcode_x + $w2, $qrcode_y + $w2);
  1261. }
  1262. @unlink($wxapp_qrcode_file_path2);
  1263. }
  1264. if ($avatar_size['w'] > 0) {
  1265. //获取头像
  1266. $avatar_w = $avatar_size['w'] * $percent;
  1267. $avatar_h = $avatar_size['h'] * $percent;
  1268. $avatar_x = $avatar_position['x'] * $percent;
  1269. $avatar_y = $avatar_position['y'] * $percent;
  1270. if ($avatar_x >= 0 && $avatar_x <= 750 && $avatar_y >= 0 && $avatar_y <= 1200) {
  1271. [$w, $h] = getimagesize($user_avatar);
  1272. $user_avatar = $this->test($user_avatar, $save_root, $w, $h);
  1273. $avatar_dst = @(new \claviska\SimpleImage($user_avatar));
  1274. //裁剪头像
  1275. $avatar_dst->resize($avatar_w, $avatar_h);
  1276. //将头像添加到背景图
  1277. $qrcode_bg_dst->overlay($avatar_dst, 'top left', 1, $avatar_x, $avatar_y);
  1278. }
  1279. }
  1280. if ($room_size['w'] > 0) {
  1281. //获取头像
  1282. $avatar_w = $room_size['w'] * $percent;
  1283. $avatar_h = $room_size['h'] * $percent;
  1284. $avatar_x = $room_position['x'] * $percent;
  1285. $avatar_y = $room_position['y'] * $percent;
  1286. if ($avatar_x >= 0 && $avatar_x <= 750 && $avatar_y >= 0 && $avatar_y <= 1200) {
  1287. if (!empty($room_pic)) {
  1288. [$w, $h] = getimagesize($room_pic);
  1289. // $room_pic = $this->test($room_pic, $save_root, $w, $h);
  1290. $avatar_dst = @(new \claviska\SimpleImage($room_pic));
  1291. //裁剪头像
  1292. $avatar_dst->resize($avatar_w, $avatar_h);
  1293. //将头像添加到背景图
  1294. $qrcode_bg_dst->overlay($avatar_dst, 'top left', 1, $avatar_x, $avatar_y);
  1295. }
  1296. }
  1297. }
  1298. if ($font_size['size'] > 0) {
  1299. // $color = \app\models\Color::find()->andWhere(['color' => (int)$font_size['color']])->asArray()->one();
  1300. //附加门店名称
  1301. $font = $font_size['size'] * $percent * 0.74;
  1302. $font_x = $font_position['x'] * $percent;
  1303. $font_y = $font_position['y'] * $percent + 1;
  1304. if ($font_x >= 0 && $font_x <= 750 && $font_y >= 0 && $font_y <= 1200) {
  1305. $qrcode_bg_dst->text($room->name, [
  1306. 'fontFile' => $font_path,
  1307. 'size' => $font,
  1308. 'color' => $font_size['color'],
  1309. 'anchor' => 'top left',
  1310. 'xOffset' => $font_x,
  1311. 'yOffset' => $font_y,
  1312. ]);
  1313. $qrcode_bg_dst->text($anchor->name, [
  1314. 'fontFile' => $font_path,
  1315. 'size' => $font * 0.65,
  1316. // 'color' => '#999999',
  1317. 'anchor' => 'top left',
  1318. 'xOffset' => $font_x + 60,
  1319. 'yOffset' => $font_y + 190,
  1320. ]);
  1321. // $qrcode_bg_dst->text('打开手机扫一扫查看店铺首页', [
  1322. // 'fontFile' => $font_path,
  1323. // 'size' => $font * 0.65,
  1324. // 'color' => '#999999',
  1325. // 'anchor' => 'top left',
  1326. // 'xOffset' => 215,
  1327. // 'yOffset' => 1000,
  1328. // ]);
  1329. }
  1330. }
  1331. //保存图片
  1332. $qrcode_bg_dst->toFile($save_root . $save_name, 'image/png', 85);
  1333. //删除临时图片
  1334. // unlink($qrcode_bg);
  1335. unlink($user_avatar);
  1336. unlink($wxapp_qrcode_file_path);
  1337. return [
  1338. 'code' => 0,
  1339. 'msg' => 'success',
  1340. 'page' => $page ?? $scene,
  1341. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  1342. ];
  1343. }
  1344. public function group_purchase_qrcode() {
  1345. try {
  1346. $share_group_setting = Option::get('share_group_setting', $this->store_id, 'share_group')['value'];
  1347. $share_group_setting = json_decode($share_group_setting ?? '', true);
  1348. $user = User::findOne($this->user_id);
  1349. $saas_user = SaasUser::findOne(['mobile' => $user->binding]);
  1350. $save_root = \Yii::$app->basePath . '/web/temp/';
  1351. if (!is_dir($save_root)) {
  1352. mkdir($save_root);
  1353. file_put_contents($save_root . '.gitignore', "*\r\n!.gitignore");
  1354. }
  1355. $version = cyy_version();
  1356. if (is_alipay_platform()) {
  1357. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id{$user->id}&alipay&groupPurchase") . '.jpg';
  1358. } else {
  1359. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id{$user->id}&groupPurchase") . '.jpg';
  1360. if (is_wechat_platform()) {
  1361. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id{$user->id}&wechat&groupPurchase") . '.jpg';
  1362. }
  1363. }
  1364. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $save_name);
  1365. if (file_exists($save_root . $save_name)) {
  1366. return [
  1367. 'code' => 0,
  1368. 'msg' => 'success',
  1369. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  1370. ];
  1371. }
  1372. //昵称位置
  1373. $font_position = ['x' => '110', 'y' => '40'];
  1374. //小程序码位置
  1375. $qrcode_position = ['x' => '65', 'y' => '180'];
  1376. //头像位置
  1377. $avatar_position = ['x' => '20', 'y' => '20'];
  1378. //头像大小
  1379. $avatar_size = ['w' => '80', 'h' => '80'];
  1380. //小程序码大小
  1381. $qrcode_size = ['w' => '170', 'h' => '170', 'c' => false];
  1382. //昵称大小
  1383. $font_size = ['size' => '21', 'color' => '#333333'];
  1384. //背景图下载到临时目录
  1385. $qrcode_bg = $share_group_setting['share_group_bg'] ?: 'https://'.\Yii::$app->request->hostName . '/web/v1/statics/images/step-qrcode-bj.jpg';
  1386. if (!$qrcode_bg) {
  1387. return [
  1388. 'code' => 1,
  1389. 'msg' => '获取背景图片失败'
  1390. ];
  1391. }
  1392. if ((!is_h5() && !is_alipay_platform() && !is_wechat_platform())) {
  1393. $qrcode_size['c'] = 'false';
  1394. }
  1395. //门店的logo下载到临时目录
  1396. $user_avatar = $this->saveTempImage($saas_user->avatar);
  1397. if (!$user_avatar) {
  1398. return [
  1399. 'code' => 1,
  1400. 'msg' => '获取LOGO失败'
  1401. ];
  1402. }
  1403. $img_src_user_avatar = @(new \claviska\SimpleImage($user_avatar));
  1404. $img_src_user_avatar->resize(200, 200);
  1405. $img_src_user_avatar->toFile($user_avatar);
  1406. //背景图宽高
  1407. //门店的logo下载到临时目录
  1408. $qrcode_bg = $this->saveTempImage($qrcode_bg);
  1409. if (!$qrcode_bg) {
  1410. return [
  1411. 'code' => 1,
  1412. 'msg' => '获取LOGO失败1'
  1413. ];
  1414. }
  1415. [$qrcode_bg_w, $qrcode_bg_h] = getimagesize($qrcode_bg);
  1416. if ($qrcode_bg_w == 0) {
  1417. return [
  1418. 'code' => 1,
  1419. 'msg' => '获取背景图片失败'
  1420. ];
  1421. }
  1422. //文字字体
  1423. $font_path = \Yii::$app->basePath . '/web/statics/font/AaBanSong.ttf';
  1424. //比例尺
  1425. $percent = 750 / 300;
  1426. $width = doubleval($qrcode_size['w'] * $percent);
  1427. $link = 'pages/home/home';
  1428. //获取小程序码图片
  1429. if (is_h5()) {
  1430. // 如果是h5环境,就生成普通二维码
  1431. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/' . $link . '?store_id=' . get_store_id() . '&user_id=' . $user->id .'&page_type=2');
  1432. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  1433. } elseif (is_app_platform()) {
  1434. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/' . $link . '?store_id=' . get_store_id() . '&user_id=' . $user->id . '&is_login=1&page_type=2');
  1435. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  1436. } else {
  1437. $scene = "u:{$user->id},s:{$this->store_id}";
  1438. $wxapp_qrcode_file_res = $this->getQrcode($scene,240,$link);
  1439. }
  1440. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  1441. if (! file_exists($wxapp_qrcode_file_path)) {
  1442. \Yii::error([$wxapp_qrcode_file_res, $link, $scene]);
  1443. return [
  1444. 'code' => 1,
  1445. 'msg' => '获取二维码失败.' . json_encode($wxapp_qrcode_file_res),
  1446. ];
  1447. }
  1448. //获取背景图
  1449. $qrcode_bg_dst = @(new \claviska\SimpleImage($qrcode_bg));//
  1450. $qrcode_bg_dst->resize(750, 1334);
  1451. //获取小程序码
  1452. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true') {
  1453. $wxapp_qrcode_file_path2 = $wxapp_qrcode_file_path . '2.jpg';
  1454. $c = copy($wxapp_qrcode_file_path, $wxapp_qrcode_file_path2);
  1455. [$w, $h] = getimagesize($wxapp_qrcode_file_path);
  1456. $wxapp_qrcode_file_path = $this->test($wxapp_qrcode_file_path, $save_root, $w, $w);
  1457. }
  1458. $wxapp_qrcode_dst = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  1459. $wxapp_qrcode_dst->resize($width, $width);
  1460. //将小程序码添加到背景图
  1461. $qrcode_x = $qrcode_position['x'] * $percent;
  1462. $qrcode_y = $qrcode_position['y'] * $percent;
  1463. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  1464. $qrcode_bg_dst->overlay($wxapp_qrcode_dst, 'top left', 1, $qrcode_x, $qrcode_y);
  1465. }
  1466. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true' && is_h5()) {
  1467. $c = 0.7;
  1468. $width = $width * $c - 15;
  1469. $w2 = (1 - $c) * $width / 2 + 30;
  1470. $wxapp_qrcode_dst2 = @(new \claviska\SimpleImage($wxapp_qrcode_file_path2));
  1471. $wxapp_qrcode_dst2->resize($width, $width);
  1472. //将小程序码添加到背景图
  1473. $qrcode_x = $qrcode_position['x'] * $percent;
  1474. $qrcode_y = $qrcode_position['y'] * $percent;
  1475. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  1476. $qrcode_bg_dst->overlay($wxapp_qrcode_dst2, 'top left', 1, $qrcode_x + $w2, $qrcode_y + $w2);
  1477. }
  1478. @unlink($wxapp_qrcode_file_path2);
  1479. }
  1480. if ($avatar_size['w'] > 0) {
  1481. //获取头像
  1482. $avatar_w = $avatar_size['w'] * $percent;
  1483. $avatar_h = $avatar_size['h'] * $percent;
  1484. $avatar_x = $avatar_position['x'] * $percent;
  1485. $avatar_y = $avatar_position['y'] * $percent;
  1486. if ($avatar_x >= 0 && $avatar_x <= 750 && $avatar_y >= 0 && $avatar_y <= 1200) {
  1487. [$w, $h] = getimagesize($user_avatar);
  1488. $user_avatar = $this->test($user_avatar, $save_root, $w, $h);
  1489. $avatar_dst = @(new \claviska\SimpleImage($user_avatar));
  1490. //裁剪头像
  1491. $avatar_dst->resize($avatar_w, $avatar_h);
  1492. //将头像添加到背景图
  1493. $qrcode_bg_dst->overlay($avatar_dst, 'top left', 1, $avatar_x, $avatar_y);
  1494. }
  1495. }
  1496. if ($font_size['size'] > 0) {
  1497. // $color = \app\models\Color::find()->andWhere(['color' => (int)$font_size['color']])->asArray()->one();
  1498. //附加门店名称
  1499. $font = $font_size['size'] * $percent * 0.74;
  1500. $font_x = $font_position['x'] * $percent;
  1501. $font_y = $font_position['y'] * $percent + 1;
  1502. if ($font_x >= 0 && $font_x <= 750 && $font_y >= 0 && $font_y <= 1200) {
  1503. $qrcode_bg_dst->text($saas_user->name, [
  1504. 'fontFile' => $font_path,
  1505. 'size' => $font,
  1506. 'color' => $font_size['color'],
  1507. 'anchor' => 'top left',
  1508. 'xOffset' => $font_x,
  1509. 'yOffset' => $font_y,
  1510. ]);
  1511. $qrcode_bg_dst->text('打开手机扫一扫来和我一起拼购!', [
  1512. 'fontFile' => $font_path,
  1513. 'size' => $font * 0.65,
  1514. 'color' => '#999999',
  1515. 'anchor' => 'top left',
  1516. 'xOffset' => 215,
  1517. 'yOffset' => 1000,
  1518. ]);
  1519. }
  1520. }
  1521. //保存图片
  1522. $qrcode_bg_dst->toFile($save_root . $save_name, 'image/png', 85);
  1523. //删除临时图片
  1524. // unlink($qrcode_bg);
  1525. unlink($user_avatar);
  1526. unlink($wxapp_qrcode_file_path);
  1527. return [
  1528. 'code' => 0,
  1529. 'msg' => 'success',
  1530. 'page' => $page ?? $scene,
  1531. 'data' => $pic_url . '?v=' . time()
  1532. ];
  1533. } catch (\Exception $e) {
  1534. var_dump($e->getMessage() . $e->getLine() . $e->getFile());die;
  1535. }
  1536. }
  1537. public function super_sales_qrcode() {
  1538. try {
  1539. $share_group_setting = Option::get('super_sales_setting', $this->store_id, 'super_sales')['value'];
  1540. $share_group_setting = json_decode($share_group_setting ?? '', true);
  1541. $user = User::findOne($this->user_id);
  1542. $saas_user = SaasUser::findOne(['mobile' => $user->binding]);
  1543. $save_root = \Yii::$app->basePath . '/web/temp/';
  1544. if (!is_dir($save_root)) {
  1545. mkdir($save_root);
  1546. file_put_contents($save_root . '.gitignore', "*\r\n!.gitignore");
  1547. }
  1548. $version = cyy_version();
  1549. if (is_alipay_platform()) {
  1550. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id{$user->id}&alipay&superSales") . '.jpg';
  1551. } else {
  1552. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id{$user->id}&superSales") . '.jpg';
  1553. if (is_wechat_platform()) {
  1554. $save_name = md5("v={$version}&store_id={$this->store_id}&user_id{$user->id}&wechat&superSales") . '.jpg';
  1555. }
  1556. }
  1557. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $save_name);
  1558. if (file_exists($save_root . $save_name)) {
  1559. return [
  1560. 'code' => 0,
  1561. 'msg' => 'success',
  1562. 'data' => $pic_url . '?v=' . time()
  1563. ];
  1564. }
  1565. //昵称位置
  1566. $font_position = ['x' => '110', 'y' => '40'];
  1567. //小程序码位置
  1568. $qrcode_position = ['x' => '65', 'y' => '180'];
  1569. //头像位置
  1570. $avatar_position = ['x' => '20', 'y' => '20'];
  1571. //头像大小
  1572. $avatar_size = ['w' => '80', 'h' => '80'];
  1573. //小程序码大小
  1574. $qrcode_size = ['w' => '170', 'h' => '170', 'c' => false];
  1575. //昵称大小
  1576. $font_size = ['size' => '21', 'color' => '#333333'];
  1577. //背景图下载到临时目录
  1578. $qrcode_bg = $share_group_setting['super_sales_bg'] ?: 'https://'.\Yii::$app->request->hostName . '/web/v1/statics/images/step-qrcode-bj.jpg';
  1579. if (!$qrcode_bg) {
  1580. return [
  1581. 'code' => 1,
  1582. 'msg' => '获取背景图片失败'
  1583. ];
  1584. }
  1585. if ((!is_h5() && !is_alipay_platform() && !is_wechat_platform())) {
  1586. $qrcode_size['c'] = 'false';
  1587. }
  1588. //门店的logo下载到临时目录
  1589. $user_avatar = $this->saveTempImage($saas_user->avatar);
  1590. if (!$user_avatar) {
  1591. return [
  1592. 'code' => 1,
  1593. 'msg' => '获取LOGO失败'
  1594. ];
  1595. }
  1596. $img_src_user_avatar = @(new \claviska\SimpleImage($user_avatar));
  1597. $img_src_user_avatar->resize(200, 200);
  1598. $img_src_user_avatar->toFile($user_avatar);
  1599. //背景图宽高
  1600. //门店的logo下载到临时目录
  1601. $qrcode_bg = $this->saveTempImage($qrcode_bg);
  1602. if (!$qrcode_bg) {
  1603. return [
  1604. 'code' => 1,
  1605. 'msg' => '获取LOGO失败1'
  1606. ];
  1607. }
  1608. [$qrcode_bg_w, $qrcode_bg_h] = getimagesize($qrcode_bg);
  1609. if ($qrcode_bg_w == 0) {
  1610. return [
  1611. 'code' => 1,
  1612. 'msg' => '获取背景图片失败'
  1613. ];
  1614. }
  1615. //文字字体
  1616. $font_path = \Yii::$app->basePath . '/web/statics/font/AaBanSong.ttf';
  1617. //比例尺
  1618. $percent = 750 / 300;
  1619. $width = doubleval($qrcode_size['w'] * $percent);
  1620. $link = 'pages/home/home';
  1621. //获取小程序码图片
  1622. if (is_h5()) {
  1623. // 如果是h5环境,就生成普通二维码
  1624. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/' . $link . '?store_id=' . get_store_id() . '&user_id=' . $user->id .'&page_type=2');
  1625. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  1626. } elseif (is_app_platform()) {
  1627. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/' . $link . '?store_id=' . get_store_id() . '&user_id=' . $user->id . '&is_login=1&page_type=2');
  1628. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  1629. } else {
  1630. $scene = "u:{$user->id},s:{$this->store_id}";
  1631. $wxapp_qrcode_file_res = $this->getQrcode($scene,240,$link);
  1632. }
  1633. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  1634. if (! file_exists($wxapp_qrcode_file_path)) {
  1635. \Yii::error([$wxapp_qrcode_file_res, $link, $scene]);
  1636. return [
  1637. 'code' => 1,
  1638. 'msg' => '获取二维码失败.' . json_encode($wxapp_qrcode_file_res),
  1639. ];
  1640. }
  1641. //获取背景图
  1642. $qrcode_bg_dst = @(new \claviska\SimpleImage($qrcode_bg));//
  1643. $qrcode_bg_dst->resize(750, 1334);
  1644. //获取小程序码
  1645. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true') {
  1646. $wxapp_qrcode_file_path2 = $wxapp_qrcode_file_path . '2.jpg';
  1647. $c = copy($wxapp_qrcode_file_path, $wxapp_qrcode_file_path2);
  1648. [$w, $h] = getimagesize($wxapp_qrcode_file_path);
  1649. $wxapp_qrcode_file_path = $this->test($wxapp_qrcode_file_path, $save_root, $w, $w);
  1650. }
  1651. $wxapp_qrcode_dst = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  1652. $wxapp_qrcode_dst->resize($width, $width);
  1653. //将小程序码添加到背景图
  1654. $qrcode_x = $qrcode_position['x'] * $percent;
  1655. $qrcode_y = $qrcode_position['y'] * $percent;
  1656. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  1657. $qrcode_bg_dst->overlay($wxapp_qrcode_dst, 'top left', 1, $qrcode_x, $qrcode_y);
  1658. }
  1659. if (isset($qrcode_size['c']) && $qrcode_size['c'] == 'true' && is_h5()) {
  1660. $c = 0.7;
  1661. $width = $width * $c - 15;
  1662. $w2 = (1 - $c) * $width / 2 + 30;
  1663. $wxapp_qrcode_dst2 = @(new \claviska\SimpleImage($wxapp_qrcode_file_path2));
  1664. $wxapp_qrcode_dst2->resize($width, $width);
  1665. //将小程序码添加到背景图
  1666. $qrcode_x = $qrcode_position['x'] * $percent;
  1667. $qrcode_y = $qrcode_position['y'] * $percent;
  1668. if ($qrcode_x >= 0 && $qrcode_x <= 750 && $qrcode_y >= 0 && $qrcode_y <= 1200) {
  1669. $qrcode_bg_dst->overlay($wxapp_qrcode_dst2, 'top left', 1, $qrcode_x + $w2, $qrcode_y + $w2);
  1670. }
  1671. @unlink($wxapp_qrcode_file_path2);
  1672. }
  1673. if ($avatar_size['w'] > 0) {
  1674. //获取头像
  1675. $avatar_w = $avatar_size['w'] * $percent;
  1676. $avatar_h = $avatar_size['h'] * $percent;
  1677. $avatar_x = $avatar_position['x'] * $percent;
  1678. $avatar_y = $avatar_position['y'] * $percent;
  1679. if ($avatar_x >= 0 && $avatar_x <= 750 && $avatar_y >= 0 && $avatar_y <= 1200) {
  1680. [$w, $h] = getimagesize($user_avatar);
  1681. $user_avatar = $this->test($user_avatar, $save_root, $w, $h);
  1682. $avatar_dst = @(new \claviska\SimpleImage($user_avatar));
  1683. //裁剪头像
  1684. $avatar_dst->resize($avatar_w, $avatar_h);
  1685. //将头像添加到背景图
  1686. $qrcode_bg_dst->overlay($avatar_dst, 'top left', 1, $avatar_x, $avatar_y);
  1687. }
  1688. }
  1689. if ($font_size['size'] > 0) {
  1690. // $color = \app\models\Color::find()->andWhere(['color' => (int)$font_size['color']])->asArray()->one();
  1691. //附加门店名称
  1692. $font = $font_size['size'] * $percent * 0.74;
  1693. $font_x = $font_position['x'] * $percent;
  1694. $font_y = $font_position['y'] * $percent + 1;
  1695. if ($font_x >= 0 && $font_x <= 750 && $font_y >= 0 && $font_y <= 1200) {
  1696. $qrcode_bg_dst->text($saas_user->name, [
  1697. 'fontFile' => $font_path,
  1698. 'size' => $font,
  1699. 'color' => $font_size['color'],
  1700. 'anchor' => 'top left',
  1701. 'xOffset' => $font_x,
  1702. 'yOffset' => $font_y,
  1703. ]);
  1704. $qrcode_bg_dst->text('打开手机扫一扫来和我一起拼购!', [
  1705. 'fontFile' => $font_path,
  1706. 'size' => $font * 0.65,
  1707. 'color' => '#999999',
  1708. 'anchor' => 'top left',
  1709. 'xOffset' => 215,
  1710. 'yOffset' => 1000,
  1711. ]);
  1712. }
  1713. }
  1714. //保存图片
  1715. $qrcode_bg_dst->toFile($save_root . $save_name, 'image/png', 85);
  1716. //删除临时图片
  1717. // unlink($qrcode_bg);
  1718. unlink($user_avatar);
  1719. unlink($wxapp_qrcode_file_path);
  1720. return [
  1721. 'code' => 0,
  1722. 'msg' => 'success',
  1723. 'page' => $page ?? $scene,
  1724. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time()
  1725. ];
  1726. } catch (\Exception $e) {
  1727. var_dump($e->getMessage() . $e->getLine() . $e->getFile());die;
  1728. }
  1729. }
  1730. // 分销海报
  1731. public function new_share_qrcode()
  1732. {
  1733. $save_root = \Yii::$app->basePath . '/web/temp/';
  1734. if (!is_dir($save_root)) {
  1735. mkdir($save_root);
  1736. file_put_contents($save_root . '.gitignore', "*\r\n!.gitignore");
  1737. }
  1738. // 获取后台配置
  1739. $option = Option::get('qrcode', $this->store_id, 'bonus_pool')['value'];
  1740. $option = Json::decode($option);
  1741. if (empty($option)) {
  1742. return [
  1743. 'code' => 1,
  1744. 'msg' => '请先后台设置'
  1745. ];
  1746. }
  1747. if (is_alipay_platform()) {
  1748. $save_name = md5("share=new&store_id={$this->store_id}&user_id={$this->user_id}&alipay") . '.jpg';
  1749. } else {
  1750. $save_name = md5("share=new&store_id={$this->store_id}&user_id={$this->user_id}") . '.jpg';
  1751. if (is_wechat_platform()) {
  1752. $save_name = md5("share=new&store_id={$this->store_id}&user_id={$this->user_id}&wechat") . '.jpg';
  1753. }
  1754. }
  1755. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $save_name);
  1756. if (file_exists($save_root . $save_name)) {
  1757. return [
  1758. 'code' => 0,
  1759. 'msg' => 'success',
  1760. 'data' => ['data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time(), 'background' => $option['backgroundImage']]
  1761. ];
  1762. }
  1763. $backgroundImage = $option['backgroundImage'] ?: 'https://'.\Yii::$app->request->hostName . '/web/v1/statics/images/step-qrcode-bj.jpg';
  1764. //下载到临时目录
  1765. $share_holder_bg = $this->saveTempImage($backgroundImage);
  1766. if (!$share_holder_bg) {
  1767. return [
  1768. 'code' => 1,
  1769. 'msg' => '获取股东背景失败'
  1770. ];
  1771. }
  1772. //用户头像下载到临时目录
  1773. $user_avatar = $this->saveTempImage(get_saas_user()->avatar);
  1774. if (!$user_avatar) {
  1775. return [
  1776. 'code' => 1,
  1777. 'msg' => '获取用户头像失败'
  1778. ];
  1779. }
  1780. //文字字体
  1781. $font_path = \Yii::$app->basePath . '/web/statics/font/AaBanSong.ttf';
  1782. //获取小程序码图片
  1783. $width = doubleval(300);
  1784. if (is_h5() || (!is_alipay_platform() && !is_wechat_platform())) {
  1785. $is_login = 0;
  1786. if (!is_alipay_platform() && !is_wechat_platform() && !is_h5()) {
  1787. $is_login = 1;
  1788. }
  1789. // 如果是h5环境,就生成普通二维码
  1790. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/?store_id=' . get_store_id() . '&user_id=' . get_user_id() . '&is_login=' . $is_login) . '&page_type=2';
  1791. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  1792. } else {
  1793. $scene = "uid:{$this->user_id},store:{$this->store_id}";//page_type=2,
  1794. $wxapp_qrcode_file_res = $this->getQrcode($scene);
  1795. }
  1796. // $scene = "uid:{$this->user_id},store:{$this->store_id}";
  1797. // \Yii::warning($scene);
  1798. // $wxapp_qrcode_file_res = $this->getQrcode($scene);
  1799. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  1800. if (! file_exists($wxapp_qrcode_file_path)) {
  1801. return [
  1802. 'code' => 1,
  1803. 'msg' => '获取分享海报失败:获取小程序码失败',
  1804. ];
  1805. }
  1806. [$w, $h] = getimagesize($wxapp_qrcode_file_path);
  1807. if (!is_h5() && (is_alipay_platform() || is_wechat_platform())) {
  1808. $wxapp_qrcode_file_path = $this->test($wxapp_qrcode_file_path, $save_root, $w, $w);
  1809. }
  1810. $test_color = SimpleImage::normalizeColor(!empty($option['backgroundColor'])?$option['backgroundColor']:"#ffffff");
  1811. $image = imagecreatetruecolor(321, 349);//图片大小
  1812. $white = imagecolorallocate($image, $test_color['red'], $test_color['green'], $test_color['blue']);//图片的rgb
  1813. imagefill($image, 0, 0, $white);
  1814. $share_image = \Yii::$app->basePath . '/web/temp/new_share.jpg';
  1815. //保存图片
  1816. $this->createRoundedImage(321, 349, $test_color, 24, $share_image);
  1817. //获取背景图
  1818. $share_box_bg_dst = @(new \claviska\SimpleImage($share_holder_bg));
  1819. $share_box_bg_dst->resize(750, 1334);
  1820. //获取背景图
  1821. $qrcode_bg_dst = @(new \claviska\SimpleImage($share_image));
  1822. $qrcode_bg_dst->resize(642, 698);
  1823. $wxapp_qrcode_dst = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  1824. $wxapp_qrcode_dst->resize($width, $width);
  1825. //将小程序码添加到背景图
  1826. $qrcode_x = 315;
  1827. $qrcode_y = 364;
  1828. if ($qrcode_x >= 0 && $qrcode_x <= 642 && $qrcode_y >= 0 && $qrcode_y <= 698) {
  1829. $qrcode_bg_dst->overlay($wxapp_qrcode_dst, 'left top', 1, $qrcode_x, $qrcode_y);
  1830. }
  1831. //获取头像
  1832. $avatar_w = 132;
  1833. $avatar_h = 132;
  1834. $avatar_x = 27;
  1835. $avatar_y = 38;
  1836. if ($avatar_x >= 0 && $avatar_x <= 642 && $avatar_y >= 0 && $avatar_y <= 698) {
  1837. [$w, $h] = getimagesize($user_avatar);
  1838. $user_avatar = $this->test($user_avatar, $save_root, $w, $h);
  1839. $avatar_dst = @(new \claviska\SimpleImage($user_avatar));
  1840. //裁剪头像
  1841. $avatar_dst->resize($avatar_w, $avatar_h);
  1842. //将头像添加到背景图
  1843. $qrcode_bg_dst->overlay($avatar_dst, 'top left', 1, $avatar_x, $avatar_y);
  1844. }
  1845. // 添加横线
  1846. $qrcode_bg_dst->rectangle(27,330, 617,330, $option['color']);
  1847. //附加用户昵称
  1848. $font = 46;
  1849. $font_x = 27;
  1850. $font_y = 200;
  1851. if ($font_x >= 0 && $font_x <= 642 && $font_y >= 0 && $font_y <= 698) {
  1852. $qrcode_bg_dst->text('我是' . get_saas_user()->name, [
  1853. 'fontFile' => $font_path,
  1854. 'size' => $font,
  1855. 'color' => $option['color'],
  1856. 'anchor' => 'top left',
  1857. 'xOffset' => $font_x,
  1858. 'yOffset' => $font_y,
  1859. ]);
  1860. $qrcode_bg_dst->text($option['title'] ?: '代言真的有钱赚!', [
  1861. 'fontFile' => $font_path,
  1862. 'size' => 28,
  1863. 'color' => $option['color'],
  1864. 'anchor' => 'top left',
  1865. 'xOffset' => 27,
  1866. 'yOffset' => 260,
  1867. ]);
  1868. $qrcode_bg_dst->text('扫描二维码', [
  1869. 'fontFile' => $font_path,
  1870. 'size' => 28,
  1871. 'color' => $option['color'],
  1872. 'anchor' => 'top left',
  1873. 'xOffset' => 27,
  1874. 'yOffset' => 560,
  1875. ]);
  1876. $qrcode_bg_dst->text($option['content'] ?: '和我一起赚钱', [
  1877. 'fontFile' => $font_path,
  1878. 'size' => 28,
  1879. 'color' => $option['color'],
  1880. 'anchor' => 'top left',
  1881. 'xOffset' => 27,
  1882. 'yOffset' => 600,
  1883. ]);
  1884. }
  1885. $share_box_bg_dst->overlay($qrcode_bg_dst, 'center top', 1, 0, 71, true);
  1886. //保存图片
  1887. $share_box_bg_dst->toFile($save_root . $save_name, 'image/jpeg', 100);
  1888. //删除临时图片
  1889. unlink($share_image);
  1890. unlink($user_avatar);
  1891. unlink($wxapp_qrcode_file_path);
  1892. return [
  1893. 'code' => 0,
  1894. 'msg' => 'success',
  1895. 'page' => $page ?? $scene,
  1896. 'data' => [
  1897. 'data' => (new StorageForm())->local2cloudLink($save_root . $save_name) ?? $pic_url . '?v=' . time(),
  1898. 'background' => $option['backgroundImage']
  1899. ]
  1900. ];
  1901. }
  1902. public function createRoundedImage($width, $height, $color_hex, $radius, $share_image) {
  1903. // 创建空白图像
  1904. $image = imagecreatetruecolor($width, $height);
  1905. // 将十六进制颜色转换为RGB
  1906. $color = imagecolorallocate($image, $color_hex['red'], $color_hex['green'], $color_hex['blue']);
  1907. // 透明背景(如果需要)
  1908. $transparent = imagecolorallocatealpha($image, 0, 0, 0, 127);
  1909. imagefill($image, 0, 0, $transparent);
  1910. imagesavealpha($image, true);
  1911. // 绘制圆角矩形
  1912. imagefilledrectangle($image, $radius, 0, $width - $radius - 1, $height - 1, $color);
  1913. imagefilledrectangle($image, 0, $radius, $width - 1, $height - $radius - 1, $color);
  1914. // 绘制四个角的圆
  1915. imagefilledellipse($image, $radius, $radius, $radius * 2, $radius * 2, $color);
  1916. imagefilledellipse($image, $width - $radius - 1, $radius, $radius * 2, $radius * 2, $color);
  1917. imagefilledellipse($image, $radius, $height - $radius - 1, $radius * 2, $radius * 2, $color);
  1918. imagefilledellipse($image, $width - $radius - 1, $height - $radius - 1, $radius * 2, $radius * 2, $color);
  1919. // 输出图像
  1920. imagepng($image, $share_image);
  1921. }
  1922. /**
  1923. * 专题海报
  1924. * @return [type] [description]
  1925. */
  1926. public function topic_qrcode()
  1927. {
  1928. $goods = Topic::findOne($this->goods_id);
  1929. if (!$goods) {
  1930. return [
  1931. 'code' => 1,
  1932. 'msg' => '专题不存在',
  1933. ];
  1934. }
  1935. $store_name = UserCenterForm::get(OptionSetting::STORE_NAME, get_store_id(), 'store');
  1936. $goods_pic_url = $goods->qrcode_pic ? $goods->qrcode_pic : $goods->cover_pic;
  1937. $goods_pic_save_path = \Yii::$app->basePath . '/web/temp/';
  1938. $version = cyy_version();
  1939. $goods_pic_save_name = md5("v={$version}&goods_id={$goods->id}&goods_name={$goods->title}&store_name={$store_name}&user_id={$this->user_id}&goods_pic_url={$goods_pic_url}&type=0") . '.jpg';
  1940. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/web/temp/' . $goods_pic_save_name);
  1941. if (file_exists($goods_pic_save_path . $goods_pic_save_name)) {
  1942. return [
  1943. 'code' => 0,
  1944. 'data' => [
  1945. 'goods_name' => $goods->title,
  1946. 'pic_url' => (new StorageForm())->local2cloudLink($goods_pic_save_path . $goods_pic_save_name) ?? $pic_url . '?v=' . time(),
  1947. ],
  1948. ];
  1949. }
  1950. $goods_pic_path = $this->saveTempImage($goods_pic_url);
  1951. if (!$goods_pic_path) {
  1952. return [
  1953. 'code' => 1,
  1954. 'msg' => '获取海报失败:显示图片丢失',
  1955. ];
  1956. }
  1957. $goods_qrcode_dst = \Yii::$app->basePath . '/web/v1/statics/images/goods-qrcode-dst.jpg';
  1958. $font_path = \Yii::$app->basePath . '/web/v1/statics/font/AaBanSong.ttf';
  1959. $bargain_hb_down = \Yii::$app->basePath . '/web/v1/statics/images/topic-hb-down.png';
  1960. $goods_qrcode = @(new \claviska\SimpleImage($goods_qrcode_dst));
  1961. $goods_pic = @(new \claviska\SimpleImage($goods_pic_path));
  1962. $goods_down = @(new \claviska\SimpleImage($bargain_hb_down));
  1963. //获取小程序码图片
  1964. if (is_h5()) {
  1965. // 如果是h5环境,就生成普通二维码
  1966. $page = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/h5/#/other/special/topic?id=' . $goods->id . 'store_id=' . $this->store_id . '&user_id=' . $this->user_id);
  1967. $wxapp_qrcode_file_res = $this->getQrcode(null, 240, $page);
  1968. } else {
  1969. $scene = "gid:{$goods->id},uid:{$this->user_id},store:{$this->store_id}";
  1970. $wxapp_qrcode_file_res = $this->getQrcode($scene, 240, "other/special/special");
  1971. }
  1972. if (!isset($wxapp_qrcode_file_res['root_path'])) {
  1973. unlink($goods_pic_path);
  1974. return [
  1975. 'code' => 1,
  1976. 'msg' => '获取专题海报失败:获取小程序码失败',
  1977. ];
  1978. }
  1979. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  1980. $wxapp_qrcode = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  1981. $name_size = 25;
  1982. $name_width = 670;
  1983. //专题标题
  1984. $name = $this->autowrap($name_size, 0, $font_path, $goods->title, $name_width, 2);
  1985. $search = ['“', '”', ':', '’', '‘'];
  1986. $name = str_replace($search, '', $name);
  1987. $goods_qrcode->text($name, [
  1988. 'fontFile' => $font_path,
  1989. 'size' => $name_size,
  1990. 'color' => '#353535',
  1991. 'anchor' => 'top left',
  1992. 'xOffset' => 40,
  1993. 'yOffset' => 48,
  1994. ]);
  1995. //专题图片
  1996. $goods_pic->resize(670, 394);
  1997. $goods_qrcode->overlay($goods_pic, 'top center', 1, 0, 178);
  1998. //专题浏览
  1999. $read = $goods->virtual_read_count + $goods->read_count;
  2000. if ($read > 10000) {
  2001. $read = ($read / 10000) . '万+人浏览';
  2002. } else {
  2003. $read = $read . '人浏览';
  2004. }
  2005. $goods_qrcode->text($read, [
  2006. 'fontFile' => $font_path,
  2007. 'size' => 20,
  2008. 'color' => '#919191',
  2009. 'anchor' => 'top left',
  2010. 'xOffset' => 40,
  2011. 'yOffset' => 604,
  2012. ]);
  2013. //专题内容
  2014. $content = strip_tags($goods->content);
  2015. $content = str_replace(array("\r\n", "\r", "\n", "&nbsp;", " "), "", $content);
  2016. $content = $this->autowrap($name_size, 0, $font_path, $content, $name_width, 2);
  2017. $content = str_replace($search, '', $content);
  2018. $goods_qrcode->text($content, [
  2019. 'fontFile' => $font_path,
  2020. 'size' => $name_size,
  2021. 'color' => '#353535',
  2022. 'anchor' => 'top left',
  2023. 'xOffset' => 40,
  2024. 'yOffset' => 660,
  2025. ]);
  2026. $goods_qrcode->text('打开小程序阅读全文', [
  2027. 'fontFile' => $font_path,
  2028. 'size' => $name_size,
  2029. 'color' => '#f87c21',
  2030. 'anchor' => 'top left',
  2031. 'xOffset' => 260,
  2032. 'yOffset' => 768,
  2033. ]);
  2034. //调整小程序码图片
  2035. $goods_down->resize(24, 14);
  2036. //附加小程序码图片
  2037. $goods_qrcode->overlay($goods_down, 'top center', 1, 0, 810);
  2038. //加商城名称
  2039. $goods_qrcode->text($store_name, [
  2040. 'fontFile' => $font_path,
  2041. 'size' => 20,
  2042. 'color' => '#888888',
  2043. 'anchor' => 'top left',
  2044. 'xOffset' => 40,
  2045. 'yOffset' => 1170,
  2046. ]);
  2047. //调整小程序码图片
  2048. $wxapp_qrcode->resize(240, 240);
  2049. //附加小程序码图片
  2050. $goods_qrcode->overlay($wxapp_qrcode, 'top left', 1, 470, 1040);
  2051. //保存图片
  2052. $goods_qrcode->toFile($goods_pic_save_path . $goods_pic_save_name, 'image/jpeg', 85);
  2053. //删除临时图片
  2054. unlink($goods_pic_path);
  2055. unlink($wxapp_qrcode_file_path);
  2056. return [
  2057. 'code' => 0,
  2058. 'data' => [
  2059. 'goods_name' => $goods->title,
  2060. 'pic_url' => (new StorageForm())->local2cloudLink($goods_pic_save_path . $goods_pic_save_name) ?? $pic_url . '?v=' . time(),
  2061. ],
  2062. ];
  2063. }
  2064. //获取网络图片到临时目录
  2065. private function saveTempImage($url)
  2066. {
  2067. if (strpos($url,'http') === false) {
  2068. $url = 'http:'. trim($url);
  2069. }
  2070. if (!is_dir(\Yii::$app->runtimePath . '/image')) {
  2071. mkdir(\Yii::$app->runtimePath . '/image');
  2072. }
  2073. $save_path = \Yii::$app->runtimePath . '/image/' . md5($url) . '.jpg';
  2074. CurlHelper::download($url, $save_path);
  2075. return $save_path;
  2076. }
  2077. //生成圆角图片
  2078. public function test($url, $path = './', $w, $h, $is_true = 'true')
  2079. {
  2080. $original_path = $url;
  2081. $dest_path = $path . uniqid('r', true) . '.png';
  2082. $src = @imagecreatefromstring(file_get_contents($original_path));
  2083. if ($is_true == 'true') {
  2084. $newpic = imagecreatetruecolor($w, $h);
  2085. imagealphablending($newpic, false);
  2086. $transparent = imagecolorallocatealpha($newpic, 0, 0, 0, 127);
  2087. $r = $w / 2;
  2088. for ($x = 0; $x < $w; $x++) {
  2089. for ($y = 0; $y < $h; $y++) {
  2090. $c = imagecolorat($src, $x, $y);
  2091. $_x = $x - $w / 2;
  2092. $_y = $y - $h / 2;
  2093. if ((($_x * $_x) + ($_y * $_y)) < ($r * $r)) {
  2094. imagesetpixel($newpic, $x, $y, $c);
  2095. } else {
  2096. imagesetpixel($newpic, $x, $y, $transparent);
  2097. }
  2098. }
  2099. }
  2100. imagesavealpha($newpic, true);
  2101. imagepng($newpic, $dest_path);
  2102. imagedestroy($newpic);
  2103. imagedestroy($src);
  2104. unlink($url);
  2105. } else {
  2106. imagesavealpha($src, true);
  2107. imagepng($src, $dest_path);
  2108. unlink($url);
  2109. }
  2110. return $dest_path;
  2111. }
  2112. /**
  2113. * @param integer $fontsize 字体大小
  2114. * @param integer $angle 角度
  2115. * @param string $fontface 字体名称
  2116. * @param string $string 字符串
  2117. * @param integer $width 预设宽度
  2118. */
  2119. private function autowrap($fontsize, $angle, $fontface, $string, $width, $max_line = null)
  2120. {
  2121. // 这几个变量分别是 字体大小, 角度, 字体名称, 字符串, 预设宽度
  2122. $content = "";
  2123. // 将字符串拆分成一个个单字 保存到数组 letter 中
  2124. $letter = [];
  2125. for ($i = 0; $i < mb_strlen($string, 'UTF-8'); $i++) {
  2126. $letter[] = mb_substr($string, $i, 1, 'UTF-8');
  2127. }
  2128. $line_count = 0;
  2129. foreach ($letter as $l) {
  2130. $teststr = $content . " " . $l;
  2131. $testbox = imagettfbbox($fontsize, $angle, $fontface, $teststr);
  2132. // 判断拼接后的字符串是否超过预设的宽度
  2133. if (($testbox[2] > $width) && ($content !== "")) {
  2134. $line_count++;
  2135. if ($max_line && $line_count >= $max_line) {
  2136. $content = mb_substr($content, 0, -1, 'UTF-8') . "...";
  2137. break;
  2138. }
  2139. $content .= PHP_EOL;
  2140. }
  2141. $content .= $l;
  2142. }
  2143. return $content;
  2144. }
  2145. /**
  2146. * @param integer $fontsize 字体大小
  2147. * @param integer $angle 角度
  2148. * @param string $fontface 字体名称
  2149. * @param string $string 字符串
  2150. * @param integer $width 预设宽度
  2151. */
  2152. public function setName($text)
  2153. {
  2154. if (mb_strlen($text, 'UTF-8') > 8) {
  2155. $text = mb_substr($text, 0, 8, 'UTF-8') . '...';
  2156. }
  2157. return $text;
  2158. }
  2159. private function getQrcode($scene, $width = 240, $page = null)
  2160. {
  2161. if (is_alipay_platform()) {
  2162. $res = ShareQrcode::getAlipayQrcode($page ?: 'pages/home/home', $scene);
  2163. if (empty($res['code']) || $res['code'] != 10000) {
  2164. return $res;
  2165. }
  2166. $res['url_path'] = $res['qr_code_url_circle_blue'];
  2167. return $res;
  2168. } else {
  2169. return ShareQrcode::wxQrcode($page, $scene, $width);
  2170. }
  2171. }
  2172. /**
  2173. * 作品海报
  2174. */
  2175. public function video_goods_qrcode()
  2176. {
  2177. if (!$this->vl_id) {
  2178. return [
  2179. 'code' => 1,
  2180. 'msg' => '未知的作品'
  2181. ];
  2182. }
  2183. $video_goods = VideoGoodsList::findOne($this->vl_id);
  2184. if (!$video_goods) {
  2185. return [
  2186. 'code' => 1,
  2187. 'msg' => '商品不存在',
  2188. ];
  2189. }
  2190. $goods_pic_url = $video_goods->cover_pic ?: \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/video_goods_cover.jpg';
  2191. $goods_pic_save_path = \Yii::$app->basePath . '/web/temp/';
  2192. $version = cyy_version();
  2193. $goods_pic_save_name = md5("v={$version}&vl_id={$video_goods->id}&user_id={$this->user_id}&goods_pic_url={$goods_pic_url}") . '.jpg';
  2194. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $goods_pic_save_name);
  2195. if (file_exists($goods_pic_save_path . $goods_pic_save_name)) {
  2196. return [
  2197. 'code' => 0,
  2198. 'data' => [
  2199. 'pic_url' => (new StorageForm())->local2cloudLink($goods_pic_save_path . $goods_pic_save_name) ?? $pic_url . '?v=' . time(),
  2200. ],
  2201. ];
  2202. }
  2203. $goods_pic_path = $this->saveTempImage($goods_pic_url);
  2204. if (!$goods_pic_path) {
  2205. return [
  2206. 'code' => 1,
  2207. 'msg' => '获取商品海报失败:商品图片丢失',
  2208. ];
  2209. }
  2210. $goods_qrcode_dst = \Yii::$app->basePath . '/web/v1/statics/images/video-goods-qrcode-bg.jpg';
  2211. $font_path = \Yii::$app->basePath . '/web/v1/statics/font/AaBanSong.ttf';
  2212. $goods_qrcode = @(new \claviska\SimpleImage($goods_qrcode_dst));
  2213. $goods_pic = @(new \claviska\SimpleImage($goods_pic_path));
  2214. //获取小程序码图片
  2215. $scene = "vid:{$video_goods->id},uid:{$this->user_id},store:{$this->store_id}";
  2216. if ($video_goods->type == 1) {
  2217. $wxapp_qrcode_file_res = $this->getQrcode($scene, 240, "videoGoods/videoDetails/index");
  2218. } else {
  2219. $wxapp_qrcode_file_res = $this->getQrcode($scene, 240, "videoGoods/imgDetails/index");
  2220. }
  2221. if (!isset($wxapp_qrcode_file_res['root_path'])) {
  2222. unlink($goods_pic_path);
  2223. return [
  2224. 'code' => 1,
  2225. 'msg' => '获取商品海报失败:获取小程序码失败',
  2226. ];
  2227. }
  2228. $wxapp_qrcode_file_path = $wxapp_qrcode_file_res['root_path'];
  2229. $wxapp_qrcode = @(new \claviska\SimpleImage($wxapp_qrcode_file_path));
  2230. $name_size = 23;
  2231. $name_width = 630;
  2232. // 标题处理换行
  2233. $name = $this->autowrap($name_size, 0, $font_path, mb_substr($video_goods->title, 0, 36, 'utf-8') . '...', $name_width, 2);
  2234. // 标题
  2235. $goods_qrcode->text($name, [
  2236. 'fontFile' => $font_path,
  2237. 'size' => $name_size,
  2238. 'color' => '#333333',
  2239. 'anchor' => 'top left',
  2240. 'xOffset' => 40,
  2241. 'yOffset' => 800,
  2242. ]);
  2243. $content_name_size = 17;
  2244. $content_name_width = 630;
  2245. // 内容处理换行
  2246. $content = $this->autowrap($content_name_size, 0, $font_path, mb_substr($video_goods->content, 0, 100, 'utf-8') . '...', $content_name_width, 5);
  2247. // 内容
  2248. $goods_qrcode->text($content, [
  2249. 'fontFile' => $font_path,
  2250. 'size' => $content_name_size,
  2251. 'color' => '#bbb',
  2252. 'anchor' => 'top left',
  2253. 'xOffset' => 40,
  2254. 'yOffset' => 890,
  2255. ]);
  2256. // 加载图片
  2257. // 获取原始图片的宽度和高度
  2258. $original_width = $goods_pic->getWidth();
  2259. $original_height = $goods_pic->getHeight();
  2260. // 设置目标宽度(保持不变)
  2261. $targetWidth = 750; // 例如,宽度保持为 800 像素
  2262. // 计算新的高度以保持宽高比
  2263. $targetHeight = round(($targetWidth / $original_width) * $original_height);
  2264. //裁剪商品图片
  2265. $goods_pic->resize($targetWidth, $targetHeight);
  2266. // 获取调整后的图像宽度和高度
  2267. $resizedWidth = $goods_pic->getWidth();
  2268. $resizedHeight = $goods_pic->getHeight();
  2269. // 设置最终的目标高度
  2270. $finalHeight = 900; // 例如,最终高度为 600 像素
  2271. // 计算剪裁的起始位置
  2272. $cropX = 0; // 宽度不变,不需要剪裁
  2273. $cropY = max(0, ($resizedHeight - $finalHeight) / 2); // 居中剪裁
  2274. // 剪裁图像
  2275. $goods_pic->crop($cropX, $cropY, $targetWidth, $finalHeight);
  2276. //附加商品图片
  2277. $goods_qrcode->overlay($goods_pic, 'top left', 1, 0, 0);
  2278. //调整小程序码图片
  2279. $wxapp_qrcode->resize(240, 240);
  2280. //附加小程序码图片
  2281. $goods_qrcode->overlay($wxapp_qrcode, 'top left', 1, 500, 765);
  2282. //保存图片
  2283. $goods_qrcode->toFile($goods_pic_save_path . $goods_pic_save_name, 'image/jpeg', 100);
  2284. //删除临时图片
  2285. unlink($goods_pic_path);
  2286. unlink($wxapp_qrcode_file_path);
  2287. return [
  2288. 'code' => 0,
  2289. 'data' => [
  2290. 'pic_url' => (new StorageForm())->local2cloudLink($goods_pic_save_path . $goods_pic_save_name) ?? $pic_url . '?v=' . time(),
  2291. ],
  2292. ];
  2293. }
  2294. }