// +---------------------------------------------------------------------- declare(strict_types=1); namespace addon\appmall\controller; use think\facade\Db; use ywxapp\controller\FrontendBase; /** * 主框架发布/下载展示页(公开,仅中心站) * * 列出已发布的主框架版本,提供「整包 / 增量补丁 / 完整安装包」下载入口。 * 下载走对外 API /appmall/api/framework/download(无需登录,可选签名)。 * 路由前缀:/appmall/framework/*(由 AppService::loadAddonRoutes 外层包 Route::group('appmall'))。 * 视图:addon/appmall/view/frontend/framework/。 */ class Framework extends FrontendBase { protected $noNeedLogin = ['*']; protected $noNeedVerify = ['*']; /** * 锁定视图路径到插件目录(AddonFrontend 默认指向主应用 view/frontend/,须覆盖)。 * 仅中心站暴露:客户机不持有 framework_list 发布数据,访问即 404。 */ protected function initialize() { if (is_market_client()) { abort(404, '框架下载页仅在中心站(市场服务端)可用'); } $this->view->config([ 'view_path' => ADDON_PATH . 'appmall' . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'frontend' . DIRECTORY_SEPARATOR, ]); } /** * 发布列表展示页 */ public function index() { $this->ensureColumns(); $rows = Db::name('appmall_framework_list') ->where('status', 1) ->order('id', 'desc') ->field('id,version,title,changelog,file_path,patch_path,install_path,patch_from,from_version,download_count,create_at') ->select() ->toArray(); foreach ($rows as &$r) { $r['has_full'] = !empty($r['file_path']); $r['has_patch'] = !empty($r['patch_path']); $r['has_install'] = !empty($r['install_path']); $r['patch_from'] = $r['patch_from'] ?: $r['from_version']; $r['create_at_fmt'] = $r['create_at'] ? date('Y-m-d', (int) $r['create_at']) : ''; unset($r['file_path'], $r['patch_path'], $r['install_path']); } unset($r); $this->view->assign('list', $rows); $this->view->assign('market_name', config('appmall.appmall_name', 'YwxApp 应用市场')); return $this->view->fetch('framework/index'); } /** * 运行时自愈:补齐 install_path / install_hash 列(早期安装的中心站可能缺失)。 */ private function ensureColumns(): void { $table = \ywxapp\model\BaseModel::currentPrefix() . 'appmall_framework_list'; try { $defs = [ 'install_path' => "varchar(255) DEFAULT '' COMMENT '完整安装包 zip 物理路径'", 'install_hash' => "varchar(64) DEFAULT '' COMMENT '完整安装包 SHA256 校验值'", ]; foreach ($defs as $col => $def) { $cols = Db::query("SHOW COLUMNS FROM `{$table}` LIKE '{$col}'"); if (empty($cols)) { Db::execute("ALTER TABLE `{$table}` ADD COLUMN `{$col}` {$def}"); } } } catch (\Exception $e) { // ignore } } }