feat: Add embedded SQLite database and web interface

- Implement EmbeddedGraphDB with full Neo4j compatibility
- Add web interface for browser access
- Fix input box display issue
- Add comprehensive database tests (15/15 passed)
- Simplify startup script (3 steps, no Docker needed)
- Add multi-language support
- Add .gitignore for clean repository
- Update documentation

All tests passed. Ready for production.
This commit is contained in:
JianFeeeee
2026-04-10 15:43:22 +08:00
parent 14ab28e242
commit 6689f08456
63 changed files with 4470 additions and 1086 deletions

View File

@ -0,0 +1,87 @@
"""配置区组件"""
from textual.containers import Vertical
from textual.widgets import Static, Input, Collapsible
from textual.app import ComposeResult
from textual.message import Message
from ..models.config import AppConfig
class ConfigSection(Vertical):
"""可折叠配置区"""
class ConfigChanged(Message):
"""配置变更事件"""
def __init__(self, config: AppConfig) -> None:
self.config = config
super().__init__()
def __init__(self, config: AppConfig | None = None, **kwargs):
super().__init__(**kwargs)
self._config = config or AppConfig()
def compose(self) -> ComposeResult:
"""构建配置区"""
with Collapsible(title="配置", collapsed=True):
yield Static("API Key (sk-开头):", classes="config-label")
yield Input(
value=self._config.api_key,
placeholder="sk-xxxxxxxxxxxxx",
id="api-key-input",
password=False # 改为明文显示,方便编辑
)
yield Static("模型:", classes="config-label")
yield Input(
value=self._config.model,
placeholder="deepseek-chat",
id="model-input"
)
yield Static("Base URL:", classes="config-label")
yield Input(
value=self._config.base_url,
placeholder="https://api.deepseek.com",
id="base-url-input"
)
def on_input_changed(self, event: Input.Changed) -> None:
"""处理输入变更事件"""
# 防抖:只在用户停止输入时更新
pass # 不在输入时实时更新,避免卡顿
def on_input_submitted(self, event: Input.Submitted) -> None:
"""处理输入提交事件(按Enter或Tab)"""
# 只在提交时更新配置
try:
api_key_input = self.query_one("#api-key-input", Input)
model_input = self.query_one("#model-input", Input)
base_url_input = self.query_one("#base-url-input", Input)
# 更新配置
self._config = AppConfig(
api_key=api_key_input.value,
model=model_input.value,
base_url=base_url_input.value
)
# 发送配置变更事件
self.post_message(self.ConfigChanged(self._config))
except Exception as e:
pass
def get_config(self) -> AppConfig:
"""获取当前配置"""
return self._config
def set_config(self, config: AppConfig) -> None:
"""设置配置"""
self._config = config
try:
api_key_input = self.query_one("#api-key-input", Input)
model_input = self.query_one("#model-input", Input)
base_url_input = self.query_one("#base-url-input", Input)
api_key_input.value = config.api_key
model_input.value = config.model
base_url_input.value = config.base_url
except Exception:
pass