layui上传图片

  1. layui 上传单图片 ```html
支持 jpg/png/jpeg/gif,最大 3MB
```javascript
  upload.render({
      elem: '#uploadThumbBtn',
      url: '/travel/upload_image_with_thumb',
      accept: 'images',
      exts: 'jpg|png|jpeg|gif',
      size: 3145728,
      done: function (res) {
        if (res.code === 200) {
          var url = res.data.url || res.data; // 使用原图URL作为封面(视频类型手动上传)
          $('#thumb').val(url);
          $('#thumbImg').attr('src', url).show();
          layer.msg('缩略图上传成功');
        } else {
          layer.msg(res.msg || '缩略图上传失败');
        }
      },
      error: function () { layer.msg('网络错误'); }
    });
  1. layui 上传多图片 ```html
图片组(可选),支持 jpg/png/jpeg/gif,最大 3MB
```javascript
upload.render({
	elem: '#uploadImagesBtn',
	url: '/travel/upload_image_with_thumb',
	accept: 'images',
	exts: 'jpg|png|jpeg|gif',
	multiple: true,
	size: 3145728,
	done: function (res, index, upload) {
		if (res.code === 200) {
			var url = res.data.url || res.data; // 使用原图URL作为封面(视频类型手动上传)
			let imagesStr = $('#cover_image').val() || '';
			let imagesArr = imagesStr.replace(/,$/, '').split(',').filter(item => item.trim() !== '');
			// 2. 添加新URL到数组
			imagesArr.push(url);
			// 3. 用join拼接成规范字符串(无多余逗号)
			$('#cover_image').val(imagesArr.join(','));
			$('#upload-images-preview').append('<span class="remove-image" style="position: relative; display: inline-block; margin-right: 8px;">' +
				'<img src="' + url + '" style="width: 90px; height: 90px; margin-right: 8px; ">' +
				'<span style="position: absolute; top: -5px; right: -5px; cursor: pointer; color: red;">×</span>' +
				'</span>')
			layer.msg('上传成功');
		} else {
			layer.msg(res.msg || '上传失败');
		}
	},
	error: function () { layer.msg('网络错误'); }
});
$(document).on('click', '.remove-image span', function () {
	console.log($(this).prev('img').attr('src'));
	$(this).parent('.remove-image').remove();
	let imagesStr = $('#cover_image').val() || '';
	let imagesArr = imagesStr.replace(/,$/, '').split(',').filter(item => item.trim() !== '');
	// 2. 删除点击的URL
	imagesArr = imagesArr.filter(url => url !== $(this).prev('img').attr('src'));
	// 3. 用join拼接成规范字符串(无多余逗号)
	$('#cover_image').val(imagesArr.join(','));
});
  1. 编辑渲染
    var initThumb = ($('#thumb').val() || '').trim();
    if (initThumb) { $('#thumbImg').attr('src', initThumb).show(); }
    var initCoverImage = ($('#cover_image').val() || '').trim();
    if (initCoverImage) {
     // 拆分:按逗号分割为单个URL数组,同时过滤空值(避免末尾逗号导致的空元素)
     var imageUrlArr = initCoverImage.split(',').filter(function (url) {
         return url.trim() !== ''; // 过滤空字符串,提升兼容性
     });
    
     for (var i = 0; i < imageUrlArr.length; i++) {
         var imgUrl = imageUrlArr[i].trim(); // 再次去除单个URL的首尾空格,避免无效地址
         // 拼接图片标签并追加到预览区域
         $('#upload-images-preview').append('<span class="remove-image" style="position: relative; display: inline-block; margin-right: 8px;">' +
         '<img src="' + imgUrl + '" alt="图片组-' + (i + 1) + '" style="width: 90px; height: 90px; margin-right: 8px; ">' +
         '<span style="position: absolute; top: -5px; right: -5px; cursor: pointer; color: red;">×</span>' +
         '</span>');
     }
    }
    
  2. PHP上传接口
    /**
     * 上传图片并自动生成缩略图(用于海报/文件为图片时自动填充封面)
     */
    public function upload_image_with_thumb(Request $request)
    {
         $file = $request->file('file');
         try {
             validate([
                 'file' => [
                     'fileSize' => 3 * 1024 * 1024,
                     'fileExt' => 'jpg,jpeg,png,gif',
                     'fileMime' => 'image/jpeg,image/png,image/gif',
                 ]
             ])->check(['file' => $file]);
    
             // 保存原图到 uploads/travel 目录
             $path = Filesystem::disk('upImage')->putFile('travel', $file);
    
             // 生成缩略图(宽度 320,按比例缩放)到 uploads/travel_thumb 目录
             $root = app()->getRootPath() . 'public/uploads/';
             $full = $root . $path;
             $ext = strtolower(pathinfo($full, PATHINFO_EXTENSION));
    
             // 创建原图资源
             switch ($ext) {
                 case 'png':
                     $src = imagecreatefrompng($full);
                     break;
                 case 'gif':
                     $src = imagecreatefromgif($full);
                     break;
                 default:
                     $src = imagecreatefromjpeg($full);
                     $ext = in_array($ext, ['jpg', 'jpeg']) ? 'jpg' : $ext;
                 }
                 if (!$src) {
                     return $this->showError('图片资源创建失败');
                 }
    
                 $origW = imagesx($src);
                 $origH = imagesy($src);
                 $thumbW = 320;
                 $thumbH = (int) round($origH * ($thumbW / max(1, $origW)));
                 if ($origW <= $thumbW) { // 小图不放大
                     $thumbW = $origW;
                     $thumbH = $origH;
                 }
    
                 $thumb = imagecreatetruecolor($thumbW, $thumbH);
                 // 透明处理
                 if (in_array($ext, ['png', 'gif'])) {
                     imagealphablending($thumb, false);
                     imagesavealpha($thumb, true);
                     $transparent = imagecolorallocatealpha($thumb, 0, 0, 0, 127);
                     imagefilledrectangle($thumb, 0, 0, $thumbW, $thumbH, $transparent);
                 }
    
                 imagecopyresampled($thumb, $src, 0, 0, 0, 0, $thumbW, $thumbH, $origW, $origH);
    
                 // 缩略图保存到 travel/thumb 子目录,统一位于 travel 目录下
                 $thumbDir = $root . 'travel/thumb';
                 if (!is_dir($thumbDir)) {
                     @mkdir($thumbDir, 0775, true);
                 }
                 $thumbName = 'travel_thumb_' . date('YmdHis') . '_' . mt_rand(1000, 9999) . '.' . $ext;
                 $thumbFull = $thumbDir . '/' . $thumbName;
    
                 switch ($ext) {
                     case 'png':
                         imagepng($thumb, $thumbFull, 6);
                         break;
                     case 'gif':
                         imagegif($thumb, $thumbFull);
                         break;
                     default:
                         imagejpeg($thumb, $thumbFull, 85);
                 }
    
                 imagedestroy($src);
                 imagedestroy($thumb);
    
                 $thumbRel = 'travel/thumb/' . $thumbName;
                 $baseUrl = config('app.img_url');
    
                 return $this->showSuccess([
                     'url' => $baseUrl . $path,
                     'thumb' => $baseUrl . $thumbRel,
                 ], '上传成功');
         } catch (ValidateException $e) {
             return json(['code' => 0, 'msg' => $e->getMessage()]);
         } catch (\Throwable $e) {
             return $this->showError('上传失败:' . $e->getMessage());
         }
    }