314 行
9.8 KiB
PHP
314 行
9.8 KiB
PHP
<?php
|
||
|
||
namespace app\admin\controller\fc;
|
||
|
||
use app\admin\model\AdminLog;
|
||
use app\common\controller\Backend;
|
||
use think\Db;
|
||
|
||
/**
|
||
* 同城-信息审核中心
|
||
*
|
||
* @icon fa fa-check-square-o
|
||
*/
|
||
class Postaudit extends Backend
|
||
{
|
||
/**
|
||
* FcPost模型对象
|
||
* @var \app\admin\model\FcPost
|
||
*/
|
||
protected $model = null;
|
||
|
||
/**
|
||
* 无需鉴权的方法(只读辅助接口)
|
||
* @var array
|
||
*/
|
||
protected $noNeedRight = ['detail', 'queue'];
|
||
|
||
/**
|
||
* 初始化控制器
|
||
*
|
||
* @return void
|
||
*/
|
||
public function _initialize()
|
||
{
|
||
parent::_initialize();
|
||
$this->model = new \app\admin\model\FcPost;
|
||
}
|
||
|
||
/**
|
||
* 查看待审核信息列表
|
||
*
|
||
* 默认展示待审核(audit_status=0)的数据,支持通用搜索
|
||
*
|
||
* @return string|\think\response\Json
|
||
* @throws \think\Exception
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
* @throws \think\exception\DbException
|
||
*/
|
||
public function index()
|
||
{
|
||
$this->request->filter(['strip_tags', 'trim']);
|
||
if (false === $this->request->isAjax()) {
|
||
return $this->view->fetch();
|
||
}
|
||
if ($this->request->request('keyField')) {
|
||
return $this->selectpage();
|
||
}
|
||
|
||
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
|
||
|
||
// 如果通用搜索未指定审核状态,默认只展示待审核信息(audit_status = 0)
|
||
$filter = (array)json_decode($this->request->get('filter', ''), true);
|
||
$hasAuditFilter = isset($filter['audit_status']) && $filter['audit_status'] !== '';
|
||
|
||
$query = $this->model->where($where);
|
||
if (!$hasAuditFilter) {
|
||
$query->where('audit_status', 0);
|
||
}
|
||
|
||
$list = $query
|
||
->order('id', 'desc')
|
||
->paginate($limit);
|
||
|
||
$result = ['total' => $list->total(), 'rows' => $list->items()];
|
||
return json($result);
|
||
}
|
||
|
||
/**
|
||
* 审核处理接口(支持单条与批量)
|
||
*
|
||
* @return void
|
||
* @throws \think\Exception
|
||
*/
|
||
public function audit()
|
||
{
|
||
$ids = $this->request->post('ids');
|
||
$auditStatus = (int)$this->request->post('auditStatus');
|
||
$reason = trim((string)$this->request->post('reason', ''));
|
||
|
||
if (!in_array($auditStatus, [1, 2], true)) {
|
||
$this->error('审核状态仅支持通过(1)或驳回(2)');
|
||
}
|
||
$ids = $this->normalizeIds($ids);
|
||
if (!$ids) {
|
||
$this->error('请选择要审核的信息');
|
||
}
|
||
if ($auditStatus === 2 && $reason === '') {
|
||
$this->error('请填写驳回原因');
|
||
}
|
||
if (mb_strlen($reason, 'utf-8') > 200) {
|
||
$reason = mb_substr($reason, 0, 200, 'utf-8');
|
||
}
|
||
|
||
$posts = Db::name('fc_post')->where('id', 'in', $ids)->whereNull('deletetime')->select();
|
||
if (!$posts) {
|
||
$this->error('信息不存在或已删除');
|
||
}
|
||
|
||
$changed = 0;
|
||
$skipped = 0;
|
||
Db::startTrans();
|
||
try {
|
||
foreach ($posts as $post) {
|
||
$from = (int)$post['audit_status'];
|
||
if ($from === $auditStatus) {
|
||
$skipped++;
|
||
continue;
|
||
}
|
||
|
||
Db::name('fc_post')->where('id', $post['id'])->update([
|
||
'audit_status' => $auditStatus,
|
||
'audit_reason' => $reason,
|
||
'updatetime' => time(),
|
||
]);
|
||
|
||
// 分类信息量维护
|
||
if (!empty($post['category_id'])) {
|
||
if ($auditStatus === 1 && $from !== 1) {
|
||
Db::name('fc_category')->where('id', $post['category_id'])->setInc('post_count');
|
||
} elseif ($auditStatus === 2 && $from === 1) {
|
||
Db::name('fc_category')
|
||
->where('id', $post['category_id'])
|
||
->where('post_count', '>', 0)
|
||
->setDec('post_count');
|
||
}
|
||
}
|
||
|
||
// 站内信通知发布用户
|
||
Db::name('fc_message')->insert([
|
||
'user_id' => $post['user_id'],
|
||
'type' => 'system',
|
||
'title' => $auditStatus === 1 ? '信息审核通过' : '信息审核未通过',
|
||
'content' => $auditStatus === 1
|
||
? sprintf('您发布的信息「%s」已通过审核并上架展示。', $post['title'])
|
||
: sprintf('您发布的信息「%s」未通过审核,原因:%s', $post['title'], $reason),
|
||
'target_id' => $post['id'],
|
||
'target_type'=> 'post',
|
||
'status' => 0,
|
||
'createtime' => time(),
|
||
]);
|
||
|
||
$changed++;
|
||
}
|
||
Db::commit();
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
$this->error('审核处理失败:' . $e->getMessage());
|
||
}
|
||
|
||
$actionText = $auditStatus === 1 ? '审核通过' : '审核驳回';
|
||
AdminLog::record(sprintf('%s,涉及 %d 条信息(成功 %d 条,跳过 %d 条)', $actionText, count($ids), $changed, $skipped));
|
||
|
||
$msg = $changed > 0
|
||
? sprintf('%s成功(已处理 %d 条)', $actionText, $changed)
|
||
: '所选信息已处于该状态,未重复处理';
|
||
$this->success($msg);
|
||
}
|
||
|
||
/**
|
||
* 快捷通过接口
|
||
*
|
||
* @return void
|
||
*/
|
||
public function pass()
|
||
{
|
||
$this->request->post(['auditStatus' => 1, 'reason' => '']);
|
||
$this->audit();
|
||
}
|
||
|
||
/**
|
||
* 快捷驳回接口
|
||
*
|
||
* @return void
|
||
*/
|
||
public function reject()
|
||
{
|
||
$this->request->post(['auditStatus' => 2]);
|
||
$this->audit();
|
||
}
|
||
|
||
/**
|
||
* 查看信息详情或进入专属审核工作台
|
||
*
|
||
* @param int|null $ids 信息ID
|
||
* @return string|\think\response\Json
|
||
*/
|
||
public function detail($ids = null)
|
||
{
|
||
$id = $this->request->param('ids', 0) ?: $this->request->param('id/d', 0);
|
||
if (!$id) {
|
||
$this->error('缺少参数ID');
|
||
}
|
||
$row = $this->model->where('id', $id)->find();
|
||
if (!$row) {
|
||
$this->error('信息不存在或已删除');
|
||
}
|
||
|
||
// 补齐分类名称
|
||
if ($row->category_id) {
|
||
$category = Db::name('fc_category')->where('id', $row->category_id)->find();
|
||
$row->category_name = $category ? $category['name'] : '未分类';
|
||
} else {
|
||
$row->category_name = '未分类';
|
||
}
|
||
|
||
// 解析多图相册
|
||
$mediaList = [];
|
||
$rawMedia = $row->getData('media');
|
||
if (!empty($rawMedia)) {
|
||
$decoded = is_string($rawMedia) ? json_decode($rawMedia, true) : $rawMedia;
|
||
if (is_array($decoded)) {
|
||
$mediaList = array_values(array_filter($decoded));
|
||
} else {
|
||
$mediaList = array_values(array_filter(explode(',', (string)$rawMedia)));
|
||
}
|
||
}
|
||
if (empty($mediaList) && !empty($row->cover)) {
|
||
$mediaList[] = $row->cover;
|
||
}
|
||
|
||
// 获取发布用户画像
|
||
$userInfo = [
|
||
'id' => $row->user_id,
|
||
'nickname' => $row->user_name ?: '未知用户',
|
||
'mobile' => '',
|
||
'avatar' => '/assets/img/avatar.png',
|
||
'post_count' => 0
|
||
];
|
||
$user = Db::name('user')->where('id', $row->user_id)->field('id,nickname,mobile,avatar')->find();
|
||
if ($user) {
|
||
$userInfo['nickname'] = $user['nickname'] ?: $userInfo['nickname'];
|
||
$userInfo['mobile'] = $user['mobile'] ?: '';
|
||
$userInfo['avatar'] = $user['avatar'] ?: $userInfo['avatar'];
|
||
$userInfo['post_count'] = Db::name('fc_post')->where('user_id', $user['id'])->count();
|
||
}
|
||
|
||
$mode = $this->request->param('mode', 'audit');
|
||
$this->view->assign('mode', $mode);
|
||
$this->view->assign('row', $row);
|
||
$this->view->assign('userInfo', $userInfo);
|
||
$this->view->assign('mediaList', $mediaList);
|
||
$this->view->assign('queue', $this->auditQueue($row->getData()));
|
||
|
||
if ($mode === 'audit') {
|
||
return $this->view->fetch('fc/post/audit');
|
||
}
|
||
return $this->view->fetch('fc/post/detail');
|
||
}
|
||
|
||
/**
|
||
* 计算待审核队列的上下文(第几条、总数、上一条、下一条)
|
||
*
|
||
* @param array $current 当前信息数组
|
||
* @return array
|
||
*/
|
||
protected function auditQueue(array $current)
|
||
{
|
||
$id = (int)$current['id'];
|
||
$pendingIds = Db::name('fc_post')
|
||
->whereNull('deletetime')
|
||
->where('audit_status', 0)
|
||
->order('id', 'desc')
|
||
->column('id');
|
||
|
||
$total = count($pendingIds);
|
||
$pos = array_search($id, $pendingIds, true);
|
||
if ($pos === false) {
|
||
return ['index' => 0, 'total' => $total, 'prev' => 0, 'next' => 0];
|
||
}
|
||
|
||
$prevId = $pos > 0 ? $pendingIds[$pos - 1] : 0;
|
||
$nextId = $pos + 1 < $total ? $pendingIds[$pos + 1] : 0;
|
||
return [
|
||
'index' => $pos + 1,
|
||
'total' => $total,
|
||
'prev' => $prevId,
|
||
'next' => $nextId,
|
||
];
|
||
}
|
||
|
||
/**
|
||
* 解析请求中的 ID 数组
|
||
*
|
||
* @param mixed $ids 前端提交的ID
|
||
* @return array
|
||
*/
|
||
protected function normalizeIds($ids)
|
||
{
|
||
if (is_array($ids)) {
|
||
$arr = $ids;
|
||
} elseif (is_string($ids)) {
|
||
$arr = explode(',', $ids);
|
||
} else {
|
||
$arr = [$ids];
|
||
}
|
||
$arr = array_map('intval', $arr);
|
||
$arr = array_filter($arr, function ($v) {
|
||
return $v > 0;
|
||
});
|
||
return array_values(array_unique($arr));
|
||
}
|
||
}
|