519 lines
22 KiB
PHP
519 lines
22 KiB
PHP
<?php
|
|
|
|
namespace app\frontend\modules\member\controllers;
|
|
|
|
use app\common\components\ApiController;
|
|
use app\common\facades\Setting;
|
|
use app\common\helpers\ImageHelper;
|
|
use app\common\services\MiniFileLimitService;
|
|
use app\common\services\Utils;
|
|
use app\frontend\models\Member;
|
|
use app\frontend\modules\member\models\MemberModel;
|
|
use Yunshop\NewPoster\services\CreateCode;
|
|
use Yunshop\Poster\models\Poster;
|
|
use Yunshop\Poster\models\PosterRecord;
|
|
use GuzzleHttp\Client;
|
|
|
|
class QrcodeController extends ApiController
|
|
{
|
|
protected $type;
|
|
protected $host;
|
|
protected $uid;
|
|
protected $posterModel;
|
|
protected $memberModel;
|
|
protected $poster_id;
|
|
|
|
const WE_CHAT_SHOW_QR_CODE_URL = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=';
|
|
|
|
/**
|
|
* 会员中心推广二维码(包含会员是否有生成海报权限)
|
|
* @return \Illuminate\Http\JsonResponse
|
|
* @throws \app\common\exceptions\AppException
|
|
*/
|
|
public function getPoster()
|
|
{
|
|
$this->type = intval(request()->type) == 2?2:1;
|
|
$this->host = $host = request()->getSchemeAndHttpHost();
|
|
$this->uid = \YunShop::app()->getMemberId();
|
|
$is_agent = Member::current()->yzMember->is_agent;
|
|
$this->memberModel = $memberModel = Member::uniacid()
|
|
->select('uid', 'avatar', 'nickname')
|
|
->with('yzMember')
|
|
->ofUid($this->uid)
|
|
->first();
|
|
//新海报
|
|
if (\YunShop::plugin()->get('new-poster')) {
|
|
$this->type = intval(request()->type);
|
|
$this->poster_id = intval(request()->poster_id);
|
|
|
|
if ($this->poster_id) {
|
|
$this->posterModel = $posterModel = \Yunshop\NewPoster\models\Poster::uniacid()
|
|
->where('id',$this->poster_id)
|
|
->first();
|
|
} else {
|
|
$this->posterModel = $posterModel = \Yunshop\NewPoster\models\Poster::uniacid()
|
|
->whereRaw('FIND_IN_SET('.$this->type.',center_show)')
|
|
->first();
|
|
}
|
|
|
|
if (!$this->posterModel) {
|
|
//默认二维码
|
|
if ($this->createPoster()) {
|
|
return $this->successJson('ok', [
|
|
'image_url' => $this->createPoster(),
|
|
'center_show'=> '0'
|
|
]);
|
|
} else {
|
|
return $this->errorJson('生成海报失败');
|
|
}
|
|
}
|
|
$this->type = $this->posterModel->poster_type; //取海报的类型
|
|
$file_name = $this->getFileName($this->posterModel, $this->type, true);
|
|
$posterRecord = \Yunshop\NewPoster\models\PosterRecord::where([
|
|
'member_id' => $this->uid,
|
|
'poster_type' => $this->type,
|
|
'poster_id' => $this->posterModel->id
|
|
])->orderby('id', 'desc')->first();
|
|
if ($posterRecord) {
|
|
$file_res = strstr($posterRecord->url, $file_name);
|
|
if ($file_res) {
|
|
return $this->successJson('ok', [
|
|
'image_url' => $posterRecord->url.'?='.str_random(6),
|
|
'center_show'=> '0',
|
|
]);
|
|
}
|
|
}
|
|
if ($posterModel->is_ago == 0) {
|
|
return $this->successJson('ok', [
|
|
'image_url' => '',
|
|
'center_show'=> '2',
|
|
'poster_id' => $posterModel->id,
|
|
]);
|
|
}
|
|
if ($posterModel->is_open || (!$posterModel->is_open && $is_agent)) {
|
|
$poster_style = json_decode($posterModel['style_data'], true);
|
|
foreach ($poster_style as &$item) {
|
|
$item = $this->getRealParams($item);
|
|
switch ($item['type']) {
|
|
case 'head' :
|
|
$item['src'] = ImageHelper::fix_wechatAvatar($memberModel->avatar_image);
|
|
break;
|
|
case 'nickname' :
|
|
$item['src'] = $memberModel->nickname;
|
|
break;
|
|
case 'qr' :
|
|
$item['src'] = $this->qrByType($item, $this->type); //$type 海报类型
|
|
break;
|
|
case 'img' :
|
|
$item['src'] = yz_tomedia($item['src']);
|
|
break;
|
|
case 'invite' :
|
|
$item['src'] = $this->memberModel->yzMember->invite_code;
|
|
break;
|
|
case 'mid' :
|
|
$item['src'] = $this->memberModel->uid;
|
|
break;
|
|
case 'shopqr' :
|
|
$item['src'] = $this->qrByType($item, 5);
|
|
break;
|
|
}
|
|
}
|
|
$posterModel['style_data'] = $poster_style;
|
|
$posterModel['background'] = yz_tomedia($posterModel['background']);
|
|
$posterModel['new'] = true;
|
|
$posterModel['center_show'] = 1;
|
|
return $this->successJson('ok', $posterModel);
|
|
}
|
|
}
|
|
//旧海报
|
|
if (\YunShop::plugin()->get('poster') && \Schema::hasColumn('yz_poster', 'center_show')) {
|
|
$posterModel = Poster::uniacid()->where('center_show', 1)->first();
|
|
if (!$posterModel) {
|
|
//默认二维码
|
|
if ($this->createPoster()) {
|
|
return $this->successJson('ok', [
|
|
'image_url' => $this->createPoster(),
|
|
'center_show'=> '0'
|
|
]);
|
|
} else {
|
|
return $this->errorJson('生成海报失败');
|
|
}
|
|
}
|
|
$file_name = $this->getFileName($posterModel, $this->type, false);
|
|
$posterRecord = PosterRecord::where([
|
|
'member_id'=>$this->uid,
|
|
'poster_id'=>$posterModel->id,
|
|
])->orderby('id', 'desc')->first();
|
|
if ($posterRecord) {
|
|
$file_res = strstr($posterRecord->url, $file_name);
|
|
if ($file_res) {
|
|
return $this->successJson('ok', [
|
|
'image_url' => $posterRecord->url.'?='.str_random(6),
|
|
'center_show'=> '0',
|
|
]);
|
|
}
|
|
}
|
|
//判断是否由后台生成海报 0后台生成海报 1前端生成
|
|
if ($posterModel->is_ago == 0) {
|
|
return $this->successJson('ok', [
|
|
'image_url' => '',
|
|
'center_show'=> '2'
|
|
]);
|
|
}
|
|
if ($posterModel->is_open || (!$posterModel->is_open && $is_agent)) {
|
|
$poster_info = $posterModel->toArray();
|
|
$params = json_decode($poster_info['style_data'], true);
|
|
foreach ($params as $key => $item) {
|
|
$item = $this->getRealParams($item);
|
|
switch ($item['type']) {
|
|
case 'head':
|
|
$item['src'] = ImageHelper::fix_wechatAvatar($memberModel->avatar_image);
|
|
break;
|
|
case 'qr_shop':
|
|
$item['src'] = $host . yzAppUrl('home', ['mid' => $this->memberModel->uid]);
|
|
break;
|
|
case 'qr_app_share':
|
|
$item['src'] = $host . yzAppUrl('member/scaneditmobile', ['mid' => $this->memberModel->uid , 'app_type' => 7]);
|
|
break;
|
|
case 'nickname':
|
|
$item['src'] = $memberModel->nickname;
|
|
break;
|
|
case 'img':
|
|
$item['src'] = yz_tomedia($item['src']);
|
|
break;
|
|
}
|
|
$params[$key] = $item;
|
|
}
|
|
$poster_info['style_data'] = $params;
|
|
$poster_info['new'] = false;
|
|
if ($poster_info) {
|
|
return $this->successJson('ok', $poster_info);
|
|
}
|
|
}
|
|
}
|
|
//默认二维码
|
|
if ($this->createPoster()) {
|
|
return $this->successJson('ok', ['image_url' => $this->createPoster(),'center_show'=> '0']);
|
|
} else {
|
|
return $this->errorJson('生成二维码失败');
|
|
}
|
|
}
|
|
/**
|
|
* 海报记录接口
|
|
*/
|
|
public function posterRecord()
|
|
{
|
|
$image_url = request()->image;
|
|
$poster_id = request()->poster_id;
|
|
$is_new = request()->is_new;
|
|
$uid = \YunShop::app()->getMemberId();
|
|
if (!$image_url || !$poster_id) {
|
|
return $this->errorJson('缺少参数');
|
|
}
|
|
if (app('plugins')->isEnabled('new-poster') && $is_new) {
|
|
$poster = \Yunshop\NewPoster\models\Poster::find($poster_id);
|
|
$poster_record = \Yunshop\NewPoster\models\PosterRecord::where([
|
|
'poster_type' => $poster->poster_type,
|
|
'url' => $image_url,
|
|
])->orderBy('id', 'desc')->first();
|
|
if ($poster_record) {
|
|
$poster_record->url = $image_url;
|
|
$poster_record->save();
|
|
} else {
|
|
$data = [
|
|
'url' => $image_url,
|
|
'poster_id' => $poster_id,
|
|
'member_id' => $uid,
|
|
'poster_type' => $poster->poster_type,
|
|
'created_at' => time(),
|
|
];
|
|
\Yunshop\NewPoster\models\PosterRecord::create($data);
|
|
}
|
|
}
|
|
if (app('plugins')->isEnabled('poster') && !$is_new) {
|
|
$poster_record = PosterRecord::where(['url'=>$image_url])->orderBy('id', 'desc')->first();
|
|
if ($poster_record) {
|
|
$poster_record->url = $image_url;
|
|
$poster_record->save();
|
|
} else {
|
|
$data = [
|
|
'url' => $image_url,
|
|
'poster_id' => $poster_id,
|
|
'member_id' => $uid,
|
|
'created_at' => time(),
|
|
];
|
|
PosterRecord::create($data);
|
|
}
|
|
}
|
|
return $this->successJson('成功');
|
|
}
|
|
/**
|
|
* 生成默认海报
|
|
* @return string
|
|
*/
|
|
private function createPoster()
|
|
{
|
|
$width = 320;
|
|
$height = 540;
|
|
$logo_width = 40;
|
|
$logo_height = 40;
|
|
$font_size = 15;
|
|
$font_size_show = 20;
|
|
$member_id = \YunShop::app()->getMemberId();
|
|
$shopInfo = Setting::get('shop.shop');
|
|
$shopName = $shopInfo['name'] ?: '商城'; //todo 默认值需要更新
|
|
$shopLogo = $shopInfo['logo'] ? replace_yunshop(yz_tomedia($shopInfo['logo'])) : base_path() . '/static/images/logo.png'; //todo 默认值需要更新
|
|
$shopImg = $shopInfo['signimg'] ? replace_yunshop(yz_tomedia($shopInfo['signimg'])) : base_path() . '/static/images/photo-mr.jpg'; //todo 默认值需要更新
|
|
$str_lenght = $logo_width + $font_size_show * mb_strlen($shopName);
|
|
$space = ($width - $str_lenght) / 2;
|
|
$uniacid = \YunShop::app()->uniacid;
|
|
$path = storage_path('app/public/personalposter/' . $uniacid);
|
|
Utils::mkdirs($path);
|
|
$md5 = md5($member_id . $shopInfo['name'] . $shopInfo['logo'] . $shopInfo['signimg'] . $this->type . '2'); //用于标识组成元素是否有变化
|
|
$extend = '.png';
|
|
$file = $md5 . $extend;
|
|
if (!file_exists($path . '/' . $file)) {
|
|
$targetImg = imagecreatetruecolor($width, $height);
|
|
$white = imagecolorallocate($targetImg, 255, 255, 255);
|
|
imagefill($targetImg, 0, 0, $white);
|
|
$imgSource = imagecreatefromstring(\Curl::to($shopImg)->get());
|
|
$logoSource = imagecreatefromstring(\Curl::to($shopLogo)->get());
|
|
if (2 == $this->type and request()->input('ingress') == 'weChatApplet') {
|
|
$qrcode = MemberModel::getWxacode();
|
|
$qrSource = imagecreatefromstring(\Curl::to($qrcode)->get());
|
|
} else {
|
|
$qrcode = MemberModel::getAgentQR();
|
|
$qrSource = imagecreatefromstring(\Curl::to($qrcode)->get());
|
|
}
|
|
$fingerPrintImg = imagecreatefromstring(\Curl::to($this->getImgUrl('ewm.png'))->get());
|
|
$mergeData = [
|
|
'dst_left' => $space,
|
|
'dst_top' => 10,
|
|
'dst_width' => $logo_width,
|
|
'dst_height' => $logo_height,
|
|
];
|
|
self::mergeImage($targetImg, $logoSource, $mergeData); //合并商城logo图片
|
|
$mergeData = [
|
|
'size' => $font_size,
|
|
'left' => $space + $logo_width + 10,
|
|
'top' => 37,
|
|
];
|
|
self::mergeText($targetImg, $shopName, $mergeData);//合并商城名称(文字)
|
|
$mergeData = [
|
|
'dst_left' => 0,
|
|
'dst_top' => 60,
|
|
'dst_width' => 320,
|
|
'dst_height' => 320,
|
|
];
|
|
self::mergeImage($targetImg, $imgSource, $mergeData); //合并商城海报图片
|
|
$mergeData = [
|
|
'dst_left' => 0,
|
|
'dst_top' => 380,
|
|
'dst_width' => 160,
|
|
'dst_height' => 160,
|
|
];
|
|
self::mergeImage($targetImg, $fingerPrintImg, $mergeData); //合并指纹图片
|
|
if ($this->type == 2) {
|
|
$mergeData = [
|
|
'dst_left' => 180,
|
|
'dst_top' => 390,
|
|
'dst_width' => 120,
|
|
'dst_height' => 120,
|
|
];
|
|
} else {
|
|
$mergeData = [
|
|
'dst_left' => 160,
|
|
'dst_top' => 380,
|
|
'dst_width' => 160,
|
|
'dst_height' => 160,
|
|
];
|
|
}
|
|
self::mergeImage($targetImg, $qrSource, $mergeData); //合并二维码图片
|
|
header("Content-Type: image/png");
|
|
$imgPath = $path . "/" . $file;
|
|
imagepng($targetImg, $imgPath);
|
|
}
|
|
$file = $path . '/' . $file;
|
|
$imgUrl = ImageHelper::getImageUrl($file).'?='.str_random(6);
|
|
return $imgUrl;
|
|
}
|
|
//合并图片并指定图片大小
|
|
private static function mergeImage($destinationImg, $sourceImg, $data)
|
|
{
|
|
$w = imagesx($sourceImg);
|
|
$h = imagesy($sourceImg);
|
|
imagecopyresampled($destinationImg,$sourceImg,$data['dst_left'],$data['dst_top'],0,0,$data['dst_width'],$data['dst_height'],$w,$h);
|
|
imagedestroy($sourceImg);
|
|
return $destinationImg;
|
|
}
|
|
//合并字符串
|
|
private static function mergeText($destinationImg, $text, $data)
|
|
{
|
|
putenv('GDFONTPATH=' . base_path('static/fonts'));
|
|
$font = base_path() . DIRECTORY_SEPARATOR . "static" . DIRECTORY_SEPARATOR . "fonts" . DIRECTORY_SEPARATOR . "source_han_sans.ttf";
|
|
$black = imagecolorallocate($destinationImg, 0, 0, 0);
|
|
imagettftext($destinationImg, $data['size'], 0, $data['left'], $data['top'], $black, $font, $text);
|
|
return $destinationImg;
|
|
}
|
|
//获取图片url
|
|
private function getImgUrl($file)
|
|
{
|
|
if (config('app.framework') == 'platform') {
|
|
return request()->getSchemeAndHttpHost().'/addons/yun_shop/static/app/images/'.$file;
|
|
} else {
|
|
return base_path() . '/static/app/images/'.$file;
|
|
}
|
|
}
|
|
//处理坐标
|
|
private function getRealParams($params)
|
|
{
|
|
$params['left'] = intval(str_replace('px', '', $params['left'])) * 2;
|
|
$params['top'] = intval(str_replace('px', '', $params['top'])) * 2;
|
|
$params['width'] = intval(str_replace('px', '', $params['width'])) * 2;
|
|
$params['height'] = intval(str_replace('px', '', $params['height'])) * 2;
|
|
$params['size'] = intval(str_replace('px', '', $params['size'])) * 2;
|
|
$params['src'] = yz_tomedia($params['src']);
|
|
return $params;
|
|
}
|
|
//根据type获取各类二维码
|
|
protected function qrByType($item, $type)
|
|
{
|
|
switch ($type) {
|
|
case 1 :
|
|
$url = $this->getQrCodeUrl();
|
|
break;
|
|
case 2 :
|
|
$url = $this->getMiniCode($item['mini_link']);
|
|
break;
|
|
case 5 :
|
|
$url = $this->getQrShopImage($item['h5_link']);
|
|
break;
|
|
case 7 :
|
|
$url = $this->getAppShareImage();
|
|
break;
|
|
default :
|
|
$url = '';
|
|
break;
|
|
}
|
|
return $url;
|
|
}
|
|
//关注二维码
|
|
protected function getQrCodeUrl()
|
|
{
|
|
$client = new Client;
|
|
$res = $client->request('GET', (new CreateCode($this->memberModel, $this->posterModel, $this->host))->getQrCodeUrl());
|
|
$extend = 'png';
|
|
$filename = 'fans_' . \YunShop::app()->uniacid . '_' . \YunShop::app()->getMemberId() . '.' . $extend;
|
|
$paths = \Storage::url('app/public/qr/');
|
|
$paths_change = ltrim($paths, '/');
|
|
file_put_contents(base_path($paths_change) . $filename, $res->getBody());
|
|
return $this->host . config('app.webPath') . $paths . $filename;
|
|
}
|
|
//小程序二维码
|
|
protected function getMiniCode($link)
|
|
{
|
|
$res = (new CreateCode($this->memberModel, $this->posterModel, $this->host))->getMiniCode($link);
|
|
if ($res == '') {
|
|
return '';
|
|
}
|
|
$extend = 'png';
|
|
$filename = 'mini_' . \YunShop::app()->uniacid . '_' . \YunShop::app()->getMemberId() . '.' . $extend;
|
|
$paths = \Storage::url('app/public/qr/');
|
|
$paths_change = ltrim($paths, '/');
|
|
file_put_contents(base_path($paths_change) . $filename, $res);
|
|
return $this->host . config('app.webPath') . $paths . $filename.'?v='.str_random(6);
|
|
}
|
|
//商城二维码
|
|
protected function getQrShopImage($link)
|
|
{
|
|
$res = (new CreateCode($this->memberModel, $this->posterModel, $this->host))->getQrShopImage($link);
|
|
$extend = 'png';
|
|
$filename = 'shop_' . \YunShop::app()->uniacid . '_' . \YunShop::app()->getMemberId() . '.' . $extend;
|
|
$paths = \Storage::url('app/public/qr/');
|
|
$paths_change = ltrim($paths, '/');
|
|
file_put_contents(base_path($paths_change) . $filename, $res);
|
|
return $this->host . config('app.webPath') . $paths . $filename;
|
|
}
|
|
//app二维码
|
|
protected function getAppShareImage()
|
|
{
|
|
$res = (new CreateCode($this->memberModel, $this->posterModel, $this->host))->getAppShareImage();
|
|
$extend = 'png';
|
|
$filename = 'share_' . \YunShop::app()->uniacid . '_' . \YunShop::app()->getMemberId() . '.' . $extend;
|
|
$paths = \Storage::url('app/public/qr/');
|
|
$paths_change = ltrim($paths, '/');
|
|
file_put_contents(base_path($paths_change) . $filename, $res);
|
|
return $this->host . config('app.webPath') . $paths . $filename;
|
|
}
|
|
|
|
/**
|
|
* 海报上传本地
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function uploadLocal()
|
|
{
|
|
$file = request()->file('file');
|
|
$ingress = request()->ingress;
|
|
$poster_id = request()->poster_id;
|
|
if (!$file) {
|
|
return $this->errorJson('请传入正确参数.');
|
|
}
|
|
if (!$file->isValid()) {
|
|
return $this->errorJson('上传失败.');
|
|
}
|
|
if ($ingress) {
|
|
if ($file->getClientSize() > 1024*1024) {
|
|
return $this->errorJson('小程序图片安全验证图片不能大于1M');
|
|
}
|
|
$check_result = (new MiniFileLimitService())->checkImg($file);
|
|
if ($check_result['errcode'] == 87014) {
|
|
return $this->errorJson('内容含有违法违规信息');
|
|
}
|
|
}
|
|
$realPath = $file->getRealPath(); //临时文件的绝对路径
|
|
$is_new = request()->is_new;
|
|
if ($is_new) {
|
|
$posterModel = \Yunshop\NewPoster\models\Poster::find($poster_id);
|
|
$type = $posterModel->poster_type;
|
|
} else {
|
|
$posterModel = Poster::find($poster_id);
|
|
$type = request()->type == 2 ? 2 : 1;
|
|
}
|
|
if (!$posterModel) {
|
|
return $this->errorJson('海报已删除');
|
|
}
|
|
$file_name = $this->getFileName($posterModel, $type, $is_new);
|
|
$path = storage_path('app/public/poster/' . \YunShop::app()->uniacid);
|
|
if (!file_exists($path)) {
|
|
Utils::mkdirs($path);
|
|
}
|
|
$full_path = $path . DIRECTORY_SEPARATOR . $file_name;
|
|
file_put_contents($full_path, file_get_contents($realPath));
|
|
return $this->successJson('ok', [
|
|
'img_url' => $this->getPosterUrl($file_name),
|
|
]);
|
|
}
|
|
private function getFileName($posterModel, $type, $is_new_poster)
|
|
{
|
|
$file = md5(json_encode([
|
|
'memberId' => \YunShop::app()->getMemberId(),
|
|
'posterId' => $posterModel->id,
|
|
'uniacid' => \YunShop::app()->uniacid,
|
|
'background' => $posterModel->background,
|
|
'style_data' => $posterModel->style_data,
|
|
]));
|
|
if ($is_new_poster) {
|
|
return $file.'_new_'.$type.'.png';
|
|
} else {
|
|
return $file.'_'.$type.'.png';
|
|
}
|
|
}
|
|
private function getPosterUrl($file_name)
|
|
{
|
|
if (config('app.framework') == 'platform') {
|
|
return request()->getSchemeAndHttpHost().DIRECTORY_SEPARATOR.'storage/app/public/poster/'.\YunShop::app()->uniacid.DIRECTORY_SEPARATOR.$file_name;
|
|
} else {
|
|
return request()->getSchemeAndHttpHost().DIRECTORY_SEPARATOR.'addons/yun_shop/storage/app/public/poster/'.\YunShop::app()->uniacid.DIRECTORY_SEPARATOR.$file_name;
|
|
}
|
|
}
|
|
} |