mirror of
https://gitee.com/technical-laohu/mpay_v2_webman.git
synced 2026-04-26 03:54:25 +08:00
插件管理更新
This commit is contained in:
@@ -54,11 +54,11 @@ class PayPluginController extends BaseController
|
|||||||
|
|
||||||
if ($className === '') {
|
if ($className === '') {
|
||||||
// 默认约定类名
|
// 默认约定类名
|
||||||
$className = 'app\\common\\payment\\' . ucfirst($pluginCode) . 'Payment';
|
$className = ucfirst($pluginCode) . 'Payment';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->pluginRepository->upsertByCode($pluginCode, [
|
$this->pluginRepository->upsertByCode($pluginCode, [
|
||||||
'plugin_name' => $pluginName,
|
'name' => $pluginName,
|
||||||
'class_name' => $className,
|
'class_name' => $className,
|
||||||
'status' => $status,
|
'status' => $status,
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -7,28 +7,36 @@ use app\common\base\BaseModel;
|
|||||||
/**
|
/**
|
||||||
* 支付插件模型
|
* 支付插件模型
|
||||||
*
|
*
|
||||||
* 对应表:ma_pay_plugin(主键 plugin_code)
|
* 对应表:ma_pay_plugin(主键 code)
|
||||||
*/
|
*/
|
||||||
class PaymentPlugin extends BaseModel
|
class PaymentPlugin extends BaseModel
|
||||||
{
|
{
|
||||||
protected $table = 'ma_pay_plugin';
|
protected $table = 'ma_pay_plugin';
|
||||||
|
|
||||||
protected $primaryKey = 'plugin_code';
|
protected $primaryKey = 'code';
|
||||||
|
|
||||||
public $incrementing = false;
|
public $incrementing = false;
|
||||||
|
|
||||||
protected $keyType = 'string';
|
protected $keyType = 'string';
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'plugin_code',
|
'code',
|
||||||
'plugin_name',
|
'name',
|
||||||
'class_name',
|
'class_name',
|
||||||
'status',
|
'status',
|
||||||
|
'config_schema',
|
||||||
|
'pay_types',
|
||||||
|
'transfer_types',
|
||||||
|
'author',
|
||||||
|
'link',
|
||||||
];
|
];
|
||||||
|
|
||||||
public $timestamps = true;
|
public $timestamps = true;
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'status' => 'integer',
|
'status' => 'integer',
|
||||||
|
'config_schema' => 'array',
|
||||||
|
'pay_types' => 'array',
|
||||||
|
'transfer_types' => 'array',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,20 @@ class PaymentPluginRepository extends BaseRepository
|
|||||||
{
|
{
|
||||||
return $this->model->newQuery()
|
return $this->model->newQuery()
|
||||||
->where('status', 1)
|
->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
|
public function findActiveByCode(string $pluginCode): ?PaymentPlugin
|
||||||
{
|
{
|
||||||
return $this->model->newQuery()
|
return $this->model->newQuery()
|
||||||
->where('plugin_code', $pluginCode)
|
->where('code', $pluginCode)
|
||||||
->where('status', 1)
|
->where('status', 1)
|
||||||
->first();
|
->first();
|
||||||
}
|
}
|
||||||
@@ -36,7 +43,7 @@ class PaymentPluginRepository extends BaseRepository
|
|||||||
public function findByCode(string $pluginCode): ?PaymentPlugin
|
public function findByCode(string $pluginCode): ?PaymentPlugin
|
||||||
{
|
{
|
||||||
return $this->model->newQuery()
|
return $this->model->newQuery()
|
||||||
->where('plugin_code', $pluginCode)
|
->where('code', $pluginCode)
|
||||||
->first();
|
->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,10 +58,10 @@ class PaymentPluginRepository extends BaseRepository
|
|||||||
$query->where('status', (int)$filters['status']);
|
$query->where('status', (int)$filters['status']);
|
||||||
}
|
}
|
||||||
if (!empty($filters['plugin_code'])) {
|
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'])) {
|
if (!empty($filters['plugin_name'])) {
|
||||||
$query->where('plugin_name', 'like', '%' . $filters['plugin_name'] . '%');
|
$query->where('name', 'like', '%' . $filters['plugin_name'] . '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
$query->orderByDesc('created_at');
|
$query->orderByDesc('created_at');
|
||||||
@@ -69,12 +76,12 @@ class PaymentPluginRepository extends BaseRepository
|
|||||||
$row = $this->findByCode($pluginCode);
|
$row = $this->findByCode($pluginCode);
|
||||||
if ($row) {
|
if ($row) {
|
||||||
$this->model->newQuery()
|
$this->model->newQuery()
|
||||||
->where('plugin_code', $pluginCode)
|
->where('code', $pluginCode)
|
||||||
->update($data);
|
->update($data);
|
||||||
return $this->findByCode($pluginCode) ?: $row;
|
return $this->findByCode($pluginCode) ?: $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['plugin_code'] = $pluginCode;
|
$data['code'] = $pluginCode;
|
||||||
/** @var PaymentPlugin $created */
|
/** @var PaymentPlugin $created */
|
||||||
$created = $this->create($data);
|
$created = $this->create($data);
|
||||||
return $created;
|
return $created;
|
||||||
@@ -83,7 +90,7 @@ class PaymentPluginRepository extends BaseRepository
|
|||||||
public function updateStatus(string $pluginCode, int $status): bool
|
public function updateStatus(string $pluginCode, int $status): bool
|
||||||
{
|
{
|
||||||
return (bool)$this->model->newQuery()
|
return (bool)$this->model->newQuery()
|
||||||
->where('plugin_code', $pluginCode)
|
->where('code', $pluginCode)
|
||||||
->update(['status' => $status]);
|
->update(['status' => $status]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,19 +31,29 @@ class PluginService extends BaseService
|
|||||||
|
|
||||||
$plugins = [];
|
$plugins = [];
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$pluginCode = $row->plugin_code;
|
$pluginCode = $row->code;
|
||||||
|
|
||||||
try {
|
$pluginName = (string)($row->name ?? '');
|
||||||
$plugin = $this->resolvePlugin($pluginCode, $row->class_name);
|
$supportedMethods = is_array($row->pay_types ?? null) ? (array)$row->pay_types : [];
|
||||||
$plugins[] = [
|
|
||||||
'code' => $pluginCode,
|
// 如果数据库里缺少元信息,则回退到实例化插件并写回数据库
|
||||||
'name' => $plugin->getName(),
|
if ($pluginName === '' || $supportedMethods === []) {
|
||||||
'supported_methods'=> $plugin->getEnabledPayTypes(),
|
try {
|
||||||
];
|
$plugin = $this->resolvePlugin($pluginCode, (string)($row->class_name ?? ''));
|
||||||
} catch (\Throwable $e) {
|
$this->syncPluginMeta($pluginCode, $plugin);
|
||||||
// 忽略无法实例化的插件
|
$pluginName = $plugin->getName();
|
||||||
continue;
|
$supportedMethods = (array)$plugin->getEnabledPayTypes();
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
// 忽略无法实例化的插件
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$plugins[] = [
|
||||||
|
'code' => $pluginCode,
|
||||||
|
'name' => $pluginName,
|
||||||
|
'supported_methods' => $supportedMethods,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $plugins;
|
return $plugins;
|
||||||
@@ -54,8 +64,15 @@ class PluginService extends BaseService
|
|||||||
*/
|
*/
|
||||||
public function getConfigSchema(string $pluginCode, string $methodCode): array
|
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);
|
$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
|
public function buildConfigFromForm(string $pluginCode, string $methodCode, array $formData): array
|
||||||
{
|
{
|
||||||
$plugin = $this->getPluginInstance($pluginCode);
|
$configSchema = $this->getConfigSchema($pluginCode, $methodCode);
|
||||||
$configSchema = $plugin->getConfigSchema();
|
|
||||||
|
|
||||||
$configJson = [];
|
$configJson = [];
|
||||||
if (isset($configSchema['fields']) && is_array($configSchema['fields'])) {
|
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
|
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)) {
|
if (!class_exists($class)) {
|
||||||
throw new NotFoundException('支付插件类不存在:' . $class);
|
throw new NotFoundException('支付插件类不存在:' . $class);
|
||||||
@@ -123,5 +143,27 @@ class PluginService extends BaseService
|
|||||||
|
|
||||||
return $plugin;
|
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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ ON DUPLICATE KEY UPDATE
|
|||||||
`status` = VALUES(`status`),
|
`status` = VALUES(`status`),
|
||||||
`updated_at` = NOW();
|
`updated_at` = NOW();
|
||||||
|
|
||||||
-- 5) 插件注册表(按项目约定:app\\common\\payment\\{Code}Payment)
|
-- 5) 插件注册表(按项目约定:类名短写,如 AlipayPayment)
|
||||||
INSERT INTO `ma_pay_plugin` (`plugin_code`, `plugin_name`, `class_name`, `status`, `created_at`, `updated_at`)
|
INSERT INTO `ma_pay_plugin` (`code`, `name`, `class_name`, `status`, `created_at`, `updated_at`)
|
||||||
VALUES
|
VALUES
|
||||||
('lakala', '拉卡拉(示例)', 'app\\\\common\\\\payment\\\\LakalaPayment', 1, NOW(), NOW()),
|
('lakala', '拉卡拉(示例)', 'LakalaPayment', 1, NOW(), NOW()),
|
||||||
('alipay', '支付宝直连', 'app\\\\common\\\\payment\\\\AlipayPayment', 1, NOW(), NOW())
|
('alipay', '支付宝直连', 'AlipayPayment', 1, NOW(), NOW())
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
`plugin_name` = VALUES(`plugin_name`),
|
`name` = VALUES(`name`),
|
||||||
`class_name` = VALUES(`class_name`),
|
`class_name` = VALUES(`class_name`),
|
||||||
`status` = VALUES(`status`),
|
`status` = VALUES(`status`),
|
||||||
`updated_at` = NOW();
|
`updated_at` = NOW();
|
||||||
|
|||||||
@@ -62,13 +62,16 @@ CREATE TABLE `ma_pay_method` (
|
|||||||
-- =======================
|
-- =======================
|
||||||
DROP TABLE IF EXISTS `ma_pay_plugin`;
|
DROP TABLE IF EXISTS `ma_pay_plugin`;
|
||||||
CREATE TABLE `ma_pay_plugin` (
|
CREATE TABLE `ma_pay_plugin` (
|
||||||
`plugin_code` varchar(32) NOT NULL DEFAULT '' COMMENT '插件编码(主键)',
|
`code` varchar(32) NOT NULL DEFAULT '' COMMENT '插件编码(主键)',
|
||||||
`plugin_name` varchar(50) NOT NULL DEFAULT '' COMMENT '插件名称',
|
`name` varchar(50) NOT NULL DEFAULT '' COMMENT '插件名称',
|
||||||
`class_name` varchar(255) 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-启用',
|
`status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '状态:0-禁用, 1-启用',
|
||||||
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
|
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
|
||||||
`updated_at` datetime DEFAULT NULL COMMENT '更新时间',
|
`updated_at` datetime DEFAULT NULL COMMENT '更新时间',
|
||||||
PRIMARY KEY (`plugin_code`)
|
PRIMARY KEY (`code`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付插件注册表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付插件注册表';
|
||||||
|
|
||||||
-- =======================
|
-- =======================
|
||||||
|
|||||||
Reference in New Issue
Block a user