Files.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. namespace common\widgets\webuploader;
  3. use Yii;
  4. use yii\helpers\Html;
  5. use yii\helpers\Json;
  6. use yii\helpers\Url;
  7. use yii\helpers\ArrayHelper;
  8. use yii\widgets\InputWidget;
  9. use yii\base\InvalidConfigException;
  10. use common\helpers\StringHelper;
  11. use common\enums\AttachmentDriveEnum;
  12. use common\widgets\webuploader\assets\AppAsset;
  13. /**
  14. * 图片上传
  15. *
  16. * Class Images
  17. * @package common\widgets\webuploader
  18. * @author jianyan74 <751393839@qq.com>
  19. */
  20. class Files extends InputWidget
  21. {
  22. /**
  23. * webuploader 参数配置
  24. *
  25. * @var array
  26. */
  27. public $config = [];
  28. /**
  29. * @var string
  30. */
  31. public $type = 'images';
  32. /**
  33. * 默认主题
  34. *
  35. * @var string
  36. */
  37. public $theme = 'default';
  38. /**
  39. * 默认主题配置
  40. *
  41. * @var array
  42. */
  43. public $themeConfig = [];
  44. /**
  45. * 盒子ID
  46. *
  47. * @var
  48. */
  49. protected $boxId;
  50. /**
  51. * @var
  52. */
  53. protected $typeConfig;
  54. /**
  55. * @throws InvalidConfigException
  56. * @throws \Exception
  57. */
  58. public function init()
  59. {
  60. parent::init();
  61. $uploadUrl = [
  62. 'images' => Url::to(['/files/images']),
  63. 'videos' => Url::to(['/files/videos']),
  64. 'voices' => Url::to(['/files/voices']),
  65. 'files' => Url::to(['/files/files']),
  66. ];
  67. // 默认配置信息
  68. $this->typeConfig = Yii::$app->params['uploadConfig'][$this->type];
  69. // 切换上传驱动
  70. if ($storageDefault = Yii::$app->services->config->backendConfig('storage_default')) {
  71. $this->typeConfig['drive'] = $storageDefault;
  72. }
  73. $name = $this->hasModel() ? Html::getInputName($this->model, $this->attribute) : $this->name;
  74. $this->boxId = md5($name) . StringHelper::uuid('uniqid');
  75. $this->themeConfig = ArrayHelper::merge([
  76. 'select' => true, // 显示选择文件
  77. 'sortable' => true, // 是否开启排序
  78. ], $this->themeConfig);
  79. $this->config = ArrayHelper::merge([
  80. 'compress' => false, // 压缩
  81. 'auto' => false, // 自动上传
  82. 'formData' => [
  83. 'guid' => null,
  84. 'md5' => null,
  85. 'writeTable' => true,
  86. 'drive' => $this->typeConfig['drive'], // 默认本地 可修改 qiniu/oss/cos 上传
  87. 'cate_id' => 0,
  88. 'upload_type' => $this->type,
  89. ], // 表单参数
  90. 'pick' => [
  91. 'id' => '.upload-album-' . $this->boxId,
  92. 'innerHTML' => '',// 指定按钮文字。不指定时优先从指定的容器中看是否自带文字。
  93. 'multiple' => false, // 是否开起同时选择多个文件能力
  94. ],
  95. 'accept' => [
  96. 'title' => 'Images',// 文字描述
  97. 'extensions' => implode(',', $this->typeConfig['extensions']), // 后缀
  98. 'mimeTypes' => $this->typeConfig['mimeTypes'],// 上传文件类型
  99. ],
  100. 'swf' => null, //
  101. 'chunked' => false,// 开启分片上传
  102. 'chunkSize' => 10 * 1024 * 1024,// 分片大小
  103. 'server' => $uploadUrl[$this->type], // 默认上传地址
  104. 'fileVal' => 'file', // 设置文件上传域的name
  105. 'disableGlobalDnd' => true, // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。
  106. 'fileNumLimit' => 20, // 验证文件总数量, 超出则不允许加入队列
  107. 'fileSizeLimit' => null, // 验证文件总大小是否超出限制, 超出则不允许加入队列 KB
  108. 'fileSingleSizeLimit' => $this->typeConfig['maxSize'], // 验证单个文件大小是否超出限制, 超出则不允许加入队列 KB
  109. 'prepareNextFile' => true,
  110. 'duplicate' => true,
  111. /**-------------- 自定义的参数 ----------------**/
  112. 'independentUrl' => false, // 独立上传地址,不受全局的地址上传影响
  113. 'md5Verify' => $this->typeConfig['md5Verify'], // md5 校验
  114. 'mergeUrl' => Url::to(['/files/merge']),
  115. 'getOssPathUrl' => Url::to(['/files/get-oss-path']),
  116. 'verifyMd5Url' => Url::to(['/files/verify-md5']),
  117. 'callback' => null, // 上传成功回调js方法
  118. 'callbackProgress' => null, // 上传进度回调
  119. 'name' => $this->name,
  120. 'boxId' => $this->boxId,
  121. 'type' => $this->type,
  122. ], $this->config);
  123. if (!empty($this->typeConfig['takeOverUrl']) && $this->config['independentUrl'] == false) {
  124. $this->config['server'] = $this->typeConfig['takeOverUrl'];
  125. }
  126. }
  127. /**
  128. * @return string
  129. * @throws \Exception
  130. */
  131. public function run()
  132. {
  133. $value = $this->hasModel() ? Html::getAttributeValue($this->model, $this->attribute) : $this->value;
  134. $name = $this->hasModel() ? Html::getInputName($this->model, $this->attribute) : $this->name;
  135. empty($value) && $value = [];
  136. if ($this->config['pick']['multiple'] == true ) {
  137. // 赋予默认值
  138. $name = $name . '[]';
  139. try {
  140. if ($value && !is_array($value)) {
  141. $value = json_decode($value, true);
  142. empty($value) && $value = unserialize($value);
  143. empty($value) && $value = [];
  144. }
  145. } catch (\Exception $e) {
  146. $value = [];
  147. }
  148. }
  149. if (!is_array($value)) {
  150. $tmp = $value;
  151. $value = [];
  152. $value[] = $tmp;
  153. }
  154. // 由于百度上传不能传递数组,所以转码成为json
  155. !isset($this->config['formData']) && $this->config['formData'] = [];
  156. // 阿里云直传
  157. if (AttachmentDriveEnum::OSS_DIRECT_PASSING == $this->config['formData']['drive']) {
  158. $path = $this->typeConfig['path'] . date($this->typeConfig['subName'], time()) . "/";
  159. $oss = Yii::$app->services->extendUpload->ossConfig($this->config['fileSingleSizeLimit'], $path, 60 * 60 * 2, $this->type);
  160. $this->config['server'] = $oss['host'];
  161. $this->config['formData'] = ArrayHelper::merge($this->config['formData'] , $oss);
  162. }
  163. foreach ($this->config['formData'] as &$datum) {
  164. if (!empty($datum) && is_array($datum)) {
  165. $datum = Json::encode($datum);
  166. }
  167. }
  168. $this->registerClientScript();
  169. return $this->render($this->theme, [
  170. 'name' => $name,
  171. 'value' => $value,
  172. 'type' => $this->type,
  173. 'boxId' => $this->boxId,
  174. 'config' => $this->config,
  175. 'themeConfig' => $this->themeConfig,
  176. ]);
  177. }
  178. /**
  179. * 注册资源
  180. */
  181. protected function registerClientScript()
  182. {
  183. $view = $this->getView();
  184. AppAsset::register($view);
  185. $boxId = $this->boxId;
  186. $jsConfig = Json::encode($this->config);
  187. $disabled = $this->themeConfig['sortable'] ?? true;
  188. // 手机端禁用拖动
  189. // Yii::$app->mobileDetect->isMobile() && $disabled = false;
  190. $view->registerJs(<<<Js
  191. var sortable = '{$disabled}';
  192. if (sortable) {
  193. // 拖动排序
  194. Sortable.create(document.getElementById('{$boxId}'),{
  195. distance : 30,
  196. filter : ".upload-box"
  197. });
  198. }
  199. $(".upload-album-{$boxId}").InitMultiUploader({$jsConfig});
  200. // 兼容老IE
  201. document.body.ondrop = function (event) {
  202. event = event || window.event;
  203. if (event.preventDefault) {
  204. event.preventDefault();
  205. event.stopPropagation();
  206. } else {
  207. event.returnValue = false;
  208. event.cancelBubble = true;
  209. }
  210. };
  211. Js
  212. );
  213. }
  214. }
粤ICP备19079148号