Skip to content

Commit 5d2d98b

Browse files
committed
优化上传文件回调逻辑,增加同步上传独立控制器,但未在项目中用到
1 parent 1224664 commit 5d2d98b

File tree

4 files changed

+194
-33
lines changed

4 files changed

+194
-33
lines changed

backend/models/Setting.php

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use yii\helpers\ArrayHelper;
1616
use yii\helpers\Html;
1717
use yii\helpers\Url;
18+
use yii\web\JsExpression;
1819

1920
/**
2021
* This is the model class for table "{{%setting}}".
@@ -430,46 +431,48 @@ public static function createInputTag($type, $alias, $value, $extra = '', $optio
430431
],
431432
'showPreview' => true,
432433
'showClose' => false,
434+
'showUpload' => false,//异步上传时,批量上传很大概率会出现第一个被第二个覆盖的bug,所以这里设置只能单个点击上传
433435
'initialPreview' => empty($value) ? [] : $valueArr,
434436
'initialPreviewConfig' => $initialPreviewConfig,
435437
'initialPreviewAsData' => true,
436438
'overwriteInitial' => $multiple ? false : true,//多文件不覆盖原有的,单文件覆盖
437439
],
438440
'pluginEvents' => [
439-
//批量上传按钮
440-
'filebatchuploadcomplete' => "function (event, files, extra){
441-
var arr=[];
442-
$('.field-setting-".$alias." .kv-file-remove').each(function(){
443-
var key=$(this).data('key');
444-
if(key && arr.indexOf(key)=='-1'){
445-
arr.push(key)
446-
}
447-
})
448-
$('input[type=\'hidden\'][name=\'" . $name . "\']').val(arr.join(','));
449-
}",
450441
//单个点击上传完毕后给隐藏表单赋值
451-
'fileuploaded' => "function (event,data){
452-
var arr=[];
453-
$('.field-setting-".$alias." .kv-file-remove').each(function(){
454-
var key=$(this).data('key');
455-
if(key && arr.indexOf(key)=='-1'){
456-
arr.push(key)
442+
'fileuploaded' => new JsExpression("function (event,data,previewId,index){
443+
var hiddenEle=$('input[type=\'hidden\'][name=\'" . $name . "\']');
444+
var hiddenValue=hiddenEle.val();
445+
var key=data.response.key;
446+
if(hiddenValue){
447+
hiddenValue=hiddenValue+','+key;
448+
}else{
449+
hiddenValue=key;
457450
}
458-
})
459-
$('input[type=\'hidden\'][name=\'" . $name . "\']').val(arr.join(','));
460-
}",
461-
//单个点击删除时清空隐藏表单(由于触发时,kv-file-remove还存在,所以需要去除本身)
462-
'filedeleted' => "function (event,key,jqXHR,data){
463-
var arr=[];
464-
var self=key;
465-
$('.field-setting-".$alias." .kv-file-remove').each(function(){
466-
var key=$(this).data('key');
467-
if(key && key!=self && arr.indexOf(key)=='-1'){
468-
arr.push(key)
451+
hiddenEle.val(hiddenValue);
452+
}"),
453+
//移动排序后交换隐藏表单值的位置
454+
'filesorted' => new JsExpression("function (event,params){
455+
var hiddenEle=$('input[type=\'hidden\'][name=\'" . $name . "\']');
456+
var hiddenValue=hiddenEle.val();
457+
var hiddenValueArr=hiddenValue.split(',');
458+
var oldIndex=params.oldIndex;
459+
var newIndex=params.newIndex;
460+
var tmp=hiddenValueArr[oldIndex];
461+
hiddenValueArr[oldIndex]=hiddenValueArr[newIndex];
462+
hiddenValueArr[newIndex]=tmp;
463+
hiddenEle.val(hiddenValueArr.join(','));
464+
}"),
465+
//单个点击删除时移除本隐藏表单值
466+
'filedeleted' => new JsExpression("function (event,key,jqXHR,data){
467+
var hiddenEle=$('input[type=\'hidden\'][name=\'" . $name . "\']');
468+
var hiddenValue=hiddenEle.val();
469+
var hiddenValueArr=hiddenValue.split(',');
470+
var index=$.inArray(key,hiddenValueArr);
471+
if(index!==-1){
472+
hiddenValueArr.splice(index,1);
473+
hiddenEle.val(hiddenValueArr.join(','));
469474
}
470-
})
471-
$('input[type=\'hidden\'][name=\'" . $name . "\']').val(arr.join(','));
472-
}",
475+
}"),
473476
]
474477
]);
475478
break;

common/components/UploadAction.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
/**
33
* fileInput上传独立控制器
4+
* 异步上传
5+
* 多文件上传时,需要设置'showUpload' => false,然后一个个上传,因为测试一键上传时很大概率第一张图会被第二张覆盖,原因暂未查明
46
*/
57

68
namespace common\components;
@@ -116,7 +118,8 @@ public function upload()
116118
//todo,后续如果用数据库存储,则需要返回对应的id,方便删除
117119
'key' => $saveFile
118120
]
119-
]
121+
],
122+
'key' => $saveFile//单独自定义,不用上面的值了
120123
];
121124
}
122125

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<?php
2+
/**
3+
* fileInput上传独立控制器
4+
* 同步上传
5+
* 前端设置:'uploadAsync' => false
6+
* 如果是多图,必须必须设置maxFiles规则不为1,且上传字段最后加[],例如Post['img'][]
7+
* 如果是单图,则不需要设置maxFiles,且上传字段不要加[]
8+
* 目前项目未采用此种上传,如果要用,还需要更改各种回调事件中的逻辑
9+
*/
10+
11+
namespace common\components;
12+
13+
use Yii;
14+
use yii\base\Action;
15+
use yii\base\DynamicModel;
16+
use yii\helpers\FileHelper;
17+
use yii\helpers\Url;
18+
use yii\web\Response;
19+
use yii\web\UploadedFile;
20+
21+
/**
22+
* ajax上传文件action
23+
*/
24+
class UploadSyncAction extends Action
25+
{
26+
/**
27+
* 上传字段名称
28+
* 可以不设置,在上传时传递name参数也可以,优先使用上传时的name参数
29+
* @var string
30+
*/
31+
public $name;
32+
/**
33+
* 保存路径
34+
* @var string
35+
*/
36+
public $path;
37+
/**
38+
* 验证规则
39+
* ['extensions'=>'png,jpg,gif','maxFiles' => 2,...]
40+
* @var array
41+
*/
42+
public $rule = [];
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function init()
48+
{
49+
//关闭csrf
50+
Yii::$app->request->enableCsrfValidation = false;
51+
//默认名称
52+
if (empty($this->name)) {
53+
$this->name = 'file_data';
54+
}
55+
//默认路径
56+
if (empty($this->path)) {
57+
$this->path = Yii::$app->params['defaultPath'];
58+
}
59+
}
60+
61+
/**
62+
* 运行
63+
* @throws \yii\base\Exception
64+
*/
65+
public function run()
66+
{
67+
if (Yii::$app->request->isAjax) {
68+
Yii::$app->response->format = Response::FORMAT_JSON;
69+
$action = Yii::$app->request->get('action');
70+
if ($action == 'upload') {
71+
//如果是上传
72+
return $this->upload();
73+
} elseif ($action == 'delete') {
74+
//如果是删除
75+
return $this->delete();
76+
} else {
77+
//参数错误
78+
return ['error' => Yii::t('common', 'Invalid Parameter')];
79+
}
80+
}
81+
}
82+
83+
/**
84+
* 上传文件
85+
* 由于用的是kartik的yii2-widget-fileinput组件,所以需要返回组件需要的格式
86+
* @throws \yii\base\Exception
87+
*/
88+
public function upload()
89+
{
90+
//文件字段名称
91+
$name = Yii::$app->request->post('name');
92+
if (empty($name)) {
93+
$name = $this->name;
94+
}
95+
//上传的文件,判断是单图上传还是多图上传
96+
if (isset($this->rule['maxFiles']) && ($this->rule['maxFiles'] != 1 || $this->rule['maxFiles'] > 1)) {
97+
$fileInstances = UploadedFile::getInstancesByName($name);
98+
$uploadFile = $fileInstances;
99+
} else {
100+
$fileInstance = UploadedFile::getInstanceByName($name);
101+
$uploadFile = $fileInstance;
102+
$fileInstances[0] = $fileInstance;
103+
}
104+
//验证文件上传
105+
$model = new DynamicModel([$name => $uploadFile]);
106+
$model->addRule($name, 'file', $this->rule)->validate();
107+
if ($model->hasErrors()) {
108+
$error = $model->getFirstError($name);
109+
return ['error' => $error];
110+
}
111+
//如果没有目录,则创建目录
112+
FileHelper::createDirectory(Yii::getAlias('@webroot') . $this->path);
113+
$saveFiles = [];
114+
$configs = [];
115+
foreach ($fileInstances as $key => $fileInstance) {
116+
//保存文件
117+
$newName = time() . rand(1000, 9999) . $key;//文件重命名
118+
if (!$fileInstance->saveAs(Yii::getAlias('@webroot') . $this->path . $newName . '.' . $fileInstance->extension)) {
119+
$uploadError = Yii::t('common', 'Upload failed!');
120+
//如果一个出错,将所有上传的都删除掉
121+
foreach ($saveFiles as $item) {
122+
@unlink(Yii::getAlias('@webroot') . $item);
123+
}
124+
return ['error' => $uploadError];
125+
}
126+
//返回正确信息
127+
$saveFile = $this->path . $newName . '.' . $fileInstance->extension;
128+
$saveFiles[] = $saveFile;
129+
$configs[] = [
130+
'caption' => $newName . '.' . $fileInstance->extension,
131+
'url' => Url::to(['upload', 'action' => 'delete']),
132+
//todo,后续如果用数据库存储,则需要返回对应的id,方便删除
133+
'key' => $saveFile,
134+
];
135+
}
136+
return [
137+
'initialPreview' => $saveFiles, //必须返回数据才能调用ajax删除
138+
'initialPreviewConfig' => $configs,
139+
'keys' => $saveFiles//单独自定义,不用上面的值了
140+
];
141+
}
142+
143+
/**
144+
* 删除文件
145+
*/
146+
public function delete()
147+
{
148+
$key = Yii::$app->request->post('key');
149+
@unlink(Yii::getAlias('@webroot') . $key);
150+
//todo,后续如果用数据库存储,需删除数据,可能返回错误什么的['error'=>'error message']
151+
return [
152+
'key' => $key
153+
];
154+
}
155+
}

console/migrations/m170424_062025_create_setting_table.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function up()
3434
$this->createTable(self::TBL_NAME, [
3535
'id' => $this->primaryKey()->comment('配置ID'),
3636
'pid' => $this->integer()->notNull()->defaultValue(0)->comment('父ID'),
37-
'name' => $this->string(64)->notNull()->defaultValue(0)->comment('配置名称'),
37+
'name' => $this->string(64)->notNull()->defaultValue('')->comment('配置名称'),
3838
'alias' => $this->string(64)->notNull()->unique()->defaultValue('')->comment('配置别名'),
3939
'type' => $this->tinyInteger()->notNull()->defaultValue(1)->comment('类别,例如1代表text,2代表radio等'),
4040
'value' => $this->text()->notNull()->comment(''),

0 commit comments

Comments
 (0)