FolderController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <?php
  2. namespace App\Http\Controllers\API;
  3. use App\Http\Controllers\Controller;
  4. use App\Http\Requests\API\Folder\CreateRequest;
  5. use App\Http\Requests\API\Folder\UpdateRequest;
  6. use App\Http\Resources\API\FileByObjectResource;
  7. use App\Http\Resources\API\FileVersioTreeByObjectResource;
  8. use App\Http\Resources\API\FolderDetailResource;
  9. use App\Models\Enums\FolderObjectType;
  10. use App\Models\File;
  11. use App\Models\Folder;
  12. use App\Models\Library;
  13. use Illuminate\Http\Request;
  14. use Illuminate\Support\Facades\Auth;
  15. use Illuminate\Support\Facades\DB;
  16. class FolderController extends Controller
  17. {
  18. /**
  19. * Display a listing of the resource.
  20. */
  21. public function tree(string $objectType, string $objectId)
  22. {
  23. $folderObjectType = FolderObjectType::from($objectType);
  24. $folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
  25. $folders = Folder::query()
  26. ->where([
  27. 'object_type' => $objectType,
  28. 'object_id' => $objectId,
  29. ])
  30. ->when(request("parent_id", 0) > 0, function ($query) {
  31. return $query->where("path", "like", "%," . \request("parent_id") . ",%")->where("id", "!=", \request("parent_id"));
  32. })
  33. ->orderByDesc("sequence")
  34. ->get([
  35. 'id',
  36. 'name',
  37. 'parent_id'
  38. ])
  39. ->each(function ($folders){
  40. $folders->type='folder';
  41. $folders->uniId=$folders->type.'_'.$folders->id;
  42. });
  43. return $this->success([
  44. 'data' => make_tree($folders->toArray(), \request("parent_id", 0)),
  45. ]);
  46. }
  47. /**
  48. * Store a newly created resource in storage.
  49. */
  50. public function store(CreateRequest $request)
  51. {
  52. $folderObjectType = FolderObjectType::from($request->object_type);
  53. $object = $folderObjectType->modelBuilderAllowed()->findOrFail($request->object_id);
  54. $objectWhere = [
  55. 'object_type' => $folderObjectType->value, 'object_id' => $object->id
  56. ];
  57. $parentFolder = $request->parent_id > 0
  58. ? Folder::query()->where($objectWhere)->findOrFail($request->parent_id)
  59. : null;
  60. $names = [];
  61. $updateFolders = [];
  62. foreach ($request->items as $item) {
  63. if (! isset($item['name']) || !$item['name']) {
  64. return $this->badRequest("Folder name cannot be empty");
  65. }
  66. if (in_array($item['name'], $names)) {
  67. return $this->badRequest("Folder names must be unique");
  68. }
  69. $names[] = $item['name'];
  70. $isUpdate = isset($item['id']) && $item['id'];
  71. $count = Folder::query()
  72. ->where($objectWhere)
  73. ->where("parent_id", $request->parent_id)
  74. ->when($isUpdate, function ($query) use ($item) {
  75. return $query->where("id", "!=", $item['id']);
  76. })
  77. ->where("name", $item['name'])
  78. ->count();
  79. if ($count > 0) {
  80. return $this->badRequest(sprintf("Folder '%s' must be unique", $item['name']));
  81. }
  82. if ($isUpdate) {
  83. $folder = Folder::query()
  84. ->where($objectWhere)
  85. ->where("parent_id", $request->parent_id)
  86. ->find($item['id']);
  87. if (! $folder) {
  88. return $this->badRequest("Illegal parameters or the file relationship that needs to be updated has changed.");
  89. }
  90. $updateFolders[$item['id']] = $folder;
  91. }
  92. }
  93. foreach ($request->items as $item) {
  94. $isUpdate = isset($item['id']) && $item['id'];
  95. $data = [
  96. 'name' => $item['name'],
  97. 'sequence' => data_get($item, "sequence", 0),
  98. ];
  99. if ($isUpdate) {
  100. $folder = $updateFolders[$item['id']];
  101. $folder->fill($data);
  102. $folder->save();
  103. } else {
  104. $folder = Folder::query()->create([
  105. 'company_id' => Auth::user()->company_id,
  106. ...$objectWhere,
  107. 'parent_id' => $request->parent_id,
  108. ...$data
  109. ]);
  110. $folder->path = $parentFolder ? $parentFolder?->path . $folder->id . "," : sprintf(",%s,", $folder->id);
  111. $folder->save();
  112. }
  113. }
  114. return $this->created();
  115. }
  116. /**
  117. * Display the specified resource.
  118. */
  119. public function show(string $id)
  120. {
  121. $folder = Folder::query()->findOrFail($id);
  122. return new FolderDetailResource($folder);
  123. }
  124. /**
  125. * Update the specified resource in storage.
  126. */
  127. public function update(UpdateRequest $request, string $id)
  128. {
  129. $folder = Folder::query()->findOrFail($id);
  130. $folderObjectType = FolderObjectType::from($folder->object_type);
  131. $object = $folderObjectType->modelBuilderAllowed()->findOrFail($folder->object_id);
  132. $objectWhere = [
  133. 'object_type' => $folderObjectType->value, 'object_id' => $object->id
  134. ];
  135. $parentFolder = Folder::query()->where($objectWhere)->findOrFail($request->parent_id ?? $folder->id);
  136. if (! $parentFolder) {
  137. return $this->badRequest("Parent folder does not exist");
  138. }
  139. $count = Folder::query()
  140. ->where($objectWhere)
  141. ->where("parent_id", $request->parent_id)
  142. ->where("name", $request->name)
  143. ->where("id", "!=", $folder->id)
  144. ->count();
  145. if ($count > 0) {
  146. return $this->badRequest(sprintf("Folder '%s' must be unique", $request->name));
  147. }
  148. $fields = ['name', 'sequence'];
  149. if ($parentFolder?->id == $folder->parent_id) {
  150. $folder->fill($request->only($fields));
  151. $folder->save();
  152. } else {
  153. $path = $parentFolder->path . $folder->id . ",";
  154. $folderData = [
  155. ...$request->only($fields),
  156. 'path' => $path,
  157. 'parent_id' => $request->parent_id,
  158. ];
  159. $children = Folder::query()
  160. ->where($objectWhere)
  161. ->where("id", "!=", $folder->id)
  162. ->where("path", "like", "%," . $folder->id . ",%")
  163. ->get();
  164. foreach ($children as $child) {
  165. $child->fill([
  166. 'path' => str_replace($folder->path, $path, $child->path),
  167. ]);
  168. $child->save();
  169. }
  170. $folder->fill($folderData);
  171. $folder->save();
  172. }
  173. return $this->noContent();
  174. }
  175. /**
  176. * Remove the specified resource from storage.
  177. */
  178. public function destroy(string $id)
  179. {
  180. $folder = Folder::query()->findOrFail($id);
  181. $folderObjectType = FolderObjectType::from($folder->object_type);
  182. $folderObjectType->modelBuilderAllowed()->findOrFail($folder->object_id);
  183. $children = Folder::query()->where("parent_id", $folder->id)->count();
  184. if ($children > 0) {
  185. return $this->badRequest("Subordinate folders or containers exist and are not allowed to be deleted.");
  186. }
  187. $folder->delete();
  188. return $this->noContent();
  189. }
  190. public function open(Request $request)
  191. {
  192. $folderId = $request->get("id", 0);
  193. if ($folderId > 0) {
  194. $folder = Folder::query()->findOrFail($folderId);
  195. $objectType = $folder->object_type;
  196. $objectId = $folder->object_id;
  197. } else {
  198. $objectType = $request->get("object_type");
  199. $objectId = $request->get("object_id");
  200. }
  201. $folderObjectType = FolderObjectType::from($objectType);
  202. $folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
  203. $objectWhere = ['object_type' => $objectType, 'object_id' => $objectId,];
  204. $folders = Folder::query()
  205. ->where($objectWhere)
  206. ->when($folderId, fn($query) => $query->where("parent_id", $folderId))
  207. ->when(! $folderId, fn($query) => $query->where("parent_id", 0))
  208. ->get(['id', 'name'])->each(function ($folders)use ($folderId){
  209. $folderCount=Folder::query()->where('parent_id',$folders->id)->count();
  210. $filesCount=File::query()->where('folder_id',$folderId>0?$folders->id:$folderId)->where("is_latest_version", 1)->count();
  211. $folders->itemCount=$folderCount+$filesCount;
  212. });
  213. $files = File::query()->where($objectWhere)
  214. ->where("folder_id", $folderId)
  215. ->where("is_latest_version", 1)
  216. ->get();
  217. return $this->success([
  218. 'data' => [
  219. 'folders' => $folders,
  220. 'files' => FileByObjectResource::collection($files),
  221. ]
  222. ]);
  223. }
  224. /**
  225. * 基于类型的文件夹、文件版本树
  226. *
  227. * @param string $objectType
  228. * @param string $objectId
  229. * @return \Illuminate\Http\JsonResponse
  230. */
  231. public function versionFileTreeByObject(string $objectType, string $objectId)
  232. {
  233. $folderObjectType = FolderObjectType::from($objectType);
  234. $folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
  235. $objectWhere = ['object_type' => $objectType, 'object_id' => $objectId,];
  236. $folders = Folder::query()->with(['files'])->where($objectWhere)->get(['id', 'name', 'parent_id']);
  237. $fileResourceFunction = function (File $file) {
  238. return [
  239. 'id' => $file->id,
  240. 'title' => $file->title,
  241. 'extension' => $file->extension,
  242. 'size' => $file->size,
  243. 'created_by' => $file->createdBy ? [
  244. 'id' => $file->createdBy->id,
  245. 'name' => $file->createdBy->name,
  246. 'username' => $file->createdBy->username,
  247. ] : [],
  248. 'created_at' => (string)$file->created_at,
  249. 'version' => $file->version,
  250. 'type' => 'file'
  251. ];
  252. };
  253. $folderItems = [];
  254. foreach ($folders as &$folder) {
  255. $files = [];
  256. foreach ($folder->files->groupBy("title") as $fileItems) {
  257. $item = $fileResourceFunction($fileItems->first());
  258. $item['children'] = [];
  259. foreach ($fileItems as $fileItem) {
  260. $item['children'][] = $fileResourceFunction($fileItem);
  261. }
  262. $files[] = $item;
  263. }
  264. $folderItems[] = [
  265. 'id' => $folder->id,
  266. 'name' => $folder->name,
  267. 'parent_id' => $folder->parent_id,
  268. 'type' => 'folder',
  269. 'files' => $files,
  270. ];
  271. }
  272. return $this->success([
  273. 'data' => make_tree($folderItems)
  274. ]);
  275. }
  276. }