feat: 重构代码架构 + 新增报表/跟单/输赢统计功能
- 拆分 HomeController → TransactionController, ReportWebController, FollowPlanController - 新增 Service 层: TransactionService, ReportService, FollowPlanService - pk10.php JS 抽离为 4 个独立文件 (sound/race/bet/poll) - 前台新增报表查询页面 (/report) + 跟单计划页面 (/follow-plan) - 后台新增跟单计划管理 + 用户输赢明细统计 - 封盘状态显示倒计时 (x:xx) - 音效仅在开奖弹窗打开时播放 - 路由按模块分组整理 - autoload 支持 App\Services 命名空间
This commit is contained in:
+333
-143
@@ -1,13 +1,5 @@
|
||||
(function() {
|
||||
|
||||
// 常量定义 - 类名移除avif并添加ja-前缀
|
||||
const CLOSE_ICON = ` <img src="https://yanxuan.nosdn.127.net/0c64ce12c71cf276504cb2e15164d4ff.png"width="25px"> `;
|
||||
const RESET_ICON = ` <img src="https://yanxuan.nosdn.127.net/8296ea39d8c548ed320f79a483756cd9.jpg"width="25px" > `;
|
||||
const PREVIEW_ICON = ` <img class="ja-action-icon" src="https://yanxuan.nosdn.127.net/520b793c329df6349a25404efefbd0f4.png"/> `;
|
||||
const COPY_ICON = ` <img class="ja-action-icon" src="https://yanxuan.nosdn.127.net/0732b6e6d1f249dad11ac7d004af5964.png"/> `;
|
||||
const UP_ICON = ` <img class="ja-button-icon" src="https://yanxuan.nosdn.127.net/94494a4dc561ae21157f50764ddf035e.png"/> `;
|
||||
const ERRO_ICON = ` <img class="ja-erro-icon" src="https://yanxuan.nosdn.127.net/74777259ff515f056e8fc340df28fcd7.png"/> `;
|
||||
|
||||
// 基础配置
|
||||
const scriptBaseUrl = getScriptBaseUrl();
|
||||
const API_CONFIG = {
|
||||
@@ -76,11 +68,265 @@ function getScriptBaseUrl() {
|
||||
window.addEventListener('resize', setVh);
|
||||
window.addEventListener('orientationchange', setVh);
|
||||
|
||||
function createIconWrapper(className, iconType) {
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = className;
|
||||
wrapper.replaceChildren(createIconNode(iconType));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function createImageElement(src, alt = '', className = '', width = '') {
|
||||
const image = document.createElement('img');
|
||||
image.src = src;
|
||||
image.alt = alt;
|
||||
if (width) {
|
||||
image.width = Number(width);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
function createIconNode(type) {
|
||||
switch (type) {
|
||||
case 'close':
|
||||
return createImageElement('https://yanxuan.nosdn.127.net/0c64ce12c71cf276504cb2e15164d4ff.png', '', '', '25');
|
||||
case 'reset':
|
||||
return createImageElement('https://yanxuan.nosdn.127.net/8296ea39d8c548ed320f79a483756cd9.jpg', '', '', '25');
|
||||
case 'preview':
|
||||
return createImageElement('https://yanxuan.nosdn.127.net/520b793c329df6349a25404efefbd0f4.png', '', 'ja-action-icon');
|
||||
case 'copy':
|
||||
return createImageElement('https://yanxuan.nosdn.127.net/0732b6e6d1f249dad11ac7d004af5964.png', '', 'ja-action-icon');
|
||||
case 'upload':
|
||||
return createImageElement('https://yanxuan.nosdn.127.net/94494a4dc561ae21157f50764ddf035e.png', '', 'ja-button-icon');
|
||||
case 'error':
|
||||
return createImageElement('https://yanxuan.nosdn.127.net/74777259ff515f056e8fc340df28fcd7.png', '', 'ja-erro-icon');
|
||||
default:
|
||||
return document.createTextNode('');
|
||||
}
|
||||
}
|
||||
|
||||
function createUploadingIcon() {
|
||||
return createFontIcon('uploading-icon');
|
||||
}
|
||||
|
||||
|
||||
function createLoadingContainer(message = '加载中...') {
|
||||
const container = document.createElement('div');
|
||||
container.className = 'ja-loading-container';
|
||||
|
||||
const icon = document.createElement('i');
|
||||
icon.className = 'loading-icon';
|
||||
|
||||
const text = document.createElement('p');
|
||||
text.className = 'ja-loading-text';
|
||||
text.textContent = message;
|
||||
|
||||
container.append(icon, text);
|
||||
return container;
|
||||
}
|
||||
|
||||
function createStatusContainer(type, message) {
|
||||
const container = document.createElement('div');
|
||||
container.className = `ja-${type}-container`;
|
||||
container.appendChild(createIconNode('error'));
|
||||
|
||||
const text = document.createElement('p');
|
||||
text.className = `ja-${type}-text`;
|
||||
text.textContent = String(message || '');
|
||||
container.appendChild(text);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
function createMediaCard(item) {
|
||||
const itemElement = document.createElement('div');
|
||||
itemElement.className = 'ja-media-item';
|
||||
|
||||
const thumbnail = document.createElement('div');
|
||||
thumbnail.className = 'ja-item-thumbnail';
|
||||
|
||||
const image = document.createElement('img');
|
||||
image.src = item.url;
|
||||
image.alt = item.name;
|
||||
image.className = 'ja-thumbnail-image';
|
||||
image.loading = 'lazy';
|
||||
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'ja-item-overlay';
|
||||
|
||||
const copyButton = document.createElement('button');
|
||||
copyButton.className = 'ja-copy-button';
|
||||
copyButton.dataset.url = item.url;
|
||||
copyButton.appendChild(createIconNode('copy'));
|
||||
|
||||
const previewButton = document.createElement('button');
|
||||
previewButton.className = 'ja-preview-button';
|
||||
previewButton.dataset.url = item.url;
|
||||
previewButton.appendChild(createIconNode('preview'));
|
||||
|
||||
overlay.append(copyButton, previewButton);
|
||||
thumbnail.append(image, overlay);
|
||||
|
||||
const info = document.createElement('div');
|
||||
info.className = 'ja-item-info';
|
||||
|
||||
const name = document.createElement('div');
|
||||
name.className = 'ja-item-name';
|
||||
name.textContent = item.name;
|
||||
|
||||
const details = document.createElement('div');
|
||||
details.className = 'ja-item-details';
|
||||
|
||||
const size = document.createElement('span');
|
||||
size.className = 'ja-item-size';
|
||||
size.textContent = formatFileSize(item.size);
|
||||
|
||||
const dimensions = document.createElement('span');
|
||||
dimensions.className = 'ja-item-dimensions';
|
||||
dimensions.textContent = `${item.width}*${item.height}`;
|
||||
|
||||
details.append(size, dimensions);
|
||||
info.append(name, details);
|
||||
itemElement.append(thumbnail, info);
|
||||
|
||||
return itemElement;
|
||||
}
|
||||
|
||||
function createUploadErrorItem(fileName, reason) {
|
||||
const errorItem = document.createElement('div');
|
||||
errorItem.className = 'ja-upload-error';
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.className = 'ja-error-header';
|
||||
|
||||
const name = document.createElement('span');
|
||||
name.className = 'ja-error-filename';
|
||||
name.textContent = fileName;
|
||||
|
||||
const status = document.createElement('span');
|
||||
status.className = 'ja-error-status';
|
||||
status.textContent = '错误';
|
||||
|
||||
header.append(name, status);
|
||||
|
||||
const message = document.createElement('div');
|
||||
message.className = 'ja-error-message';
|
||||
message.textContent = reason;
|
||||
|
||||
errorItem.append(header, message);
|
||||
return errorItem;
|
||||
}
|
||||
|
||||
function createUploadSuccessItem(data) {
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'ja-media-item';
|
||||
|
||||
const thumbnail = document.createElement('div');
|
||||
thumbnail.className = 'ja-item-thumbnail relative';
|
||||
|
||||
const image = document.createElement('img');
|
||||
image.src = data.url;
|
||||
image.alt = data.name;
|
||||
image.className = 'ja-thumbnail-image';
|
||||
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'ja-item-overlay';
|
||||
|
||||
const copyButton = document.createElement('button');
|
||||
copyButton.className = 'ja-copy-button';
|
||||
copyButton.dataset.url = data.url;
|
||||
copyButton.appendChild(createIconNode('copy'));
|
||||
|
||||
const previewButton = document.createElement('button');
|
||||
previewButton.className = 'ja-preview-button';
|
||||
previewButton.dataset.url = data.url;
|
||||
previewButton.appendChild(createIconNode('preview'));
|
||||
|
||||
overlay.append(copyButton, previewButton);
|
||||
thumbnail.append(image, overlay);
|
||||
|
||||
const info = document.createElement('div');
|
||||
info.className = 'ja-item-info';
|
||||
|
||||
const detailTop = document.createElement('div');
|
||||
detailTop.className = 'ja-item-details';
|
||||
|
||||
const name = document.createElement('span');
|
||||
name.className = 'ja-item-name';
|
||||
name.textContent = data.name;
|
||||
|
||||
const success = document.createElement('span');
|
||||
success.className = 'ja-upload-success';
|
||||
success.textContent = '已完成';
|
||||
|
||||
detailTop.append(name, success);
|
||||
|
||||
const detailBottom = document.createElement('div');
|
||||
detailBottom.className = 'ja-item-details';
|
||||
|
||||
const size = document.createElement('span');
|
||||
size.className = 'ja-item-size';
|
||||
size.textContent = formatFileSize(data.size || 0);
|
||||
|
||||
const dimensions = document.createElement('span');
|
||||
dimensions.className = 'ja-item-dimensions';
|
||||
dimensions.textContent = `${data.width}*${data.height}`;
|
||||
|
||||
detailBottom.append(size, dimensions);
|
||||
info.append(detailTop, detailBottom);
|
||||
wrapper.append(thumbnail, info);
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function createUploadFailureContent(message) {
|
||||
const fragment = document.createDocumentFragment();
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.className = 'ja-upload-header';
|
||||
|
||||
const fileName = document.createElement('span');
|
||||
fileName.className = 'ja-upload-filename';
|
||||
|
||||
const failure = document.createElement('span');
|
||||
failure.className = 'ja-upload-failure';
|
||||
|
||||
header.append(fileName, failure);
|
||||
|
||||
const detail = document.createElement('div');
|
||||
detail.className = 'ja-upload-error-message';
|
||||
detail.textContent = message;
|
||||
|
||||
fragment.append(header, detail);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
function createPreviewModal(url) {
|
||||
const modal = document.createElement('div');
|
||||
modal.className = 'ja-image-preview-modal';
|
||||
|
||||
const content = document.createElement('div');
|
||||
content.className = 'ja-modal-content';
|
||||
|
||||
const image = document.createElement('img');
|
||||
image.src = url;
|
||||
image.alt = '预览图片';
|
||||
image.className = 'ja-modal-image';
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.className = 'ja-close-button';
|
||||
button.appendChild(createIconNode('close'));
|
||||
|
||||
content.append(image, button);
|
||||
modal.appendChild(content);
|
||||
|
||||
return { modal, content, image, button };
|
||||
}
|
||||
|
||||
// UI 创建函数 - 所有ID和类名添加ja-前缀并移除avif
|
||||
function createUI() {
|
||||
// 动态插入 CSS,禁止顶部下拉刷新
|
||||
const style = document.createElement('style');
|
||||
style.innerHTML = `
|
||||
style.textContent = `
|
||||
html, body {
|
||||
overscroll-behavior-y: contain;
|
||||
}
|
||||
@@ -100,14 +346,14 @@ function getScriptBaseUrl() {
|
||||
// 创建关闭按钮
|
||||
closeBtn = document.createElement('button');
|
||||
closeBtn.className = 'ja-modal-close';
|
||||
closeBtn.innerHTML = `${CLOSE_ICON}`;
|
||||
closeBtn.appendChild(createIconNode('close'));
|
||||
|
||||
|
||||
// 创建重置按钮
|
||||
resetBtn = document.createElement('button');
|
||||
resetBtn.className = 'ja-img-close';
|
||||
resetBtn.setAttribute('data-action', 'reset');
|
||||
resetBtn.innerHTML = `${RESET_ICON}`;
|
||||
resetBtn.appendChild(createIconNode('reset'));
|
||||
|
||||
// 标签页导航
|
||||
const tabs = document.createElement('div');
|
||||
@@ -143,27 +389,56 @@ function getScriptBaseUrl() {
|
||||
|
||||
const qualityLabel = document.createElement('label');
|
||||
qualityLabel.className = 'ja-param-label';
|
||||
qualityLabel.innerHTML = `
|
||||
<span class="ja-param-title">质量设置 (1-100)</span>
|
||||
<div class="ja-range-wrapper">
|
||||
<input type="range" id="ja-quality" min="1" max="100" value="60" class="ja-range-input">
|
||||
<span id="ja-quality-value" class="ja-range-span">60</span>
|
||||
</div>
|
||||
`;
|
||||
const qualityTitle = document.createElement('span');
|
||||
qualityTitle.className = 'ja-param-title';
|
||||
qualityTitle.textContent = '质量设置 (1-100)';
|
||||
|
||||
const qualityWrapper = document.createElement('div');
|
||||
qualityWrapper.className = 'ja-range-wrapper';
|
||||
|
||||
const qualityRange = document.createElement('input');
|
||||
qualityRange.type = 'range';
|
||||
qualityRange.id = 'ja-quality';
|
||||
qualityRange.min = '1';
|
||||
qualityRange.max = '100';
|
||||
qualityRange.value = '60';
|
||||
qualityRange.className = 'ja-range-input';
|
||||
|
||||
const qualityValue = document.createElement('span');
|
||||
qualityValue.id = 'ja-quality-value';
|
||||
qualityValue.className = 'ja-range-span';
|
||||
qualityValue.textContent = '60';
|
||||
|
||||
qualityWrapper.append(qualityRange, qualityValue);
|
||||
qualityLabel.append(qualityTitle, qualityWrapper);
|
||||
|
||||
const widthLabel = document.createElement('label');
|
||||
widthLabel.className = 'ja-param-label';
|
||||
widthLabel.innerHTML = `
|
||||
<span class="ja-param-title">转换宽度</span>
|
||||
<input type="number" id="ja-width" placeholder="留空为自动" class="ja-text-input">
|
||||
`;
|
||||
const widthTitle = document.createElement('span');
|
||||
widthTitle.className = 'ja-param-title';
|
||||
widthTitle.textContent = '转换宽度';
|
||||
|
||||
const widthInput = document.createElement('input');
|
||||
widthInput.type = 'number';
|
||||
widthInput.id = 'ja-width';
|
||||
widthInput.placeholder = '留空为自动';
|
||||
widthInput.className = 'ja-text-input';
|
||||
|
||||
widthLabel.append(widthTitle, widthInput);
|
||||
|
||||
const heightLabel = document.createElement('label');
|
||||
heightLabel.className = 'ja-param-label';
|
||||
heightLabel.innerHTML = `
|
||||
<span class="ja-param-title">转换高度</span>
|
||||
<input type="number" id="ja-height" placeholder="留空为自动" class="ja-text-input">
|
||||
`;
|
||||
const heightTitle = document.createElement('span');
|
||||
heightTitle.className = 'ja-param-title';
|
||||
heightTitle.textContent = '转换高度';
|
||||
|
||||
const heightInput = document.createElement('input');
|
||||
heightInput.type = 'number';
|
||||
heightInput.id = 'ja-height';
|
||||
heightInput.placeholder = '留空为自动';
|
||||
heightInput.className = 'ja-text-input';
|
||||
|
||||
heightLabel.append(heightTitle, heightInput);
|
||||
|
||||
// 上传控件
|
||||
const uploadInput = document.createElement('input');
|
||||
@@ -176,10 +451,12 @@ function getScriptBaseUrl() {
|
||||
const uploadBtn = document.createElement('button');
|
||||
uploadBtn.id = 'ja-upload-btn';
|
||||
uploadBtn.className = 'ja-button ja-button-primary';
|
||||
uploadBtn.innerHTML = `
|
||||
<div id="ja-upload-svg"> ${UP_ICON} </div>
|
||||
<div id="ja-upload-status">开始上传</div>
|
||||
`;
|
||||
const uploadSvg = createIconWrapper('ja-upload-svg', 'upload');
|
||||
uploadSvg.id = 'ja-upload-svg';
|
||||
const uploadStatus = document.createElement('div');
|
||||
uploadStatus.id = 'ja-upload-status';
|
||||
uploadStatus.textContent = '开始上传';
|
||||
uploadBtn.append(uploadSvg, uploadStatus);
|
||||
|
||||
const uploadResults = document.createElement('div');
|
||||
uploadResults.id = 'ja-upload-results';
|
||||
@@ -189,9 +466,9 @@ function getScriptBaseUrl() {
|
||||
const loadMoreBtn = document.createElement('button');
|
||||
loadMoreBtn.id = 'ja-load-more';
|
||||
loadMoreBtn.className = 'ja-load-more ja-button ja-button-secondary mt-4';
|
||||
loadMoreBtn.innerHTML = `
|
||||
<i class="fa fa-refresh mr-2"></i> 加载更多
|
||||
`;
|
||||
const loadMoreIcon = document.createElement('i');
|
||||
loadMoreIcon.className = 'fa fa-refresh mr-2';
|
||||
loadMoreBtn.append(loadMoreIcon, document.createTextNode(' 加载更多'));
|
||||
|
||||
document.head.appendChild(style);
|
||||
|
||||
@@ -343,7 +620,7 @@ function getScriptBaseUrl() {
|
||||
|
||||
// 清空上传结果
|
||||
const uploadResults = document.getElementById('ja-upload-results');
|
||||
if (uploadResults) uploadResults.innerHTML = '';
|
||||
if (uploadResults) uploadResults.replaceChildren();
|
||||
|
||||
// 清空文件选择
|
||||
const uploadInput = document.getElementById('ja-upload-input');
|
||||
@@ -384,22 +661,12 @@ function getScriptBaseUrl() {
|
||||
|
||||
// 首次加载显示加载状态
|
||||
if (isInitialLoad) {
|
||||
grid.innerHTML = `
|
||||
<div class="ja-loading-container">
|
||||
<i class="loading-icon"></i>
|
||||
<p class="ja-loading-text">加载中...</p>
|
||||
</div>
|
||||
`;
|
||||
grid.replaceChildren(createLoadingContainer());
|
||||
// 初始加载时隐藏加载更多按钮
|
||||
loadMoreBtn.style.display = 'none';
|
||||
} else {
|
||||
// 非首次加载时显示加载状态
|
||||
const loadingIndicator = document.createElement('div');
|
||||
loadingIndicator.className = 'ja-loading-container';
|
||||
loadingIndicator.innerHTML = `
|
||||
<i class="loading-icon"></i>
|
||||
<p class="ja-loading-text">加载中...</p>
|
||||
`;
|
||||
const loadingIndicator = createLoadingContainer();
|
||||
grid.appendChild(loadingIndicator);
|
||||
}
|
||||
|
||||
@@ -430,15 +697,17 @@ function getScriptBaseUrl() {
|
||||
|
||||
// 控制加载更多按钮显示
|
||||
if (state.currentPage >= state.totalPages) {
|
||||
loadMoreBtn.innerHTML = `
|
||||
<i class="fa fa-check mr-2"></i> 没有更多图片了
|
||||
`;
|
||||
loadMoreBtn.replaceChildren();
|
||||
const doneIcon = document.createElement('i');
|
||||
doneIcon.className = 'fa fa-check mr-2';
|
||||
loadMoreBtn.append(doneIcon, document.createTextNode(' 没有更多图片了'));
|
||||
loadMoreBtn.disabled = true;
|
||||
loadMoreBtn.classList.add('opacity-50', 'cursor-not-allowed');
|
||||
} else {
|
||||
loadMoreBtn.innerHTML = `
|
||||
<i class="fa fa-refresh mr-2"></i> 加载更多
|
||||
`;
|
||||
loadMoreBtn.replaceChildren();
|
||||
const refreshIcon = document.createElement('i');
|
||||
refreshIcon.className = 'fa fa-refresh mr-2';
|
||||
loadMoreBtn.append(refreshIcon, document.createTextNode(' 加载更多'));
|
||||
loadMoreBtn.disabled = false;
|
||||
loadMoreBtn.classList.remove('opacity-50', 'cursor-not-allowed');
|
||||
}
|
||||
@@ -452,23 +721,13 @@ function getScriptBaseUrl() {
|
||||
}
|
||||
} else {
|
||||
// 错误处理
|
||||
grid.innerHTML = `
|
||||
<div class="ja-error-container">
|
||||
${ERRO_ICON}
|
||||
<p class="ja-error-text">${data.message}</p>
|
||||
</div>
|
||||
`;
|
||||
grid.replaceChildren(createStatusContainer('error', data.message));
|
||||
loadMoreBtn.style.display = 'none';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取图片列表失败:', error);
|
||||
grid.innerHTML = `
|
||||
<div class="ja-error-container">
|
||||
${ERRO_ICON}
|
||||
<p class="ja-error-text">网络错误,请重试</p>
|
||||
</div>
|
||||
`;
|
||||
grid.replaceChildren(createStatusContainer('error', '网络错误,请重试'));
|
||||
loadMoreBtn.style.display = 'none';
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -498,39 +757,17 @@ function getScriptBaseUrl() {
|
||||
function renderMediaGrid() {
|
||||
const grid = document.getElementById('ja-media-grid');
|
||||
const itemsToRender = state.mediaItems;
|
||||
grid.innerHTML = '';
|
||||
grid.replaceChildren();
|
||||
|
||||
if (itemsToRender.length === 0) {
|
||||
// 空状态显示
|
||||
grid.innerHTML = `
|
||||
<div class="ja-empty-container">
|
||||
${ERRO_ICON}
|
||||
<p class="ja-empty-text">没有找到图片</p>
|
||||
</div>
|
||||
`;
|
||||
grid.replaceChildren(createStatusContainer('empty', '没有找到图片'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 正常渲染图片列表
|
||||
itemsToRender.forEach(item => {
|
||||
const itemElement = document.createElement('div');
|
||||
itemElement.className = 'ja-media-item';
|
||||
itemElement.innerHTML = `
|
||||
<div class="ja-item-thumbnail">
|
||||
<img src="${item.url}" alt="${item.name}" class="ja-thumbnail-image" loading="lazy">
|
||||
<div class="ja-item-overlay">
|
||||
<button class="ja-copy-button" data-url="${item.url}"> ${COPY_ICON} </button>
|
||||
<button class="ja-preview-button" data-url="${item.url}"> ${PREVIEW_ICON} </button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ja-item-info">
|
||||
<div class="ja-item-name">${item.name}</div>
|
||||
<div class="ja-item-details">
|
||||
<span class="ja-item-size">${formatFileSize(item.size)}</span>
|
||||
<span class="ja-item-dimensions">${item.width}*${item.height}</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
const itemElement = createMediaCard(item);
|
||||
grid.appendChild(itemElement);
|
||||
});
|
||||
}
|
||||
@@ -561,15 +798,7 @@ function getScriptBaseUrl() {
|
||||
if (invalidFiles.length > 0) {
|
||||
const uploadResults = document.getElementById('ja-upload-results');
|
||||
invalidFiles.forEach(({ file, reason }) => {
|
||||
const errorItem = document.createElement('div');
|
||||
errorItem.className = 'ja-upload-error';
|
||||
errorItem.innerHTML = `
|
||||
<div class="ja-error-header">
|
||||
<span class="ja-error-filename"></span>
|
||||
<span class="ja-error-status">错误</span>
|
||||
</div>
|
||||
<div class="ja-error-message">${reason}</div>
|
||||
`;
|
||||
const errorItem = createUploadErrorItem(file.name, reason);
|
||||
uploadResults.appendChild(errorItem);
|
||||
});
|
||||
}
|
||||
@@ -588,7 +817,7 @@ function uploadFiles(files) {
|
||||
const height = document.getElementById('ja-height').value;
|
||||
const uploadResults = document.getElementById('ja-upload-results');
|
||||
saveFormState(width, height);
|
||||
uploadResults.innerHTML = '';
|
||||
uploadResults.replaceChildren();
|
||||
|
||||
files.forEach(file => {
|
||||
const formData = new FormData();
|
||||
@@ -622,7 +851,7 @@ function uploadFiles(files) {
|
||||
progressItem.style.width = `${percentComplete}%`;
|
||||
if (ja.statusText) {
|
||||
ja.statusText.textContent = `上传中 ${Math.round(percentComplete)}%`;
|
||||
ja.upsvg.innerHTML = '<i class="uploading-icon"></i>';
|
||||
ja.upsvg.replaceChildren(createUploadingIcon());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -684,37 +913,14 @@ function resetUploadButton() {
|
||||
const ja = window.ja;
|
||||
if (ja.statusText) {
|
||||
ja.statusText.textContent = `开始上传`;
|
||||
ja.upsvg.innerHTML = `
|
||||
${UP_ICON}
|
||||
`;
|
||||
ja.upsvg.replaceChildren(createIconNode('upload'));
|
||||
}
|
||||
}
|
||||
|
||||
// 处理上传成功
|
||||
function handleUploadSuccess(response, progressItem) {
|
||||
updateButtonVisibility(true);
|
||||
progressItem.innerHTML = `
|
||||
|
||||
<div class="ja-media-item">
|
||||
<div class="ja-item-thumbnail relative">
|
||||
<img src="${response.data.url}" alt="${response.data.name}" class="ja-thumbnail-image">
|
||||
<div class="ja-item-overlay">
|
||||
<button class="ja-copy-button" data-url="${response.data.url}"> ${COPY_ICON} </button>
|
||||
<button class="ja-preview-button" data-url="${response.data.url}"> ${PREVIEW_ICON} </button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ja-item-info">
|
||||
<div class="ja-item-details">
|
||||
<span class="ja-item-name">${response.data.name}</span>
|
||||
<span class="ja-upload-success">已完成</span>
|
||||
</div>
|
||||
<div class="ja-item-details">
|
||||
<span class="ja-item-size">${formatFileSize(response.data.size || 0)}</span>
|
||||
<span class="ja-item-dimensions">${response.data.width}*${response.data.height}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
progressItem.replaceChildren(createUploadSuccessItem(response.data));
|
||||
|
||||
// 确保响应中包含正确的URL
|
||||
if (!response.data || !response.data.url) {
|
||||
@@ -748,28 +954,12 @@ function resetUploadButton() {
|
||||
// 处理上传失败
|
||||
function handleUploadError(file, message, progressItem) {
|
||||
progressItem.className = 'ja-upload-item ja-upload-error';
|
||||
progressItem.innerHTML = `
|
||||
<div class="ja-upload-header">
|
||||
<span class="ja-upload-filename"></span>
|
||||
<span class="ja-upload-failure"></span>
|
||||
</div>
|
||||
<div class="ja-upload-error-message">${message}</div>
|
||||
`;
|
||||
progressItem.replaceChildren(createUploadFailureContent(message));
|
||||
}
|
||||
|
||||
// 预览图片
|
||||
function previewFile(url) {
|
||||
const modal = document.createElement('div');
|
||||
modal.className = 'ja-image-preview-modal';
|
||||
modal.innerHTML = `
|
||||
<div class="ja-modal-content">
|
||||
<img src="${url}" alt="预览图片" class="ja-modal-image">
|
||||
<button class="ja-close-button">${CLOSE_ICON}</button>
|
||||
</div>
|
||||
`;
|
||||
const modalContent = modal.querySelector('.ja-modal-content');
|
||||
const image = modal.querySelector('.ja-modal-image');
|
||||
const closeButton = modal.querySelector('.ja-close-button');
|
||||
const { modal, content: modalContent, image, button: closeButton } = createPreviewModal(url);
|
||||
|
||||
// 关闭模态窗口
|
||||
closeButton.addEventListener('click', () => {
|
||||
|
||||
Reference in New Issue
Block a user