|
|
@@ -3,75 +3,16 @@ namespace app\api\controller;
|
|
|
use app\common\controller\Api;
|
|
|
use think\Db;
|
|
|
use think\Request;
|
|
|
-
|
|
|
+use RecursiveIteratorIterator;
|
|
|
+use RecursiveDirectoryIterator;
|
|
|
class Facility extends Api
|
|
|
{
|
|
|
protected $noNeedLogin = ['*'];
|
|
|
protected $noNeedRight = ['*'];
|
|
|
|
|
|
- public function packImagess()
|
|
|
- {
|
|
|
- try {
|
|
|
- $params = $this->request->post();
|
|
|
- $paths = $params['paths'] ?? [];
|
|
|
-
|
|
|
- if (empty($paths) || !is_array($paths)) {
|
|
|
- return json(['code' => 1, 'msg' => '路径参数不能为空或格式不正确']);
|
|
|
- }
|
|
|
-
|
|
|
- // 设置基础路径和压缩目录路径
|
|
|
- $basePath = ROOT_PATH . 'public/';
|
|
|
- $zipDir = $basePath . 'uploads/operate/ai/zip/';
|
|
|
-
|
|
|
- if (!is_dir($zipDir)) {
|
|
|
- mkdir($zipDir, 0755, true);
|
|
|
- }
|
|
|
-
|
|
|
- // 压缩包文件名及完整路径
|
|
|
- $fileName = 'images_' . date('Ymd_His') . '.zip';
|
|
|
- $zipPath = $zipDir . $fileName;
|
|
|
-
|
|
|
- // 创建 Zip 文件
|
|
|
- $zip = new \ZipArchive();
|
|
|
- if ($zip->open($zipPath, \ZipArchive::CREATE) !== TRUE) {
|
|
|
- return json(['code' => 1, 'msg' => '无法创建压缩包']);
|
|
|
- }
|
|
|
-
|
|
|
- // 添加文件到压缩包
|
|
|
- $addCount = 0;
|
|
|
- foreach ($paths as $relativePath) {
|
|
|
- $relativePath = ltrim($relativePath, '/');
|
|
|
- $fullPath = $basePath . $relativePath;
|
|
|
-
|
|
|
- if (file_exists($fullPath)) {
|
|
|
- $zip->addFile($fullPath, basename($fullPath)); // 仅保存文件名
|
|
|
- $addCount++;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- $zip->close();
|
|
|
-
|
|
|
- if ($addCount === 0) {
|
|
|
- return json(['code' => 1, 'msg' => '未找到有效图片,未生成压缩包']);
|
|
|
- }
|
|
|
-
|
|
|
- // 返回下载地址(注意路径与保存路径一致)
|
|
|
- $downloadUrl = request()->domain() . '/uploads/operate/ai/zip/' . $fileName;
|
|
|
-
|
|
|
- return json([
|
|
|
- 'code' => 0,
|
|
|
- 'msg' => '打包成功',
|
|
|
- 'download_url' => $downloadUrl
|
|
|
- ]);
|
|
|
- } catch (\Exception $e) {
|
|
|
- return json([
|
|
|
- 'code' => 1,
|
|
|
- 'msg' => '异常错误:' . $e->getMessage()
|
|
|
- ]);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
+ /**
|
|
|
+ * 获取一张原目录图片对应明细数据
|
|
|
+ */
|
|
|
public function getlsit()
|
|
|
{
|
|
|
// 获取前端传入的图片路径参数
|
|
|
@@ -87,12 +28,15 @@ class Facility extends Api
|
|
|
}
|
|
|
|
|
|
|
|
|
- //获取指定目录所有图片
|
|
|
+ /**
|
|
|
+ * 获取指定目录所有图片
|
|
|
+ */
|
|
|
public function getPreviewimg()
|
|
|
{
|
|
|
$page = (int)$this->request->param('page', 1);
|
|
|
$limit = (int)$this->request->param('limit', 50);
|
|
|
$status = $this->request->param('status', '');
|
|
|
+ $status_name = $this->request->param('status_name', '');
|
|
|
$relativePath = $this->request->param('path', '');
|
|
|
|
|
|
$basePath = ROOT_PATH . 'public/';
|
|
|
@@ -102,66 +46,124 @@ class Facility extends Api
|
|
|
return json(['code' => 1, 'msg' => '原图目录不存在']);
|
|
|
}
|
|
|
|
|
|
- // 1. 获取所有图片路径
|
|
|
- $allImages = glob($fullPath . '/*.{jpg,jpeg,png}', GLOB_BRACE);
|
|
|
- if (empty($allImages)) {
|
|
|
- return json(['code' => 0, 'msg' => '暂无图片', 'data' => [], 'total' => 0]);
|
|
|
+ // 设置缓存路径
|
|
|
+ $cacheDir = RUNTIME_PATH . 'image_cache/';
|
|
|
+ if (!is_dir($cacheDir)) {
|
|
|
+ mkdir($cacheDir, 0755, true);
|
|
|
}
|
|
|
-
|
|
|
- // 2. 构建路径信息映射(路径 => 文件信息)
|
|
|
- $imageInfoMap = [];
|
|
|
- foreach ($allImages as $imgPath) {
|
|
|
- $relative = str_replace('\\', '/', trim(str_replace($basePath, '', $imgPath), '/'));
|
|
|
- $info = @getimagesize($imgPath);
|
|
|
- $imageInfoMap[$relative] = [
|
|
|
- 'width' => $info[0] ?? 0,
|
|
|
- 'height' => $info[1] ?? 0,
|
|
|
- 'size_kb' => round(filesize($imgPath) / 1024, 2),
|
|
|
- 'created_time' => date('Y-m-d H:i:s', filectime($imgPath))
|
|
|
- ];
|
|
|
+ $cacheFile = $cacheDir . md5($relativePath) . '.json';
|
|
|
+
|
|
|
+ // 判断缓存文件是否存在,并且最后修改时间在1小时(3600秒)以内
|
|
|
+ if (file_exists($cacheFile) && time() - filemtime($cacheFile) < 3600) {
|
|
|
+ $imageInfoMap = json_decode(file_get_contents($cacheFile), true);
|
|
|
+ } else {
|
|
|
+ // 没有缓存或缓存过期,重新扫描目录
|
|
|
+ $allImages = glob($fullPath . '/*.{jpg,jpeg,png}', GLOB_BRACE);
|
|
|
+ $imageInfoMap = [];
|
|
|
+ foreach ($allImages as $imgPath) {
|
|
|
+ $relative = str_replace('\\', '/', trim(str_replace($basePath, '', $imgPath), '/'));
|
|
|
+ $info = @getimagesize($imgPath);
|
|
|
+ $imageInfoMap[$relative] = [
|
|
|
+ 'width' => $info[0] ?? 0,
|
|
|
+ 'height' => $info[1] ?? 0,
|
|
|
+ 'size_kb' => round(filesize($imgPath) / 1024, 2),
|
|
|
+ 'created_time' => date('Y-m-d H:i:s', filectime($imgPath))
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ file_put_contents($cacheFile, json_encode($imageInfoMap));
|
|
|
}
|
|
|
|
|
|
+ // 1. 获取所有图片路径
|
|
|
$relativeImages = array_keys($imageInfoMap);
|
|
|
|
|
|
- // 3. 获取数据库记录
|
|
|
+ // 2. 查询数据库记录(一次性查询所有相关记录)
|
|
|
$dbRecords = Db::name('text_to_image')
|
|
|
->whereIn('old_image_url', $relativeImages)
|
|
|
- ->field('id as img_id, old_image_url, new_image_url, custom_image_url, chinese_description, english_description, img_name, status')
|
|
|
+ ->field('id as img_id, old_image_url, new_image_url, custom_image_url, chinese_description, english_description, img_name, status, status_name')
|
|
|
+ ->select();
|
|
|
+
|
|
|
+ // 3. 查询队列表中的记录(获取队列状态信息)
|
|
|
+ $queueRecords = Db::name('image_task_log')
|
|
|
+ // ->where('status', 0)
|
|
|
+ // ->where('log', '队列中')
|
|
|
+ ->field('file_name, log')
|
|
|
->select();
|
|
|
|
|
|
- // 4. 构建映射表:路径 => 整条数据库记录
|
|
|
+ // 4. 创建队列信息映射
|
|
|
+ $queueMap = [];
|
|
|
+ foreach ($queueRecords as $queueItem) {
|
|
|
+ $key = str_replace('\\', '/', trim($queueItem['file_name'], '/'));
|
|
|
+ $queueMap[$key] = $queueItem['log'];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 映射记录
|
|
|
$processedMap = [];
|
|
|
foreach ($dbRecords as $item) {
|
|
|
$key = str_replace('\\', '/', trim($item['old_image_url'], '/'));
|
|
|
$processedMap[$key] = $item;
|
|
|
}
|
|
|
|
|
|
- // 5. 获取 same_count 统计
|
|
|
- $sameCountMap = Db::name('text_to_image')
|
|
|
- ->whereIn('old_image_url', $relativeImages)
|
|
|
- ->where('status', 1)
|
|
|
- ->group('old_image_url')
|
|
|
- ->column('count(*) as cnt', 'old_image_url');
|
|
|
-
|
|
|
- // 6. 构建结果数据
|
|
|
- $allData = [];
|
|
|
+ // 6. 构建完整数据并进行筛选
|
|
|
+ $filteredData = [];
|
|
|
foreach ($relativeImages as $path) {
|
|
|
$item = $processedMap[$path] ?? [];
|
|
|
$info = $imageInfoMap[$path];
|
|
|
|
|
|
- $isProcessed = !empty($item['img_name']) && !empty($item['custom_image_url']);
|
|
|
$dbStatus = isset($item['status']) ? (int)$item['status'] : 0;
|
|
|
+ $dbStatusName = isset($item['status_name']) ? trim($item['status_name']) : '';
|
|
|
|
|
|
- // 状态过滤(0:未出图,1:已出图)
|
|
|
+ // 状态筛选条件
|
|
|
if ($status !== '' && (int)$status !== $dbStatus) {
|
|
|
continue;
|
|
|
}
|
|
|
+ if ($status_name !== '' && $dbStatusName !== $status_name) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $isProcessed = !empty($item['img_name']) && !empty($item['custom_image_url']);
|
|
|
+ $queueStatus = $queueMap[$path] ?? '';
|
|
|
+
|
|
|
+ $filteredData[] = [
|
|
|
+ 'path' => $path,
|
|
|
+ 'item' => $item,
|
|
|
+ 'info' => $info,
|
|
|
+ 'dbStatus' => $dbStatus,
|
|
|
+ 'dbStatusName' => $dbStatusName,
|
|
|
+ 'isProcessed' => $isProcessed,
|
|
|
+ 'queueStatus' => $queueStatus
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 获取相同图片数量统计(基于筛选后的结果,只统计有new_image_url的记录)
|
|
|
+ $filteredPaths = array_column($filteredData, 'path');
|
|
|
+ $sameCountMap = [];
|
|
|
+ if (!empty($filteredPaths)) {
|
|
|
+ $sameCountMap = Db::name('text_to_image')
|
|
|
+ ->whereIn('old_image_url', $filteredPaths)
|
|
|
+ ->where('new_image_url', '<>', '') // 只统计有new_image_url的记录
|
|
|
+ ->group('old_image_url')
|
|
|
+ ->column('count(*) as cnt', 'old_image_url');
|
|
|
+ }
|
|
|
|
|
|
- $allData[] = [
|
|
|
- 'path' => $path,//原图路径
|
|
|
- 'status' => $dbStatus,//状态
|
|
|
- 'same_count' => $sameCountMap[$path] ?? 0, // 出图数量
|
|
|
- 'is_processed' => $isProcessed ? 1 : 0,
|
|
|
+ // 8. 分页处理
|
|
|
+ $total = count($filteredData);
|
|
|
+ $pagedData = array_slice($filteredData, ($page - 1) * $limit, $limit);
|
|
|
+
|
|
|
+ // 9. 构建最终响应数据
|
|
|
+ $resultData = [];
|
|
|
+ foreach ($pagedData as $i => $data) {
|
|
|
+ $path = $data['path'];
|
|
|
+ $item = $data['item'];
|
|
|
+ $info = $data['info'];
|
|
|
+
|
|
|
+ $resultData[] = [
|
|
|
+ 'id' => ($page - 1) * $limit + $i + 1,
|
|
|
+ 'path' => $path,
|
|
|
+ 'status' => $data['dbStatus'],
|
|
|
+ 'status_name' => $data['dbStatusName'],
|
|
|
+ 'same_count' => $sameCountMap[$path] ?? 0,
|
|
|
+ 'is_processed' => $data['isProcessed'] ? 1 : 0,
|
|
|
+ 'queue_status' => $data['queueStatus'], // 新增队列状态字段
|
|
|
'new_image_url' => $item['new_image_url'] ?? '',
|
|
|
'custom_image_url' => $item['custom_image_url'] ?? '',
|
|
|
'chinese_description' => $item['chinese_description'] ?? '',
|
|
|
@@ -174,252 +176,67 @@ class Facility extends Api
|
|
|
];
|
|
|
}
|
|
|
|
|
|
- // 7. 分页处理
|
|
|
- $total = count($allData);
|
|
|
- $pagedData = array_slice(array_values($allData), ($page - 1) * $limit, $limit);
|
|
|
- foreach ($pagedData as $i => &$row) {
|
|
|
- $row['id'] = ($page - 1) * $limit + $i + 1;
|
|
|
- }
|
|
|
-
|
|
|
return json([
|
|
|
'code' => 0,
|
|
|
'msg' => '获取成功',
|
|
|
- 'data' => $pagedData,
|
|
|
+ 'data' => $resultData,
|
|
|
'total' => $total,
|
|
|
'page' => $page,
|
|
|
'limit' => $limit
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-// public function getPreviewimg()
|
|
|
-// {
|
|
|
-// $page = (int)$this->request->param('page', 1);
|
|
|
-// $limit = (int)$this->request->param('limit', 50);
|
|
|
-// $status = $this->request->param('status', '');
|
|
|
-// $relativePath = $this->request->param('path', '');
|
|
|
-//
|
|
|
-// $basePath = ROOT_PATH . 'public/';
|
|
|
-// $fullPath = $basePath . $relativePath;
|
|
|
-//
|
|
|
-// if (!is_dir($fullPath)) {
|
|
|
-// return json(['code' => 1, 'msg' => '原图目录不存在']);
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 1. 获取所有图片路径
|
|
|
-// $allImages = glob($fullPath . '/*.{jpg,jpeg,png}', GLOB_BRACE);
|
|
|
-// if (empty($allImages)) {
|
|
|
-// return json(['code' => 0, 'msg' => '暂无图片', 'data' => [], 'total' => 0]);
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 2. 构建路径信息映射(路径 => 文件信息)
|
|
|
-// $imageInfoMap = [];
|
|
|
-// foreach ($allImages as $imgPath) {
|
|
|
-// $relative = str_replace('\\', '/', trim(str_replace($basePath, '', $imgPath), '/'));
|
|
|
-// $info = @getimagesize($imgPath);
|
|
|
-// $imageInfoMap[$relative] = [
|
|
|
-// 'width' => $info[0] ?? 0,
|
|
|
-// 'height' => $info[1] ?? 0,
|
|
|
-// 'size_kb' => round(filesize($imgPath) / 1024, 2),
|
|
|
-// 'created_time' => date('Y-m-d H:i:s', filectime($imgPath))
|
|
|
-// ];
|
|
|
-// }
|
|
|
-//
|
|
|
-// $relativeImages = array_keys($imageInfoMap);
|
|
|
-//
|
|
|
-// // 3. 获取数据库记录
|
|
|
-// $dbRecords = Db::name('text_to_image')
|
|
|
-// ->whereIn('old_image_url', $relativeImages)
|
|
|
-// ->field('id as img_id, old_image_url, new_image_url, custom_image_url, chinese_description, english_description, img_name,status')
|
|
|
-// ->select();
|
|
|
-//
|
|
|
-// // 4. 构建映射表:路径 => 整条数据库记录
|
|
|
-// $processedMap = [];
|
|
|
-// foreach ($dbRecords as $item) {
|
|
|
-// $key = str_replace('\\', '/', trim($item['old_image_url'], '/'));
|
|
|
-// $processedMap[$key] = $item;
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 5. 获取 same_count 统计
|
|
|
-// $sameCountMap = Db::name('text_to_image')
|
|
|
-// ->whereIn('old_image_url', $relativeImages)
|
|
|
-// ->where('status', 1)
|
|
|
-// ->group('old_image_url')
|
|
|
-// ->column('count(*) as cnt', 'old_image_url');
|
|
|
-//
|
|
|
-// // 6. 构建结果数据
|
|
|
-// $allData = [];
|
|
|
-// foreach ($relativeImages as $path) {
|
|
|
-// $item = $processedMap[$path] ?? [];
|
|
|
-// $info = $imageInfoMap[$path];
|
|
|
-//
|
|
|
-// $isProcessed = !empty($item['img_name']) && !empty($item['custom_image_url']);
|
|
|
-//
|
|
|
-// // 状态过滤
|
|
|
-// if ($status === '1') {
|
|
|
-// if (!$isProcessed) continue;
|
|
|
-// } elseif ($status === '2') {
|
|
|
-// if ($isProcessed) continue;
|
|
|
-// }
|
|
|
-//
|
|
|
-// $allData[] = [
|
|
|
-// 'path' => $path,
|
|
|
-// 'status' => (int)($item['status'] ?? 0),
|
|
|
-// 'same_count' => $sameCountMap[$path] ?? 0,//出图数量
|
|
|
-// 'is_processed' => $isProcessed ? 1 : 0,
|
|
|
-// 'new_image_url' => $item['new_image_url'] ?? '',
|
|
|
-// 'custom_image_url' => $item['custom_image_url'] ?? '',
|
|
|
-// 'chinese_description' => $item['chinese_description'] ?? '',
|
|
|
-// 'english_description' => $item['english_description'] ?? '',
|
|
|
-// 'img_name' => $item['img_name'] ?? '',
|
|
|
-// 'width' => $info['width'],
|
|
|
-// 'height' => $info['height'],
|
|
|
-// 'size_kb' => $info['size_kb'],
|
|
|
-// 'created_time' => $info['created_time']
|
|
|
-// ];
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 7. 分页处理
|
|
|
-// $total = count($allData);
|
|
|
-// $pagedData = array_slice(array_values($allData), ($page - 1) * $limit, $limit);
|
|
|
-// foreach ($pagedData as $i => &$row) {
|
|
|
-// $row['id'] = ($page - 1) * $limit + $i + 1;
|
|
|
-// }
|
|
|
-//
|
|
|
-// return json([
|
|
|
-// 'code' => 0,
|
|
|
-// 'msg' => '获取成功',
|
|
|
-// 'data' => $pagedData,
|
|
|
-// 'total' => $total,
|
|
|
-// 'page' => $page,
|
|
|
-// 'limit' => $limit
|
|
|
-// ]);
|
|
|
-// }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-// public function getPreviewimg()
|
|
|
-// {
|
|
|
-// $page = (int)$this->request->param('page', 1);
|
|
|
-// $limit = (int)$this->request->param('limit', 50);
|
|
|
-// $status = $this->request->param('status', '');
|
|
|
-//
|
|
|
-// $relativePath = $this->request->param('path', '');
|
|
|
-// $basePath = ROOT_PATH . 'public/';
|
|
|
-// $fullPath = $basePath . $relativePath;
|
|
|
-//
|
|
|
-// if (!is_dir($fullPath)) {
|
|
|
-// return json(['code' => 1, 'msg' => '目录不存在']);
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 1. 获取所有图片路径(不再全部加载到内存)
|
|
|
-// $allImages = glob($fullPath . '/*.{jpg,jpeg,png}', GLOB_BRACE);
|
|
|
-// if (empty($allImages)) {
|
|
|
-// return json(['code' => 0, 'msg' => '暂无图片', 'data' => [], 'total' => 0]);
|
|
|
-// }
|
|
|
-// // ✅ 加入排序:按照创建时间从新到旧
|
|
|
-// usort($allImages, function ($a, $b) {
|
|
|
-// return filectime($b) - filectime($a);
|
|
|
-// });
|
|
|
-// // 构建相对路径数组
|
|
|
-// $relativeImages = array_map(function ($imgPath) use ($basePath) {
|
|
|
-// return str_replace($basePath, '', $imgPath);
|
|
|
-// }, $allImages);
|
|
|
-//
|
|
|
-// // 2. 提前构建是否已出图map
|
|
|
-// $dbRecords = Db::name('text_to_image')
|
|
|
-// ->whereIn('old_image_url', $relativeImages)
|
|
|
-// ->where('img_name', '<>', '')
|
|
|
-// ->where('custom_image_url', '<>', '')
|
|
|
-// ->where('status',1)
|
|
|
-// ->field('id,old_image_url,new_image_url,custom_image_url,chinese_description,english_description,img_name')
|
|
|
-// ->select();
|
|
|
-//
|
|
|
-// $processedMap = [];
|
|
|
-// foreach ($dbRecords as $item) {
|
|
|
-// $processedMap[$item['old_image_url']] = $item;
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 3. 提前获取 same_count 的统计
|
|
|
-// $sameCountMap = Db::name('text_to_image')
|
|
|
-// ->whereIn('old_image_url', $relativeImages)
|
|
|
-// ->where('img_name', '<>', '')
|
|
|
-// ->where('custom_image_url', '<>', '')
|
|
|
-// ->group('old_image_url')
|
|
|
-// ->where('status',1)
|
|
|
-// ->column('count(*) as cnt', 'old_image_url');
|
|
|
-//
|
|
|
-// // 4. 构造最终筛选数据(分页前进行状态筛选)
|
|
|
-// $filtered = [];
|
|
|
-// foreach ($allImages as $imgPath) {
|
|
|
-// $relative = str_replace($basePath, '', $imgPath);
|
|
|
-// $processed = $processedMap[$relative] ?? null;
|
|
|
-// $isProcessed = $processed ? 1 : 0;
|
|
|
-//
|
|
|
-// // 状态过滤
|
|
|
-// if ($status === 'processed' && !$isProcessed) continue;
|
|
|
-// if ($status === 'unprocessed' && $isProcessed) continue;
|
|
|
-//
|
|
|
-// $info = @getimagesize($imgPath); // 加@防止报错
|
|
|
-// $sizeKB = round(filesize($imgPath) / 1024, 2);
|
|
|
-// $ctime = date('Y-m-d H:i:s', filectime($imgPath));
|
|
|
-//
|
|
|
-// $filtered[] = [
|
|
|
-// 'path' => $relative,
|
|
|
-// 'width' => $info[0] ?? 0,
|
|
|
-// 'height' => $info[1] ?? 0,
|
|
|
-// 'size_kb' => $sizeKB,
|
|
|
-// 'created_time' => $ctime,
|
|
|
-// 'img_name' => $processed['img_name'] ?? '',
|
|
|
-// 'is_processed' => $isProcessed,
|
|
|
-// 'new_image_url' => $processed['new_image_url'] ?? '',
|
|
|
-// 'custom_image_url' => $processed['custom_image_url'] ?? '',
|
|
|
-// 'chinese_description' => ($processed['chinese_description'] ?? '') . ($processed['english_description'] ?? ''),
|
|
|
-// 'english_description' => ($processed['english_description'] ?? '') . ($processed['english_description'] ?? ''),
|
|
|
-// 'same_count' => $sameCountMap[$relative] ?? 0
|
|
|
-// ];
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 5. 手动分页(对少量已筛选后的数据)
|
|
|
-// $total = count($filtered);
|
|
|
-// $pagedData = array_slice($filtered, ($page - 1) * $limit, $limit);
|
|
|
-// foreach ($pagedData as $index => &$item) {
|
|
|
-// $item['id'] = ($page - 1) * $limit + $index + 1;
|
|
|
-// }
|
|
|
-//
|
|
|
-// return json([
|
|
|
-// 'code' => 0,
|
|
|
-// 'msg' => '获取成功',
|
|
|
-// 'data' => $pagedData,
|
|
|
-// 'total' => $total,
|
|
|
-// 'page' => $page,
|
|
|
-// 'limit' => $limit
|
|
|
-// ]);
|
|
|
-// }
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
- * 获取原图目录及每个目录下的图片数量
|
|
|
+ * 采用缓存机制
|
|
|
+ * 获取原图目录及每个目录下的图片数量(优化版)
|
|
|
*/
|
|
|
public function getPreviewSubDirs()
|
|
|
{
|
|
|
+ // 1. 设置基础路径
|
|
|
$baseDir = rtrim(str_replace('\\', '/', ROOT_PATH), '/') . '/public/uploads/operate/ai/Preview';
|
|
|
$baseRelativePath = 'uploads/operate/ai/Preview';
|
|
|
|
|
|
+ // 2. 检查目录是否存在
|
|
|
if (!is_dir($baseDir)) {
|
|
|
return json(['code' => 1, 'msg' => '目录不存在']);
|
|
|
}
|
|
|
|
|
|
+ // 3. 获取目录最后修改时间作为缓存标识
|
|
|
+ $cacheKey = 'preview_dirs_' . md5($baseDir);
|
|
|
+ $lastModified = filemtime($baseDir);
|
|
|
+ $cacheVersionKey = $cacheKey . '_version';
|
|
|
+
|
|
|
+ // 4. 检查缓存版本是否匹配
|
|
|
+ if (cache($cacheVersionKey) != $lastModified) {
|
|
|
+ cache($cacheKey, null);
|
|
|
+ cache($cacheVersionKey, $lastModified, 86400);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 尝试从缓存获取
|
|
|
+ if (!$dirList = cache($cacheKey)) {
|
|
|
+ // 6. 重新扫描目录
|
|
|
+ $dirList = $this->scanDirectories($baseDir, $baseRelativePath);
|
|
|
+ cache($cacheKey, $dirList, 86400); // 缓存1天
|
|
|
+ }
|
|
|
+
|
|
|
+ return json([
|
|
|
+ 'code' => 0,
|
|
|
+ 'msg' => '获取成功',
|
|
|
+ 'data' => $dirList
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 扫描目录结构
|
|
|
+ */
|
|
|
+ private function scanDirectories($baseDir, $baseRelativePath)
|
|
|
+ {
|
|
|
$dirs = [];
|
|
|
$index = 1;
|
|
|
+ $processedDirs = [];
|
|
|
|
|
|
- /**
|
|
|
- * 递归扫描目录,提取含图片的子目录信息
|
|
|
- */
|
|
|
- $scanDir = function ($dirPath, $relativePath) use (&$scanDir, &$dirs, &$index) {
|
|
|
- $items = scandir($dirPath);
|
|
|
+ $scanDir = function ($dirPath, $relativePath) use (&$scanDir, &$dirs, &$index, &$processedDirs) {
|
|
|
+ $items = @scandir($dirPath) ?: [];
|
|
|
foreach ($items as $item) {
|
|
|
if ($item === '.' || $item === '..') continue;
|
|
|
|
|
|
@@ -427,67 +244,164 @@ class Facility extends Api
|
|
|
$relPath = $relativePath . '/' . $item;
|
|
|
|
|
|
if (is_dir($fullPath)) {
|
|
|
- // 递归子目录
|
|
|
- $scanDir($fullPath, $relPath);
|
|
|
- } else {
|
|
|
- // 匹配图片文件
|
|
|
- if (preg_match('/\.(jpg|jpeg|png)$/i', $item)) {
|
|
|
- $parentDir = dirname($fullPath);
|
|
|
- $relativeDir = dirname($relPath);
|
|
|
- $key = md5($parentDir);
|
|
|
-
|
|
|
- if (!isset($dirs[$key])) {
|
|
|
- $ctime = filectime($parentDir);
|
|
|
-
|
|
|
- // 数据库统计:已处理图片数量
|
|
|
- $hasData = Db::name('text_to_image')
|
|
|
- ->where('custom_image_url', '<>', '')
|
|
|
- ->where('img_name', '<>', '')
|
|
|
- ->whereLike('old_image_url', $relativeDir . '/%')
|
|
|
- ->where('status',1)
|
|
|
- ->whereNotNull('custom_image_url')
|
|
|
- ->count();
|
|
|
-
|
|
|
- // 当前目录下图片数量
|
|
|
- $imageFiles = glob($parentDir . '/*.{jpg,jpeg,png}', GLOB_BRACE);
|
|
|
- $imageCount = is_array($imageFiles) ? count($imageFiles) : 0;
|
|
|
-
|
|
|
- $dirs[$key] = [
|
|
|
- 'id' => $index++,
|
|
|
- 'name' => basename($parentDir),
|
|
|
- 'count' => $hasData,
|
|
|
- 'ctime' => $ctime, // 时间戳,用于排序
|
|
|
- 'ctime_text' => date('Y-m-d H:i:s', $ctime), // 格式化日期,用于显示
|
|
|
- 'image_count' => $imageCount,
|
|
|
- 'new_image_url' => "/uploads/operate/ai/dall-e/",
|
|
|
- 'old_image_url' => $relativeDir
|
|
|
- ];
|
|
|
- }
|
|
|
+ $dirKey = md5($fullPath);
|
|
|
+ if (!isset($processedDirs[$dirKey])) {
|
|
|
+ $processedDirs[$dirKey] = true;
|
|
|
+ $scanDir($fullPath, $relPath);
|
|
|
+ }
|
|
|
+ } elseif (preg_match('/\.(jpg|jpeg|png)$/i', $item)) {
|
|
|
+ $parentDir = dirname($fullPath);
|
|
|
+ $relativeDir = dirname($relPath);
|
|
|
+ $key = md5($parentDir);
|
|
|
+
|
|
|
+ if (!isset($dirs[$key])) {
|
|
|
+ $ctime = @filectime($parentDir) ?: time();
|
|
|
+
|
|
|
+ // 数据库查询
|
|
|
+ $hasData = Db::name('text_to_image')
|
|
|
+ ->where('custom_image_url', '<>', '')
|
|
|
+ ->where('img_name', '<>', '')
|
|
|
+ ->whereLike('old_image_url', $relativeDir . '/%')
|
|
|
+ ->where('status',1)
|
|
|
+ ->cache(true, 300)
|
|
|
+ ->count();
|
|
|
+
|
|
|
+ $imageFiles = @glob($parentDir . '/*.{jpg,jpeg,png}', GLOB_BRACE);
|
|
|
+ $imageCount = $imageFiles ? count($imageFiles) : 0;
|
|
|
+
|
|
|
+ $dirs[$key] = [
|
|
|
+ 'id' => $index++,
|
|
|
+ 'name' => basename($parentDir),
|
|
|
+ 'count' => $hasData,
|
|
|
+ 'ctime' => $ctime,
|
|
|
+ 'ctime_text' => date('Y-m-d H:i:s', $ctime),
|
|
|
+ 'image_count' => $imageCount,
|
|
|
+ 'new_image_url' => "/uploads/operate/ai/dall-e/",
|
|
|
+ 'old_image_url' => $relativeDir
|
|
|
+ ];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- // 执行目录扫描
|
|
|
$scanDir($baseDir, $baseRelativePath);
|
|
|
|
|
|
- // 排序:按照创建时间(从新到旧)
|
|
|
+ // 按ID降序排序
|
|
|
$dirList = array_values($dirs);
|
|
|
usort($dirList, function ($a, $b) {
|
|
|
- return $b['ctime'] - $a['ctime'];
|
|
|
+ return $b['id'] - $a['id'];
|
|
|
});
|
|
|
|
|
|
- return json([
|
|
|
- 'code' => 0,
|
|
|
- 'msg' => '获取成功',
|
|
|
- 'data' => $dirList
|
|
|
- ]);
|
|
|
+ return $dirList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 手动清除缓存(在目录变更后调用)
|
|
|
+ */
|
|
|
+ public function clearCache()
|
|
|
+ {
|
|
|
+ $baseDir = rtrim(str_replace('\\', '/', ROOT_PATH), '/') . '/public/uploads/operate/ai/Preview';
|
|
|
+ $cacheKey = 'preview_dirs_' . md5($baseDir);
|
|
|
+
|
|
|
+ cache($cacheKey, null);
|
|
|
+ cache($cacheKey . '_version', null);
|
|
|
+
|
|
|
+ return json(['code' => 0, 'msg' => '缓存已清除']);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 不使用缓存机制(查询速度较慢)
|
|
|
+ * 获取原图目录及每个目录下的图片数量
|
|
|
+ */
|
|
|
+// public function getPreviewSubDirs()
|
|
|
+// {
|
|
|
+// $baseDir = rtrim(str_replace('\\', '/', ROOT_PATH), '/') . '/public/uploads/operate/ai/Preview';
|
|
|
+// $baseRelativePath = 'uploads/operate/ai/Preview';
|
|
|
+//
|
|
|
+// if (!is_dir($baseDir)) {
|
|
|
+// return json(['code' => 1, 'msg' => '目录不存在']);
|
|
|
+// }
|
|
|
+//
|
|
|
+// $dirs = [];
|
|
|
+// $index = 1;
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 递归扫描目录,提取含图片的子目录信息
|
|
|
+// */
|
|
|
+// $scanDir = function ($dirPath, $relativePath) use (&$scanDir, &$dirs, &$index) {
|
|
|
+// $items = scandir($dirPath);
|
|
|
+// foreach ($items as $item) {
|
|
|
+// if ($item === '.' || $item === '..') continue;
|
|
|
+//
|
|
|
+// $fullPath = $dirPath . '/' . $item;
|
|
|
+// $relPath = $relativePath . '/' . $item;
|
|
|
+//
|
|
|
+// if (is_dir($fullPath)) {
|
|
|
+// // 递归子目录
|
|
|
+// $scanDir($fullPath, $relPath);
|
|
|
+// } else {
|
|
|
+// // 匹配图片文件
|
|
|
+// if (preg_match('/\.(jpg|jpeg|png)$/i', $item)) {
|
|
|
+// $parentDir = dirname($fullPath);
|
|
|
+// $relativeDir = dirname($relPath);
|
|
|
+// $key = md5($parentDir);
|
|
|
+//
|
|
|
+// if (!isset($dirs[$key])) {
|
|
|
+// $ctime = filectime($parentDir);
|
|
|
+//
|
|
|
+// // 数据库统计:已处理图片数量
|
|
|
+// $hasData = Db::name('text_to_image')
|
|
|
+// ->where('custom_image_url', '<>', '')
|
|
|
+// ->where('img_name', '<>', '')
|
|
|
+// ->whereLike('old_image_url', $relativeDir . '/%')
|
|
|
+// ->where('status',1)
|
|
|
+// ->whereNotNull('custom_image_url')
|
|
|
+// ->count();
|
|
|
+//
|
|
|
+// // 当前目录下图片数量
|
|
|
+// $imageFiles = glob($parentDir . '/*.{jpg,jpeg,png}', GLOB_BRACE);
|
|
|
+// $imageCount = is_array($imageFiles) ? count($imageFiles) : 0;
|
|
|
+//
|
|
|
+// $dirs[$key] = [
|
|
|
+// 'id' => $index++,
|
|
|
+// 'name' => basename($parentDir),
|
|
|
+// 'count' => $hasData,
|
|
|
+// 'ctime' => $ctime, // 时间戳,用于排序
|
|
|
+// 'ctime_text' => date('Y-m-d H:i:s', $ctime), // 格式化日期,用于显示
|
|
|
+// 'image_count' => $imageCount,
|
|
|
+// 'new_image_url' => "/uploads/operate/ai/dall-e/",
|
|
|
+// 'old_image_url' => $relativeDir
|
|
|
+// ];
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// };
|
|
|
+//
|
|
|
+// // 执行目录扫描
|
|
|
+// $scanDir($baseDir, $baseRelativePath);
|
|
|
+//
|
|
|
+// // 排序:按照创建时间(从新到旧)
|
|
|
+// $dirList = array_values($dirs);
|
|
|
+//// usort($dirList, function ($a, $b) {
|
|
|
+//// return $b['ctime'] - $a['ctime'];
|
|
|
+//// });
|
|
|
+//
|
|
|
+// usort($dirList, function ($a, $b) {
|
|
|
+// return $b['id'] - $a['id'];
|
|
|
+// });
|
|
|
+//
|
|
|
+//
|
|
|
+// return json([
|
|
|
+// 'code' => 0,
|
|
|
+// 'msg' => '获取成功',
|
|
|
+// 'data' => $dirList
|
|
|
+// ]);
|
|
|
+// }
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 图片上传
|
|
|
- * @return void
|
|
|
*/
|
|
|
public function ImgUpload()
|
|
|
{
|
|
|
@@ -500,10 +414,10 @@ class Facility extends Api
|
|
|
exit(204);
|
|
|
}
|
|
|
|
|
|
-// 实际请求必须返回 CORS 头
|
|
|
+ // 实际请求必须返回 CORS 头
|
|
|
header('Access-Control-Allow-Origin: *');
|
|
|
|
|
|
-// 获取上传的文件
|
|
|
+ // 获取上传的文件
|
|
|
$file = request()->file('image');
|
|
|
|
|
|
if ($file) {
|
|
|
@@ -536,16 +450,17 @@ class Facility extends Api
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * 模版
|
|
|
+ * 查询模版
|
|
|
*/
|
|
|
public function Template(){
|
|
|
- $Template = Db::name("template")->find();
|
|
|
+ $Template = Db::name("template")->where('ids',1)->find();
|
|
|
return json([
|
|
|
'code' => 0,
|
|
|
'msg' => '模版',
|
|
|
'data' => $Template
|
|
|
]);
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
* 更新模版
|
|
|
*/
|
|
|
@@ -553,26 +468,18 @@ class Facility extends Api
|
|
|
if (Request::instance()->isPost() == false){
|
|
|
$this->error('非法请求');
|
|
|
}
|
|
|
-
|
|
|
$params = Request::instance()->post();
|
|
|
-
|
|
|
-
|
|
|
- // 验证传入的参数是否存在,避免空值
|
|
|
if (empty($params['textareaContent']) || empty($params['width']) || empty($params['height'])) {
|
|
|
return json(['code' => 1, 'msg' => '参数缺失']);
|
|
|
}
|
|
|
-
|
|
|
- // 更新模板数据
|
|
|
$Template = Db::name("template")
|
|
|
- ->where('id', 1) // 假设模板 ID 是 1,需根据实际情况修改
|
|
|
+ ->where('ids', 1)
|
|
|
->update([
|
|
|
'english_content' => $params['english_content'], // 更新文生文模版内容
|
|
|
'content' => $params['textareaContent'], // 更新图生文模版内容
|
|
|
'width' => $params['width'], // 更新宽度
|
|
|
'height' => $params['height'], // 更新宽度
|
|
|
]);
|
|
|
-
|
|
|
- // 判断数据库更新是否成功
|
|
|
if ($Template){
|
|
|
return json(['code' => 0, 'msg' => '成功']);
|
|
|
}else{
|
|
|
@@ -580,4 +487,69 @@ class Facility extends Api
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 打包图片
|
|
|
+ */
|
|
|
+ public function packImagess()
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $params = $this->request->post();
|
|
|
+ $paths = $params['paths'] ?? [];
|
|
|
+
|
|
|
+ if (empty($paths) || !is_array($paths)) {
|
|
|
+ return json(['code' => 1, 'msg' => '路径参数不能为空或格式不正确']);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置基础路径和压缩目录路径
|
|
|
+ $basePath = ROOT_PATH . 'public/';
|
|
|
+ $zipDir = $basePath . 'uploads/operate/ai/zip/';
|
|
|
+
|
|
|
+ if (!is_dir($zipDir)) {
|
|
|
+ mkdir($zipDir, 0755, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 压缩包文件名及完整路径
|
|
|
+ $fileName = 'images_' . date('Ymd_His') . '.zip';
|
|
|
+ $zipPath = $zipDir . $fileName;
|
|
|
+
|
|
|
+ // 创建 Zip 文件
|
|
|
+ $zip = new \ZipArchive();
|
|
|
+ if ($zip->open($zipPath, \ZipArchive::CREATE) !== TRUE) {
|
|
|
+ return json(['code' => 1, 'msg' => '无法创建压缩包']);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加文件到压缩包
|
|
|
+ $addCount = 0;
|
|
|
+ foreach ($paths as $relativePath) {
|
|
|
+ $relativePath = ltrim($relativePath, '/');
|
|
|
+ $fullPath = $basePath . $relativePath;
|
|
|
+
|
|
|
+ if (file_exists($fullPath)) {
|
|
|
+ $zip->addFile($fullPath, basename($fullPath)); // 仅保存文件名
|
|
|
+ $addCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $zip->close();
|
|
|
+
|
|
|
+ if ($addCount === 0) {
|
|
|
+ return json(['code' => 1, 'msg' => '未找到有效图片,未生成压缩包']);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回下载地址(注意路径与保存路径一致)
|
|
|
+ $downloadUrl = request()->domain() . '/uploads/operate/ai/zip/' . $fileName;
|
|
|
+
|
|
|
+ return json([
|
|
|
+ 'code' => 0,
|
|
|
+ 'msg' => '打包成功',
|
|
|
+ 'download_url' => $downloadUrl
|
|
|
+ ]);
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ return json([
|
|
|
+ 'code' => 1,
|
|
|
+ 'msg' => '异常错误:' . $e->getMessage()
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|