mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-01 20:52:49 +08:00
- 新增手机图片排版功能,支持小红书/抖音尺寸输出 - 新增AI智能排版顾问,支持内容分析与优化推荐 - 新增AI供应商管理,支持多渠道配置与同步 - 新增文章输出管理页面,支持图片预览与批量下载 - 新增字体文件与排版样式配置
556 lines
16 KiB
PHP
556 lines
16 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace app\admin\controller;
|
|
|
|
use app\model\Nav;
|
|
use app\model\Post as ModelPost;
|
|
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 League\HTMLToMarkdown\HtmlConverter;
|
|
use think\facade\Cache;
|
|
use think\facade\View;
|
|
use think\Request;
|
|
|
|
class Post extends Common
|
|
{
|
|
/**
|
|
* 显示资源列表.
|
|
*
|
|
* @return \think\Response
|
|
*/
|
|
public function index()
|
|
{
|
|
//
|
|
|
|
$model_list = ModelPost::with(['categorys.category', 'tags.tag'])
|
|
->where('type', $this->request->param('type', 1))
|
|
->order('id desc');
|
|
|
|
$category_id = $this->request->param('category_id', 0);
|
|
|
|
if (!empty($category_id)) {
|
|
$model_list = $model_list->where('category_id', $category_id);
|
|
}
|
|
|
|
$list = $model_list->paginate([
|
|
'query' => $this->request->get(),
|
|
]);
|
|
|
|
View::assign('list', $list);
|
|
|
|
return View::fetch();
|
|
}
|
|
|
|
public function indexOutput()
|
|
{
|
|
$platform_type = $this->request->param('platform_type', '');
|
|
if (empty($platform_type)) {
|
|
$this->error('参数platform_type不能为空');
|
|
}
|
|
$platform_status = $this->request->param('platform_status', '');
|
|
$model_list = ModelPost::with(['categorys.category', 'tags.tag'])
|
|
->where('type', $this->request->param('type', 1))
|
|
->order('id desc');
|
|
|
|
if ($platform_status == 1) {
|
|
$model_list = $model_list->where('post_platform_status', 'like', "%,{$platform_type},%");
|
|
} elseif ($platform_status === '0') {
|
|
$model_list = $model_list->where('post_platform_status', 'not like', "%,{$platform_type},%");
|
|
}
|
|
|
|
$list = $model_list->paginate([
|
|
'query' => $this->request->get(),
|
|
]);
|
|
|
|
foreach ($list as $model_post) {
|
|
if (empty($model_post->post_platform_status)) {
|
|
$model_post->platform_status = 0;
|
|
} else {
|
|
if (strpos($model_post->post_platform_status, ",$platform_type,") === false) {
|
|
$model_post->platform_status = 0;
|
|
} else {
|
|
$model_post->platform_status = 1;
|
|
}
|
|
}
|
|
$model_post->platform_status_title = ModelPost::LIST_POST_PLATFORM_STATUS[$model_post->platform_status];
|
|
}
|
|
|
|
$platform_data = item_post_platform($platform_type);
|
|
|
|
View::assign('platform_data', $platform_data);
|
|
View::assign('list', $list);
|
|
View::assign('platform_type', $platform_type);
|
|
|
|
return View::fetch();
|
|
}
|
|
|
|
/**
|
|
* 显示创建资源表单页.
|
|
*
|
|
* @return \think\Response
|
|
*/
|
|
public function create()
|
|
{
|
|
//
|
|
|
|
return View::fetch();
|
|
}
|
|
|
|
/**
|
|
* 保存新建的资源.
|
|
*
|
|
* @param Request $request
|
|
* @return \think\Response
|
|
*/
|
|
public function save(Request $request)
|
|
{
|
|
//
|
|
$post_data = $request->post();
|
|
|
|
$post_data['uid'] = uniqid();
|
|
|
|
$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']);
|
|
}
|
|
|
|
$model_post = ModelPost::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 $this->success('添加成功', url('index', [
|
|
'type' => $this->request->param('type'),
|
|
'category_id' => $this->request->param('category_id'),
|
|
]));
|
|
}
|
|
|
|
public function convertHtml2Markdown()
|
|
{
|
|
$content = $this->request->post('content');
|
|
|
|
$converter = new HtmlConverter();
|
|
|
|
$markdown = $converter->convert($content);
|
|
|
|
return json_message(['markdown' => $markdown]);
|
|
}
|
|
|
|
/**
|
|
* 显示指定的资源.
|
|
*
|
|
* @param int $id
|
|
* @return \think\Response
|
|
*/
|
|
public function read($id)
|
|
{
|
|
//
|
|
}
|
|
|
|
/**
|
|
* 显示编辑资源表单页.
|
|
*
|
|
* @param int $id
|
|
* @return \think\Response
|
|
*/
|
|
public function edit($id)
|
|
{
|
|
//
|
|
|
|
$model_post = ModelPost::find($id);
|
|
|
|
View::assign('post', $model_post);
|
|
|
|
return View::fetch();
|
|
}
|
|
|
|
public function editContent($id)
|
|
{
|
|
$model_post = ModelPost::find($id);
|
|
|
|
View::assign('post', $model_post);
|
|
|
|
if ($model_post->content_type === 'markdown') {
|
|
return View::fetch('edit_content_markdown');
|
|
}
|
|
|
|
return View::fetch();
|
|
}
|
|
|
|
public function output($id)
|
|
{
|
|
$model_post = ModelPost::find($id);
|
|
$list_post_platform = list_post_platform();
|
|
|
|
foreach ($list_post_platform as $model_platform) {
|
|
$platform_info = explode("\n", $model_platform->desc);
|
|
$model_platform->home_url = $platform_info[0] ?? '';
|
|
$model_platform->account = $platform_info[1] ?? '';
|
|
}
|
|
|
|
View::assign('post', $model_post);
|
|
View::assign('list_post_platform', $list_post_platform);
|
|
|
|
$list_post_category = PostCategory::with('category')->where('post_id', $id)->select();
|
|
View::assign('list_post_category', $list_post_category);
|
|
|
|
return View::fetch();
|
|
}
|
|
|
|
/**
|
|
* 保存更新的资源.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return \think\Response
|
|
*/
|
|
public function update(Request $request, $id)
|
|
{
|
|
//
|
|
$post_data = $request->post();
|
|
|
|
// 禁止修改 content_type
|
|
unset($post_data['content_type']);
|
|
|
|
$model_post = ModelPost::find($id);
|
|
|
|
$categorys = [];
|
|
$tags = [];
|
|
if (isset($post_data['categorys'])) {
|
|
$categorys = $post_data['categorys'];
|
|
unset($post_data['categorys']);
|
|
|
|
$old_category_list = PostCategory::where('post_id', $id)->select();
|
|
$old_category_id_list = array_column((array) $old_category_list, 'id');
|
|
|
|
// 旧的有新的没有
|
|
foreach ($old_category_list as $model_category) {
|
|
if (!in_array($model_category->id, $categorys)) {
|
|
$model_category->delete();
|
|
}
|
|
}
|
|
|
|
// 旧的没有新的有
|
|
foreach ($categorys as $category) {
|
|
if (!in_array($category, $old_category_id_list)) {
|
|
PostCategory::create([
|
|
'post_id' => $model_post->id,
|
|
'category_id' => $category,
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
if (isset($post_data['tags'])) {
|
|
$tags = $post_data['tags'];
|
|
unset($post_data['tags']);
|
|
|
|
$old_tag_list = PostTag::where('post_id', $id)->select();
|
|
$old_tag_id_list = array_column((array) $old_tag_list, 'id');
|
|
|
|
foreach ($old_tag_list as $model_tag) {
|
|
if (!in_array($model_tag->id, $tags)) {
|
|
$model_tag->delete();
|
|
}
|
|
}
|
|
|
|
foreach ($tags as $tag) {
|
|
if (!in_array($tag, $old_tag_id_list)) {
|
|
PostTag::create([
|
|
'post_id' => $model_post->id,
|
|
'tag_id' => $tag,
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Markdown->HTML 自动转换
|
|
if ($model_post->getData('content_type') === 'markdown' && isset($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);
|
|
|
|
Cache::delete('sitemap_last_etag');
|
|
|
|
return $this->success('保存成功', url('index', ['type' => $model_post->getData('type')]));
|
|
}
|
|
|
|
public function setPostPlatformData()
|
|
{
|
|
$type = $this->request->param('type', 1);
|
|
$value = $this->request->param('value', '');
|
|
$post_id = $this->request->param('post_id', 0);
|
|
$model_post = ModelPost::find($post_id);
|
|
|
|
if (empty($model_post)) {
|
|
return json_message('文章不存在');
|
|
}
|
|
|
|
$post_platform_data = $model_post->post_platform_data_array;
|
|
$post_platform_data[$type] = $value;
|
|
$model_post->post_platform_data = json_encode($post_platform_data);
|
|
$model_post->post_platform_status = ',' . implode(',', array_keys($post_platform_data)) . ',';
|
|
$model_post->save();
|
|
|
|
return htmx()->message('文章设置成功');
|
|
}
|
|
|
|
/**
|
|
* 删除指定资源.
|
|
*
|
|
* @param int $id
|
|
* @return \think\Response
|
|
*/
|
|
public function delete($id)
|
|
{
|
|
//
|
|
|
|
$model_post = ModelPost::find($id);
|
|
|
|
$model_post->delete();
|
|
|
|
PostCategory::where('post_id', $id)->delete();
|
|
|
|
PostTag::where('post_id', $id)->delete();
|
|
|
|
return json_message();
|
|
}
|
|
|
|
public function downloadMarkdown($id)
|
|
{
|
|
$model_post = ModelPost::find($id);
|
|
$mardkown = $model_post->content_markdown;
|
|
|
|
return download($mardkown, $model_post->title . '.md', true);
|
|
}
|
|
|
|
/**
|
|
* 手机图片排版操作页
|
|
*/
|
|
public function phoneImage($id)
|
|
{
|
|
$model_post = ModelPost::find($id);
|
|
if (empty($model_post)) {
|
|
$this->error('文章不存在');
|
|
}
|
|
View::assign('post', $model_post);
|
|
return View::fetch();
|
|
}
|
|
|
|
/**
|
|
* 输出管理列表页
|
|
*/
|
|
public function postOutputList($id)
|
|
{
|
|
$model_post = ModelPost::find($id);
|
|
if (empty($model_post)) {
|
|
$this->error('文章不存在');
|
|
}
|
|
$output_list = \app\model\PostOutput::where('post_id', $id)
|
|
->order('id', 'desc')
|
|
->paginate(10);
|
|
View::assign('post', $model_post);
|
|
View::assign('list', $output_list);
|
|
return View::fetch('post_output/index');
|
|
}
|
|
|
|
/**
|
|
* 保存输出记录
|
|
*/
|
|
public function savePostOutput()
|
|
{
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
if (empty($data['post_id'])) {
|
|
return json(['code' => 500, 'msg' => '缺少文章ID']);
|
|
}
|
|
|
|
$post = ModelPost::find($data['post_id']);
|
|
if (empty($post)) {
|
|
return json(['code' => 500, 'msg' => '文章不存在']);
|
|
}
|
|
|
|
$config = $data['config'] ?? [];
|
|
$pages = $data['pages'] ?? [];
|
|
|
|
$admin_id = session('admin_id') ?? 0;
|
|
|
|
$phoneImage = new \app\common\tools\PhoneImage();
|
|
|
|
$output = $phoneImage->createOutput((int) $data['post_id'], $config, (int) $admin_id);
|
|
|
|
foreach ($pages as $index => $pageData) {
|
|
$phoneImage->savePageImage($output->id, $index + 1, $pageData);
|
|
}
|
|
|
|
$phoneImage->completeOutput($output->id, count($pages));
|
|
|
|
return json(['code' => 0, 'msg' => '保存成功', 'data' => ['output_id' => $output->id]]);
|
|
}
|
|
|
|
/**
|
|
* 删除输出记录
|
|
*/
|
|
public function deletePostOutput()
|
|
{
|
|
$id = $this->request->param('id', 0);
|
|
if (empty($id)) {
|
|
return json(['code' => 500, 'msg' => '缺少ID']);
|
|
}
|
|
|
|
$phoneImage = new \app\common\tools\PhoneImage();
|
|
$phoneImage->deleteOutput((int) $id);
|
|
|
|
return json(['code' => 0, 'msg' => '删除成功']);
|
|
}
|
|
|
|
/**
|
|
* 重新生成(用相同配置)
|
|
*/
|
|
public function regeneratePostOutput()
|
|
{
|
|
$id = $this->request->param('id', 0);
|
|
if (empty($id)) {
|
|
return json(['code' => 500, 'msg' => '缺少ID']);
|
|
}
|
|
|
|
$output = \app\model\PostOutput::find($id);
|
|
if (empty($output)) {
|
|
return json(['code' => 500, 'msg' => '输出记录不存在']);
|
|
}
|
|
|
|
$phoneImage = new \app\common\tools\PhoneImage();
|
|
$phoneImage->deleteOutput((int) $id);
|
|
|
|
return json(['code' => 0, 'msg' => '请重新排版', 'data' => ['config' => $output->config]]);
|
|
}
|
|
|
|
/**
|
|
* 下载ZIP
|
|
*/
|
|
public function downloadPostOutputZip($id)
|
|
{
|
|
$phoneImage = new \app\common\tools\PhoneImage();
|
|
try {
|
|
$zipPath = $phoneImage->createZip((int) $id);
|
|
$output = \app\model\PostOutput::find($id);
|
|
if (empty($output)) {
|
|
throw new \Exception('输出记录不存在');
|
|
}
|
|
$post = ModelPost::find($output->post_id);
|
|
$fileName = ($post ? $post->title : 'output') . '_phone_image_' . date('Ymd') . '.zip';
|
|
|
|
// 请求结束后清理临时ZIP文件
|
|
$tempFile = $zipPath;
|
|
register_shutdown_function(function () use ($tempFile) {
|
|
if (file_exists($tempFile)) {
|
|
@unlink($tempFile);
|
|
}
|
|
});
|
|
|
|
return download($zipPath, $fileName);
|
|
} catch (\Exception $e) {
|
|
$this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取输出文件列表(AJAX)
|
|
*/
|
|
public function getOutputFiles()
|
|
{
|
|
$outputId = $this->request->param('output_id', 0);
|
|
|
|
if (empty($outputId)) {
|
|
return json(['code' => 500, 'msg' => '缺少输出ID']);
|
|
}
|
|
|
|
$output = \app\model\PostOutput::find((int) $outputId);
|
|
if (empty($output)) {
|
|
return json(['code' => 500, 'msg' => '输出记录不存在']);
|
|
}
|
|
|
|
$files = \app\model\PostOutputFile::getByOutput((int) $outputId);
|
|
|
|
$result = [];
|
|
foreach ($files as $file) {
|
|
$result[] = [
|
|
'id' => $file->id,
|
|
'page' => $file->page,
|
|
'file_url' => $file->file_url,
|
|
'file_size' => $file->file_size,
|
|
'width' => $file->width,
|
|
'height' => $file->height,
|
|
];
|
|
}
|
|
|
|
return json(['code' => 0, 'data' => $result]);
|
|
}
|
|
|
|
/**
|
|
* AI智能排版推荐.
|
|
*/
|
|
public function aiRecommend()
|
|
{
|
|
$postId = $this->request->post('post_id', 0);
|
|
$post = ModelPost::find($postId);
|
|
if (empty($post)) {
|
|
return json(['code' => 500, 'msg' => '文章不存在']);
|
|
}
|
|
|
|
$advisor = new \app\common\tools\AiLayoutAdvisor();
|
|
$result = $advisor->analyzeAndRecommend($post);
|
|
|
|
if ($result['success']) {
|
|
return json(['code' => 0, 'data' => $result['data']]);
|
|
}
|
|
|
|
return json(['code' => 500, 'msg' => $result['msg']]);
|
|
}
|
|
|
|
/**
|
|
* AI内容优化.
|
|
*/
|
|
public function aiOptimizeContent()
|
|
{
|
|
$postId = $this->request->post('post_id', 0);
|
|
$post = ModelPost::find($postId);
|
|
if (empty($post)) {
|
|
return json(['code' => 500, 'msg' => '文章不存在']);
|
|
}
|
|
|
|
$advisor = new \app\common\tools\AiLayoutAdvisor();
|
|
$result = $advisor->optimizeContent($post);
|
|
|
|
if ($result['success']) {
|
|
return json(['code' => 0, 'data' => $result['data']]);
|
|
}
|
|
|
|
return json(['code' => 500, 'msg' => $result['msg']]);
|
|
}
|
|
}
|