Files
ulthon_information/app/api/controller/Articles.php
augushong a09f7397cd fix: 将文章默认类型从'1'更改为'3'
当创建文章未指定类型时,系统原默认设置为'1',现根据业务需求调整为'3'以匹配新的文章分类标准。
2026-05-01 20:37:38 +08:00

312 lines
9.8 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\BaseController;
use app\model\Post;
use app\model\PostCategory;
use app\model\PostTag;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\Table\TableExtension;
use League\CommonMark\MarkdownConverter;
use think\Request;
class Articles extends BaseController
{
protected $middleware = [\app\middleware\ApiKeyAuth::class];
/**
* 文章列表
*/
public function index(Request $request)
{
$page = $request->param('page', 1, 'intval');
$limit = $request->param('limit', 15, 'intval');
$type = $request->param('type', '');
$category_id = $request->param('category_id', 0, 'intval');
$keyword = $request->param('keyword', '');
$model_list = Post::with(['categorys.category', 'tags.tag'])
->order('id desc');
if (!empty($type)) {
$model_list = $model_list->where('type', $type);
}
if (!empty($category_id)) {
$model_list = $model_list->where('category_id', $category_id);
}
if (!empty($keyword)) {
$model_list = $model_list->where('title', 'like', "%{$keyword}%");
}
$list = $model_list->paginate([
'page' => $page,
'list_rows' => $limit,
]);
return json_message([
'list' => $list->items(),
'total' => $list->total(),
'page' => $page,
]);
}
/**
* 文章详情
*/
public function read(Request $request)
{
$id = $request->param('id', 0, 'intval');
if ($id <= 0) {
return json_message('参数错误');
}
$post = Post::with(['categorys.category', 'tags.tag'])->find($id);
if (empty($post)) {
return json_message('文章不存在');
}
return json_message(['post' => $post]);
}
/**
* 创建文章
*/
public function save(Request $request)
{
if ($request->can_write_own != 1) {
return json_message('无权操作', 403);
}
$post_data = $request->post();
if (empty($post_data['title'])) {
return json_message('标题必填');
}
$categorys = [];
$tags = [];
if (isset($post_data['categorys'])) {
$categorys = $post_data['categorys'];
unset($post_data['categorys']);
}
if (isset($post_data['tags'])) {
$tags = $post_data['tags'];
unset($post_data['tags']);
}
// 禁止客户端设置的时间字段
unset($post_data['create_time'], $post_data['update_time']);
$post_data['uid'] = uniqid();
$post_data['source'] = 'api';
$post_data['create_time'] = time();
$post_data['update_time'] = time();
if (!isset($post_data['type'])) {
$post_data['type'] = '3';
}
if (!isset($post_data['status'])) {
$post_data['status'] = 0;
}
if (!isset($post_data['content_type'])) {
$post_data['content_type'] = 'html';
}
// 校验 publish_time 格式(必须是 Y-m-d H:i:s
if (isset($post_data['publish_time']) && !empty($post_data['publish_time'])) {
if (!preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $post_data['publish_time'])) {
return json_message('publish_time 格式错误,应为 Y-m-d H:i:s如 2024-01-15 14:30:00');
}
}
// content_type 白名单校验
$allowed_content_types = ['html', 'markdown'];
if (!in_array($post_data['content_type'], $allowed_content_types)) {
return json_message('无效的content_type', 500);
}
// Markdown→HTML 自动转换(启用表格扩展)
if ($post_data['content_type'] === 'markdown' && !empty($post_data['content'])) {
$environment = Environment::createCommonMarkEnvironment();
$environment->addExtension(new TableExtension());
$converter = new MarkdownConverter($environment);
$post_data['content_html'] = $converter->convert($post_data['content'])->getContent();
}
// 提供字段默认值,避免数据库严格模式报错
$default_fields = [
'jump_to_btn_title' => '',
'jump_to_url' => '',
'jump_to_url_status' => 0,
'poster' => '',
'desc' => '',
'author_name' => '',
'hits' => 0,
'is_top' => 0,
'sort' => 0,
'files' => '',
'pictures' => '',
'tpl_name' => '',
];
foreach ($default_fields as $field => $default) {
if (!isset($post_data[$field])) {
$post_data[$field] = $default;
}
}
$model_post = Post::create($post_data);
foreach ($categorys as $category) {
PostCategory::create([
'post_id' => $model_post->id,
'category_id' => $category,
]);
}
foreach ($tags as $tag) {
PostTag::create([
'post_id' => $model_post->id,
'tag_id' => $tag,
]);
}
return json_message(['id' => $model_post->id, 'uid' => $model_post->uid], 0, '创建成功');
}
/**
* 编辑文章
*/
public function update(Request $request)
{
$id = $request->param('id', 0, 'intval');
if ($id <= 0) {
return json_message('参数错误');
}
$model_post = Post::find($id);
if (empty($model_post)) {
return json_message('文章不存在');
}
$source = $model_post->getData('source');
if ($source === 'api') {
if ($request->can_write_own != 1) {
return json_message('无权操作', 403);
}
} else {
if ($request->can_write_other != 1) {
return json_message('无权操作', 403);
}
}
$post_data = $request->post();
unset($post_data['id']);
// 禁止客户端设置的时间字段
unset($post_data['create_time'], $post_data['update_time']);
// 校验 publish_time 格式(必须是 Y-m-d H:i:s
if (isset($post_data['publish_time']) && !empty($post_data['publish_time'])) {
if (!preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $post_data['publish_time'])) {
return json_message('publish_time 格式错误,应为 Y-m-d H:i:s如 2024-01-15 14:30:00');
}
}
// categorys diff update
if (isset($post_data['categorys'])) {
$categorys = $post_data['categorys'];
unset($post_data['categorys']);
$old_category_list = PostCategory::where('post_id', $id)->select();
$old_category_ids = array_column($old_category_list->toArray(), 'category_id');
// old has, new doesn't -> delete
foreach ($old_category_list as $model_category) {
if (!in_array($model_category->category_id, $categorys)) {
$model_category->delete();
}
}
// new has, old doesn't -> create
foreach ($categorys as $category) {
if (!in_array($category, $old_category_ids)) {
PostCategory::create([
'post_id' => $id,
'category_id' => $category,
]);
}
}
}
// tags diff update
if (isset($post_data['tags'])) {
$tags = $post_data['tags'];
unset($post_data['tags']);
$old_tag_list = PostTag::where('post_id', $id)->select();
$old_tag_ids = array_column($old_tag_list->toArray(), 'tag_id');
foreach ($old_tag_list as $model_tag) {
if (!in_array($model_tag->tag_id, $tags)) {
$model_tag->delete();
}
}
foreach ($tags as $tag) {
if (!in_array($tag, $old_tag_ids)) {
PostTag::create([
'post_id' => $id,
'tag_id' => $tag,
]);
}
}
}
// Markdown→HTML 自动转换(启用表格扩展)
if (isset($post_data['content_type']) && $post_data['content_type'] === 'markdown' && !empty($post_data['content'])) {
$environment = Environment::createCommonMarkEnvironment();
$environment->addExtension(new TableExtension());
$converter = new MarkdownConverter($environment);
$post_data['content_html'] = $converter->convert($post_data['content'])->getContent();
}
$model_post->save($post_data);
return json_message([], 0, '更新成功');
}
/**
* 删除文章
*/
public function delete(Request $request)
{
$id = $request->param('id', 0, 'intval');
if ($id <= 0) {
return json_message('参数错误');
}
$model_post = Post::find($id);
if (empty($model_post)) {
return json_message('文章不存在');
}
$source = $model_post->getData('source');
if ($source === 'api') {
if ($request->can_delete < 1) {
return json_message('无权删除', 403);
}
} else {
if ($request->can_delete != 2) {
return json_message('无权删除', 403);
}
}
$model_post->delete();
PostCategory::where('post_id', $id)->delete();
PostTag::where('post_id', $id)->delete();
return json_message([], 0, '删除成功');
}
}