diff --git a/app/http/admin/controller/PayPluginController.php b/app/http/admin/controller/PayPluginController.php index 2480e07..01c1168 100644 --- a/app/http/admin/controller/PayPluginController.php +++ b/app/http/admin/controller/PayPluginController.php @@ -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, ]); diff --git a/app/models/PaymentPlugin.php b/app/models/PaymentPlugin.php index 1c5cb47..36ed767 100644 --- a/app/models/PaymentPlugin.php +++ b/app/models/PaymentPlugin.php @@ -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', ]; } diff --git a/app/repositories/PaymentPluginRepository.php b/app/repositories/PaymentPluginRepository.php index 5b5e345..34f324c 100644 --- a/app/repositories/PaymentPluginRepository.php +++ b/app/repositories/PaymentPluginRepository.php @@ -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]); } } diff --git a/app/services/PluginService.php b/app/services/PluginService.php index 4941341..656ec4d 100644 --- a/app/services/PluginService.php +++ b/app/services/PluginService.php @@ -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, + ]); + } } diff --git a/database/dev_seed.sql b/database/dev_seed.sql index f009ec9..a4a6aca 100644 --- a/database/dev_seed.sql +++ b/database/dev_seed.sql @@ -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(); diff --git a/database/mvp_payment_tables.sql b/database/mvp_payment_tables.sql index 9f450a7..a96cc2a 100644 --- a/database/mvp_payment_tables.sql +++ b/database/mvp_payment_tables.sql @@ -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='支付插件注册表'; -- =======================