邮件API

This commit is contained in:
2025-11-16 19:58:51 +08:00
parent 9d442b017a
commit 3b3d6dea66
91 changed files with 6017 additions and 413 deletions

View File

@@ -0,0 +1,712 @@
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>系统首页</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#E3F2FD',
secondary: '#BBDEFB',
accent: '#64B5F6',
dark: '#1976D2',
},
},
}
}
</script>
<style type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
.scrollbar-thin {
scrollbar-width: thin;
}
.scrollbar-thin::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
background-color: rgba(100, 181, 246, 0.5);
border-radius: 3px;
}
.status-online {
@apply bg-green-500;
}
.status-offline {
@apply bg-red-500;
}
.status-warning {
@apply bg-yellow-500;
}
/* 自定义提示弹窗样式 */
.custom-toast {
position: fixed;
top: 20px;
right: 20px;
padding: 12px 20px;
border-radius: 6px;
color: white;
font-size: 14px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
z-index: 9999;
opacity: 0;
transform: translateY(-20px);
transition: all 0.3s ease;
}
.toast-success {
background-color: #10B981; /* 成功绿色 */
}
.toast-error {
background-color: #EF4444; /* 错误红色 */
}
.toast-show {
opacity: 1;
transform: translateY(0);
}
}
</style>
</head>
<body class="bg-primary h-screen overflow-hidden flex flex-col">
<!-- 顶部区域 -->
<header class="bg-primary border-b border-accent/30 py-3 px-6 flex items-center justify-between shadow-sm">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 bg-dark rounded-lg flex items-center justify-center text-white">
<i class="fa fa-cogs text-xl"></i>
</div>
<h1 class="text-xl font-bold text-dark"><a th:href="@{/biz/index}">智慧门户</a></h1>
</div>
<!-- 中间模块导航 -->
<nav class="flex items-center space-x-8">
<a href="javascript:loadContent('dataMap')"
class="text-dark hover:text-accent transition-colors duration-200 flex items-center cursor-pointer">
<i class="fa fa-map-o mr-2"></i>
<span>数据地图</span>
</a>
<a href="javascript:loadContent('dataDoc')"
class="text-dark hover:text-accent transition-colors duration-200 flex items-center cursor-pointer">
<i class="fa fa-book mr-2"></i>
<span>文档中心</span>
</a>
</nav>
<!-- 右侧账号信息 -->
<div class="relative">
<button id="userMenuBtn" class="flex items-center space-x-2 focus:outline-none">
<img th:src="@{/images/user.jpg}" alt="用户头像"
class="w-8 h-8 rounded-full border-2 border-accent">
<span class="text-dark font-medium" th:text="${uname}"></span>
<i class="fa fa-chevron-down text-xs text-dark"></i>
</button>
<div id="userMenu" class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 hidden z-10">
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-primary transition-colors duration-200">
<i class="fa fa-user mr-2"></i>个人信息
</a>
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-primary transition-colors duration-200">
<i class="fa fa-cog mr-2"></i>系统设置
</a>
<div class="border-t border-gray-200 my-1"></div>
<a href="javascript:void(0);" id="logoutLink"
class="block px-4 py-2 text-sm text-red-600 hover:bg-red-50 transition-colors duration-200">
<i class="fa fa-sign-out mr-2"></i>退出登录
</a>
</div>
</div>
</header>
<!-- 内容区域 -->
<main class="flex-1 bg-primary overflow-hidden flex flex-col">
<!-- 状态栏 -->
<div class="bg-secondary/50 px-6 py-2 flex justify-between items-center border-b border-accent/20">
<div class="flex space-x-6">
<div class="flex items-center text-dark">
<i class="fa fa-clock-o mr-2"></i>
<span id="systemUptime">系统运行时长: <span th:text="${times}"></span> </span>
</div>
<div class="flex items-center text-dark">
<i class="fa fa-users mr-2"></i>
<span>在线人数: <span id="onlineUsers">24</span></span>
</div>
</div>
<div class="text-dark font-medium" id="currentTime"></div>
</div>
<!-- 主题区域 -->
<div class="flex-1 px-6 py-4 overflow-hidden mb-15">
<!-- 内容切换核心容器 -->
<div id="contentContainer" class="h-full bg-white rounded-lg shadow-sm overflow-hidden">
<!-- 默认首页内容 -->
<div id="defaultContent" class="h-full p-4 overflow-hidden">
<div class="flex h-full space-x-4">
<!-- 第一部分 (30%) -->
<div class="w-[30%] bg-secondary/50 rounded-lg shadow-sm flex flex-col overflow-hidden">
<!-- 日历 (50%) -->
<div class="h-[50%] p-4 border-b border-accent/20 overflow-hidden">
<h2 class="text-dark font-semibold mb-3 flex items-center">
<i class="fa fa-calendar mr-2"></i>日历
</h2>
<div id="calendar" class="bg-white/70 rounded-lg p-3 h-[calc(100%-30px)] flex flex-col">
<div class="flex justify-between items-center mb-2">
<button class="text-dark hover:text-accent"><i class="fa fa-chevron-left"></i>
</button>
<h3 class="font-medium text-dark">2025年11月</h3>
<button class="text-dark hover:text-accent"><i class="fa fa-chevron-right"></i>
</button>
</div>
<div class="grid grid-cols-7 gap-1 text-center text-xs text-gray-600 mb-1">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="grid grid-cols-7 gap-1 text-center flex-1"></div>
</div>
</div>
<!-- 主机列表 (50%) -->
<div class="h-[50%] p-4 overflow-hidden">
<h2 class="text-dark font-semibold mb-3 flex items-center">
<i class="fa fa-server mr-2"></i>主机列表
</h2>
<div class="bg-white/70 rounded-lg p-3 h-[calc(100%-30px)] overflow-y-auto scrollbar-thin">
<div class="space-y-3">
<div class="flex items-center justify-between p-2 border-b border-gray-100"
th:each="host : ${hosts}">
<div>
<div class="font-medium text-dark">
<a class="text-primary" style="cursor: pointer;"
data-bs-toggle="modal"
data-bs-target="#serverDetailModal"
th:data-hostid="${host.getHostId()}">
<span th:text="${host.getHostname()}">主机名</span>
</a>
</div>
<div class="text-xs text-gray-500"><p>主机地址:<span
th:text="${host.getIpAddress()}"></span></p>
</div>
<div class="text-xs text-gray-500"><p>在线时间:<span
th:text="${host.getLastOnlineTime()}"></span></p>
</div>
</div>
<div class="flex items-center">
<span class="w-2 h-2 rounded-full status-online mr-2"></span>
<span class="text-sm text-green-600"
th:text="${host.getUstatus() == '1' ? '运行中' : '已离线' }"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 第二部分 (45%) -->
<div class="w-[45%] bg-secondary/50 rounded-lg shadow-sm flex flex-col overflow-hidden">
<div class="h-full p-4 overflow-hidden">
<div class="flex border-b border-accent/20 pb-2 mb-3">
<button id="todoBtn" class="px-4 py-1 bg-accent text-white rounded-md mr-2 font-medium">
<i class="fa fa-tasks mr-1"></i>待办信息
</button>
<button id="notificationBtn"
class="px-4 py-1 bg-white/50 text-dark hover:bg-accent/30 rounded-md font-medium transition-colors duration-200">
<i class="fa fa-bell mr-1"></i>通知信息
</button>
</div>
<!-- 待办信息内容 -->
<div id="todoContent"
class="bg-white/70 rounded-lg p-3 h-[calc(100%-50px)] overflow-y-auto scrollbar-thin">
<div class="space-y-4">
<div class="p-3 border-l-4 border-accent bg-primary/50 rounded-r"
th:each="todo : ${todoViews}" th:data-task-id="${todo.getSubTaskId()}">
<div class="flex justify-between items-start">
<h3 class="font-medium text-dark" th:text="${todo.getTaskName()}"></h3>
<span class="text-xs bg-red-100 text-red-600 px-2 py-0.5 rounded"
th:text="${todo.getPriority()}"></span>
</div>
<p class="text-sm text-gray-600 mt-1" th:text="${todo.getTaskDesc()}"></p>
<div class="flex justify-between items-center mt-2">
<span class="text-xs text-gray-500">截止日期:<span
th:text="${todo.getDeadline()}"></span></span>
<button class="text-xs text-accent hover:underline">处理</button>
</div>
</div>
</div>
</div>
<!-- 通知信息内容 (默认隐藏) -->
<div id="notificationContent"
class="bg-white/70 rounded-lg p-3 h-[calc(100%-50px)] overflow-y-auto scrollbar-thin hidden">
<div class="space-y-4">
<div class="p-3 border-b border-gray-100">
<div class="flex justify-between items-start">
<h3 class="font-medium text-dark">数据库备份成功</h3>
<span class="text-xs text-gray-500">今天 08:30</span>
</div>
<p class="text-sm text-gray-600 mt-1">
主数据库自动备份已完成备份文件大小2.4GB,存储路径:/backup/db/20251115/</p>
</div>
<div class="p-3 border-b border-gray-100">
<div class="flex justify-between items-start">
<h3 class="font-medium text-dark">用户登录提醒</h3>
<span class="text-xs text-gray-500">昨天 16:45</span>
</div>
<p class="text-sm text-gray-600 mt-1">您的账号在新设备Windows 10, Chrome
120登录IP地址113.25.XX.XX如非本人操作请及时修改密码。</p>
</div>
</div>
</div>
</div>
</div>
<!-- 第三部分 (25%) -->
<div class="w-[25%] bg-secondary/50 rounded-lg shadow-sm flex flex-col overflow-hidden">
<!-- 快捷登录 -->
<div class="h-full p-4 overflow-hidden">
<h2 class="text-dark font-semibold mb-3 flex items-center">
<i class="fa fa-rocket mr-2"></i>快捷登录
</h2>
<!-- 搜索框 -->
<div class="relative mb-3">
<input type="text" id="quickSearch" placeholder="搜索快捷登录..."
class="w-full pl-9 pr-3 py-2 bg-white/70 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-accent">
<i class="fa fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"></i>
</div>
<!-- 快捷登录图标列表 -->
<div id="quickLinks"
class="bg-white/70 rounded-lg p-4 h-[calc(100%-80px)] overflow-y-auto scrollbar-thin">
<div class="grid grid-cols-4 gap-4">
<!-- 快捷登录项 -->
<a th:each="storage : ${storages}" th:href="${storage.getHomepageUrl()}"
target="_blank"
class="flex flex-col items-center p-3 hover:bg-primary rounded-lg transition-colors duration-200 group">
<div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center text-blue-600 group-hover:bg-blue-600 group-hover:text-white transition-colors duration-200">
<i th:class="${storage.getIconClass()}"></i>
</div>
<span class="text-xs mt-2 text-center text-dark"
th:text="${storage.getSystemName()}"></span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 内容加载iframe默认隐藏 -->
<iframe id="contentFrame" class="w-full h-full border-0 hidden" src=""></iframe>
</div>
</div>
</main>
<!-- 服务器详情模态框 -->
<div class="modal fade" id="serverDetailModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered" style="width: 80%; max-width: 1400px;">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">服务器详情</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-0" style="max-height: 60vh; height: 60vh; overflow: hidden;">
<div style="height: 100%; overflow-y: auto; scrollbar-width: thin; position: relative;">
<!-- 加载中动画 -->
<div id="loadingMask"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.8); display: none; justify-content: center; align-items: center; z-index: 100;">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">加载中...</span>
</div>
</div>
<iframe id="detailFrame" width="100%" height="100%" frameborder="0"
style="min-height: 600px;"></iframe>
</div>
</div>
</div>
</div>
</div>
<!-- 退出确认弹窗 -->
<div id="logoutModal"
class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 opacity-0 pointer-events-none transition-opacity duration-300">
<div class="bg-white rounded-lg w-full max-w-md p-6 transform scale-95 transition-transform duration-300">
<h3 class="text-lg font-medium text-gray-900 mb-4">温馨提示</h3>
<p class="text-gray-600 mb-6">您确定要退出当前系统吗?</p>
<div class="flex justify-end gap-3">
<button id="cancelLogout"
class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">
取消
</button>
<button id="confirmLogout"
class="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 transition-colors">
确认
</button>
</div>
</div>
</div>
<!-- 处理意见弹窗 -->
<div id="handleTaskModal"
class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 opacity-0 pointer-events-none transition-opacity duration-300">
<div class="bg-white rounded-lg w-full max-w-md p-6 transform scale-95 transition-transform duration-300">
<h3 class="text-lg font-medium text-gray-900 mb-4">待办信息处理意见:</h3>
<div class="mb-4">
<textarea id="taskOpinion" rows="3"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-accent"
placeholder="请输入处理意见..."></textarea>
</div>
<div class="flex justify-end gap-3">
<button id="cancelHandleTask"
class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">
取消
</button>
<button id="confirmHandleTask"
class="px-4 py-2 bg-accent text-white rounded-md hover:bg-dark transition-colors">
确认
</button>
</div>
</div>
</div>
<!-- 引入Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// 提示弹窗工具函数 - 新增
function showToast(message, type = 'success') {
// 创建弹窗元素
const toast = document.createElement('div');
toast.className = `custom-toast toast-${type}`;
toast.textContent = message;
document.body.appendChild(toast);
// 显示弹窗
setTimeout(() => toast.classList.add('toast-show'), 10);
// 3秒后隐藏并移除
setTimeout(() => {
toast.classList.remove('toast-show');
setTimeout(() => document.body.removeChild(toast), 300);
}, 3000);
}
// 动态日历渲染函数
function renderCalendar(year, month) {
const calendarContainer = document.querySelector('#calendar .grid:last-child');
const monthTitle = document.querySelector('#calendar h3');
calendarContainer.innerHTML = '';
monthTitle.textContent = `${year}${month + 1}`;
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
const lastDayOfPrevMonth = new Date(year, month, 0).getDate();
// 渲染上月剩余天数
for (let i = firstDay - 1; i >= 0; i--) {
const prevDay = document.createElement('div');
prevDay.className = 'py-2 text-gray-400 text-sm';
prevDay.textContent = lastDayOfPrevMonth - i;
calendarContainer.appendChild(prevDay);
}
// 渲染当月天数
const today = new Date();
const isCurrentMonth = today.getFullYear() === year && today.getMonth() === month;
const currentDate = today.getDate();
for (let i = 1; i <= daysInMonth; i++) {
const day = document.createElement('div');
day.className = 'py-2 text-sm';
if (isCurrentMonth && i === currentDate) {
day.classList.add('bg-accent', 'text-white', 'rounded-full', 'font-medium');
}
day.textContent = i;
calendarContainer.appendChild(day);
}
// 渲染下月起始天数
const totalDays = firstDay + daysInMonth;
const nextMonthDays = totalDays % 7 !== 0 ? 7 - (totalDays % 7) : 0;
for (let i = 1; i <= nextMonthDays; i++) {
const nextDay = document.createElement('div');
nextDay.className = 'py-2 text-gray-400 text-sm';
nextDay.textContent = i;
calendarContainer.appendChild(nextDay);
}
}
// 初始化日历
let currentDate = new Date();
let currentYear = currentDate.getFullYear();
let currentMonth = currentDate.getMonth();
renderCalendar(currentYear, currentMonth);
// 绑定月份切换事件
document.querySelectorAll('#calendar button')[0].addEventListener('click', () => {
currentMonth--;
if (currentMonth < 0) {
currentMonth = 11;
currentYear--;
}
renderCalendar(currentYear, currentMonth);
});
document.querySelectorAll('#calendar button')[1].addEventListener('click', () => {
currentMonth++;
if (currentMonth > 11) {
currentMonth = 0;
currentYear++;
}
renderCalendar(currentYear, currentMonth);
});
// 内容加载函数
function loadContent(pageUrl) {
const defaultContent = document.getElementById('defaultContent');
const contentFrame = document.getElementById('contentFrame');
defaultContent.classList.add('hidden');
contentFrame.classList.remove('hidden');
contentFrame.src = pageUrl;
}
// 返回首页函数
function backToHome() {
const defaultContent = document.getElementById('defaultContent');
const contentFrame = document.getElementById('contentFrame');
defaultContent.classList.remove('hidden');
contentFrame.classList.add('hidden');
contentFrame.src = '';
}
// 用户菜单切换
const userMenuBtn = document.getElementById('userMenuBtn');
const userMenu = document.getElementById('userMenu');
userMenuBtn.addEventListener('click', () => userMenu.classList.toggle('hidden'));
document.addEventListener('click', (e) => {
if (!userMenuBtn.contains(e.target) && !userMenu.contains(e.target)) {
userMenu.classList.add('hidden');
}
});
// 待办和通知切换
const todoBtn = document.getElementById('todoBtn');
const notificationBtn = document.getElementById('notificationBtn');
const todoContent = document.getElementById('todoContent');
const notificationContent = document.getElementById('notificationContent');
todoBtn.addEventListener('click', () => {
todoBtn.classList.remove('bg-white/50', 'text-dark');
todoBtn.classList.add('bg-accent', 'text-white');
notificationBtn.classList.remove('bg-accent', 'text-white');
notificationBtn.classList.add('bg-white/50', 'text-dark', 'hover:bg-accent/30');
todoContent.classList.remove('hidden');
notificationContent.classList.add('hidden');
});
notificationBtn.addEventListener('click', () => {
notificationBtn.classList.remove('bg-white/50', 'text-dark', 'hover:bg-accent/30');
notificationBtn.classList.add('bg-accent', 'text-white');
todoBtn.classList.remove('bg-accent', 'text-white');
todoBtn.classList.add('bg-white/50', 'text-dark');
notificationContent.classList.remove('hidden');
todoContent.classList.add('hidden');
});
// 快捷登录搜索功能
const quickSearch = document.getElementById('quickSearch');
const quickLinks = document.querySelectorAll('#quickLinks a');
quickSearch.addEventListener('input', (e) => {
const searchTerm = e.target.value.toLowerCase();
quickLinks.forEach(link => {
const text = link.querySelector('span').textContent.toLowerCase();
link.style.display = text.includes(searchTerm) ? 'flex' : 'none';
});
});
// 更新当前时间
function updateCurrentTime() {
const now = new Date();
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
};
document.getElementById('currentTime').textContent = now.toLocaleString('zh-CN', options);
}
updateCurrentTime();
setInterval(updateCurrentTime, 1000);
// 服务器详情模态框
document.addEventListener('DOMContentLoaded', function () {
const modal = new bootstrap.Modal(document.getElementById('serverDetailModal'));
const detailFrame = document.getElementById('detailFrame');
document.getElementById('serverDetailModal').addEventListener('show.bs.modal', function (e) {
const hostId = e.relatedTarget.getAttribute('data-hostid');
detailFrame.src = `getServerInfo?hostId=${hostId}`;
});
document.getElementById('serverDetailModal').addEventListener('hide.bs.modal', function () {
detailFrame.src = '';
});
});
// 服务器详情模态框加载动画
const detailModal = document.getElementById('serverDetailModal');
const loadingMask = document.getElementById('loadingMask');
const detailFrame = document.getElementById('detailFrame');
detailModal.addEventListener('show.bs.modal', function (e) {
loadingMask.style.display = 'flex';
const targetUrl = e.relatedTarget.dataset.url;
detailFrame.src = targetUrl;
});
detailFrame.addEventListener('load', function () {
loadingMask.style.display = 'none';
});
detailModal.addEventListener('hide.bs.modal', function () {
detailFrame.src = '';
loadingMask.style.display = 'none';
});
// 退出登录功能
const logoutLink = document.getElementById('logoutLink');
const logoutModal = document.getElementById('logoutModal');
const cancelLogout = document.getElementById('cancelLogout');
const confirmLogout = document.getElementById('confirmLogout');
function showModal() {
logoutModal.classList.remove('opacity-0', 'pointer-events-none');
logoutModal.querySelector('div').classList.remove('scale-95');
logoutModal.querySelector('div').classList.add('scale-100');
document.body.style.overflow = 'hidden';
}
function hideModal() {
logoutModal.classList.add('opacity-0', 'pointer-events-none');
logoutModal.querySelector('div').classList.remove('scale-100');
logoutModal.querySelector('div').classList.add('scale-95');
document.body.style.overflow = '';
}
logoutLink.addEventListener('click', showModal);
cancelLogout.addEventListener('click', hideModal);
logoutModal.addEventListener('click', (e) => {
if (e.target === logoutModal) hideModal();
});
// 处理待办任务弹窗功能
const handleButtons = document.querySelectorAll('#todoContent button.text-accent');
const handleTaskModal = document.getElementById('handleTaskModal');
const cancelHandleTask = document.getElementById('cancelHandleTask');
const confirmHandleTask = document.getElementById('confirmHandleTask');
const taskOpinion = document.getElementById('taskOpinion');
let currentTaskId = null;
handleButtons.forEach(button => {
button.addEventListener('click', (e) => {
e.preventDefault();
const taskItem = button.closest('.border-l-4');
currentTaskId = taskItem.dataset.taskId || 'default-task-id';
taskOpinion.value = '';
showHandleModal();
});
});
function showHandleModal() {
handleTaskModal.classList.remove('opacity-0', 'pointer-events-none');
handleTaskModal.querySelector('div').classList.remove('scale-95');
handleTaskModal.querySelector('div').classList.add('scale-100');
document.body.style.overflow = 'hidden';
}
function hideHandleModal() {
handleTaskModal.classList.add('opacity-0', 'pointer-events-none');
handleTaskModal.querySelector('div').classList.remove('scale-100');
handleTaskModal.querySelector('div').classList.add('scale-95');
document.body.style.overflow = '';
currentTaskId = null;
}
cancelHandleTask.addEventListener('click', hideHandleModal);
handleTaskModal.addEventListener('click', (e) => {
if (e.target === handleTaskModal) hideHandleModal();
});
// 确认处理替换alert为弹窗
confirmHandleTask.addEventListener('click', () => {
const opinion = taskOpinion.value.trim();
if (!opinion) {
showToast('请输入处理意见', 'error');
return;
}
fetch('finishTodoSub', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
taskId: currentTaskId,
opinion: opinion
})
})
.then(response => {
if (response.ok) {
showToast('处理成功');
hideHandleModal();
location.reload();
} else {
showToast('处理失败,请重试', 'error');
}
})
.catch(error => {
console.error('处理请求失败:', error);
showToast('网络错误,处理失败', 'error');
});
});
// 确认退出替换alert为弹窗
confirmLogout.addEventListener('click', () => {
fetch('logout', {method: 'POST'})
.then(response => {
if (response.ok) {
sessionStorage.removeItem('token');
window.location.href = '/cApi/login';
} else {
showToast('退出失败,请重试', 'error'); // 替换alert
}
})
.catch(error => {
console.error('退出请求失败:', error);
showToast('网络错误,退出失败', 'error'); // 替换alert
});
});
</script>
</body>
</html>