feat: 添加 toast 通知替代 alert 提示

This commit is contained in:
Cp0204 2025-12-28 01:30:10 +08:00
parent 66f39ea9e2
commit 000618ac5e
2 changed files with 90 additions and 7 deletions

View File

@ -45,7 +45,7 @@ body {
margin-bottom: 10px; margin-bottom: 10px;
} }
table.jsoneditor-tree > tbody > tr.jsoneditor-expandable:first-child { table.jsoneditor-tree>tbody>tr.jsoneditor-expandable:first-child {
display: none; display: none;
} }
@ -196,3 +196,48 @@ table.jsoneditor-tree > tbody > tr.jsoneditor-expandable:first-child {
max-width: 100%; max-width: 100%;
height: auto; height: auto;
} }
/* Toast */
.toast-container {
position: fixed;
top: 80px;
right: 20px;
z-index: 9999;
width: 300px;
}
.toast {
background-color: rgba(255, 255, 255, 0.95);
border-radius: 8px;
border-width: 0 0 0 5px !important;
margin-bottom: 10px;
animation: slideIn 0.3s ease forwards;
}
.toast.success {
border-left-color: #28a745 !important;
}
.toast.error {
border-left-color: #dc3545 !important;
}
.toast.warning {
border-left-color: #ffc107 !important;
}
.toast.info {
border-left-color: #17a2b8 !important;
}
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}

View File

@ -596,6 +596,19 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Toast 提示 -->
<div class="toast-container">
<div v-for="toast in toasts" :key="toast.id" class="toast show shadow-sm" :class="toast.type" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-body d-flex align-items-center">
<i class="bi mr-2" :class="getToastIcon(toast.type)"></i>
<span>{{ toast.message }}</span>
<button type="button" class="ml-auto close" @click="removeToast(toast.id)" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
</div>
</div> </div>
@ -628,6 +641,7 @@
} }
}, },
}, },
toasts: [],
newTask: { newTask: {
taskname: "", taskname: "",
shareurl: "", shareurl: "",
@ -803,8 +817,10 @@
.then(response => { .then(response => {
if (response.data.success) { if (response.data.success) {
this.configModified = false; this.configModified = false;
this.showToast(response.data.message, 'success');
} else {
this.showToast(response.data.message, 'error');
} }
alert(response.data.message);
console.log('Config saved result:', response.data); console.log('Config saved result:', response.data);
}) })
.catch(error => { .catch(error => {
@ -1067,7 +1083,7 @@
updateMagicRegexKey(oldKey, newKey) { updateMagicRegexKey(oldKey, newKey) {
if (oldKey !== newKey) { if (oldKey !== newKey) {
if (this.formData.magic_regex[newKey]) { if (this.formData.magic_regex[newKey]) {
alert(`魔法名 [${newKey}] 已存在,请使用其他名称`); this.showToast(`魔法名 [${newKey}] 已存在,请使用其他名称`, 'warning');
return; return;
} }
this.$set(this.formData.magic_regex, newKey, this.formData.magic_regex[oldKey]); this.$set(this.formData.magic_regex, newKey, this.formData.magic_regex[oldKey]);
@ -1087,7 +1103,7 @@
if (response.data.code == 0) { if (response.data.code == 0) {
this.fileSelect.fileList = this.fileSelect.fileList.filter(item => item.fid != fid); this.fileSelect.fileList = this.fileSelect.fileList.filter(item => item.fid != fid);
} else { } else {
alert('删除失败:' + response.data.message); this.showToast('删除失败:' + response.data.message, 'error');
} }
}).catch(error => { }).catch(error => {
console.error('Error /delete_file:', error); console.error('Error /delete_file:', error);
@ -1170,9 +1186,9 @@
currentIndex = this.smart_param.taskSuggestions.data.indexOf(this.fileSelect.share); currentIndex = this.smart_param.taskSuggestions.data.indexOf(this.fileSelect.share);
nextIndex = currentIndex + index; nextIndex = currentIndex + index;
if (nextIndex < 0) { if (nextIndex < 0) {
alert("没有上一个啦"); this.showToast("没有上一个啦", "info");
} else if (nextIndex >= this.smart_param.taskSuggestions.data.length) { } else if (nextIndex >= this.smart_param.taskSuggestions.data.length) {
alert("没有下一个啦"); this.showToast("没有下一个啦", "info");
} else { } else {
this.fileSelect.error = ""; this.fileSelect.error = "";
this.fileSelect.stoken = ""; this.fileSelect.stoken = "";
@ -1282,8 +1298,9 @@
copyTaskToClipboard(index) { copyTaskToClipboard(index) {
const task = { ...this.formData.tasklist[index] }; const task = { ...this.formData.tasklist[index] };
delete task.addition; delete task.addition;
const _this = this;
this.copyText(JSON.stringify(task), function () { this.copyText(JSON.stringify(task), function () {
console.log("任务参数已复制到剪贴板"); _this.showToast("任务参数已复制到剪贴板", "success");
}); });
}, },
addTaskForClipboard() { addTaskForClipboard() {
@ -1294,15 +1311,36 @@
const task = JSON.parse(text); const task = JSON.parse(text);
task.addition = config_data.task_plugins_config_default;; task.addition = config_data.task_plugins_config_default;;
this.formData.tasklist.push(task); this.formData.tasklist.push(task);
this.showToast("剪贴板参数已成功导入任务", "success");
} catch (error) { } catch (error) {
this.showToast("剪贴板内容不是有效的任务参数", "error");
console.error("解析剪贴板内容失败:", error); console.error("解析剪贴板内容失败:", error);
return; return;
} }
} }
}).catch(err => { }).catch(err => {
this.showToast("读取剪贴板内容失败", "error");
console.error("读取剪贴板内容失败:", err); console.error("读取剪贴板内容失败:", err);
}); });
}, },
showToast(message, type = 'info', duration = 3000) {
const id = Date.now();
this.toasts.push({ id, message, type });
setTimeout(() => {
this.removeToast(id);
}, duration);
},
removeToast(id) {
this.toasts = this.toasts.filter(t => t.id !== id);
},
getToastIcon(type) {
switch (type) {
case 'success': return 'bi-check-circle-fill text-success';
case 'error': return 'bi-exclamation-circle-fill text-danger';
case 'warning': return 'bi-exclamation-triangle-fill text-warning';
default: return 'bi-info-circle-fill text-info';
}
},
} }
}); });
</script> </script>