alias('w') ->leftJoin('mp_user u', 'u.id = w.user_id') ->where('w.status', 'pending') ->field('w.*,u.nickname as author_name,u.openid as author_openid') ->order('w.id', 'desc') ->select() ->toArray(); $list = []; foreach ($rows as $w) { $cats = Db::name('work_category')->where('work_id', $w['id'])->column('category'); $list[] = [ 'id' => (int) $w['id'], 'userId' => (int) $w['user_id'], 'imageUrl' => $w['cover_image'], 'title' => $w['title'], 'author' => $w['author_name'] ?: '用户', 'authorOpenid' => $this->maskOpenid((string) ($w['author_openid'] ?? '')), 'uploadDate' => date('Y-m-d', strtotime((string) $w['create_time'])), 'category' => $cats[0] ?? '', ]; } return json(['code' => 0, 'msg' => 'ok', 'data' => ['list' => $list]]); } /** 已拒绝列表(含拒绝原因摘要) */ public function rejectedList() { $rows = Db::name('work')->alias('w') ->leftJoin('mp_user u', 'u.id = w.user_id') ->where('w.status', 'rejected') ->field('w.*,u.nickname as author_name,u.openid as author_openid') ->order('w.update_time', 'desc') ->order('w.id', 'desc') ->select() ->toArray(); $list = []; foreach ($rows as $w) { $cats = Db::name('work_category')->where('work_id', $w['id'])->column('category'); $reason = trim((string) ($w['reject_reason'] ?? '')); $list[] = [ 'id' => (int) $w['id'], 'userId' => (int) $w['user_id'], 'imageUrl' => $w['cover_image'], 'title' => $w['title'], 'author' => $w['author_name'] ?: '用户', 'authorOpenid' => $this->maskOpenid((string) ($w['author_openid'] ?? '')), 'uploadDate' => date('Y-m-d', strtotime((string) $w['create_time'])), 'rejectDate' => date('Y-m-d', strtotime((string) ($w['update_time'] ?? 'now'))), 'rejectReason' => $reason, 'category' => $cats[0] ?? '', ]; } return json(['code' => 0, 'msg' => 'ok', 'data' => ['list' => $list]]); } /** 已通过列表(含排序);keyword 搜标题、作者昵称、作品 ID、日期(YYYY-MM-DD / YYYY-MM) */ public function approvedList() { $keyword = trim((string) $this->request->get('keyword', '')); $q = Db::name('work')->alias('w') ->leftJoin('mp_user u', 'u.id = w.user_id') ->where('w.status', 'approved') ->field('w.*,u.nickname as author_name,u.openid as author_openid'); if ($keyword !== '') { $like = '%' . addcslashes($keyword, '%_\\') . '%'; $clauses = ['w.title LIKE ?', 'u.nickname LIKE ?']; $bind = [$like, $like]; if (ctype_digit($keyword)) { $clauses[] = 'w.id = ?'; $bind[] = (int) $keyword; } if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $keyword)) { $clauses[] = 'DATE(w.create_time) = ?'; $bind[] = $keyword; $clauses[] = '(w.publish_date IS NOT NULL AND DATE(w.publish_date) = ?)'; $bind[] = $keyword; } elseif (preg_match('/^\d{4}-\d{2}$/', $keyword)) { $pfx = $keyword . '%'; $clauses[] = 'w.create_time LIKE ?'; $bind[] = $pfx; $clauses[] = 'w.publish_date LIKE ?'; $bind[] = $pfx; } $q->whereRaw('(' . implode(' OR ', $clauses) . ')', $bind); } $rows = $q->order('w.sort_order', 'asc') ->order('w.id', 'asc') ->select() ->toArray(); $list = []; foreach ($rows as $w) { $cats = Db::name('work_category')->where('work_id', $w['id'])->column('category'); $createTs = strtotime((string) ($w['create_time'] ?? '')); $pub = $w['publish_date'] ? (string) $w['publish_date'] : ''; $list[] = [ 'id' => (int) $w['id'], 'userId' => (int) $w['user_id'], 'imageUrl' => $w['cover_image'], 'title' => $w['title'], 'author' => $w['author_name'] ?: '用户', 'authorOpenid' => $this->maskOpenid((string) ($w['author_openid'] ?? '')), 'uploadDate' => $createTs ? date('Y-m-d', $createTs) : '', 'createTime' => (string) ($w['create_time'] ?? ''), 'publishDate' => $pub, 'approvedDate' => $pub !== '' ? $pub : date('Y-m-d', strtotime((string) ($w['update_time'] ?? 'now'))), 'updateTime' => (string) ($w['update_time'] ?? ''), 'category' => $cats[0] ?? '', 'order' => (int) $w['sort_order'], ]; } return json(['code' => 0, 'msg' => 'ok', 'data' => ['list' => $list]]); } /** 作品完整信息(审核用,含多图、类别、作者) */ public function detail(int $id) { if ($id <= 0) { return json(['code' => 400, 'msg' => '参数错误', 'data' => []]); } $w = Db::name('work')->alias('w') ->leftJoin('mp_user u', 'u.id = w.user_id') ->where('w.id', $id) ->field('w.*,u.nickname as author_name,u.openid as author_openid,u.phone as author_phone') ->find(); if (!$w) { return json(['code' => 404, 'msg' => '作品不存在', 'data' => []]); } $imgRows = Db::name('work_image') ->where('work_id', $id) ->order('sort', 'asc') ->order('id', 'asc') ->field('url,sort') ->select() ->toArray(); $images = []; foreach ($imgRows as $r) { $images[] = [ 'url' => (string) $r['url'], 'sort' => (int) $r['sort'], ]; } $cover = (string) ($w['cover_image'] ?? ''); if ($images === [] && $cover !== '') { $images[] = ['url' => $cover, 'sort' => 0]; } $cats = Db::name('work_category')->where('work_id', $id)->column('category'); return json([ 'code' => 0, 'msg' => 'ok', 'data' => [ 'work' => [ 'id' => (int) $w['id'], 'userId' => (int) $w['user_id'], 'title' => (string) $w['title'], 'description' => (string) $w['description'], 'shootDate' => $w['shoot_date'] ? (string) $w['shoot_date'] : '', 'status' => (string) $w['status'], 'coverImage' => $cover, 'likesCount' => (int) $w['likes_count'], 'createTime' => (string) ($w['create_time'] ?? ''), 'categories' => $cats, 'images' => $images, 'author' => $w['author_name'] ? (string) $w['author_name'] : '用户', 'authorOpenid' => $this->maskOpenid((string) ($w['author_openid'] ?? '')), 'authorPhone' => trim((string) ($w['author_phone'] ?? '')), 'rejectReason' => trim((string) ($w['reject_reason'] ?? '')), ], ], ]); } public function approve(int $id) { $w = Db::name('work')->where('id', $id)->where('status', 'pending')->find(); if (!$w) { return json(['code' => 404, 'msg' => '记录不存在', 'data' => []]); } $maxSort = (int) Db::name('work')->where('status', 'approved')->max('sort_order'); Db::name('work')->where('id', $id)->update([ 'status' => 'approved', 'publish_date' => date('Y-m-d'), 'sort_order' => $maxSort + 1, 'update_time' => date('Y-m-d H:i:s'), ]); return json(['code' => 0, 'msg' => '已通过', 'data' => []]); } public function reject(int $id) { $w = Db::name('work')->where('id', $id)->where('status', 'pending')->find(); if (!$w) { return json(['code' => 404, 'msg' => '记录不存在', 'data' => []]); } $reason = trim((string) $this->request->post('reason', '')); if ($reason === '' || mb_strlen($reason) > 500) { return json(['code' => 400, 'msg' => '请填写拒绝原因(1~500 字)', 'data' => []]); } Db::name('work')->where('id', $id)->update([ 'status' => 'rejected', 'reject_reason' => $reason, 'update_time' => date('Y-m-d H:i:s'), ]); return json(['code' => 0, 'msg' => '已拒绝', 'data' => []]); } /** 物理删除作品及关联数据(待审核 / 已通过 / 已拒绝均可) */ public function delete(int $id) { if ($id <= 0) { return json(['code' => 400, 'msg' => '参数错误', 'data' => []]); } $w = Db::name('work')->where('id', $id)->find(); if (!$w) { return json(['code' => 404, 'msg' => '记录不存在', 'data' => []]); } Db::transaction(function () use ($id): void { Db::name('work_like')->where('work_id', $id)->delete(); Db::name('work_category')->where('work_id', $id)->delete(); Db::name('work_image')->where('work_id', $id)->delete(); Db::name('work')->where('id', $id)->delete(); }); return json(['code' => 0, 'msg' => '已删除', 'data' => []]); } /** body: { "ids": [3,1,2] } 按数组顺序写 sort_order */ public function sortApproved() { $ids = $this->request->post('ids', []); if (!is_array($ids) || $ids === []) { return json(['code' => 400, 'msg' => 'ids 必填', 'data' => []]); } $i = 1; foreach ($ids as $id) { $id = (int) $id; if ($id <= 0) { continue; } Db::name('work')->where('id', $id)->where('status', 'approved')->update([ 'sort_order' => $i++, 'update_time' => date('Y-m-d H:i:s'), ]); } return json(['code' => 0, 'msg' => '已更新排序', 'data' => []]); } }