Sfoglia il codice sorgente

HasMany表单使用图片/文件上传功能

jqh 5 anni fa
parent
commit
f6dba406ba

+ 20 - 2
resources/assets/dcat/extra/upload.js

@@ -3,6 +3,7 @@
         opts = $.extend({
             wrapper: '.web-uploader', // 图片显示容器选择器
             addFileButton: '.add-file-button', // 继续添加按钮选择器
+            inputSelector: '',
             isImage: false,
             preview: [], // 数据预览
             server: '',
@@ -66,6 +67,7 @@
 
         var $selector = $(opts.selector),
             updateColumn = opts.upload.formData.upload_column || ('webup' + Math.floor(Math.random()*10000)),
+            relation = opts.upload.formData._relation, // 一对多关联关系名称
             elementName = opts.elementName;
 
         if (typeof opts.upload.formData._id == "undefined" || !opts.upload.formData._id) {
@@ -100,7 +102,7 @@
             originalFilesNum = Dcat.helpers.len(opts.preview),
 
             // 上传表单
-            $input = $selector.find('input[name="' + elementName + '"]'),
+            $input = $selector.find(opts.inputSelector),
 
             // 获取文件视图选择器
             getFileViewSelector = function (fileId) {
@@ -357,6 +359,7 @@
                                 return uploader.removeFile(file);
                             }
                             post._column = updateColumn;
+                            post._relation = relation;
 
                             Dcat.loading();
                             $.post(opts.deleteUrl, post, function (result) {
@@ -484,7 +487,21 @@
                 return;
             }
 
-            form[updateColumn] = values.join(',');
+            if (relation) {
+                if (! relation[1]) {
+                    // 新增子表记录,则不调用update接口
+                    return;
+                }
+
+                form[relation[0]] = {};
+
+                form[relation[0]][relation[1]] = {};
+                form[relation[0]][relation[1]][updateColumn] = values.join(',');
+            } else {
+                form[updateColumn] = values.join(',');
+            }
+
+            delete form['_relation'];
             delete form['upload_column'];
 
             $.post(opts.updateServer, form);
@@ -867,6 +884,7 @@
                 Dcat.confirm(__('confirm_delete_file'), file.serverId, function () {
                     post.key = fileId;
                     post._column = updateColumn;
+                    post._relation = relation;
 
                     Dcat.loading();
                     $.post(opts.deleteUrl, post, function (result) {

File diff suppressed because it is too large
+ 0 - 0
resources/dist/dcat/extra/upload.js


File diff suppressed because it is too large
+ 0 - 0
resources/dist/dcat/extra/upload.js.map


+ 31 - 0
src/Form.php

@@ -10,6 +10,7 @@ use Dcat\Admin\Form\Builder;
 use Dcat\Admin\Form\Concerns;
 use Dcat\Admin\Form\Condition;
 use Dcat\Admin\Form\Field;
+use Dcat\Admin\Form\NestedForm;
 use Dcat\Admin\Form\Row;
 use Dcat\Admin\Form\Tab;
 use Dcat\Admin\Traits\HasBuilderEvents;
@@ -802,6 +803,8 @@ class Form implements Renderable
 
         $this->inputs = $this->handleFileDelete($this->inputs);
 
+        $this->inputs = $this->handleHasManyValues($this->inputs);
+
         if ($response = $this->handleOrderable($this->inputs)) {
             return $response;
         }
@@ -818,6 +821,34 @@ class Form implements Renderable
         }
     }
 
+    /**
+     * @param array $inputs
+     *
+     * @return array
+     */
+    protected function handleHasManyValues(array $inputs)
+    {
+        foreach ($inputs as $column => &$input) {
+            $field = $this->builder()->field($column);
+
+            if (is_array($input) && $field instanceof Field\HasMany) {
+                $keyName = $field->getKeyName();
+
+                foreach ($input as $k => &$v) {
+                    if (empty($v[$keyName])) {
+                        $v[$keyName] = $k;
+                    }
+
+                    if (empty($v[NestedForm::REMOVE_FLAG_NAME])) {
+                        $v[NestedForm::REMOVE_FLAG_NAME] = null;
+                    }
+                }
+            }
+        }
+
+        return $inputs;
+    }
+
     /**
      * @param $key
      * @param $redirectTo

+ 59 - 21
src/Form/Concerns/HasFiles.php

@@ -5,6 +5,7 @@ namespace Dcat\Admin\Form\Concerns;
 use Dcat\Admin\Contracts\UploadField as UploadFieldInterface;
 use Dcat\Admin\Form\Builder;
 use Dcat\Admin\Form\Field;
+use Dcat\Admin\Form\NestedForm;
 use Dcat\Admin\Support\WebUploader;
 use Symfony\Component\HttpFoundation\File\UploadedFile;
 use Symfony\Component\HttpFoundation\Response;
@@ -15,6 +16,8 @@ use Symfony\Component\HttpFoundation\Response;
 trait HasFiles
 {
     /**
+     * 文件上传操作.
+     *
      * @param array $data
      *
      * @return Response|void
@@ -28,7 +31,16 @@ trait HasFiles
             return;
         }
 
-        $field = $this->findFieldByName($column);
+        $relation = $data['_relation'] ?? null;
+
+        if (empty($relation)) {
+            $field = $this->findFieldByName($column);
+        } else {
+            // hasMany表单文件上传
+            $relation = explode(',', $relation)[0];
+
+            $field = $this->getFieldByRelationName($relation, $column);
+        }
 
         if ($field && $field instanceof UploadFieldInterface) {
             if (($results = $this->callUploading($field, $file)) && $results instanceof Response) {
@@ -58,24 +70,12 @@ trait HasFiles
             return $field;
         }
 
-        if (mb_strpos($column, '.')) {
-            [$relation, $column] = explode('.', $column);
-
-            $relation = $this->findFieldByName($relation);
-
-            if ($relation instanceof Field\HasMany) {
-                return $relation->buildNestedForm()->fields()->first(function ($field) use ($column) {
-                    return $field->column() === $column;
-                });
-            }
-
-            return null;
-        }
-
         return $this->builder->field($column) ?: $this->builder->stepField($column);
     }
 
     /**
+     * 新增之前删除文件操作.
+     *
      * @param array $data
      *
      * @return \Illuminate\Http\JsonResponse|void
@@ -88,12 +88,17 @@ trait HasFiles
 
         $column = $data['_column'] ?? null;
         $file = $data['key'] ?? null;
+        $relation = $data['_relation'] ?? null;
 
         if (! $column && ! $file) {
             return;
         }
 
-        $field = $this->builder->field($column) ?: $this->builder->stepField($column);
+        if (empty($relation)) {
+            $field = $this->builder->field($column) ?: $this->builder->stepField($column);
+        } else {
+            $field = $this->getFieldByRelationName($relation[0], $column);
+        }
 
         if ($field && $field instanceof UploadFieldInterface) {
             $field->deleteFile($file);
@@ -102,6 +107,25 @@ trait HasFiles
         }
     }
 
+    /**
+     * 获取hasMany的子表单字段.
+     *
+     * @param string $relation
+     * @param string $column
+     *
+     * @return mixed
+     */
+    protected function getFieldByRelationName($relation, $column)
+    {
+        $relation = $this->findFieldByName($relation);
+
+        if ($relation && $relation instanceof Field\HasMany) {
+            return $relation->buildNestedForm()->fields()->first(function ($field) use ($column) {
+                return $field->column() === $column;
+            });
+        }
+    }
+
     /**
      * @param array $input
      *
@@ -122,7 +146,7 @@ trait HasFiles
     }
 
     /**
-     * Remove files in record.
+     * 根据传入数据删除文件.
      *
      * @param array $data
      * @param bool  $forceDelete
@@ -145,6 +169,8 @@ trait HasFiles
     }
 
     /**
+     * 编辑页面删除上传文件操作.
+     *
      * @param array $input
      *
      * @return array
@@ -156,14 +182,26 @@ trait HasFiles
         }
 
         $input[Field::FILE_DELETE_FLAG] = $input['key'];
-        unset($input['key']);
 
         if (! empty($input['_column'])) {
-            $input[$input['_column']] = '';
-
-            unset($input['_column']);
+            if (empty($input['_relation'])) {
+                $input[$input['_column']] = '';
+            } else {
+                [$relation, $relationKey] = $input['_relation'];
+                $keyName = $this->builder()->field($relation)->getKeyName();
+
+                $input[$relation] = [
+                    $relationKey => [
+                        $keyName                     => $relationKey,
+                        $input['_column']            => '',
+                        NestedForm::REMOVE_FLAG_NAME => null,
+                    ],
+                ];
+            }
         }
 
+        unset($input['key'], $input['_column'], $input['_relation']);
+
         $this->request->replace($input);
 
         return $input;

+ 3 - 3
src/Form/Field/File.php

@@ -112,11 +112,10 @@ class File extends Field implements UploadFieldInterface
      *
      * @return $this
      */
-    public function setRelation(?string $name)
+    public function setRelation(?string $name, $key)
     {
         $this->relationName = $name;
-
-        $this->options['formData']['upload_column'] = $name.'.'.$this->column();
+        $this->options['formData']['_relation'] = [$name, $key];
 
         return $this;
     }
@@ -207,6 +206,7 @@ class File extends Field implements UploadFieldInterface
         var opts = $.extend({
             selector: '#{$this->containerId}',
             addFileButton: '#{$this->containerId} .add-file-button',
+            inputSelector: '#{$this->id}',
         }, options);
 
         opts.upload = $.extend({

+ 8 - 2
src/Form/NestedForm.php

@@ -256,7 +256,7 @@ class NestedForm
 
             $value = $this->fetchColumnValue($record, $columns);
 
-            if (is_null($value)) {
+            if ($value === false) {
                 continue;
             }
 
@@ -291,6 +291,10 @@ class NestedForm
     protected function fetchColumnValue($data, $columns)
     {
         if (is_string($columns)) {
+            if (! Arr::has($data, $columns)) {
+                return false;
+            }
+
             return Arr::get($data, $columns);
         }
 
@@ -305,6 +309,8 @@ class NestedForm
 
             return $value;
         }
+
+        return false;
     }
 
     /**
@@ -322,7 +328,7 @@ class NestedForm
         }
 
         if ($field instanceof UploadField) {
-            $field->setRelation($this->relationName);
+            $field->setRelation($this->relationName, $this->key);
         }
 
         $field::collectAssets();

Some files were not shown because too many files changed in this diff