$thumbnailUrl) {
$largeUrl = $largeImages[$index];
if ($hasLink) {
$html .= "
";
} else {
$html .= "
";
}
}
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 .= '
';
}
$html .= '';
}
//视频播放CSS
Admin::style("
.video-container {
position: relative;
display: inline-block;
}
.video-container img {
height: 200px;
margin-right: 5px;
border: 1px solid #ececf1;
}
.video-download-button {
position: absolute;
top: 50%;
left: 35%;
transform: translate(-50%, -50%);
width: 35px;
height: 35px;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
cursor: pointer;
}
.video-download-button::after {
content: '↓';
font-size: 15px;
color: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.play-button {
position: absolute;
top: 50%;
left: 58%;
transform: translate(-50%, -50%);
width: 35px;
height: 35px;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
cursor: pointer;
}
.play-button::after {
content: '▶';
font-size: 15px;
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
});
$('.downloadVideo').on('click', function(e) {
e.preventDefault();
const button = $(this);
const videoUrl = button.attr('videoUrl');
// 使用 Dcat Admin 内置 loading 组件
const loading = Dcat.loading({
});
fetch(videoUrl, {
headers: new Headers({
'Origin': location.origin,
'X-CSRF-TOKEN': Dcat.token // 集成 CSRF 保护[7](@ref)
}),
mode: 'cors'
}).then(response => {
if (!response.ok) throw new Error(`HTTP \${response.status}`);
// 动态创建进度条组件
const progress = new Dcat.Progress({
title: '下载进度',
showCancel: true,
onCancel: () => controller.abort()
});
const reader = response.body.getReader();
const controller = new AbortController();
const contentLength = +response.headers.get('Content-Length');
let receivedLength = 0;
const chunks = [];
// 流式处理优化
const processChunk = ({ done, value }) => {
if (done || progress.canceled) {
if (!progress.canceled) {
const blob = new Blob(chunks);
const filename = videoUrl.split('/').pop() || 'video.mp4';
const link = document.createElement('a');
// 集成 Dcat 文件管理器[6](@ref)
Dcat.handleFileDownload(blob, filename);
}
progress.close();
loading.close();
return;
}
chunks.push(value);
receivedLength += value.length;
progress.update({
percent: Math.round((receivedLength / contentLength) * 100),
statusText: `\${formatBytes(receivedLength)} / \${formatBytes(contentLength)}`
});
return reader.read().then(processChunk);
};
return reader.read().then(processChunk);
}).catch(error => {
loading.close();
Dcat.error(`下载失败: \${error.message}`);
console.error('Download Error:', error);
});
});
// 字节单位转换工具函数
function formatBytes(bytes) {
const units = ['B', 'KB', 'MB', 'GB'];
let i = 0;
while (bytes >= 1024 && i < units.length - 1) {
bytes /= 1024;
i++;
}
return `\${bytes.toFixed(1)} \${units[i]}`;
}
// 点击关闭按钮关闭视频
$('.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(
<<或已有download-wrapper则跳过
if ($(this).parent().hasClass('download-wrapper') || $(this).parent().is('a')) return;
if ($(this).hasClass('fullscreen-image') || $(this).hasClass('video-thumbnail')) {
return;
}
const fileName = this.src.split('/').pop().split('?')[0];
$(this).wrap('')
.after(`
`);
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) {
url = url.replace(/\?.*$/, '');
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 '';
}
}