zzwy2/app/model/Article.php

644 lines
22 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace app\model;
use think\model\relation\HasOne;
use think\Paginator;
class Article extends Base
{
public const STATUS_NORMAL = 1; // 正常
public const STATUS_DISABLE = 0; // 禁用
// 文章属性(默认)
protected static $defaultAttributeList = [
'top' => '置顶',
'hot' => '热门',
'recommend' => '推荐',
];
/**
* 栏目
* @return HasOne
*/
public function archivesCategory(): HasOne
{
return $this->hasOne(Category::class, 'id', 'category_id');
}
public static function getAttributeList(array $categoryIds = [])
{
$data = [];
$recommendCategoryList = [];
if (count(array_intersect($categoryIds, $recommendCategoryList)) > 0) {
$data['recommend'] = '推荐';
}
// 新闻动态
$communityCategoryIds = Category::getCategoryWithChildrenIds(Category::CATEGORY_NEWS);
if (count(array_intersect($categoryIds, $communityCategoryIds)) > 0) {
$data['top'] = '置顶';
$data['hot'] = '热门';
$data['recommend'] = '推荐';
}
return $data;
}
/*********************************************
* 分割线
*********************************************/
//获取最高访问的文章列表
public static function getMostVisited($limit = 5)
{
if ($limit <= 0) {
$limit = 5;
}
return self::with(["archivesCategory"])
->order('views', 'desc')
->limit($limit)
->select();
}
//获取栏目下最新记录
public static function getLatestByCategory($categoryId, $limit = 5)
{
if (empty($categoryId)) {
return [];
}
if ($limit <= 0) {
$limit = 5;
}
return self::with(["archivesCategory"])
->where('category_id', $categoryId)
->order('id', 'desc')
->limit($limit)
->select();
}
//根据文章ID和栏目ID获取下一篇文章
public static function getNextArticleBySortAndCategoryId($sort, $categoryId)
{
return self::with(["archivesCategory"])
->where('sort', '<', $sort)
->where('category_id', $categoryId)
->where('status', 1)
->order('sort', 'desc')
->find();
}
//根据文章ID和栏目ID获取上一篇文章
public static function getPrevArticleBySortAndCategoryId($sort, $categoryId)
{
return self::with(["archivesCategory"])
->where('sort', '>', $sort)
->where('category_id', $categoryId)
->where('status', 1)
->order('sort', 'asc')
->find();
}
//根据栏目ID获取文章列表
public static function getListByCategory($categoryId, $limit = 10)
{
return self::with(["archivesCategory"])
->where('category_id', $categoryId)
->where('status', 1)
->order("sort", 'desc')
->limit($limit)
->select();
}
//根据栏目ID获取文章分页列表
public static function getListPageByCategory($categoryId, $per = 20, $keyword = '')
{
$where = [
['category_id', '=', $categoryId],
['status', '=', 1],
];
$param['category_id'] = $categoryId;
if ($keyword != '') {
$where[] = ['title', 'like', '%'.$keyword.'%'];
$param['keyword'] = $keyword;
}
$paginate = [
'list_rows' => $per,
'query' => $param
];
return self::with(["archivesCategory"])
->where($where)
->order("sort", 'desc')
->paginate($paginate, false);
}
//根据栏目ID获取文章数量状态正常
public static function getNormalListCount($categoryId)
{
$where = [
['category_id', '=', $categoryId],
['status', '=', 1],
];
return self::where($where)
->count();
}
public static function onAfterInsert($article)
{
$article->sort = $article->id;
$article->create_time = $article->update_time = time();
$auth = session('auth');
$article->created = $article->updated = $auth['userName'];
$article->save();
}
/**
* 获取文章列表
* @param int $categoryId 分类ID
* @param int $per 每页数量
* @param string $keyword 关键词
* @param array $param 文章类型:置顶、热门、推荐 ['top','hot','recommend']
* @param int $status 文章状态,-1表示不限制
* @param array $orderList 排序
* @param bool $onlyChild 仅获取下级 默认true false=获取所有后代分类
* @return Paginator
*/
public static function getList($categoryId, $per = 20, $keyword = '', $param = [], $status = -1, $orderList = ['top' => 'desc','sort' => 'desc'], bool $onlyChild = true, $prev = '')
{
$whereMap = [];
$pageParam = [];
if (is_numeric($categoryId) && $categoryId > 0) {
$children = Category::getChildrenByParentId($categoryId, $onlyChild);
if (!empty($children)) {
$categoryIds = [$categoryId];
foreach ($children as $child) {
if ($child['model_id'] == Model::MODEL_ARTICLE) {
$categoryIds[] = $child['id'];
}
}
$whereMap[] = ['category_id', 'in', $categoryIds];
} else {
$whereMap[] = ['category_id', '=', $categoryId];
}
$pageParam['category_id'] = $categoryId;
}
if (!empty($keyword)) {
$whereMap[] = ['title', 'like', '%'.$keyword.'%'];
$pageParam['keyword'] = $keyword;
}
if (is_array($param) && count($param) > 0) {
$pageParam['param'] = $param;
foreach ($param as $vo) {
if (in_array($vo, ['top', 'hot', 'recommend', 'is_prev'], true)) {
$whereMap[] = ["{$vo}", '=', 1];
}
}
}
if (!empty($prev) || $prev == '0') {
$whereMap[] = ['is_prev', '=', $prev];
$pageParam['is_prev'] = $prev;
}
$paginate = [
'list_rows' => $per,
'query' => $pageParam
];
return self::with(["archivesCategory"])
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
$query->where($whereMap);
})
->when($status != -1, function ($query) use ($status) {
$query->where('status', $status);
})
->order($orderList)
->paginate($paginate, false);
}
/**
* @param array $where
* @return \think\Paginator
* @throws \think\db\exception\DbException
*/
public static function getListByWhere(array $where)
{
$categoryId = $where['category_id'];
$per = $where['size'];
$keyword = $where['keyword'] ?? '';
$param = $where['param'] ?? [];
$status = $where['status'] ?? -1;
$orderList = $where['order'] ?? ['sort' => 'desc'];
$onlyChild = $where['only_child'] ?? true;
$whereList = $where['where'] ?? [];
$whereMap = [];
$pageParam = [];
if (!empty($whereList)) {
foreach ($whereList as $w) {
$whereMap[] = $w;
}
}
if (is_numeric($categoryId) && $categoryId > 0) {
$children = Category::getChildrenByParentId($categoryId, $onlyChild);
if (!empty($children)) {
$categoryIds = [$categoryId];
foreach ($children as $child) {
if ($child['model_id'] == Model::MODEL_ARTICLE) {
$categoryIds[] = $child['id'];
}
}
$whereMap[] = ['category_id', 'in', $categoryIds];
} else {
$whereMap[] = ['category_id', '=', $categoryId];
}
$pageParam['category_id'] = $categoryId;
}
if (!empty($keyword)) {
$whereMap[] = ['title', 'like', '%'.$keyword.'%'];
$pageParam['keyword'] = $keyword;
}
if (is_array($param) && count($param) > 0) {
$pageParam['param'] = $param;
foreach ($param as $vo) {
if (in_array($vo, ['top', 'hot', 'recommend', 'is_prev'], true)) {
$whereMap[] = ["{$vo}", '=', 1];
}
}
}
$paginate = [
'list_rows' => $per,
'query' => $pageParam
];
return self::with(["archivesCategory"])
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
$query->where($whereMap);
})
->when($status != -1, function ($query) use ($status) {
$query->where('status', $status);
})
->order($orderList)
->paginate($paginate, false);
}
//获取文章涉及到的图片
public static function getFilesInUse()
{
$items = self::select()->toArray();
$data = [];
foreach ($items as $item) {
$src = trim($item['src']);
if (!empty($src)) {
$key = getKeyByPath($src);
$data[$key] = $src;
}
$imgs = getImageUrlFromText($item['content']);
if (!empty($imgs)) {
$data = array_merge($data, $imgs);
}
$videos = getVideoUrlFromText($item['content']);
if (!empty($videos)) {
$data = array_merge($data, $videos);
}
}
return $data;
}
//推荐列表(其他推荐类)
public static function getRecommendList($categoryId, $recommend = '', $limit = 3, $excludeIds = [], $orderList = ['a.id' => 'desc'])
{
if (empty($categoryId) || empty($recommend)) {
return [];
}
$whereMap = [];
if (is_numeric($categoryId) && $categoryId > 0) {
$children = Category::getChildrenByParentId($categoryId);
if (!empty($children)) {
$categoryIds = [$categoryId];
foreach ($children as $child) {
if ($child['model_id'] == Model::MODEL_ARTICLE) {
$categoryIds[] = $child['id'];
}
}
$whereMap[] = ['category_id', 'in', $categoryIds];
} else {
$whereMap[] = ['category_id', '=', $categoryId];
}
}
if (!empty($excludeIds)) {
$whereMap[] = ['id', 'not in', $excludeIds];
}
return self::with(["archivesCategory"])
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
$query->where($whereMap);
})
->whereRaw("FIND_IN_SET(:recommend, `recommend_other`)", ['recommend' => $recommend])
->where('status', 1)
->order($orderList)
->limit($limit)
->select();
}
// 转换文章的推荐设置
public static function convertRecommendOther($categoryIds = [], $articles, $isMulti = true)
{
if (empty($articles) || count($articles) == 0) {
return $articles;
}
$attributeList = self::getAttributeList($categoryIds);
if ($isMulti) {
foreach ($articles as &$article) {
$recommendOtherList = [];
$recommendOtherStrList = [];
if (isset($article['recommend_other']) && !empty($article['recommend_other'])) {
$recommendOtherList = explode(',', $article['recommend_other']);
foreach ($recommendOtherList as $recommendKey) {
if (isset($attributeList[$recommendKey]) && !empty($attributeList[$recommendKey])) {
$recommendOtherStrList[] = $attributeList[$recommendKey];
}
}
}
$article['recommend_other_list'] = $recommendOtherList;
$article['recommend_other_str'] = implode(',', $recommendOtherStrList);
}
unset($article);
} else {
$recommendOtherList = [];
$recommendOtherStrList = [];
if (isset($articles['recommend_other']) && !empty($articles['recommend_other'])) {
$recommendOtherList = explode(',', $articles['recommend_other']);
foreach ($recommendOtherList as $recommendKey) {
if (isset($attributeList[$recommendKey]) && !empty($attributeList[$recommendKey])) {
$recommendOtherStrList[] = $attributeList[$recommendKey];
}
}
}
$articles['recommend_other_list'] = $recommendOtherList;
$articles['recommend_other_str'] = implode(',', $recommendOtherStrList);
}
return $articles;
}
// 获取最新动态
public static function getLastDynamicsList($categoryId, $withChild = false, $limit = 10)
{
$categoryIds = [$categoryId];
if ($withChild) {
$childCategories = Category::getChildrenByParentId($categoryId);
if (!empty($childCategories)) {
foreach ($childCategories as $category) {
if ($category['model_id'] == Model::MODEL_ARTICLE) {
$categoryIds[] = $category['id'];
}
}
}
}
return self::with(["archivesCategory"])
->whereIn('category_id', $categoryIds)
->where('status', 1)
->order('id', 'desc')
->limit($limit)
->select();
}
//根据文章ID和栏目IDs默认按创建时间获取下一篇文章
public static function getNextArticleByTimeAndCategoryIds(array $where, $sortOrder = ['id' => 'desc'])
{
return self::with(["archivesCategory"])
->where($where)
->where('status', 1)
->order($sortOrder)
->find();
}
//根据文章ID和栏目IDs默认按创建时间获取上一篇文章
public static function getPrevArticleByTimeAndCategoryIds(array $where, $sortOrder = ['id' => 'asc'])
{
return self::with(["archivesCategory"])
// ->where('a.id','>',$curId)
// ->whereIn('a.category_id', $categoryIds)
->where($where)
->where('status', 1)
->order($sortOrder)
->find();
}
public static function getLastTopList($categoryId, $limit = 3, $excludeIds = [], $orderList = ['recommend_other' => 'desc', 'id' => 'desc'])
{
if (empty($categoryId)) {
return [];
}
$whereMap = [];
if (is_numeric($categoryId) && $categoryId > 0) {
$children = Category::getChildrenByParentId($categoryId);
if (!empty($children)) {
$categoryIds = [$categoryId];
foreach ($children as $child) {
if ($child['model_id'] == Model::MODEL_ARTICLE) {
$categoryIds[] = $child['id'];
}
}
$whereMap[] = ['category_id', 'in', $categoryIds];
} else {
$whereMap[] = ['category_id', '=', $categoryId];
}
}
if (!empty($excludeIds)) {
$whereMap[] = ['id', 'not in', $excludeIds];
}
$items = self::with(["archivesCategory"])
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
$query->where($whereMap);
})
->where('status', 1)
->order($orderList);
if ($limit > 0) {
$items = $items->limit($limit);
}
$items = $items->limit($limit)
->select();
return $items;
}
// 分页获取最新动态
public static function getLastDynamicsPageList($categoryId, $withChild = true, $per = 20)
{
$categoryIds = [$categoryId];
if ($withChild) {
$childCategories = Category::getChildrenByParentId($categoryId);
if (!empty($childCategories)) {
foreach ($childCategories as $category) {
if ($category['model_id'] == Model::MODEL_ARTICLE) {
$categoryIds[] = $category['id'];
}
}
}
}
$paginate = [
'list_rows' => $per,
'query' => [
'category_id' => $categoryId
]
];
return self::with(["archivesCategory"])
->whereIn('category_id', $categoryIds)
->where('status', 1)
->order('id', 'desc')
->paginate($paginate, false);
}
// 根据栏目ID进行分组按sort倒序排列每组最多获取n条(默认10条)数据
public static function getGroupListByCategoryIds(array $categoryIds, int $size = 10)
{
return self::alias('ca')
->where($size, '>', function ($q) {
$q->table('bee_article cb')
->whereRaw('ca.category_id = cb.category_id and ca.sort < cb.sort')->field('count(*)');
})
->whereIn('ca.category_id', $categoryIds)
->field('ca.*')
->order(['ca.sort' => 'desc'])
->select();
}
public static function parseList($items)
{
try {
$tagNameList = [];
foreach ($items as $ki => $item) {
$tagStr = trim($item['tag'] ?? '');
$tagNames = empty($tagStr) ? [] : explode(',', $tagStr);
$tagNameList = array_merge($tagNameList, $tagNames);
}
$tagNameList = array_unique($tagNameList);
$tagKVs = ArticleTags::findByNames($tagNameList)->column('id', 'name');
foreach ($items as $ki => $item) {
$tagStr = trim($item['tag'] ?? '');
$tagNames = empty($tagStr) ? [] : explode(',', $tagStr);
$tagList = [];
foreach ($tagNames as $tagName) {
$tagList[] = [
'name' => $tagName,
'id' => $tagKVs[$tagName] ?? 0
];
}
$items[$ki]['tag_list'] = $tagList;
$createTime = is_numeric($item['create_time']) ? $item['create_time'] : strtotime($item['create_time']);
$items[$ki]['create_date'] = date('Y-m-d', $createTime);
$item['create_dateTime'] = date('Y-m-d H:i:s', $createTime);
}
} catch (\Exception $e) {
}
return $items;
}
public static function parseInfo($item)
{
if ($item) {
$tagStr = trim($item['tag'] ?? '');
$tagNameList = empty($tagStr) ? [] : explode(',', $tagStr);
$tagKVs = ArticleTags::findByNames($tagNameList)->column('id', 'name');
$tagList = [];
foreach ($tagNameList as $tagName) {
$tagList[] = [
'name' => $tagName,
'id' => $tagKVs[$tagName] ?? 0
];
}
$item['tag_list'] = $tagList;
$createTime = is_numeric($item['create_time']) ? $item['create_time'] : strtotime($item['create_time']);
$item['create_date'] = date('Y-m-d', $createTime);
$item['create_dateTime'] = date('Y-m-d H:i:s', $createTime);
$item['create_y_m_d'] = date('Y.m.d', $createTime);
}
return $item;
}
public static function countList(array $where, callable $call = null)
{
$q = new static();
$q = $q->where($where);
if ($call) {
$q = $call($q);
}
return $q->count();
}
public static function findListByWhere(array $where, int $page = 1, int $size = 10, callable $call = null, array $sortList = ['sort' => 'desc'])
{
$q = new static();
$q = $q->with(["archivesCategory"])->where($where);
if ($call) {
$q = $call($q);
}
if ($size > 0) {
$q = $q->page($page, $size);
}
if (count($sortList)) {
$q = $q->order($sortList);
}
return $q->select();
}
public static function getTeam()
{
$categoryIds = Category::where('parent_id', Category::CATEGORY_INFO)->order('sort', 'asc')->column('title', 'id');
$list = self::with(["archivesCategory"])
->whereIn("category_id", array_keys($categoryIds))
->order(["sort" => "desc", "id" => "desc"])
->select();
$data = [];
foreach ($categoryIds as $categoryId => $title) {
if (!isset($data[$categoryId])) {
$data[$categoryId]['title'] = $title;
$data[$categoryId]['list'] = [];
}
foreach ($list as $item) {
if ($item['category_id'] == $categoryId) {
$data[$categoryId]['list'][] = $item;
}
}
}
return $data;
}
public static function getIndexTop($categoryId)
{
return self::with(["archivesCategory"])
->where("category_id", $categoryId)
->where("top", 1)
->order(["sort" => "desc"])
->find();
}
public static function getIndexList($categoryId, $num)
{
return self::with(["archivesCategory"])
->where("category_id", $categoryId)
->where("top", "<>", 1)
->order(['sort' => 'desc', "id" => "desc"])
->limit($num)
->select();
}
}