文件
fenleixinxi/application/admin/controller/fc/Postaudit.php

314 行
9.8 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?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));
}
}