Fastadmin中定时任务中使用epay插件,执行时报错Class 'Yansongda\Pay\Pay' not found
目录
关闭订单
因为业务需要,对未支付的订单超过2小时执行关闭订单操作需要在定时任务中执行。
在epay的Service类中新增了关闭订单方法调用Pay类中的close方法。
只需要一个商家订单号参数即可,如下:
/**
* 关闭未支付微信订单
* @param $orderNo
* @return array
* @throws \ReflectionException
* @throws \Yansongda\Artful\Exception\ContainerException
* @throws \Yansongda\Artful\Exception\InvalidParamsException
* @throws \Yansongda\Artful\Exception\ServiceNotFoundException
* @throws \Yansongda\Pay\Exception\ContainerException
* @throws \Yansongda\Pay\Exception\InvalidParamsException
* @throws \Yansongda\Pay\Exception\ServiceNotFoundException
* @throws \Yansongda\Pay\Exceptions\GatewayException
* @throws \Yansongda\Pay\Exceptions\InvalidArgumentException
* @throws \Yansongda\Pay\Exceptions\InvalidSignException
*/
public static function submitClose($orderNo)
{
// 创建对象
$config = Service::getConfig('wechat');
$pay = Pay::wechat($config);
$params = [
'out_trade_no' => $orderNo
];
$result = $pay->close($params);
return $result->toArray();
}
在接口中请求是正常的,返回如下:
Yansongda\Supports\Collection Object
(
[items:protected] => Array
(
[return_code] => SUCCESS
[return_msg] => OK
[result_code] => SUCCESS
[mch_id] => 1728831214
[appid] => wxdxxxxxxxxxxxxxx
[nonce_str] => w9jTyBrYVOQck7Yg
[sign] => FB968DD63410F25760C90E71E7B45FB3
)
)
问题
但是在定时任务中测试的时候,发现直接抛出异常,如下:

提示Class 'Yansongda\Pay\Pay' not found
排查
排查composer加载情况,设置没有问题。

经过检查,并非不能请求到epay插件,而是找不到Pay类。
在epay/library中有v2、v3、v3new三个版本的文件夹。其中都有Pay类。
且Pay类的命名空间一样。怀疑可能是命名空间一致,在接口请求中时有指定加载的版本类型。而在定时执行时没有指定命名空间,导致找不到Pay类。
在定时任务的execute方法的顶部使用了
Require_once方法直接加载v2版本的pay.php文件。
发现这种方法确实可以找到Pay类,但是又抛出了Pay类中依赖的其他类无法找到的错误。
而Pay类依赖的类和文件过多,这种方法不太行。
还有一种方法是直接更改v2版本中的所有类文件命名空间,直接指定如:
namespace Yansongda\v2\Pay;
但这种工程量太大,且更改了原有的插件接口,容易出错。
解决方法
最终通过查看epay插件的源代码在epay中的Epay类,如下:

在Epay中actionBegin方法对设置的版本进行加载命名空间处理,如下:
// 模块控制器方法加载开始
public function actionBegin()
{
//添加命名空间
if (!class_exists('\Yansongda\Pay\Pay')) {
//SDK版本
$version = Service::getSdkVersion();
$libraryDir = ADDON_PATH . 'epay' . DS . 'library' . DS;
if (PHP_VERSION_ID >= 80000 && $version == Service::SDK_VERSION_V3) {
$yansongdaDir = $libraryDir . $version . 'new' . DS . 'Yansongda' . DS;
// PHP 8.0+ 版本且为V3接口,需要加载 Artful 的命名空间
Loader::addNamespace('Yansongda\Artful', $yansongdaDir . 'Artful' . DS);
require_once $yansongdaDir . 'Artful' . DS . 'Functions.php';
} else {
$yansongdaDir = $libraryDir . $version . DS . 'Yansongda' . DS;
}
// 注册Pay命名空间
Loader::addNamespace('Yansongda\Pay', $yansongdaDir . 'Pay' . DS);
$checkArr = [
'\Hyperf\Context\Context' => 'context',
'\Hyperf\Contract\Castable' => 'contract',
'\Hyperf\Engine\Constant' => 'engine',
'\Hyperf\Macroable\Macroable' => 'macroable',
'\Hyperf\Pimple\Container' => 'pimple',
'\Hyperf\Utils\Arr' => 'utils',
];
foreach ($checkArr as $index => $item) {
if (!class_exists($index)) {
Loader::addNamespace(substr($index, 1, strrpos($index, '\\') - 1), $libraryDir . 'hyperf' . DS . $item . DS . 'src' . DS);
}
}
if (!class_exists('\Yansongda\Supports\Logger')) {
Loader::addNamespace('Yansongda\Supports', $yansongdaDir . 'Supports' . DS);
}
// V3需载入辅助函数
if ($version == Service::SDK_VERSION_V3) {
require_once $yansongdaDir . 'Pay' . DS . 'Functions.php';
}
}
}
在execute方法中的顶部手动加载epay插件命名空间
// 执行命令的逻辑
protected function execute(Input $input, Output $output)
{
// 手动初始化epay插件命名空间
(new \addons\epay\Epay)->actionBegin();
$flag = $this->wxClose('TMF2025100909430279312');
print_r($flag);die;
$output->writeln("定时订单过期任务执行成功:" . date('Y-m-d H:i:s'));
}
/**
* 关闭未支付订单
* @param $orderNo
* @return mixed|string
*/
public function wxClose($orderNo)
{
try {
$response = \addons\epay\library\Service::submitClose($orderNo);
if ($response['return_code'] == 'SUCCESS') {
return ['code' => 1];
}
return $response['return_msg'];
} catch (\Exception $e) {
return $e->getMessage();
}
}
返回不再抛出异常,正常返回:

总结
Fastadmin中定时任务中使用epay插件,执行时报错Class 'Yansongda\Pay\Pay' not found 排查及解决
865

被折叠的 条评论
为什么被折叠?



