123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- <?php
- namespace App\Admin\Forms;
- use App\Admin\Renderable\DistDistributorTable;
- use App\Admin\Repositories\DistAppearance;
- use App\Admin\Repositories\DistAppearanceTemplate;
- use App\Admin\Repositories\DistInquiry;
- use Dcat\Admin\Models\DistAdminUser;
- use Dcat\Admin\Widgets\Form;
- use Dcat\Admin\Contracts\LazyRenderable;
- use Dcat\Admin\Traits\LazyWidget;
- use ZipArchive;
- class AppearanceImPortForm extends Form implements LazyRenderable
- {
- use LazyWidget;
- protected $appearanceId = 0;
- // 处理请求
- public function handle(array $input)
- {
- // 获取外部传递参数
- $appearanceId = $this->payload['id'] ?? null;
- $file = $input['file'] ?? null;
- $appearanceRs = DistAppearance::getOneById($appearanceId);
- if ($file && $appearanceRs) {
- $folder = $appearanceRs->folder;
- $extractPath = resource_path().'/appearance/tmp';
- $path = resource_path().'/appearance/'.$folder;
- //解压
- $unzip = $this->unzip($file,$extractPath,$path);
- if (!$unzip['status']) {
- return $this->response()->error($unzip['error']);
- }
- //导入模板
- if (!is_dir($path)) {
- return $this->response()->error("The directory does not exist")->refresh();
- }
- $this->sourcePath = $path;
- $this->appearanceId = $appearanceId;
- // 清空旧的
- DistAppearanceTemplate::deleteTemplates($appearanceId, config('dictionary.base_dist_id'));
- // 导入模板
- $this->readDirectory($path);
- // 更新状态
- DistAppearance::setStatusToImported($appearanceId);
- return $this->response()->success('allocation successful')->refresh();
- }
- return $this->response()->error('No file data');
- }
- /*
- * 下载并解压
- */
- private function unzip($savePath,$extractPath,$trulyPath)
- {
- // 检查 $extractPath 是否存在且是否是一个目录
- if (!is_dir($extractPath)) {
- mkdir($extractPath, 0755, true);
- }
- if (!is_dir($trulyPath)) {
- mkdir($trulyPath, 0755, true);
- }
- $savePath = storage_path().'/app/'.$savePath;
- // 检查是否支持 ZipArchive 扩展
- if (!extension_loaded('zip')) {
- return ['status' => false, 'error' => 'ZipArchive 扩展未加载'];
- }
- // 保存文件到本地
- $zip = new ZipArchive;
- if ($zip->open($savePath) !== TRUE) {
- return ['status' => false, 'error' => 'ZipArchive 解压失败'];
- }
- if ($zip->extractTo($extractPath) !== TRUE) {
- return ['status' => false, 'error' => "解压文件到 $extractPath 失败。"];
- }
- $zip->close();
- //解压后,停0.1秒
- usleep(100000);
- //判断tmp下是否只有一个文件夹,如果是,移动到trulyPath
- // 递归删除 $trulyPath 下的所有文件和文件夹
- $deleteDirectoryContents = $this->deleteDirectoryContents($trulyPath);
- if ($deleteDirectoryContents) {
- return ['status' => false, 'error' => $deleteDirectoryContents];
- }
- // 获取 $extractPath 下的所有文件和文件夹
- $items = scandir($extractPath);
- // 过滤掉 '.' 和 '..'
- $items = array_diff($items, ['.', '..']);
- // 判断 $extractPath 是否只有一个文件夹
- if (count($items) != 1 || !is_dir($extractPath . '\\' . reset($items))) {
- return ['status' => false, 'error' => "Error: unzip file does not contain exactly one folder."];
- }
- // 获取文件夹名称
- $folderName = reset($items);
- $folderPath = $extractPath . '\\' . $folderName;
- // 获取文件夹下的所有文件和文件夹
- $folderContents = scandir($folderPath);
- $folderContents = array_diff($folderContents, ['.', '..']);
- // 将文件夹中的所有内容移动到 $trulyPath
- foreach ($folderContents as $fileOrDir) {
- $sourcePath = $folderPath . '\\' . $fileOrDir;
- $destinationPath = $trulyPath . '\\' . $fileOrDir;
- // 如果是文件,移动文件
- if (is_file($sourcePath)) {
- if (!rename($sourcePath, $destinationPath)) {
- return ['status' => false, 'error' => "Error: Failed to move file $fileOrDir\n"];
- }
- }
- // 如果是目录,递归移动目录内容
- elseif (is_dir($sourcePath)) {
- // 创建目标文件夹
- if (!mkdir($destinationPath)) {
- return ['status' => false, 'error' => "Error: Failed to create folder $fileOrDir\n"];
- }
- // 递归移动文件夹内容
- $folderFiles = scandir($sourcePath);
- $folderFiles = array_diff($folderFiles, ['.', '..']);
- foreach ($folderFiles as $subFile) {
- $subSourcePath = $sourcePath . '\\' . $subFile;
- $subDestinationPath = $destinationPath . '\\' . $subFile;
- if (!rename($subSourcePath, $subDestinationPath)) {
- return ['status' => false, 'error' => "Error: Failed to move subfolder file $subFile\n"];
- }
- }
- }
- }
- // 删除原文件夹及其内容
- $this->deleteDirectoryContents($folderPath);
- return ['status' => true];
- }
- // 递归删除文件夹及其内容
- private function deleteDirectoryContents($dir)
- {
- // 获取目录下所有文件和文件夹
- $items = scandir($dir);
- // 过滤掉 '.' 和 '..'
- $items = array_diff($items, ['.', '..']);
- // 循环遍历目录下的每一项
- foreach ($items as $item) {
- $itemPath = $dir . '\\' . $item;
- // 如果是文件,删除文件
- if (is_file($itemPath)) {
- if (!unlink($itemPath)) {
- return "Error: Failed to delete file $itemPath\n";
- }
- }
- // 如果是目录,递归删除该目录
- elseif (is_dir($itemPath)) {
- $this->deleteDirectoryContents($itemPath); // 递归删除目录内容
- if (!rmdir($itemPath)) {
- return "Error: Failed to delete directory $itemPath\n";
- }
- }
- }
- }
- public function form()
- {
- $this->file('file')
- ->disk('local') // 使用本地存储
- ->uniqueName()
- ->autoUpload()
- ->required()
- ->accept('zip')
- ->dir(config("admin.upload.directory.file").'/tmp/')
- ->help('Please upload a zip file');
- }
- private function readDirectory($dirPath) {
- // 检查目录是否存在
- if (!is_dir($dirPath)) {
- return;
- }
- // 打开目录
- $dir = opendir($dirPath);
- // 读取目录内容
- while (($file = readdir($dir)) !== false) {
- // 忽略当前目录和上级目录
- if ($file == '.' || $file == '..') {
- continue;
- }
- // 获取文件或文件夹的完整路径
- $fullPath = $dirPath . '/' . $file;
- // 如果是文件夹,递归读取
- if (is_dir($fullPath)) {
- $this->readDirectory($fullPath); // 递归调用
- } else {
- // 如果是文件,读取文件内容
- $content = file_get_contents($fullPath);
- $filePath = str_replace($this->sourcePath, '', $dirPath);
- $filePath = trim($filePath, '/');
- $fileName = basename($fullPath);
- // 插入数据库
- DistAppearanceTemplate::insertTemplateContent(config('dictionary.base_dist_id'), $this->appearanceId, $filePath,$fileName, $content);
- }
- }
- // 关闭目录
- closedir($dir);
- }
- }
|