<?php // app/Libraries/CommonHelper.php namespace App\Libraries; use Dcat\Admin\Admin; class CommonHelper { /* * $images 格式:['image.jpg','image2.jpg'] * $ossSource 1:本地 2:相册 * 返回显示的HTML显示图片 */ public static function displayImage($images,$boxSize=60,$imgSize=1024,$ossSource=1,$hasLink=true) { if (empty($images) || empty($images[0])) { $html = ""; } else { // 默认显示 100x100 的图片 $thumbnailImages = array_map(function ($imageUrl) use ($boxSize,$ossSource) { if ($ossSource == 1) { $imageUrl= CommonHelper::ossUrl($imageUrl); } else { $imageUrl= CommonHelper::albumUrl($imageUrl); } $extension = pathinfo($imageUrl, PATHINFO_EXTENSION); if ($extension == 'svg') { return $imageUrl; } else { return $imageUrl . "?x-oss-process=image/resize,m_pad,h_{$boxSize},w_{$boxSize},color_ffffff"; } }, $images); // 生成点击查看大图的链接 $largeImages = array_map(function ($imageUrl) use ($imgSize,$ossSource) { if ($ossSource == 1) { $imageUrl= CommonHelper::ossUrl($imageUrl); } else { $imageUrl= CommonHelper::albumUrl($imageUrl); } $extension = pathinfo($imageUrl, PATHINFO_EXTENSION); if ($extension == 'svg') { return $imageUrl; } else { return $imageUrl . "?x-oss-process=image/resize,m_lfit,w_{$imgSize},h_{$imgSize}"; } }, $images); // 显示缩略图,并添加点击查看大图的功能 $html = ''; foreach ($thumbnailImages as $index => $thumbnailUrl) { $largeUrl = $largeImages[$index]; if ($hasLink) { $html .= "<a href='$largeUrl' target='_blank'><img src='$thumbnailUrl' style='height:{$boxSize}px; margin-right:5px; border: 1px solid #ececf1;'></a>"; } else { $html .= "<img src='$thumbnailUrl' style='height:{$boxSize}px; margin-right:5px; border: 1px solid #ececf1;'>"; } } return $html; } return $html; } /* * 返回oss的url */ public static function ossUrl($imageUrl) { if (strpos($imageUrl, 'http:') === 0 || strpos($imageUrl, 'https:') === 0) { return $imageUrl; } if (env('OSS_DOMAIN')) { return "http://".env('OSS_DOMAIN').'/'.$imageUrl; } return "http://".env('OSS_BUCKET').'.'.env('OSS_ENDPOINT').'/'.$imageUrl; } /* * 图库图片URL */ public static function albumUrl($imageUrl) { if (strpos($imageUrl, 'http:') === 0 || strpos($imageUrl, 'https:') === 0) { return $imageUrl; } return env('ALBUM_OSS_URL').'/'.$imageUrl; } /* * 显示视频 */ public static function displayVideo($items,$videoCover,$videoSrc,$boxSize=150,$ossSource=1) { $html = ''; if (is_array($items)) { foreach ($items as $item) { $item = (array) $item; $cover = $item[$videoCover]; $src = $item[$videoSrc]; if ($ossSource == 1) { $videoUrl = CommonHelper::ossUrl($src); } else { $videoUrl = CommonHelper::albumUrl($src); } if ($ossSource == 1) { $thumbnailUrl = CommonHelper::ossUrl($cover) . "?x-oss-process=image/resize,m_pad,h_{$boxSize},w_{$boxSize},color_ffffff"; } else { $thumbnailUrl = CommonHelper::albumUrl($cover) . "?x-oss-process=image/resize,m_pad,h_{$boxSize},w_{$boxSize},color_ffffff"; } $html .= '<div class="video-container"><a href="#" class="playVideo" videoUrl="'.$videoUrl.'")"><img src="'.$thumbnailUrl.'" alt="Video Thumbnail"><div class="play-button"></div></a></div>'; } $html .= '<div class="video-popup" id="videoPopup"><span class="close-btn">×</span> <iframe src="" frameborder="0" allowfullscreen></iframe></div>'; } //视频播放CSS Admin::style(" .video-container { position: relative; display: inline-block; } .video-container img { height: 200px; margin-right: 5px; border: 1px solid #ececf1; } .play-button { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 50px; height: 50px; background-color: rgba(0, 0, 0, 0.7); border-radius: 50%; cursor: pointer; } .play-button::after { content: '▶'; font-size: 30px; color: white; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .video-popup { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 25px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 1000; } .video-popup iframe { width: 800px; height: 450px; } .close-btn { position: absolute; top: 0px; right: 5px; font-size: 24px; color: #000; cursor: pointer; } .close-btn:hover { color: #f00; } "); Admin::script(" $('.playVideo').on('click', function(e) { e.preventDefault(); // 阻止默认跳转行为 var videoUrl = $(this).attr('videoUrl'); // 获取 videoUrl 属性 $('#videoPopup').css('display', 'block'); $('#videoPopup iframe').attr('src', videoUrl); // 设置 iframe 的 src }); // 点击关闭按钮关闭视频 $('.close-btn').on('click', function() { $('#videoPopup').css('display', 'none'); $('#videoPopup iframe').attr('src', ''); // 停止播放视频 }); "); return $html; // 当没有数组数据时 } /* * 替换新增与编辑的url,在后边加上指定的参数 (适用于弹出框的新增与编辑) * $addButton = '.tree-quick-create'; * $editButton = '.tree-quick-edit'; * $paramsUrl = 'location=0'; */ public static function replaceAddEditerUrl($addButton,$editButton,$paramsUrl) { Admin::script( <<<JS var button = $('{$addButton}'); var currentUrl = button.attr('data-url'); if (currentUrl.indexOf('?') === -1) { button.attr('data-url', currentUrl + '?{$paramsUrl}'); } else { button.attr('data-url', currentUrl + '&{$paramsUrl}'); } $('{$editButton}').each(function() { var currentUrl = $(this).attr('data-url'); if (currentUrl.indexOf('?') === -1) { $(this).attr('data-url', currentUrl + '?{$paramsUrl}'); } else { // 如果已经有查询参数,添加 &id=123 $(this).attr('data-url', currentUrl + '&{$paramsUrl}'); } }); JS ); } public static function seoReplace($titleName = 'title',$modelName = 'pages') { if ($titleName) { Admin::script( <<<JS $('input[name="{$titleName}"]').on('input', function() { // 将 title 的值赋给 seo_title $('input[name="seo_title"]').val($(this).val()); }); JS ); } //ajax 生成slug if ($modelName) { Admin::script( <<<JS $('input[name="{$titleName}"]').on('blur', function() { //通过ajax请求修改slug title = $(this).val(); $.ajax({ url: '/dist/api/generate-slug', type: 'GET', data: { model:'{$modelName}', title: title, }, success: function(response) { $('input[name="slug"]').val(response.slug); } }); }); JS ); } } public static function slug_fix($slug) { if ($slug == '') { return ''; } else { $slug = preg_replace('/\s+/', '-', $slug); $slug = strtolower($slug); return $slug; } } /* * 用于详情页,图片下载与放大 */ public static function viewDownloadEnlarge() { //css Admin::style( <<<CSS .download-wrapper::after { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(58, 54, 54, 0.34); /* 浅灰色半透明 */ opacity: 0; transition: opacity 0.3s ease; pointer-events: none; border-radius: 8px; } .download-wrapper { position: relative; display: inline-block; margin: 15px; overflow: hidden; border-radius: 8px; transition: transform 0.3s ease; } .download-hover { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); opacity: 0; transition: opacity 0.3s ease; display: flex; gap: 12px; z-index: 1; /* 确保按钮在遮罩层上方 */ } .download-btn { background: rgba(255, 255, 255, 0.95); border: none; width: 42px; height: 42px; border-radius: 50%; cursor: pointer; box-shadow: 0 3px 6px rgba(0,0,0,0.16); transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); } .download-btn.disabled { background: rgba(189, 189, 189, 0.95); cursor: not-allowed; } .download-btn i { font-size: 18px; color: #2196F3; } .download-wrapper:hover::after { opacity: 1; } .download-wrapper:hover .download-hover { opacity: 1; } .auto-download-image { display: block; transition: transform 0.3s ease; max-width: 100%; height: auto; border-radius: 8px; } .download-wrapper:hover img { transform: scale(1.04); } /* 新增全屏样式 */ .fullscreen-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.95); display: none; z-index: 1000; cursor: zoom-out; } .fullscreen-image { position: absolute; max-width: 90%; max-height: 90%; top: 50%; left: 50%; transform: translate(-50%, -50%); border-radius: 8px; animation: zoomIn 0.3s ease; } @keyframes zoomIn { from { transform: translate(-50%, -50%) scale(0.8); } to { transform: translate(-50%, -50%) scale(1); } } .download-wrapper:hover .download-hover { opacity: 1; } CSS ); //js Admin::script( <<<JS const fullscreenOverlay = $('.fullscreen-overlay'); const fullscreenImage = $('.fullscreen-image'); function initDownloadButtons() { $('.box-body').find("img").each(function() { // 新增判断:如果父元素是<a>或已有download-wrapper则跳过 if ($(this).parent().hasClass('download-wrapper') || $(this).parent().is('a')) return; if ($(this).hasClass('fullscreen-image')) { return; } const fileName = this.src.split('/').pop().split('?')[0]; $(this).wrap('<div class="download-wrapper"></div>') .after(`<div class="download-hover"> <button class="download-btn" title="下载"> <i class="feather icon-download"></i> </button> <button class="download-btn zoom-btn" title="放大"> <i class="feather icon-zoom-in"></i> </button> </div>`); const \$btn = $(this).parent().find('.download-btn').first(); \$btn.click(function() { const btn = $(this); btn.addClass('disabled'); downloadImage( btn.closest('.download-wrapper').find('img')[0].src, fileName ).finally(() => btn.removeClass('disabled')); }); // 全屏放大功能 $(this).next().find('.zoom-btn').click(function() { let imgSrc = $(this).closest('.download-wrapper').find('img').attr('src'); imgSrc = imgSrc.replace(/\?.*$/, ''); fullscreenImage.attr('src', imgSrc); fullscreenOverlay.fadeIn(200); }); }); } // 关闭全屏 fullscreenOverlay.click(function(e) { if (e.target === this) $(this).fadeOut(200); }); function downloadImage(url, filename) { return new Promise((resolve, reject) => { fetch(url) .then(response => { if (!response.ok) throw new Error('网络异常'); return response.blob() }) .then(blob => { const blobUrl = URL.createObjectURL(blob); console.log(blobUrl); const link = document.createElement('a'); link.href = blobUrl; link.download = filename || 'image.jpg'; document.body.appendChild(link); link.click(); setTimeout(() => { document.body.removeChild(link); URL.revokeObjectURL(blobUrl); }, 100); resolve(); }) .catch(error => { console.error(error); alert('下载失败'); reject(error); }); }); } initDownloadButtons(); JS); } /* * 用于详情页,图片下载与放大 HTML */ public static function viewDownloadEnlargeHtml() { return '<div class="fullscreen-overlay"><img src="" class="fullscreen-image"></div>'; } }