// +---------------------------------------------------------------------- declare(strict_types=1); namespace app\api\controller\v1; use ywxapp\controller\ApiBase; use ywxapp\model\SystemConfig; use ywxapp\service\FileStorageService; /** * 通用基础接口(App 启动所需,聊天 / 商城等应用共用) * * 路由前缀:/api/v1/common/ * 鉴权:config / init 公开;upload 需登录(防滥用)。 * * @package app\api\controller\v1 */ class Common extends ApiBase { /** * 免登录(公开)接口白名单。 * * @var array */ protected $noNeedLogin = ['config', 'init']; /** * App 启动初始化数据(公开)。 * * 返回站点基础信息、可用的注册方式开关、接口版本等,供客户端冷启动时读取。 * * @return \think\Response JSON 响应,携带 site / register_methods / version * * @route GET /api/v1/common/init */ public function init() { $config = $this->siteConfig(); $data = [ 'site' => $config, 'register_methods' => [ 'password' => 1, 'sms' => 1, 'email' => 1, ], 'version' => '1.0.0', ]; return $this->apiSuccess($data); } /** * 获取站点配置(公开)。 * * 返回站点名称、Logo、备案号等基础配置。 * * @return \think\Response JSON 响应,携带站点配置数组 * * @route GET /api/v1/common/config */ public function config() { return $this->apiSuccess($this->siteConfig()); } /** * 文件上传(需登录)。 * * 接收 multipart/form-data 中的 file 字段,统一走 FileStorageService: * 内置驱动兜底,插件监听 FileUpload 事件可接管(OSS / FTP / 自定义存储), * 上传成功后触发 FileUploaded 事件(缩略图 / 水印等扩展)。 * * @param \think\file\UploadedFile $file 上传的文件(form-data: file) * * @return \think\Response JSON 响应,成功携带 url / path / name / size * * @throws \Throwable 当文件存储失败时 * * @route POST /api/v1/common/upload */ public function upload() { $file = $this->request->file('file'); if (!$file) { return $this->apiError('请选择上传文件'); } try { $storage = new FileStorageService(); $data = $storage->upload($file, '', [ 'module' => 'api', 'uid' => $this->uid(), 'rules' => [ 'fileSize' => 10 * 1024 * 1024, 'fileExt' => 'jpg,jpeg,png,gif,webp,bmp,mp4,mov,mp3,wav,zip,rar,doc,docx,xls,xlsx,pdf,txt', ], ]); return $this->apiSuccess([ 'url' => $data['url'], 'path' => $data['path'], 'name' => $data['name'] ?? '', 'size' => $data['size'] ?? 0, ], '上传成功'); } catch (\Throwable $e) { return $this->apiError('上传失败:' . $e->getMessage()); } } /** * 读取站点配置。 * * 优先从 SystemConfig 表读取,表不存在或字段缺失时回退到默认值。 * * @return array 站点配置数组(name / logo / icp) */ protected function siteConfig(): array { $defaults = [ 'name' => 'YwxApp', 'logo' => '', 'icp' => '', ]; try { $rows = SystemConfig::column('value', 'name'); if ($rows) { foreach ($defaults as $k => $v) { if (isset($rows[$k])) { $defaults[$k] = $rows[$k]; } } } } catch (\Throwable $e) { // 表不存在时用默认值 } return $defaults; } }