|
|
@@ -0,0 +1,219 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="zh-CN">
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
+ <title>自动评价SSE通知示例</title>
|
|
|
+ <style>
|
|
|
+ body {
|
|
|
+ font-family: 'Arial', sans-serif;
|
|
|
+ max-width: 800px;
|
|
|
+ margin: 0 auto;
|
|
|
+ padding: 20px;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ }
|
|
|
+ .container {
|
|
|
+ background-color: white;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+ h1 {
|
|
|
+ color: #333;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ .status {
|
|
|
+ margin: 20px 0;
|
|
|
+ padding: 10px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .connected {
|
|
|
+ background-color: #e8f5e8;
|
|
|
+ color: #2e7d2e;
|
|
|
+ border: 1px solid #a5d6a7;
|
|
|
+ }
|
|
|
+ .disconnected {
|
|
|
+ background-color: #ffebee;
|
|
|
+ color: #c62828;
|
|
|
+ border: 1px solid #ef9a9a;
|
|
|
+ }
|
|
|
+ .updates {
|
|
|
+ margin-top: 20px;
|
|
|
+ }
|
|
|
+ .update-item {
|
|
|
+ margin-bottom: 15px;
|
|
|
+ padding: 15px;
|
|
|
+ border-radius: 4px;
|
|
|
+ border-left: 4px solid #2196f3;
|
|
|
+ background-color: #e3f2fd;
|
|
|
+ }
|
|
|
+ .update-item .timestamp {
|
|
|
+ font-size: 0.9em;
|
|
|
+ color: #555;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+ .update-item .content {
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ .score-update {
|
|
|
+ border-left-color: #4caf50;
|
|
|
+ background-color: #e8f5e8;
|
|
|
+ }
|
|
|
+ .notification {
|
|
|
+ border-left-color: #ff9800;
|
|
|
+ background-color: #fff8e1;
|
|
|
+ }
|
|
|
+ button {
|
|
|
+ background-color: #2196f3;
|
|
|
+ color: white;
|
|
|
+ border: none;
|
|
|
+ padding: 10px 15px;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+ button:hover {
|
|
|
+ background-color: #0d8aee;
|
|
|
+ }
|
|
|
+ button:disabled {
|
|
|
+ background-color: #cccccc;
|
|
|
+ cursor: not-allowed;
|
|
|
+ }
|
|
|
+ .controls {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+ <div class="container">
|
|
|
+ <h1>自动评价SSE通知</h1>
|
|
|
+
|
|
|
+ <div class="controls">
|
|
|
+ <button id="connectBtn">连接SSE</button>
|
|
|
+ <button id="disconnectBtn" disabled>断开连接</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div id="status" class="status disconnected">未连接</div>
|
|
|
+
|
|
|
+ <div class="updates">
|
|
|
+ <h2>评价更新记录</h2>
|
|
|
+ <div id="updatesList">
|
|
|
+ <p style="color: #666;">暂无更新记录</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <script>
|
|
|
+ let eventSource = null;
|
|
|
+ let clientID = 'web_client_' + Math.floor(Math.random() * 10000);
|
|
|
+
|
|
|
+ const connectBtn = document.getElementById('connectBtn');
|
|
|
+ const disconnectBtn = document.getElementById('disconnectBtn');
|
|
|
+ const statusDiv = document.getElementById('status');
|
|
|
+ const updatesList = document.getElementById('updatesList');
|
|
|
+
|
|
|
+ // 连接SSE
|
|
|
+ function connectSSE() {
|
|
|
+ eventSource = new EventSource(`/sse/register/${clientID}`);
|
|
|
+
|
|
|
+ eventSource.onopen = function(event) {
|
|
|
+ updateStatus('已连接', 'connected');
|
|
|
+ connectBtn.disabled = true;
|
|
|
+ disconnectBtn.disabled = false;
|
|
|
+ console.log('SSE连接已建立');
|
|
|
+ };
|
|
|
+
|
|
|
+ eventSource.onerror = function(event) {
|
|
|
+ updateStatus('连接错误', 'disconnected');
|
|
|
+ connectBtn.disabled = false;
|
|
|
+ disconnectBtn.disabled = true;
|
|
|
+ console.error('SSE连接错误:', event);
|
|
|
+ };
|
|
|
+
|
|
|
+ eventSource.addEventListener('connected', function(event) {
|
|
|
+ const data = JSON.parse(event.data);
|
|
|
+ addUpdateItem('系统通知', `SSE连接已建立 (ID: ${data.clientID})`, 'notification');
|
|
|
+ });
|
|
|
+
|
|
|
+ eventSource.addEventListener('ping', function(event) {
|
|
|
+ const data = JSON.parse(event.data);
|
|
|
+ console.log('心跳:', data);
|
|
|
+ });
|
|
|
+
|
|
|
+ eventSource.addEventListener('evaluation_update', function(event) {
|
|
|
+ const data = JSON.parse(event.data);
|
|
|
+ handleEvaluationUpdate(data);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 断开SSE连接
|
|
|
+ function disconnectSSE() {
|
|
|
+ if (eventSource) {
|
|
|
+ eventSource.close();
|
|
|
+ eventSource = null;
|
|
|
+ updateStatus('已断开', 'disconnected');
|
|
|
+ connectBtn.disabled = false;
|
|
|
+ disconnectBtn.disabled = true;
|
|
|
+ console.log('SSE连接已断开');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新连接状态
|
|
|
+ function updateStatus(text, className) {
|
|
|
+ statusDiv.textContent = text;
|
|
|
+ statusDiv.className = 'status ' + className;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理评价更新
|
|
|
+ function handleEvaluationUpdate(data) {
|
|
|
+ if (data.type === 'evaluation_update') {
|
|
|
+ const message = `
|
|
|
+ <strong>评价项目:</strong> ${data.evaName}<br>
|
|
|
+ <strong>序号:</strong> ${data.seqNo}<br>
|
|
|
+ <strong>操作得分:</strong> ${data.operScore}<br>
|
|
|
+ <strong>课程总分:</strong> ${data.courseScore}<br>
|
|
|
+ <strong>更新时间:</strong> ${data.timestamp}
|
|
|
+ `;
|
|
|
+
|
|
|
+ addUpdateItem('评价得分更新', message, 'score-update');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加更新记录
|
|
|
+ function addUpdateItem(title, content, className) {
|
|
|
+ const item = document.createElement('div');
|
|
|
+ item.className = `update-item ${className}`;
|
|
|
+
|
|
|
+ const timestamp = new Date().toLocaleString();
|
|
|
+
|
|
|
+ item.innerHTML = `
|
|
|
+ <div class="timestamp">${timestamp}</div>
|
|
|
+ <div class="content">
|
|
|
+ <strong>${title}</strong><br>
|
|
|
+ ${content}
|
|
|
+ </div>
|
|
|
+ `;
|
|
|
+
|
|
|
+ // 如果是第一条记录,清空"暂无更新记录"的提示
|
|
|
+ if (updatesList.children.length === 1 && updatesList.children[0].textContent.includes('暂无更新记录')) {
|
|
|
+ updatesList.innerHTML = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将新记录插入到顶部
|
|
|
+ updatesList.insertBefore(item, updatesList.firstChild);
|
|
|
+
|
|
|
+ // 限制显示的记录数量
|
|
|
+ while (updatesList.children.length > 10) {
|
|
|
+ updatesList.removeChild(updatesList.lastChild);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 绑定按钮事件
|
|
|
+ connectBtn.addEventListener('click', connectSSE);
|
|
|
+ disconnectBtn.addEventListener('click', disconnectSSE);
|
|
|
+ </script>
|
|
|
+</body>
|
|
|
+</html>
|