adminOnly(); } /** * AP1 待审核信息列表 * GET /api/v1/admin/posts/pending 入参 {page,size} * → 分页 {list:[{id,title,categoryId,categoryName,userId,userName,area,price,priceUnit,createdAt,isPaid,content}],page,size,total,hasMore} * 条件:audit_status=0 且未删除(deletetime is null),按 createtime 升序 */ public function pending() { // 闭包重建查询:TP5.0 的 count() 会清空 Query::options,不能复用同一对象 list($rows, $total, $page, $size) = $this->pageQuery(function ($forCount) { $q = Db::name('fc_post')->alias('p') ->join('fc_category c', 'c.id = p.category_id', 'LEFT') ->join('user u', 'u.id = p.user_id', 'LEFT') ->where('p.audit_status', 0) ->whereNull('p.deletetime'); if ($forCount) { return $q; } return $q->field('p.*, c.name AS category_name, u.nickname AS user_name') ->order('p.createtime asc'); }); $list = []; foreach ($rows as $row) { $list[] = [ 'id' => (int)$row['id'], 'title' => (string)$row['title'], 'categoryId' => (int)$row['category_id'], 'categoryName' => (string)$row['category_name'], 'userId' => (int)$row['user_id'], 'userName' => (string)$row['user_name'], 'area' => (string)$row['area'], 'price' => (float)$row['price'], 'priceUnit' => (string)$row['price_unit'], 'createdAt' => $this->iso($row['createtime']), 'isPaid' => (bool)$row['is_paid'], 'content' => (string)$row['content'], ]; } $this->ok($this->paginate($list, $total, $page, $size)); } /** * AP2 信息审核 * POST /api/v1/admin/post/:id/audit 入参 {auditStatus,reason?} → {id,auditStatus} * 规则 BR-11:auditStatus 仅允许 1(通过)/2(驳回) */ public function audit() { $id = (int)$this->request->param('id', 0); $auditStatus = (int)$this->input('auditStatus', 0); $reason = trim((string)$this->input('reason', '')); if (!in_array($auditStatus, [1, 2], true)) { $this->fail('审核状态仅支持通过(1)/驳回(2)'); } $post = Db::name('fc_post')->where('id', $id)->find(); if (!$post) { $this->fail('信息不存在', 404); } Db::name('fc_post')->where('id', $id)->update([ 'audit_status' => $auditStatus, 'audit_reason' => $reason, 'updatetime' => time(), ]); if ($auditStatus === 1) { Db::name('fc_category')->where('id', $post['category_id'])->setInc('post_count'); $this->notify($post['user_id'], 'system', '审核通过', '您发布的信息「' . $post['title'] . '」已审核通过。'); } else { $this->notify($post['user_id'], 'system', '审核驳回', '您发布的信息「' . $post['title'] . '」被驳回:' . $reason); } $this->adminLog('审核信息 #' . $id . ' 结果' . $auditStatus); // 订阅消息:审核结果(模板未配置/用户未授权时静默跳过) \app\common\library\WxSubscribe::send( (int)$post['user_id'], 'audit', [ 'thing1' => ['value' => mb_substr((string)$post['title'], 0, 20)], 'phrase2' => ['value' => $auditStatus === 1 ? '审核通过' : '审核未通过'], 'thing3' => ['value' => $auditStatus === 1 ? '信息已公开展示' : mb_substr((string)$reason, 0, 20)], ], 'pages/detail/detail?id=' . $id ); $this->ok(['id' => (int)$id, 'auditStatus' => (int)$auditStatus]); } /** * AP3 信息下架 * POST /api/v1/admin/post/:id/offline → {id,offline} */ public function offline() { $id = (int)$this->request->param('id', 0); $post = Db::name('fc_post')->where('id', $id)->find(); if (!$post) { $this->fail('信息不存在', 404); } Db::name('fc_post')->where('id', $id)->update([ 'status' => 0, 'updatetime' => time(), ]); $this->notify($post['user_id'], 'system', '信息已下架', '您发布的信息「' . $post['title'] . '」已被下架。'); $this->adminLog('下架信息 #' . $id); $this->ok(['id' => (int)$id, 'offline' => true]); } }