Skip to content

Commit

Permalink
优化上传文件回调逻辑,增加同步上传独立控制器,但未在项目中用到
Browse files Browse the repository at this point in the history
  • Loading branch information
nadirvishun committed Jun 23, 2018
1 parent 1224664 commit 5d2d98b
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 33 deletions.
65 changes: 34 additions & 31 deletions backend/models/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Url;
use yii\web\JsExpression;

/**
* This is the model class for table "{{%setting}}".
Expand Down Expand Up @@ -430,46 +431,48 @@ public static function createInputTag($type, $alias, $value, $extra = '', $optio
],
'showPreview' => true,
'showClose' => false,
'showUpload' => false,//异步上传时,批量上传很大概率会出现第一个被第二个覆盖的bug,所以这里设置只能单个点击上传
'initialPreview' => empty($value) ? [] : $valueArr,
'initialPreviewConfig' => $initialPreviewConfig,
'initialPreviewAsData' => true,
'overwriteInitial' => $multiple ? false : true,//多文件不覆盖原有的,单文件覆盖
],
'pluginEvents' => [
//批量上传按钮
'filebatchuploadcomplete' => "function (event, files, extra){
var arr=[];
$('.field-setting-".$alias." .kv-file-remove').each(function(){
var key=$(this).data('key');
if(key && arr.indexOf(key)=='-1'){
arr.push(key)
}
})
$('input[type=\'hidden\'][name=\'" . $name . "\']').val(arr.join(','));
}",
//单个点击上传完毕后给隐藏表单赋值
'fileuploaded' => "function (event,data){
var arr=[];
$('.field-setting-".$alias." .kv-file-remove').each(function(){
var key=$(this).data('key');
if(key && arr.indexOf(key)=='-1'){
arr.push(key)
'fileuploaded' => new JsExpression("function (event,data,previewId,index){
var hiddenEle=$('input[type=\'hidden\'][name=\'" . $name . "\']');
var hiddenValue=hiddenEle.val();
var key=data.response.key;
if(hiddenValue){
hiddenValue=hiddenValue+','+key;
}else{
hiddenValue=key;
}
})
$('input[type=\'hidden\'][name=\'" . $name . "\']').val(arr.join(','));
}",
//单个点击删除时清空隐藏表单(由于触发时,kv-file-remove还存在,所以需要去除本身)
'filedeleted' => "function (event,key,jqXHR,data){
var arr=[];
var self=key;
$('.field-setting-".$alias." .kv-file-remove').each(function(){
var key=$(this).data('key');
if(key && key!=self && arr.indexOf(key)=='-1'){
arr.push(key)
hiddenEle.val(hiddenValue);
}"),
//移动排序后交换隐藏表单值的位置
'filesorted' => new JsExpression("function (event,params){
var hiddenEle=$('input[type=\'hidden\'][name=\'" . $name . "\']');
var hiddenValue=hiddenEle.val();
var hiddenValueArr=hiddenValue.split(',');
var oldIndex=params.oldIndex;
var newIndex=params.newIndex;
var tmp=hiddenValueArr[oldIndex];
hiddenValueArr[oldIndex]=hiddenValueArr[newIndex];
hiddenValueArr[newIndex]=tmp;
hiddenEle.val(hiddenValueArr.join(','));
}"),
//单个点击删除时移除本隐藏表单值
'filedeleted' => new JsExpression("function (event,key,jqXHR,data){
var hiddenEle=$('input[type=\'hidden\'][name=\'" . $name . "\']');
var hiddenValue=hiddenEle.val();
var hiddenValueArr=hiddenValue.split(',');
var index=$.inArray(key,hiddenValueArr);
if(index!==-1){
hiddenValueArr.splice(index,1);
hiddenEle.val(hiddenValueArr.join(','));
}
})
$('input[type=\'hidden\'][name=\'" . $name . "\']').val(arr.join(','));
}",
}"),
]
]);
break;
Expand Down
5 changes: 4 additions & 1 deletion common/components/UploadAction.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php
/**
* fileInput上传独立控制器
* 异步上传
* 多文件上传时,需要设置'showUpload' => false,然后一个个上传,因为测试一键上传时很大概率第一张图会被第二张覆盖,原因暂未查明
*/

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

Expand Down
155 changes: 155 additions & 0 deletions common/components/UploadSyncAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php
/**
* fileInput上传独立控制器
* 同步上传
* 前端设置:'uploadAsync' => false
* 如果是多图,必须必须设置maxFiles规则不为1,且上传字段最后加[],例如Post['img'][]
* 如果是单图,则不需要设置maxFiles,且上传字段不要加[]
* 目前项目未采用此种上传,如果要用,还需要更改各种回调事件中的逻辑
*/

namespace common\components;

use Yii;
use yii\base\Action;
use yii\base\DynamicModel;
use yii\helpers\FileHelper;
use yii\helpers\Url;
use yii\web\Response;
use yii\web\UploadedFile;

/**
* ajax上传文件action
*/
class UploadSyncAction extends Action
{
/**
* 上传字段名称
* 可以不设置,在上传时传递name参数也可以,优先使用上传时的name参数
* @var string
*/
public $name;
/**
* 保存路径
* @var string
*/
public $path;
/**
* 验证规则
* ['extensions'=>'png,jpg,gif','maxFiles' => 2,...]
* @var array
*/
public $rule = [];

/**
* {@inheritdoc}
*/
public function init()
{
//关闭csrf
Yii::$app->request->enableCsrfValidation = false;
//默认名称
if (empty($this->name)) {
$this->name = 'file_data';
}
//默认路径
if (empty($this->path)) {
$this->path = Yii::$app->params['defaultPath'];
}
}

/**
* 运行
* @throws \yii\base\Exception
*/
public function run()
{
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
$action = Yii::$app->request->get('action');
if ($action == 'upload') {
//如果是上传
return $this->upload();
} elseif ($action == 'delete') {
//如果是删除
return $this->delete();
} else {
//参数错误
return ['error' => Yii::t('common', 'Invalid Parameter')];
}
}
}

/**
* 上传文件
* 由于用的是kartik的yii2-widget-fileinput组件,所以需要返回组件需要的格式
* @throws \yii\base\Exception
*/
public function upload()
{
//文件字段名称
$name = Yii::$app->request->post('name');
if (empty($name)) {
$name = $this->name;
}
//上传的文件,判断是单图上传还是多图上传
if (isset($this->rule['maxFiles']) && ($this->rule['maxFiles'] != 1 || $this->rule['maxFiles'] > 1)) {
$fileInstances = UploadedFile::getInstancesByName($name);
$uploadFile = $fileInstances;
} else {
$fileInstance = UploadedFile::getInstanceByName($name);
$uploadFile = $fileInstance;
$fileInstances[0] = $fileInstance;
}
//验证文件上传
$model = new DynamicModel([$name => $uploadFile]);
$model->addRule($name, 'file', $this->rule)->validate();
if ($model->hasErrors()) {
$error = $model->getFirstError($name);
return ['error' => $error];
}
//如果没有目录,则创建目录
FileHelper::createDirectory(Yii::getAlias('@webroot') . $this->path);
$saveFiles = [];
$configs = [];
foreach ($fileInstances as $key => $fileInstance) {
//保存文件
$newName = time() . rand(1000, 9999) . $key;//文件重命名
if (!$fileInstance->saveAs(Yii::getAlias('@webroot') . $this->path . $newName . '.' . $fileInstance->extension)) {
$uploadError = Yii::t('common', 'Upload failed!');
//如果一个出错,将所有上传的都删除掉
foreach ($saveFiles as $item) {
@unlink(Yii::getAlias('@webroot') . $item);
}
return ['error' => $uploadError];
}
//返回正确信息
$saveFile = $this->path . $newName . '.' . $fileInstance->extension;
$saveFiles[] = $saveFile;
$configs[] = [
'caption' => $newName . '.' . $fileInstance->extension,
'url' => Url::to(['upload', 'action' => 'delete']),
//todo,后续如果用数据库存储,则需要返回对应的id,方便删除
'key' => $saveFile,
];
}
return [
'initialPreview' => $saveFiles, //必须返回数据才能调用ajax删除
'initialPreviewConfig' => $configs,
'keys' => $saveFiles//单独自定义,不用上面的值了
];
}

/**
* 删除文件
*/
public function delete()
{
$key = Yii::$app->request->post('key');
@unlink(Yii::getAlias('@webroot') . $key);
//todo,后续如果用数据库存储,需删除数据,可能返回错误什么的['error'=>'error message']
return [
'key' => $key
];
}
}
2 changes: 1 addition & 1 deletion console/migrations/m170424_062025_create_setting_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function up()
$this->createTable(self::TBL_NAME, [
'id' => $this->primaryKey()->comment('配置ID'),
'pid' => $this->integer()->notNull()->defaultValue(0)->comment('父ID'),
'name' => $this->string(64)->notNull()->defaultValue(0)->comment('配置名称'),
'name' => $this->string(64)->notNull()->defaultValue('')->comment('配置名称'),
'alias' => $this->string(64)->notNull()->unique()->defaultValue('')->comment('配置别名'),
'type' => $this->tinyInteger()->notNull()->defaultValue(1)->comment('类别,例如1代表text,2代表radio等'),
'value' => $this->text()->notNull()->comment(''),
Expand Down

0 comments on commit 5d2d98b

Please sign in to comment.