插件管理更新

This commit is contained in:
技术老胡
2026-03-20 12:05:54 +08:00
parent f3919c9899
commit 0eee3b92c2
6 changed files with 98 additions and 38 deletions

View File

@@ -54,11 +54,11 @@ class PayPluginController extends BaseController
if ($className === '') {
// 默认约定类名
$className = 'app\\common\\payment\\' . ucfirst($pluginCode) . 'Payment';
$className = ucfirst($pluginCode) . 'Payment';
}
$this->pluginRepository->upsertByCode($pluginCode, [
'plugin_name' => $pluginName,
'name' => $pluginName,
'class_name' => $className,
'status' => $status,
]);

View File

@@ -7,28 +7,36 @@ use app\common\base\BaseModel;
/**
* 支付插件模型
*
* 对应表ma_pay_plugin主键 plugin_code
* 对应表ma_pay_plugin主键 code
*/
class PaymentPlugin extends BaseModel
{
protected $table = 'ma_pay_plugin';
protected $primaryKey = 'plugin_code';
protected $primaryKey = 'code';
public $incrementing = false;
protected $keyType = 'string';
protected $fillable = [
'plugin_code',
'plugin_name',
'code',
'name',
'class_name',
'status',
'config_schema',
'pay_types',
'transfer_types',
'author',
'link',
];
public $timestamps = true;
protected $casts = [
'status' => 'integer',
'config_schema' => 'array',
'pay_types' => 'array',
'transfer_types' => 'array',
];
}

View File

@@ -19,13 +19,20 @@ class PaymentPluginRepository extends BaseRepository
{
return $this->model->newQuery()
->where('status', 1)
->get(['plugin_code', 'class_name']);
->get([
'code',
'name',
'class_name',
'pay_types',
'transfer_types',
'config_schema',
]);
}
public function findActiveByCode(string $pluginCode): ?PaymentPlugin
{
return $this->model->newQuery()
->where('plugin_code', $pluginCode)
->where('code', $pluginCode)
->where('status', 1)
->first();
}
@@ -36,7 +43,7 @@ class PaymentPluginRepository extends BaseRepository
public function findByCode(string $pluginCode): ?PaymentPlugin
{
return $this->model->newQuery()
->where('plugin_code', $pluginCode)
->where('code', $pluginCode)
->first();
}
@@ -51,10 +58,10 @@ class PaymentPluginRepository extends BaseRepository
$query->where('status', (int)$filters['status']);
}
if (!empty($filters['plugin_code'])) {
$query->where('plugin_code', 'like', '%' . $filters['plugin_code'] . '%');
$query->where('code', 'like', '%' . $filters['plugin_code'] . '%');
}
if (!empty($filters['plugin_name'])) {
$query->where('plugin_name', 'like', '%' . $filters['plugin_name'] . '%');
$query->where('name', 'like', '%' . $filters['plugin_name'] . '%');
}
$query->orderByDesc('created_at');
@@ -69,12 +76,12 @@ class PaymentPluginRepository extends BaseRepository
$row = $this->findByCode($pluginCode);
if ($row) {
$this->model->newQuery()
->where('plugin_code', $pluginCode)
->where('code', $pluginCode)
->update($data);
return $this->findByCode($pluginCode) ?: $row;
}
$data['plugin_code'] = $pluginCode;
$data['code'] = $pluginCode;
/** @var PaymentPlugin $created */
$created = $this->create($data);
return $created;
@@ -83,7 +90,7 @@ class PaymentPluginRepository extends BaseRepository
public function updateStatus(string $pluginCode, int $status): bool
{
return (bool)$this->model->newQuery()
->where('plugin_code', $pluginCode)
->where('code', $pluginCode)
->update(['status' => $status]);
}
}

View File

@@ -31,19 +31,29 @@ class PluginService extends BaseService
$plugins = [];
foreach ($rows as $row) {
$pluginCode = $row->plugin_code;
$pluginCode = $row->code;
try {
$plugin = $this->resolvePlugin($pluginCode, $row->class_name);
$plugins[] = [
'code' => $pluginCode,
'name' => $plugin->getName(),
'supported_methods'=> $plugin->getEnabledPayTypes(),
];
} catch (\Throwable $e) {
// 忽略无法实例化的插件
continue;
$pluginName = (string)($row->name ?? '');
$supportedMethods = is_array($row->pay_types ?? null) ? (array)$row->pay_types : [];
// 如果数据库里缺少元信息,则回退到实例化插件并写回数据库
if ($pluginName === '' || $supportedMethods === []) {
try {
$plugin = $this->resolvePlugin($pluginCode, (string)($row->class_name ?? ''));
$this->syncPluginMeta($pluginCode, $plugin);
$pluginName = $plugin->getName();
$supportedMethods = (array)$plugin->getEnabledPayTypes();
} catch (\Throwable $e) {
// 忽略无法实例化的插件
continue;
}
}
$plugins[] = [
'code' => $pluginCode,
'name' => $pluginName,
'supported_methods' => $supportedMethods,
];
}
return $plugins;
@@ -54,8 +64,15 @@ class PluginService extends BaseService
*/
public function getConfigSchema(string $pluginCode, string $methodCode): array
{
$row = $this->pluginRepository->findActiveByCode($pluginCode);
if ($row && is_array($row->config_schema ?? null) && $row->config_schema !== []) {
return (array)$row->config_schema;
}
$plugin = $this->getPluginInstance($pluginCode);
return $plugin->getConfigSchema();
$schema = (array)$plugin->getConfigSchema();
$this->syncPluginMeta($pluginCode, $plugin);
return $schema;
}
/**
@@ -76,8 +93,7 @@ class PluginService extends BaseService
*/
public function buildConfigFromForm(string $pluginCode, string $methodCode, array $formData): array
{
$plugin = $this->getPluginInstance($pluginCode);
$configSchema = $plugin->getConfigSchema();
$configSchema = $this->getConfigSchema($pluginCode, $methodCode);
$configJson = [];
if (isset($configSchema['fields']) && is_array($configSchema['fields'])) {
@@ -110,7 +126,11 @@ class PluginService extends BaseService
*/
private function resolvePlugin(string $pluginCode, ?string $className = null): PaymentInterface&PayPluginInterface
{
$class = $className ?: 'app\\common\\payment\\' . ucfirst($pluginCode) . 'Payment';
$class = $className ?: (ucfirst($pluginCode) . 'Payment');
// 允许 DB 中只存短类名(如 AlipayPayment这里统一补全命名空间
if ($class !== '' && !str_contains($class, '\\')) {
$class = 'app\\common\\payment\\' . $class;
}
if (!class_exists($class)) {
throw new NotFoundException('支付插件类不存在:' . $class);
@@ -123,5 +143,27 @@ class PluginService extends BaseService
return $plugin;
}
/**
* 把插件元信息写回数据库,供“列表/Schema 直接从DB读取”
*/
private function syncPluginMeta(string $pluginCode, PaymentInterface&PayPluginInterface $plugin): void
{
$payTypes = (array)$plugin->getEnabledPayTypes();
$transferTypes = method_exists($plugin, 'getEnabledTransferTypes') ? (array)$plugin->getEnabledTransferTypes() : [];
$configSchema = (array)$plugin->getConfigSchema();
$author = method_exists($plugin, 'getAuthorName') ? (string)$plugin->getAuthorName() : '';
$link = method_exists($plugin, 'getAuthorLink') ? (string)$plugin->getAuthorLink() : '';
$this->pluginRepository->upsertByCode($pluginCode, [
'name' => $plugin->getName(),
'pay_types' => $payTypes,
'transfer_types' => $transferTypes,
'config_schema' => $configSchema,
'author' => $author,
'link' => $link,
]);
}
}

View File

@@ -40,13 +40,13 @@ ON DUPLICATE KEY UPDATE
`status` = VALUES(`status`),
`updated_at` = NOW();
-- 5) 插件注册表(按项目约定:app\\common\\payment\\{Code}Payment
INSERT INTO `ma_pay_plugin` (`plugin_code`, `plugin_name`, `class_name`, `status`, `created_at`, `updated_at`)
-- 5) 插件注册表(按项目约定:类名短写,如 AlipayPayment
INSERT INTO `ma_pay_plugin` (`code`, `name`, `class_name`, `status`, `created_at`, `updated_at`)
VALUES
('lakala', '拉卡拉(示例)', 'app\\\\common\\\\payment\\\\LakalaPayment', 1, NOW(), NOW()),
('alipay', '支付宝直连', 'app\\\\common\\\\payment\\\\AlipayPayment', 1, NOW(), NOW())
('lakala', '拉卡拉(示例)', 'LakalaPayment', 1, NOW(), NOW()),
('alipay', '支付宝直连', 'AlipayPayment', 1, NOW(), NOW())
ON DUPLICATE KEY UPDATE
`plugin_name` = VALUES(`plugin_name`),
`name` = VALUES(`name`),
`class_name` = VALUES(`class_name`),
`status` = VALUES(`status`),
`updated_at` = NOW();

View File

@@ -62,13 +62,16 @@ CREATE TABLE `ma_pay_method` (
-- =======================
DROP TABLE IF EXISTS `ma_pay_plugin`;
CREATE TABLE `ma_pay_plugin` (
`plugin_code` varchar(32) NOT NULL DEFAULT '' COMMENT '插件编码(主键)',
`plugin_name` varchar(50) NOT NULL DEFAULT '' COMMENT '插件名称',
`class_name` varchar(255) NOT NULL DEFAULT '' COMMENT '插件类名(完整命名空间',
`code` varchar(32) NOT NULL DEFAULT '' COMMENT '插件编码(主键)',
`name` varchar(50) NOT NULL DEFAULT '' COMMENT '插件名称',
`class_name` varchar(255) NOT NULL DEFAULT '' COMMENT '插件类名(短类名',
`config_schema` json DEFAULT NULL COMMENT '插件配置schema(JSON)',
`pay_types` json DEFAULT NULL COMMENT '插件支持支付类型(JSON)',
`transfer_types` json DEFAULT NULL COMMENT '插件支持转账类型(JSON)',
`status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '状态0-禁用, 1-启用',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`plugin_code`)
PRIMARY KEY (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付插件注册表';
-- =======================