feat: 公共表更名 common/member 前缀 + 插件命令自动加载 + 版本 1.1.1

- 18 张公共表更名(addon/attachment/configure/links/spider_log/spider_stat/sms/notice/ad/task/prop/medal/help/card -> common_*,member_wallets->member_wallet,score_rule/score_log -> member_*,addon_config->common_addonconf),模型全部对齐新表名,Db 直引用清零
- Attachment 模型补  表名绑定,修复富文本上传查 wxapp_attachment 1146 隐患
- install.sql + 迁移 SQL:backend_admin/backend_role delete_at 默认 0,修复软删除(NULL != 0)误过滤导致后台菜单为空
- AppService::boot() 支持插件 info.php 声明 commands 自动注册插件命令(psr-4 自动加载,坏类名自动跳过)
- 各插件(haonav/mqttbroker/wxchat/articles/blog/forum 等)字段与配置同步调整
- 框架版本 1.1.0 -> 1.1.1
This commit is contained in:
ywxapp
2026-08-20 20:19:15 +08:00
parent 303f548664
commit 1d49e6f5ee
395 changed files with 13342 additions and 2012 deletions
+38 -17
View File
@@ -3,7 +3,7 @@
* @Author: YwxApp <ywx@ywxapp.cn>
* @Date: 2026-08-06 22:05:48
* @LastEditors: YwxApp <ywx@ywxapp.cn>
* @LastEditTime: 2026-08-13 16:46:11
* @LastEditTime: 2026-08-20 11:19:15
* @Description:
* @FilePath: \ywxapp_dev\ywxapp\service\AppService.php
* @CustomString: Copyright (c) 2026 YwxApp
@@ -74,7 +74,7 @@ class AppService extends Service
continue;
}
try {
\think\facade\Config::set(\ywxapp\addon::readConfig($name), $name);
\think\facade\Config::set(\ywxapp\AddonBase::readConfig($name), $name);
} catch (\Throwable $e) {
// 单个插件预热失败不影响主流程
}
@@ -82,23 +82,29 @@ class AppService extends Service
});
// 默认短信发送监听:开发环境不实际下发(仅记录验证码到日志并回传前端用于调试),
// 生产环境返回 null,交由短信插件(监听 SmsSend 事件)实际发送。
\think\facade\Event::listen('SmsSend', function ($sms) {
if (Env::get('app_debug')) {
\think\facade\Log::info('[DEV] 短信验证码(未实际下发): ' . ($sms['code'] ?? '') . ' -> ' . ($sms['mobile'] ?? ''));
return true;
}
return null;
});
// \think\facade\Event::listen('SmsSend', function ($sms) {
// if (Env::get('app_debug')) {
// \think\facade\Log::info('[DEV] 短信验证码(未实际下发): ' . ($sms['code'] ?? '') . ' -> ' . ($sms['mobile'] ?? ''));
// return true;
// }
// return null;
// });
}
public function boot()
{
$this->app->middleware->import([MultiApp::class], 'global');
// 2. 替换 url() 使用的 UrlBuild 类
$this->app->bind(\think\route\Url::class, UrlBuild::class);
$this->commands([
// 插件命令自动注册约定:
// 插件在 info.php 声明 'commands' => ['插件名:动作' => \addon\<插件名>\command\Xxx::class]
// 命令类 extends think\console\Command,psr-4 (addon\ => addon) 自动加载。
// 执行链:Console 构造 → app->initialize() → BootService 触发本 boot() →
// $this->commands() 挂 Console::starting 回调 → Console::run() 统一 addCommands。
// 坏类名/非 Command 子类会被 addCommands 跳过,单个插件声明错误不影响整体。
$commands = [
'app' => \ywxapp\command\AppCommand::class,
'addon:manage' => \ywxapp\command\AddonManage::class,
'addon:make' => \ywxapp\command\AddonMake::class,
@@ -106,7 +112,14 @@ class AppService extends Service
'addon:license-check' => \ywxapp\command\AddonLicenseCheck::class,
'addon:repair' => \ywxapp\command\AddonRepair::class,
'ywxapp:upgrade' => \ywxapp\command\Upgrade::class,
]);
];
foreach ($this->getEnabledaddon() as $info) {
$addonCmds = $info['commands'] ?? [];
if (is_array($addonCmds) && $addonCmds) {
$commands = array_merge($commands, $addonCmds);
}
}
$this->commands($commands);
$this->loadAddonRelevant();
// $this->loadAddonRoutes();
Route::rule('ueditor', function () {
@@ -252,10 +265,18 @@ class AppService extends Service
public static function clearAddonCache(): void
{
\think\facade\Cache::delete('addon_loaded_config');
// 同时清除配置缓存
$addon = \think\facade\Config::get('addon', []);
foreach ($addon as $addon) {
\think\facade\Cache::delete('addon_config_' . $addon['name']);
// 同时清除各插件的配置缓存。
// 注意:Config::get('addon') 返回的是框架 addon 组件自身配置(含 multi_app/priority 等),
// 并非插件列表,切勿直接 foreach 它(遍历到 multi_app=true 会触发 "array offset on true")。
// 正确的插件名来源是 addon 主表的 name 列。
try {
$names = \ywxapp\model\CommonAddon::column('name');
foreach ($names as $name) {
\think\facade\Cache::delete('addon_config_' . $name);
}
} catch (\Throwable $e) {
// 数据表可能尚未创建,忽略
\think\facade\Log::warning('clearAddonCache 获取插件列表失败:' . $e->getMessage());
}
}
@@ -270,7 +291,7 @@ class AppService extends Service
return true; // 无市场插件 → 无授权域,放行
}
try {
$addonId = \ywxapp\model\AddonModel::where('name', $addon)->value('id');
$addonId = \ywxapp\model\CommonAddon::where('name', $addon)->value('id');
if (!$addonId) {
return false;
}