feat: 实现前端组件库和API服务基础架构

refactor: 移除废弃的AGI策略演进服务

fix: 修正磁盘I/O指标字段命名

chore: 更新项目依赖版本

test: 添加前后端集成测试用例

docs: 更新AI模块接口文档

style: 统一审计日志字段命名规范

perf: 优化Redis订阅连接错误处理

build: 配置多项目工作区结构

ci: 添加Vite开发服务器CORS支持
This commit is contained in:
2026-03-18 15:22:55 +08:00
parent b31591e04c
commit c932a67be2
96 changed files with 37748 additions and 16326 deletions

View File

@@ -0,0 +1,96 @@
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom/client';
import './popup.css';
const Popup: React.FC = () => {
const [isConnected, setIsConnected] = useState(false);
const [status, setStatus] = useState('初始化中...');
useEffect(() => {
// 检查与后台脚本的连接
chrome.runtime.sendMessage({ action: 'ping' }, (response) => {
if (response && response.pong) {
setIsConnected(true);
setStatus('已连接到后台服务');
} else {
setIsConnected(false);
setStatus('无法连接到后台服务');
}
});
}, []);
const handleStartCollection = () => {
chrome.runtime.sendMessage({ action: 'startCollection' }, (response) => {
if (response && response.success) {
setStatus('开始采集数据');
} else {
setStatus('采集失败');
}
});
};
const handleSyncLogistics = () => {
chrome.runtime.sendMessage({ action: 'syncLogistics' }, (response) => {
if (response && response.success) {
setStatus('开始同步物流');
} else {
setStatus('同步失败');
}
});
};
return (
<div className="popup-container">
<div className="header">
<h2>Crawlful</h2>
<p></p>
</div>
<div className="status-section">
<div className={`status-indicator ${isConnected ? 'connected' : 'disconnected'}`}>
{isConnected ? '已连接' : '未连接'}
</div>
<p className="status-message">{status}</p>
</div>
<div className="action-buttons">
<button
className="action-button primary"
onClick={handleStartCollection}
>
</button>
<button
className="action-button secondary"
onClick={handleSyncLogistics}
>
</button>
</div>
<div className="info-section">
<h3></h3>
<ul>
<li></li>
<li>AI </li>
<li></li>
<li></li>
</ul>
</div>
<div className="footer">
<p>版本: 1.0.0</p>
</div>
</div>
);
};
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<Popup />
</React.StrictMode>
);

View File

@@ -0,0 +1,137 @@
.popup-container {
width: 350px;
padding: 20px;
font-family: Arial, sans-serif;
background-color: #f5f5f5;
}
.header {
text-align: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
}
.header h2 {
margin: 0 0 5px 0;
color: #1890ff;
font-size: 18px;
}
.header p {
margin: 0;
color: #666;
font-size: 14px;
}
.status-section {
margin-bottom: 20px;
padding: 15px;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.status-indicator {
display: inline-block;
padding: 4px 12px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
margin-bottom: 10px;
}
.status-indicator.connected {
background-color: #f6ffed;
color: #52c41a;
border: 1px solid #b7eb8f;
}
.status-indicator.disconnected {
background-color: #fff2f0;
color: #ff4d4f;
border: 1px solid #ffccc7;
}
.status-message {
margin: 0;
color: #666;
font-size: 14px;
}
.action-buttons {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 20px;
}
.action-button {
padding: 10px 15px;
border: none;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
}
.action-button:hover {
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}
.action-button.primary {
background-color: #1890ff;
color: white;
}
.action-button.primary:hover {
background-color: #40a9ff;
}
.action-button.secondary {
background-color: #13c2c2;
color: white;
}
.action-button.secondary:hover {
background-color: #36cfc9;
}
.info-section {
background-color: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
.info-section h3 {
margin: 0 0 10px 0;
color: #333;
font-size: 14px;
}
.info-section ul {
margin: 0;
padding-left: 20px;
}
.info-section li {
color: #666;
font-size: 13px;
margin-bottom: 5px;
}
.footer {
text-align: center;
padding-top: 15px;
border-top: 1px solid #e0e0e0;
}
.footer p {
margin: 0;
color: #999;
font-size: 12px;
}