request->isPost()) { $appName = trim((string)$this->input('appName', '')); if ($appName === '') { $this->fail('小程序名称不能为空'); } $this->setCfg('base.appName', $appName); $this->setCfg('base.logo', (string)$this->input('logo', $this->cfg('base.logo', ''))); $this->setCfg('base.servicePhone', (string)$this->input('servicePhone', $this->cfg('base.servicePhone', '400-000-0000'))); $this->setCfg('base.aboutUs', (string)$this->input('aboutUs', $this->cfg('base.aboutUs', ''))); $this->setCfg('base.shareTitle', (string)$this->input('shareTitle', $this->cfg('base.shareTitle', ''))); $this->adminLog('修改基础配置'); } $this->ok($this->baseConfig()); } /** * AS2 微信支付配置 * POST /api/v1/admin/setting/pay 入参 {mchId,apiKey} → {configured:true} */ public function pay() { $mchId = trim((string)$this->input('mchId', '')); $apiKey = trim((string)$this->input('apiKey', '')); if ($mchId === '') { $this->fail('微信支付商户号不能为空'); } if ($apiKey === '') { $this->fail('支付密钥不能为空'); } $this->setCfg('pay.mchId', $mchId); $this->setCfg('pay.apiKey', $apiKey); $this->adminLog('修改微信支付配置'); $this->ok(['configured' => true]); } /** * AS3 费用配置 * GET → {singlePost,freePostPerDay,memberMonth,memberQuarter,memberYear} * POST 入参同字段 → 合并后配置;同时同步 fc_plan 价格 */ public function fee() { if ($this->request->isPost()) { $singlePost = (float)$this->input('singlePost', $this->cfg('fee.singlePost', 5)); if ($singlePost < 0) { $this->fail('单条发布价格不能为负'); } $freePostPerDay = (int)$this->input('freePostPerDay', $this->cfg('fee.freePostPerDay', 2)); $memberMonth = (float)$this->input('memberMonth', $this->cfg('fee.memberMonth', 19.9)); $memberQuarter = (float)$this->input('memberQuarter', $this->cfg('fee.memberQuarter', 49.9)); $memberYear = (float)$this->input('memberYear', $this->cfg('fee.memberYear', 168)); $this->setCfg('fee.singlePost', $singlePost); $this->setCfg('fee.freePostPerDay', $freePostPerDay); $this->setCfg('fee.memberMonth', $memberMonth); $this->setCfg('fee.memberQuarter', $memberQuarter); $this->setCfg('fee.memberYear', $memberYear); Db::name('fc_plan')->where('plan_code', 'M1')->update(['price' => $memberMonth]); Db::name('fc_plan')->where('plan_code', 'M3')->update(['price' => $memberQuarter]); Db::name('fc_plan')->where('plan_code', 'M12')->update(['price' => $memberYear]); $this->adminLog('修改费用配置'); } $this->ok($this->feeConfig()); } /** * AS4 区域列表 * GET /api/v1/admin/setting/areas → 数组 [{id,name,sort,enabled}] */ public function areas() { $rows = Db::name('fc_area')->order('sort asc')->select(); $list = []; foreach ($rows as $row) { $list[] = [ 'id' => (int)$row['id'], 'name' => (string)$row['name'], 'sort' => (int)$row['sort'], 'enabled' => (bool)$row['enabled'], ]; } $this->ok($list); } /** * AS5 保存区域 * POST /api/v1/admin/setting/area 入参 {id?,name,sort,enabled} → {id,name} */ public function saveArea() { $id = (int)$this->input('id', 0); $name = trim((string)$this->input('name', '')); $sort = (int)$this->input('sort', 0); $enabled = (bool)$this->input('enabled', true); if ($name === '') { $this->fail('区域名称不能为空'); } $data = [ 'name' => $name, 'sort' => $sort, 'enabled' => $enabled ? 1 : 0, ]; if ($id && Db::name('fc_area')->where('id', $id)->find()) { Db::name('fc_area')->where('id', $id)->update($data); } else { $id = Db::name('fc_area')->insertGetId($data); } $this->adminLog('保存区域 #' . $id . ' ' . $name); $this->ok(['id' => (int)$id, 'name' => $name]); } /** * AS6 站点 UI 配置(LOGO / 图标) * GET → {siteName,logo,icons,updatedAt} * POST 入参 {siteName?,logo?,icons?}(合并语义:只覆盖传入的 key) → 完整配置 */ public function ui() { if ($this->request->isPost()) { $siteName = $this->input('siteName', null); if ($siteName !== null) { $this->setCfg('ui.siteName', (string)$siteName); } $logo = $this->input('logo', null); if ($logo !== null) { $this->setCfg('ui.logo', (string)$logo); } $icons = $this->input('icons', null); if ($icons !== null) { if (is_string($icons)) { $icons = json_decode($icons, true); } $icons = is_array($icons) ? $icons : (array)$icons; $merged = (array)$this->cfg('ui.icons', []); foreach ($icons as $k => $v) { if (!is_string($v)) { $this->fail('图标 ' . $k . ' 的地址必须是字符串'); } $merged[$k] = $v; } $this->setCfg('ui.icons', $merged); } $this->setCfg('ui.updatedAt', date('c')); $this->adminLog('修改LOGO与图标配置'); } $this->ok($this->uiConfig()); } /** * AS7 重置 UI 配置 * POST /api/v1/admin/setting/ui/reset → {siteName,logo,icons,reset} */ public function uiReset() { $this->setCfg('ui.logo', ''); $this->setCfg('ui.icons', []); $this->setCfg('ui.updatedAt', date('c')); $this->adminLog('重置LOGO与图标配置'); $this->ok([ 'siteName' => (string)$this->cfg('ui.siteName', '同城分类信息'), 'logo' => '', 'icons' => (object)[], 'reset' => true, ]); } /** * AS8 文件上传 * POST /api/v1/admin/upload multipart 字段 file → {url} */ public function upload() { $file = $this->request->file('file'); if (!$file) { $this->fail('未接收到上传文件'); } try { $upload = new \app\common\library\Upload($file); $attachment = $upload->upload(); } catch (\Exception $e) { $this->fail($e->getMessage()); } $this->ok(['url' => cdnurl($attachment->url, true)]); } /** 基础配置结构 */ protected function baseConfig() { return [ 'appName' => (string)$this->cfg('base.appName', '同城分类信息'), 'logo' => (string)$this->cfg('base.logo', ''), 'servicePhone' => (string)$this->cfg('base.servicePhone', '400-000-0000'), 'aboutUs' => (string)$this->cfg('base.aboutUs', ''), 'shareTitle' => (string)$this->cfg('base.shareTitle', ''), ]; } /** 费用配置结构 */ protected function feeConfig() { return [ 'singlePost' => (float)$this->cfg('fee.singlePost', 5), 'freePostPerDay' => (int)$this->cfg('fee.freePostPerDay', 2), 'memberMonth' => (float)$this->cfg('fee.memberMonth', 19.9), 'memberQuarter' => (float)$this->cfg('fee.memberQuarter', 49.9), 'memberYear' => (float)$this->cfg('fee.memberYear', 168), ]; } /** UI 配置结构(icons 保证为对象) */ protected function uiConfig() { $icons = $this->cfg('ui.icons', []); $icons = is_array($icons) ? $icons : (array)$icons; return [ 'siteName' => (string)$this->cfg('ui.siteName', '同城分类信息'), 'logo' => (string)$this->cfg('ui.logo', ''), 'icons' => (object)$icons, 'updatedAt' => (string)$this->cfg('ui.updatedAt', date('c')), ]; } }