提交其他文件
This commit is contained in:
367
app/adminapi/controller/WxcodeController.php
Normal file
367
app/adminapi/controller/WxcodeController.php
Normal file
@ -0,0 +1,367 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
|
||||
// | github下载:https://github.com/likeshop-github/likeadmin
|
||||
// | 访问官网:https://www.likeadmin.cn
|
||||
// | likeadmin团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeadminTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace app\adminapi\controller;
|
||||
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\lists\WxcodeLists;
|
||||
use app\adminapi\logic\WxcodeLogic;
|
||||
use app\adminapi\validate\WxcodeValidate;
|
||||
use app\common\service\wechat\WeChatConfigService;
|
||||
use EasyWeChat\MiniApp\Application;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* Wxcode控制器
|
||||
* Class WxcodeController
|
||||
* @package app\adminapi\controller
|
||||
*/
|
||||
class WxcodeController extends BaseAdminController
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @notes 获取列表
|
||||
* @return \think\response\Json
|
||||
* @author likeadmin
|
||||
* @date 2026/03/06 13:28
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
return $this->dataLists(new WxcodeLists());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notes 添加
|
||||
* @return \think\response\Json
|
||||
* @author likeadmin
|
||||
* @date 2026/03/06 13:28
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$params = (new WxcodeValidate())->post()->goCheck('add');
|
||||
$return = $this->getWxacode($params);
|
||||
// var_dump($return);
|
||||
$result = WxcodeLogic::add($params,$return);
|
||||
if (true === $result) {
|
||||
return $this->success('添加成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(WxcodeLogic::getError());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notes 编辑
|
||||
* @return \think\response\Json
|
||||
* @author likeadmin
|
||||
* @date 2026/03/06 13:28
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$params = (new WxcodeValidate())->post()->goCheck('edit');
|
||||
$result = WxcodeLogic::edit($params);
|
||||
if (true === $result) {
|
||||
return $this->success('编辑成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(WxcodeLogic::getError());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notes 删除
|
||||
* @return \think\response\Json
|
||||
* @author likeadmin
|
||||
* @date 2026/03/06 13:28
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$params = (new WxcodeValidate())->post()->goCheck('delete');
|
||||
WxcodeLogic::delete($params);
|
||||
return $this->success('删除成功', [], 1, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notes 获取详情
|
||||
* @return \think\response\Json
|
||||
* @author likeadmin
|
||||
* @date 2026/03/06 13:28
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$params = (new WxcodeValidate())->goCheck('detail');
|
||||
$result = WxcodeLogic::detail($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
public function getWxacode($params)
|
||||
{
|
||||
try {
|
||||
// 1. 获取参数
|
||||
$scene = 'default';
|
||||
$url = 'pages/index/index';
|
||||
$width = 430;
|
||||
// 'env_version' => 'trial',
|
||||
// 'env_version' => 'develop'
|
||||
$envVersion = 'develop';
|
||||
|
||||
// 2. 参数验证
|
||||
if (strlen($scene) > 32) {
|
||||
return $this->fail('场景值不能超过32个字符');
|
||||
}
|
||||
|
||||
// 3. 获取微信配置
|
||||
$config = WeChatConfigService::getMnpConfig();
|
||||
|
||||
if (empty($config['app_id']) || empty($config['secret'])) {
|
||||
return $this->fail('微信小程序配置不完整');
|
||||
}
|
||||
|
||||
// 4. 创建微信小程序应用实例
|
||||
$app = new Application($config);
|
||||
|
||||
// 5. 使用新的方式调用:通过 createClient() 调用API
|
||||
$response = $app->createClient()->postJson('/wxa/getwxacodeunlimit', [
|
||||
'scene' => 'registerSource='.$params['type'] , // 0普通 1电梯 2充电宝
|
||||
'page' => $url,
|
||||
'width' => $width,
|
||||
'auto_color' => false,
|
||||
'line_color' => ['r' => 0, 'g' => 0, 'b' => 0],
|
||||
'is_hyaline' => false,
|
||||
'env_version' => $envVersion,
|
||||
'check_path' => false,
|
||||
]);
|
||||
|
||||
// 6. 处理响应结果
|
||||
if ($this->isImageResponse($response)) {
|
||||
// 保存到文件并返回URL
|
||||
return $this->saveQrCodeToFile($response, $scene, $url);
|
||||
} else {
|
||||
// 处理错误响应
|
||||
return $this->handleErrorResponse($response);
|
||||
}
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('生成小程序码异常:' . $e->getMessage());
|
||||
Log::error('异常追踪:' . $e->getTraceAsString());
|
||||
return $this->fail('生成失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为图片响应
|
||||
*/
|
||||
private function isImageResponse($response): bool
|
||||
{
|
||||
$contentType = $response->getHeaderLine('content-type');
|
||||
return strpos($contentType, 'image/') !== false
|
||||
|| strpos($contentType, 'application/octet-stream') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存二维码到文件
|
||||
*/
|
||||
private function saveQrCodeToFile($response, $scene, $page)
|
||||
{
|
||||
try {
|
||||
// 生成文件名
|
||||
$filename = 'wxacode_' . date('YmdHis') . '_' . substr(md5($scene . $page), 0, 8) . '.png';
|
||||
|
||||
// 保存目录
|
||||
$saveDir = public_path() . 'uploads/wxqrcode/';
|
||||
|
||||
// 确保目录存在
|
||||
if (!is_dir($saveDir)) {
|
||||
mkdir($saveDir, 0755, true);
|
||||
}
|
||||
|
||||
$savePath = $saveDir . $filename;
|
||||
|
||||
// 保存文件(新版本方式)
|
||||
$content = $response->getContent();
|
||||
file_put_contents($savePath, $content);
|
||||
|
||||
// 验证文件
|
||||
if (!file_exists($savePath) || filesize($savePath) === 0) {
|
||||
throw new \Exception('文件保存失败或为空');
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
$fileUrl = request()->domain() . '/uploads/wxqrcode/' . $filename;
|
||||
return $fileUrl;
|
||||
// return $this->success('生成成功', [
|
||||
// 'url' => $fileUrl,
|
||||
// 'path' => '/uploads/wxqrcode/' . $filename,
|
||||
// 'filename' => $filename,
|
||||
// 'file_size' => filesize($savePath),
|
||||
// 'scene' => $scene,
|
||||
// 'page' => $page,
|
||||
// ]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('保存文件失败:' . $e->getMessage());
|
||||
|
||||
// 备用方案:返回Base64
|
||||
$content = $response->getContent();
|
||||
$base64 = 'data:image/png;base64,' . base64_encode($content);
|
||||
|
||||
return $this->success('生成成功(Base64格式)', [
|
||||
'base64' => $base64,
|
||||
'scene' => $scene,
|
||||
'page' => $page,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理错误响应
|
||||
*/
|
||||
private function handleErrorResponse($response)
|
||||
{
|
||||
$content = $response->getContent();
|
||||
$data = json_decode($content, true);
|
||||
|
||||
if (JSON_ERROR_NONE === json_last_error() && isset($data['errcode'])) {
|
||||
$errorMsg = $this->getWeChatErrorMessage($data['errcode']);
|
||||
Log::error('微信接口错误:' . $errorMsg . ',数据:' . $content);
|
||||
return $this->fail('微信接口错误:' . $errorMsg);
|
||||
}
|
||||
|
||||
Log::error('未知错误响应:' . $content);
|
||||
return $this->fail('生成失败:未知的响应格式');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信错误信息
|
||||
*/
|
||||
private function getWeChatErrorMessage($errcode)
|
||||
{
|
||||
$errorMap = [
|
||||
-1 => '系统繁忙,请稍候再试',
|
||||
40001 => 'AppSecret错误或access_token无效',
|
||||
40002 => '无效的凭证类型',
|
||||
40013 => '无效的AppID',
|
||||
41030 => '页面路径不存在或有权限限制',
|
||||
45009 => '接口调用频率超限',
|
||||
85064 => '找不到该小程序',
|
||||
85065 => '小程序未发布或已下架',
|
||||
86004 => '无效的scene参数',
|
||||
87009 => '无效的页面路径',
|
||||
9401020 => '小程序未发布',
|
||||
];
|
||||
|
||||
return $errorMap[$errcode] ?? ('错误码:' . $errcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试版本 - 直接输出图片
|
||||
*/
|
||||
public function testGenerate()
|
||||
{
|
||||
try {
|
||||
$scene = $this->request->param('scene', 'test');
|
||||
$page = $this->request->param('page', 'pages/index/index');
|
||||
|
||||
$config = WeChatConfigService::getMnpConfig();
|
||||
$app = new Application($config);
|
||||
|
||||
$response = $app->createClient()->postJson('/wxa/getwxacodeunlimit', [
|
||||
'scene' => $scene,
|
||||
'page' => $page,
|
||||
'width' => 430,
|
||||
]);
|
||||
|
||||
// 直接输出图片
|
||||
header('Content-Type: ' . $response->getHeaderLine('content-type'));
|
||||
echo $response->getContent();
|
||||
exit;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return json([
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查配置和环境
|
||||
*/
|
||||
public function checkEnv()
|
||||
{
|
||||
try {
|
||||
$config = WeChatConfigService::getMnpConfig();
|
||||
|
||||
$checks = [
|
||||
'config_exists' => !empty($config),
|
||||
'app_id_exists' => !empty($config['app_id']),
|
||||
'secret_exists' => !empty($config['secret']),
|
||||
'class_exists' => class_exists('EasyWeChat\MiniApp\Application'),
|
||||
'createClient_method' => method_exists('EasyWeChat\MiniApp\Application', 'createClient'),
|
||||
];
|
||||
|
||||
// 测试创建实例
|
||||
if ($checks['class_exists']) {
|
||||
$app = new Application($config);
|
||||
$checks['instance_created'] = true;
|
||||
|
||||
// 测试获取access_token
|
||||
try {
|
||||
$accessToken = $app->getAccessToken()->getToken();
|
||||
$checks['access_token_ok'] = !empty($accessToken);
|
||||
} catch (\Exception $e) {
|
||||
$checks['access_token_error'] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success('环境检查', [
|
||||
'checks' => $checks,
|
||||
'config' => [
|
||||
'app_id' => $config['app_id'] ?? '未设置',
|
||||
'secret_set' => !empty($config['secret']),
|
||||
],
|
||||
'suggestions' => $this->getSuggestions($checks),
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->fail('检查失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function getSuggestions($checks)
|
||||
{
|
||||
$suggestions = [];
|
||||
|
||||
if (!$checks['config_exists']) {
|
||||
$suggestions[] = '配置不存在,请检查 WeChatConfigService::getMnpConfig()';
|
||||
}
|
||||
|
||||
if (!$checks['app_id_exists']) {
|
||||
$suggestions[] = '请在.env中设置 WECHAT_MINI_PROGRAM_APPID';
|
||||
}
|
||||
|
||||
if (!$checks['secret_exists']) {
|
||||
$suggestions[] = '请在.env中设置 WECHAT_MINI_PROGRAM_SECRET';
|
||||
}
|
||||
|
||||
if (!$checks['class_exists']) {
|
||||
$suggestions[] = 'EasyWeChat未安装或版本不兼容,请执行:composer require overtrue/wechat';
|
||||
}
|
||||
|
||||
return $suggestions;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user