manghe/app/api/controller/News.php
2025-06-22 19:12:07 +08:00

260 lines
7.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace app\api\controller;
use app\api\controller\Base;
use app\common\model\News as NewsModel;
use app\common\model\UserNewsFavorite;
class News extends Base
{
/**
* 获取精选新闻列表
* @return \think\Response
*/
public function getFeaturedNewsList()
{
$where = [];
$where['status'] = 1;
$where['is_featured'] = 1;
$limit = $this->request->param('limit', 10);
$title = $this->request->param('title', '');
if ($title) {
$where[] = ['title', 'like', '%' . $title . '%'];
}
$newsList = NewsModel::getList($where, 'id,title,cover_image,publish_time', 'publish_time desc', $limit);
return $this->renderSuccess('', $newsList);
}
/**
* 获取热榜新闻列表
* @return \think\Response
*/
public function getHotNewsList()
{
$where = [];
$where['status'] = 1;
$where['is_hot'] = 1;
$title = $this->request->param('title', '');
if ($title) {
$where[] = ['title', 'like', '%' . $title . '%'];
}
$limit = $this->request->param('limit', 10);
$newsList = NewsModel::getList($where, 'id,title,cover_image,publish_time,is_hot', 'publish_time desc', $limit);
return $this->renderSuccess('', $newsList);
}
/**
* 获取用户关注的新闻列表
* @return \think\Response
*/
public function getFollowNewsList()
{
$title = $this->request->param('title', '');
$limit = intval($this->request->param('limit', 10));
$page = intval($this->request->param('page', 1));
$userId = $this->getUserId();
if ($userId == 0) {
return $this->renderSuccess('', ['list' => [], 'count' => 0]);
}
// 构建查询
$model = NewsModel::alias('n')
->join('user_news_favorite u', 'n.id=u.news_id')
->where('u.user_id', '=', $userId)
->where('u.is_canceled', '=', 0)
->where('n.status', '=', 1);
// 如果有标题搜索条件
if ($title) {
$model = $model->where('n.title', 'like', '%' . $title . '%');
}
// 获取总数
$count = $model->count();
// 查询数据并分页
$list = $model->field('n.id, n.title, n.cover_image, n.publish_time, n.author_name')
->order('u.create_time', 'desc')
->page($page, $limit)
->select()
->toArray();
return $this->renderSuccess('', [
'list' => $list,
'count' => $count,
'limit' => $limit,
'page' => $page
]);
}
/**
* 获取新闻详情
* @return \think\Response
*/
public function getNewsDetail()
{
$id = $this->request->param('id', 0);
//来源 0: 热榜1精选2关注
$current = $this->request->param('current', 0);
$newsInfo = NewsModel::getInfo(['id' => $id], 'id,title,cover_image,publish_time,content,author_name');
if (!$newsInfo) {
return $this->renderError('新闻不存在');
}
$newsInfo['content'] = htmlspecialchars_decode($newsInfo['content']);
// 获取上下篇数据
$condition = $this->getCondition($current);
if ($condition) {
// 获取上一篇(发布时间小于当前文章)
$newsInfo['next_data'] = $this->getAdjacentNews($id, $newsInfo['publish_time'], $condition, '<', 'desc');
// 获取下一篇(发布时间大于当前文章)
$newsInfo['prev_data'] = $this->getAdjacentNews($id, $newsInfo['publish_time'], $condition, '>', 'asc');
} else {
$newsInfo['next_data'] = null;
$newsInfo['prev_data'] = null;
}
$newsInfo['user_follow'] = false;
$userId = $this->getUserId();
if ($userId > 0) {
$newsInfo['user_follow'] = UserNewsFavorite::isFavorite($userId, $id);
}
// 随机查询5条新闻数据
$re = NewsModel::where('status', 1)
->where($condition, '=', 1)
->where('cover_image', '!=', '')
->field('id,title,cover_image,publish_time,author_name,is_hot,is_featured')
->orderRaw('rand()')
->limit(5)
->select()
->toArray();
$newsInfo['recommend_news'] = $re;
// $newsInfo['publish_time'] = date('Y-m-d H:i:s', $newsInfo['publish_time']);
return $this->renderSuccess('', $newsInfo);
}
/**
* 根据来源类型获取条件
* @param int $current 来源类型 0: 热榜1精选2关注
* @return string|null 对应的条件字段
*/
private function getCondition($current)
{
switch ($current) {
case 0:
return 'is_hot';
case 1:
return 'is_featured';
case 2:
// 可以根据需求扩展
// return 'is_follow';
return null;
default:
return null;
}
}
/**
* 获取相邻的新闻
* @param int $id 当前新闻ID
* @param int $publishTime 当前发布时间
* @param string $condition 条件字段
* @param string $comparison 比较符号
* @param string $orderType 排序方式
* @return mixed 查询结果
*/
private function getAdjacentNews($id, $publishTime, $condition, $comparison, $orderType)
{
return NewsModel::where('id', '!=', $id)
->where($condition, '=', 1)
->where('status', '=', 1)
->where('publish_time', $comparison, $publishTime)
->field('id,title,cover_image,publish_time,is_hot,is_featured')
->order('publish_time ' . $orderType)
->find();
}
/**
* 收藏新闻
* @return \think\Response
*/
public function addFavorite()
{
$newsId = $this->request->param('news_id', 0);
if (empty($newsId)) {
return $this->renderError('参数错误');
}
// 检查新闻是否存在
$newsInfo = NewsModel::getInfo(['id' => $newsId], 'id');
if (!$newsInfo) {
return $this->renderError('新闻不存在');
}
// 获取当前用户ID
$userId = $this->getUserId();
if (!$userId) {
return $this->renderError('请先登录');
}
// 添加收藏
$result = UserNewsFavorite::addFavorite($userId, $newsId);
if ($result) {
return $this->renderSuccess('收藏成功');
}
return $this->renderError('收藏失败');
}
/**
* 取消收藏新闻
* @return \think\Response
*/
public function cancelFavorite()
{
$newsId = $this->request->param('news_id', 0);
if (empty($newsId)) {
return $this->renderError('参数错误');
}
// 获取当前用户ID
$userId = $this->getUserId();
if (!$userId) {
return $this->renderError('请先登录');
}
// 取消收藏
$result = UserNewsFavorite::cancelFavorite($userId, $newsId);
if ($result) {
return $this->renderSuccess('取消收藏成功');
}
return $this->renderError('取消收藏失败或未收藏该新闻');
}
/**
* 检查新闻是否已收藏
* @return \think\Response
*/
public function checkFavorite()
{
$newsId = $this->request->param('news_id', 0);
if (empty($newsId)) {
return $this->renderError('参数错误');
}
// 获取当前用户ID
$userId = $this->getUserId();
if (!$userId) {
return $this->renderError('请先登录');
}
// 检查是否已收藏
$favorite = UserNewsFavorite::isFavorite($userId, $newsId);
return $this->renderSuccess('', ['is_favorite' => $favorite ? true : false]);
}
}