HasFiles.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <?php
  2. namespace Dcat\Admin\Form\Concerns;
  3. use Dcat\Admin\Contracts\UploadField as UploadFieldInterface;
  4. use Dcat\Admin\Form\Builder;
  5. use Dcat\Admin\Form\Field;
  6. use Dcat\Admin\Form\NestedForm;
  7. use Dcat\Admin\Support\WebUploader;
  8. use Illuminate\Support\Arr;
  9. use Symfony\Component\HttpFoundation\File\UploadedFile;
  10. use Symfony\Component\HttpFoundation\Response;
  11. /**
  12. * @property Builder $builder
  13. */
  14. trait HasFiles
  15. {
  16. /**
  17. * 文件上传操作.
  18. *
  19. * @param array $data
  20. *
  21. * @return Response|void
  22. */
  23. protected function handleUploadFile($data)
  24. {
  25. $column = $data['upload_column'] ?? null;
  26. $file = app('admin.web-uploader')->getUploadedFile() ?: ($data[WebUploader::FILE_NAME] ?? null);
  27. if (! $column || ! $file instanceof UploadedFile) {
  28. return;
  29. }
  30. $relation = $data['_relation'] ?? null;
  31. if (empty($relation)) {
  32. $field = $this->findFieldByName($column);
  33. } else {
  34. // hasMany表单文件上传
  35. $relation = explode(',', $relation)[0];
  36. $field = $this->getFieldByRelationName($relation, $column);
  37. }
  38. if ($field && $field instanceof UploadFieldInterface) {
  39. if ($results = $this->callUploading($field, $file)) {
  40. return $this->sendResponse($results);
  41. }
  42. $response = $field->upload($file);
  43. if ($results = $this->callUploaded($field, $file, $response)) {
  44. return $this->sendResponse($results);
  45. }
  46. return $response;
  47. }
  48. }
  49. /**
  50. * 根据字段名称查找字段.
  51. *
  52. * @param string|null $column
  53. *
  54. * @return Field|null
  55. */
  56. public function findFieldByName(?string $column)
  57. {
  58. return $this->builder->field($column);
  59. }
  60. /**
  61. * 新增页面删除文件.
  62. *
  63. * @param array $input
  64. *
  65. * @return \Illuminate\Http\JsonResponse
  66. */
  67. protected function deleteFileWhenCreating(array $input)
  68. {
  69. if (! array_key_exists(Field::FILE_DELETE_FLAG, $input)) {
  70. return;
  71. }
  72. $column = $input['_column'] ?? null;
  73. $filePath = $input['key'] ?? null;
  74. $relation = $input['_relation'] ?? null;
  75. if (! $column && ! $filePath) {
  76. return;
  77. }
  78. if (empty($relation)) {
  79. $field = $this->findFieldByName($column);
  80. } else {
  81. $field = $this->getFieldByRelationName($relation[0], $column);
  82. }
  83. if ($field && $field instanceof UploadFieldInterface) {
  84. $this->deleteFile($field, $filePath);
  85. return $this
  86. ->response()
  87. ->status(true)
  88. ->send();
  89. }
  90. }
  91. /**
  92. * 删除文件.
  93. *
  94. * @param UploadFieldInterface|Field $field
  95. * @param array $input
  96. */
  97. protected function deleteFile(UploadFieldInterface $field, $input = null)
  98. {
  99. if ($input) {
  100. if (
  101. is_string($input)
  102. || (is_array($input) && ! Arr::isAssoc($input))
  103. ) {
  104. $input = [$field->column() => $input];
  105. }
  106. $field->setOriginal($input);
  107. }
  108. if ($this->callFileDeleting($field) === false) {
  109. return;
  110. }
  111. $field->destroy();
  112. $this->callFileDeleted($field);
  113. }
  114. /**
  115. * 获取hasMany的子表单字段.
  116. *
  117. * @param string $relation
  118. * @param string $column
  119. *
  120. * @return mixed
  121. */
  122. public function getFieldByRelationName($relation, $column)
  123. {
  124. $relation = $this->findFieldByName($relation);
  125. if ($relation && $relation instanceof Field\HasMany) {
  126. return $relation->buildNestedForm()->fields()->first(function ($field) use ($column) {
  127. return $field->column() === $column;
  128. });
  129. }
  130. }
  131. /**
  132. * 根据传入数据删除文件.
  133. *
  134. * @param array $input
  135. * @param bool $forceDelete
  136. */
  137. public function deleteFiles($input, $forceDelete = false)
  138. {
  139. // If it's a soft delete, the files in the data will not be deleted.
  140. if (! $forceDelete && $this->isSoftDeletes) {
  141. return;
  142. }
  143. $this->builder
  144. ->fields()
  145. ->filter(function ($field) {
  146. return $field instanceof UploadFieldInterface;
  147. })
  148. ->each(function (UploadFieldInterface $field) use ($input) {
  149. $this->deleteFile($field, $input);
  150. });
  151. }
  152. /**
  153. * @param array $input
  154. *
  155. * @return array
  156. */
  157. protected function handleFileDelete(array $input = [])
  158. {
  159. if (! array_key_exists(Field::FILE_DELETE_FLAG, $input)) {
  160. return $input;
  161. }
  162. $input[Field::FILE_DELETE_FLAG] = $input['key'];
  163. if (! empty($input['_column'])) {
  164. if (empty($input['_relation'])) {
  165. $input[$input['_column']] = '';
  166. } else {
  167. [$relation, $relationKey] = $input['_relation'];
  168. $keyName = $this->builder()->field($relation)->getKeyName();
  169. $input[$relation] = [
  170. $relationKey => [
  171. $keyName => $relationKey,
  172. $input['_column'] => '',
  173. NestedForm::REMOVE_FLAG_NAME => null,
  174. ],
  175. ];
  176. }
  177. }
  178. $input = Arr::only($input, [Field::FILE_DELETE_FLAG, $input['_column']]);
  179. $this->request->replace($input);
  180. return $input;
  181. }
  182. }