Files
c-api/src/main/resources/templates/index.html
2025-11-16 19:58:51 +08:00

712 lines
33 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>