444 lines
16 KiB
PHP
444 lines
16 KiB
PHP
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
|
||
|
||
<?php
|
||
if (isset($post) || isset($page)) {
|
||
$cid = isset($post) ? $post->cid : $page->cid;
|
||
|
||
if ($cid) {
|
||
\Widget\Contents\Attachment\Related::alloc(['parentId' => $cid])->to($attachment);
|
||
} else {
|
||
\Widget\Contents\Attachment\Unattached::alloc()->to($attachment);
|
||
}
|
||
}
|
||
?>
|
||
|
||
<div id="upload-panel" class="p">
|
||
<div class="upload-area" data-url="<?php $security->index('/action/upload'); ?>">
|
||
<?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?>
|
||
</div>
|
||
<ul id="file-list">
|
||
<?php while ($attachment->next()): ?>
|
||
<li data-cid="<?php $attachment->cid(); ?>" data-url="<?php echo $attachment->attachment->url; ?>" data-image="<?php echo $attachment->attachment->isImage ? 1 : 0; ?>"><input type="hidden" name="attachment[]" value="<?php $attachment->cid(); ?>" />
|
||
<a class="insert" title="<?php _e('点击插入文件'); ?>" href="###"><?php $attachment->title(); ?></a>
|
||
<div class="info">
|
||
<?php echo number_format(ceil($attachment->attachment->size / 1024)); ?> Kb
|
||
<a class="file" target="_blank" href="<?php $options->adminUrl('media.php?cid=' . $attachment->cid); ?>" title="<?php _e('编辑'); ?>"><i class="i-edit"></i></a>
|
||
<a href="###" class="delete" title="<?php _e('删除'); ?>"><i class="i-delete"></i></a>
|
||
</div>
|
||
</li>
|
||
<?php endwhile; ?>
|
||
</ul>
|
||
</div>
|
||
|
||
<style>
|
||
#upload-notice {
|
||
position: fixed;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
z-index: 99999;
|
||
background: rgba(0, 0, 0, 0.8);
|
||
color: #fff;
|
||
padding: 60px 150px;
|
||
border-radius: 4px;
|
||
font-size: 16px;
|
||
text-align: center;
|
||
white-space: nowrap;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||
animation: fadeInOut 3s ease-in-out forwards;
|
||
pointer-events: none;
|
||
}
|
||
|
||
@keyframes fadeInOut {
|
||
0% { opacity: 0; }
|
||
10% { opacity: 1; }
|
||
90% { opacity: 1; }
|
||
100% { opacity: 0; visibility: hidden; }
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
(function() {
|
||
// 防止重复初始化
|
||
if (window._uploadFinalFixed) return;
|
||
window._uploadFinalFixed = true;
|
||
|
||
var uploadUrl = document.querySelector('.upload-area').getAttribute('data-url');
|
||
var fileList = document.getElementById('file-list');
|
||
var isUploading = false;
|
||
var isSelecting = false;
|
||
|
||
// 显示居中提示
|
||
function showNotice(message) {
|
||
var oldNotice = document.getElementById('upload-notice');
|
||
if (oldNotice) {
|
||
oldNotice.remove();
|
||
}
|
||
var notice = document.createElement('div');
|
||
notice.id = 'upload-notice';
|
||
notice.textContent = message;
|
||
document.body.appendChild(notice);
|
||
setTimeout(function() {
|
||
var n = document.getElementById('upload-notice');
|
||
if (n) n.remove();
|
||
}, 3000);
|
||
}
|
||
|
||
// 获取当前文章cid
|
||
function getCurrentCid() {
|
||
var cidInput = document.querySelector('input[name="cid"]');
|
||
return cidInput && cidInput.value ? cidInput.value : '';
|
||
}
|
||
|
||
// 激活附件菜单(切换到附件选项卡)
|
||
function activateAttachmentsMenu() {
|
||
// 根据实际HTML结构,附件选项卡的ID是 tab-files-btn
|
||
var attachmentsTab = document.getElementById('tab-files-btn');
|
||
|
||
if (!attachmentsTab) {
|
||
// 备用选择器
|
||
attachmentsTab = document.querySelector('a[href="#tab-files"]');
|
||
}
|
||
|
||
if (!attachmentsTab) {
|
||
// 再尝试查找包含"附件"文字的选项卡
|
||
var allTabs = document.querySelectorAll('.typecho-option-tabs li a');
|
||
for (var i = 0; i < allTabs.length; i++) {
|
||
var text = allTabs[i].innerText || allTabs[i].textContent;
|
||
if (text && text.indexOf('附件') !== -1) {
|
||
attachmentsTab = allTabs[i];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (attachmentsTab) {
|
||
// 检查是否已经是激活状态
|
||
var parentLi = attachmentsTab.parentNode;
|
||
if (parentLi && parentLi.className.indexOf('active') !== -1) {
|
||
return; // 已经是激活状态,不需要切换
|
||
}
|
||
|
||
// 模拟点击附件选项卡
|
||
if (typeof attachmentsTab.click === 'function') {
|
||
attachmentsTab.click();
|
||
} else if (typeof jQuery !== 'undefined') {
|
||
jQuery(attachmentsTab).trigger('click');
|
||
}
|
||
|
||
// 手动切换选项卡内容
|
||
var tabFiles = document.getElementById('tab-files');
|
||
var tabAdvance = document.getElementById('tab-advance');
|
||
if (tabFiles && tabAdvance) {
|
||
tabFiles.classList.remove('hidden');
|
||
tabAdvance.classList.add('hidden');
|
||
}
|
||
|
||
// 更新选项卡样式
|
||
if (parentLi) {
|
||
var allTabsLis = document.querySelectorAll('.typecho-option-tabs li');
|
||
for (var i = 0; i < allTabsLis.length; i++) {
|
||
allTabsLis[i].classList.remove('active');
|
||
}
|
||
parentLi.classList.add('active');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 刷新附件列表(不刷新整个页面)
|
||
function refreshAttachmentList() {
|
||
var cid = getCurrentCid();
|
||
var url = window.location.origin + '/admin/ajax/attachment-list?cid=' + cid;
|
||
|
||
var xhr = new XMLHttpRequest();
|
||
xhr.open('GET', url, true);
|
||
xhr.onload = function() {
|
||
if (xhr.status === 200) {
|
||
try {
|
||
var data = JSON.parse(xhr.responseText);
|
||
if (data && data.html) {
|
||
// 保存当前滚动位置
|
||
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||
// 更新附件列表
|
||
fileList.innerHTML = data.html;
|
||
// 重新绑定事件
|
||
document.querySelectorAll('#file-list li').forEach(bindFileEvents);
|
||
// 恢复滚动位置
|
||
window.scrollTo(0, scrollTop);
|
||
// 更新附件数量显示
|
||
updateAttachmentCount();
|
||
// 上传成功后激活附件菜单
|
||
activateAttachmentsMenu();
|
||
} else {
|
||
// 降级方案:刷新整个页面
|
||
window.location.reload();
|
||
}
|
||
} catch(e) {
|
||
window.location.reload();
|
||
}
|
||
} else {
|
||
window.location.reload();
|
||
}
|
||
};
|
||
xhr.onerror = function() {
|
||
window.location.reload();
|
||
};
|
||
xhr.send();
|
||
}
|
||
|
||
// 更新附件数量显示
|
||
function updateAttachmentCount() {
|
||
var attachmentCount = fileList.children.length;
|
||
var tabBtn = document.getElementById('tab-files-btn');
|
||
if (tabBtn) {
|
||
var balloon = tabBtn.querySelector('.balloon');
|
||
if (!balloon && attachmentCount > 0) {
|
||
balloon = document.createElement('span');
|
||
balloon.className = 'balloon';
|
||
tabBtn.appendChild(balloon);
|
||
}
|
||
if (balloon) {
|
||
balloon.textContent = attachmentCount;
|
||
if (attachmentCount === 0) {
|
||
balloon.style.display = 'none';
|
||
} else {
|
||
balloon.style.display = '';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 上传文件
|
||
function uploadFiles(files) {
|
||
if (!files || files.length === 0 || isUploading) return;
|
||
|
||
isUploading = true;
|
||
var total = files.length;
|
||
var completed = 0;
|
||
var successCount = 0;
|
||
var failCount = 0;
|
||
|
||
function checkComplete() {
|
||
if (completed === total) {
|
||
isUploading = false;
|
||
if (successCount > 0 || failCount > 0) {
|
||
var message = '';
|
||
if (successCount > 0 && failCount > 0) {
|
||
message = '已成功上传 ' + successCount + ' 个附件,失败 ' + failCount + ' 个附件。';
|
||
} else if (successCount > 0) {
|
||
message = '已成功上传 ' + successCount + ' 个附件。';
|
||
} else if (failCount > 0) {
|
||
message = '上传失败 ' + failCount + ' 个附件。';
|
||
}
|
||
showNotice(message);
|
||
}
|
||
if (successCount > 0) {
|
||
// 上传成功后刷新附件列表(会自动激活附件菜单)
|
||
refreshAttachmentList();
|
||
}
|
||
}
|
||
}
|
||
|
||
for (var i = 0; i < files.length; i++) {
|
||
(function(file) {
|
||
var formData = new FormData();
|
||
formData.append('file', file);
|
||
|
||
var url = uploadUrl;
|
||
var cid = getCurrentCid();
|
||
if (cid) {
|
||
url = uploadUrl + '?cid=' + cid;
|
||
}
|
||
|
||
var xhr = new XMLHttpRequest();
|
||
xhr.open('POST', url, true);
|
||
|
||
xhr.onload = function() {
|
||
completed++;
|
||
if (xhr.status === 200) {
|
||
try {
|
||
var response = JSON.parse(xhr.responseText);
|
||
if (response && response[1] && response[1].cid) {
|
||
successCount++;
|
||
} else {
|
||
failCount++;
|
||
}
|
||
} catch(e) {
|
||
failCount++;
|
||
}
|
||
} else {
|
||
failCount++;
|
||
}
|
||
checkComplete();
|
||
};
|
||
|
||
xhr.onerror = function() {
|
||
completed++;
|
||
failCount++;
|
||
checkComplete();
|
||
};
|
||
|
||
xhr.send(formData);
|
||
})(files[i]);
|
||
}
|
||
}
|
||
|
||
function bindFileEvents(li) {
|
||
// 插入按钮
|
||
var insertBtn = li.querySelector('.insert');
|
||
if (insertBtn) {
|
||
insertBtn.onclick = function(e) {
|
||
e.preventDefault();
|
||
var url = li.getAttribute('data-url');
|
||
var isImage = li.getAttribute('data-image') === '1';
|
||
var title = insertBtn.innerText;
|
||
var textarea = document.querySelector('#text, .wmd-input');
|
||
if (textarea) {
|
||
var insertText = isImage ? '' : '<a href="' + url + '">' + title + '</a>';
|
||
insertAtCursor(textarea, insertText);
|
||
}
|
||
return false;
|
||
};
|
||
}
|
||
|
||
// 删除按钮
|
||
var deleteBtn = li.querySelector('.delete');
|
||
if (deleteBtn) {
|
||
deleteBtn.onclick = function(e) {
|
||
e.preventDefault();
|
||
var cid = li.getAttribute('data-cid');
|
||
if (confirm('确定要删除这个附件吗?')) {
|
||
var xhr = new XMLHttpRequest();
|
||
xhr.open('POST', window.location.origin + '/action/upload?do=delete&cid=' + cid, true);
|
||
xhr.onload = function() {
|
||
if (xhr.status === 200) {
|
||
li.remove();
|
||
// 更新附件数量
|
||
updateAttachmentCount();
|
||
// 删除后如果列表为空,保持在附件菜单
|
||
if (fileList.children.length === 0) {
|
||
activateAttachmentsMenu();
|
||
}
|
||
}
|
||
};
|
||
xhr.send();
|
||
}
|
||
return false;
|
||
};
|
||
}
|
||
}
|
||
|
||
function insertAtCursor(textarea, text) {
|
||
if (textarea.selectionStart !== undefined) {
|
||
var start = textarea.selectionStart;
|
||
var end = textarea.selectionEnd;
|
||
textarea.value = textarea.value.substring(0, start) + text + textarea.value.substring(end);
|
||
textarea.selectionStart = textarea.selectionEnd = start + text.length;
|
||
} else if (textarea.createTextRange) {
|
||
var range = textarea.createTextRange();
|
||
range.collapse(true);
|
||
range.pasteHTML(text);
|
||
}
|
||
textarea.focus();
|
||
}
|
||
|
||
// 绑定现有列表项
|
||
document.querySelectorAll('#file-list li').forEach(bindFileEvents);
|
||
|
||
// 更新初始附件数量
|
||
updateAttachmentCount();
|
||
|
||
// 获取上传链接
|
||
var uploadLink = document.querySelector('.upload-file');
|
||
if (uploadLink) {
|
||
// 移除原有的 onclick 属性
|
||
uploadLink.removeAttribute('onclick');
|
||
|
||
// 解绑 jQuery 事件
|
||
if (typeof jQuery !== 'undefined') {
|
||
jQuery(uploadLink).off('click');
|
||
}
|
||
|
||
// 添加新的事件监听
|
||
uploadLink.addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
e.stopImmediatePropagation();
|
||
|
||
if (isUploading) {
|
||
return false;
|
||
}
|
||
|
||
if (isSelecting) {
|
||
return false;
|
||
}
|
||
|
||
isSelecting = true;
|
||
|
||
var input = document.createElement('input');
|
||
input.type = 'file';
|
||
input.multiple = true;
|
||
input.setAttribute('multiple', 'multiple');
|
||
input.style.position = 'fixed';
|
||
input.style.left = '-9999px';
|
||
input.style.top = '-9999px';
|
||
input.style.opacity = '0';
|
||
document.body.appendChild(input);
|
||
|
||
var cleanup = function() {
|
||
setTimeout(function() {
|
||
if (input && input.parentNode) {
|
||
input.parentNode.removeChild(input);
|
||
}
|
||
isSelecting = false;
|
||
}, 100);
|
||
};
|
||
|
||
input.onchange = function(e) {
|
||
var files = input.files;
|
||
cleanup();
|
||
if (files && files.length > 0) {
|
||
uploadFiles(files);
|
||
}
|
||
};
|
||
|
||
input.click();
|
||
return false;
|
||
}, true);
|
||
}
|
||
|
||
// 拖放上传
|
||
var uploadArea = document.querySelector('.upload-area');
|
||
if (uploadArea) {
|
||
if (typeof jQuery !== 'undefined') {
|
||
jQuery(uploadArea).off('drop dragover');
|
||
}
|
||
|
||
uploadArea.ondrop = function(e) {
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
|
||
if (isUploading) {
|
||
return false;
|
||
}
|
||
|
||
var files = e.dataTransfer.files;
|
||
if (files && files.length > 0) {
|
||
uploadFiles(files);
|
||
}
|
||
return false;
|
||
};
|
||
|
||
uploadArea.ondragover = function(e) {
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
return false;
|
||
};
|
||
}
|
||
|
||
// 确保初始时如果 URL 包含 #tab-files,激活附件菜单
|
||
if (window.location.hash === '#tab-files') {
|
||
activateAttachmentsMenu();
|
||
}
|
||
})();
|
||
</script>
|