* @Date: 2026-07-21 13:36:46 * @LastEditors: YwxApp * @LastEditTime: 2026-08-16 11:31:01 * @Description: 应用市场插件统一路由(对外 API + 主应用业务路由) * @FilePath: \ywxapp_dev\addon\appmall\route\app.php * @CustomString: Copyright (c) 2026 YwxApp */ // ============================================================ // 应用市场插件「统一路由入口」(替代原散落的 route/api.php)。 // // 插件名前缀(/appmall)由外层加载器统一补全,本文件【不要】自行写前缀: // 主应用:ywxapp/service/AppService::loadAddonRoutes() 包 Route::group('appmall') // // 全部路由(业务 + 对外 API)都在主应用 boot 阶段注册,形式为「相对组名」, // 由外层 Route::group('appmall') 补全 → /appmall/backend、/appmall/developer、 // /appmall/api(与「插件名开头」约定一致,彻底避免多插件路由冲突)。 // 注意:group 前缀是累加的,文件内【不要】再写 /appmall/ 或 /api/ 这样的前缀(会双重前缀)。 // ============================================================ use think\facade\Route; use addon\appmall\controller\api\Market; use addon\appmall\controller\backend\AddonReview; use addon\appmall\controller\backend\Developer; use addon\appmall\controller\backend\Revenue as BackendRevenue; use addon\appmall\controller\Developer as DeveloperCenter; use addon\appmall\controller\backend\Framework; use addon\appmall\controller\api\Framework as ApiFramework; use addon\appmall\controller\Framework as FrontendFramework; use addon\appmall\controller\Store; // ===================== 业务路由 + 对外 API(/appmall/*) ===================== // 插件名前缀 /appmall 由 AppService::loadAddonRoutes() 的 Route::group('appmall') 补全。 // ---------- 后台:插件审核 / 开发者管理 / 收益与结算(统一前缀 /appmall/backend) ---------- Route::group('backend', function () { // 插件审核 Route::get('addonreview', [AddonReview::class, 'index']); Route::get('addonreview/index', [AddonReview::class, 'index']); Route::post('addonreview/approve', [AddonReview::class, 'approve']); Route::post('addonreview/reject', [AddonReview::class, 'reject']); Route::post('addonreview/updatePrice', [AddonReview::class, 'updatePrice']); Route::get('addonreview/download', [AddonReview::class, 'download']); Route::get('addonreview/detail', [AddonReview::class, 'detail']); Route::get('addonreview/detailview', [AddonReview::class, 'detailview']); Route::get('addonreview/history', [AddonReview::class, 'history']); // 开发者管理 Route::get('developer', [Developer::class, 'index']); Route::get('developer/index', [Developer::class, 'index']); Route::post('developer/approve', [Developer::class, 'approve']); Route::post('developer/disable', [Developer::class, 'disable']); Route::post('developer/resend', [Developer::class, 'resend']); Route::post('developer/reset', [Developer::class, 'reset']); // 收益与结算 Route::get('revenue', [BackendRevenue::class, 'index']); Route::get('revenue/index', [BackendRevenue::class, 'index']); Route::get('revenue/withdrawals', [BackendRevenue::class, 'withdrawals']); Route::post('revenue/settle', [BackendRevenue::class, 'settle']); Route::post('revenue/reject', [BackendRevenue::class, 'rejectWithdrawal']); // 主框架升级(原 upgrade 插件,已合并进 market) Route::get('framework', [Framework::class, 'index']); Route::get('framework/index', [Framework::class, 'index']); Route::post('framework/upload', [Framework::class, 'upload']); Route::post('framework/publish', [Framework::class, 'publish']); Route::post('framework/delete', [Framework::class, 'delete']); Route::get('framework/download', [Framework::class, 'download']); }); // ---------- 开发者中心(独立前台应用,公开注册/令牌/收益/提现,非会员中心):统一前缀 /appmall/developer ---------- // 仅【中心站】暴露:开发者自助注册/收益/提现依赖 appmall_developers / appmall_addon_revenues / appmall_addon_withdrawals 等 // 运营表,客户机(ywxapp.api_url 指向其他服务器,见 is_market_client())作为中心站客户端不持有这些表,故不在路由层注册, // 访问即 404。配合 Developer 控制器 initialize() 的运行时兜底(即便路由缓存陈旧或被直连也能拦截)。 // ---------- 开发者中心(独立前台,令牌认证):/appmall/Developer/* ---------- Route::group('Developer', function () { Route::get('index', [DeveloperCenter::class, 'index']); Route::post('save', [DeveloperCenter::class, 'save']); Route::get('mine', [DeveloperCenter::class, 'mine']); Route::post('lookup', [DeveloperCenter::class, 'lookup']); Route::get('dashboard', [DeveloperCenter::class, 'dashboard']); Route::get('console', [DeveloperCenter::class, 'console']); Route::post('overview', [DeveloperCenter::class, 'overview']); Route::post('apps', [DeveloperCenter::class, 'apps']); Route::post('price', [DeveloperCenter::class, 'price']); Route::post('earnings', [DeveloperCenter::class, 'earnings']); Route::post('withdraw', [DeveloperCenter::class, 'withdraw']); }); // ---------- 对外 API(统一前缀 /appmall/api):远程客户机经 Remote/Addon/FrameworkService 调用 ---------- // 由 AppService::loadAddonRoutes() 的 Route::group('appmall') 补全插件名前缀 → /appmall/api/* //(与 /appmall/backend、/appmall/developer 同源同构,均为「插件名开头」约定)。 // 调用方契约(勿单侧改动): // RemoteAppmallService → /appmall/api/addon/*、/appmall/api/index // AddonService → /appmall/api/addon/valid、/appmall/api/index/index // FrameworkService → /appmall/api/framework/version、/appmall/api/framework/download Route::group('api', function () { Route::get('addon/lists', [Market::class, 'lists']); Route::get('addon/info', [Market::class, 'info']); Route::post('addon/valid', [Market::class, 'valid']); Route::post('addon/submit', [Market::class, 'submit']); Route::post('addon/buy', [Market::class, 'buy']); Route::get('addon/orderStatus', [Market::class, 'orderStatus']); Route::post('addon/notify', [Market::class, 'notify']); Route::get('addon/payResult', [Market::class, 'payResult']); Route::post('addon/refund', [Market::class, 'refund']); Route::get('addon/my', [Market::class, 'my']); // 插件 zip 下载(RemoteAppmallService 走 /appmall/api/index,AddonService 走 /appmall/api/index/index) Route::get('index', [Market::class, 'index']); Route::get('index/index', [Market::class, 'index']); // 主框架升级分发(FrameworkService 走 /appmall/api/framework/*) Route::get('framework/version', [ApiFramework::class, 'version']); Route::get('framework/download', [ApiFramework::class, 'download']); }); // ---------- 前台展示(公开,仅中心站):主框架发布/下载页 + 应用商店 ---------- // 前台控制器直接置于 addon\appmall\controller 下(如 ForumFrontend 惯例), // 不套 frontend 子目录;URL 前缀为 /appmall/framework、/appmall/store。 Route::get('framework', [FrontendFramework::class, 'index']); Route::get('framework/index', [FrontendFramework::class, 'index']); // 应用商店:上线插件列表(/appmall/store) Route::get('store', [Store::class, 'index'])->completeMatch(); Route::get('store/index', [Store::class, 'index'])->completeMatch(); // 插件详情页(/appmall/store/detail/) Route::get('store/detail/:name', [Store::class, 'detail']) ->pattern(['name' => '[\w\-]+']);