# 密码预设 实现计划 > ⚠️ **已归档** — 2026-05-22 > 本文档引用的文件结构已过时:`server/database.py` 已拆分为 `server/domain/models/`;PHP 前端 (`servers.php`/`settings.php`) 已迁移到 Tailwind CSS v4 + Alpine.js (`web/app/servers.html`/`settings.html`);认证已从 X-API-Key 改为 JWT。功能已实现,保留本文档供历史参考。 > **面向 AI 代理的工作者:** 必需子技能:使用 superpowers:executing-plans 逐任务实现此计划。 **目标:** 提供加密存储的 SSH 密码预设列表,新建服务器时下拉选择自动填充 **架构:** PasswordPreset 模型复用 Fernet 加密;4 个 REST 端点挂在 servers 路由下;servers.php 加下拉联动;settings.php 加管理面板 **技术栈:** Python FastAPI + SQLAlchemy + PHP 7.4 + Fernet --- ### 任务 1:数据模型 + API 端点 **文件:** `server/database.py`、`server/api/servers.py` - [ ] **步骤 1:database.py 添加 PasswordPreset 模型** 在 `Setting` 类之后、`init_db()` 之前插入: ```python class PasswordPreset(Base): """SSH password preset — encrypted storage""" __tablename__ = "password_presets" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(100), nullable=False, comment="预设名称") encrypted_pw = Column(String(500), nullable=False, comment="加密后的密码") created_at = Column(DateTime, default=datetime.datetime.utcnow) ``` - [ ] **步骤 2:servers.py 添加 4 个预设端点** 在 `servers.py` 导入 `PasswordPreset`: ```python from server.database import get_db, Server, SyncLog, PasswordPreset, encrypt_value, decrypt_value ``` 在文件末尾(`PushRequest` 类之前)添加: ```python # --- Password Presets --- class PresetCreate(BaseModel): name: str password: str class PresetResponse(BaseModel): id: int name: str @router.get("/password-presets", response_model=List[PresetResponse]) def list_presets(db: Session = Depends(get_db)): return db.query(PasswordPreset).order_by(PasswordPreset.id).all() @router.post("/password-presets", response_model=PresetResponse) def create_preset(data: PresetCreate, db: Session = Depends(get_db)): preset = PasswordPreset(name=data.name, encrypted_pw=encrypt_value(data.password)) db.add(preset) db.commit() db.refresh(preset) return preset @router.delete("/password-presets/{preset_id}") def delete_preset(preset_id: int, db: Session = Depends(get_db)): preset = db.query(PasswordPreset).filter(PasswordPreset.id == preset_id).first() if not preset: raise HTTPException(status_code=404, detail="Preset not found") db.delete(preset) db.commit() return {"message": "deleted"} @router.post("/password-presets/{preset_id}/reveal") def reveal_preset(preset_id: int, db: Session = Depends(get_db)): preset = db.query(PasswordPreset).filter(PasswordPreset.id == preset_id).first() if not preset: raise HTTPException(status_code=404, detail="Preset not found") return {"password": decrypt_value(preset.encrypted_pw)} ``` - [ ] **步骤 3:验证编译 + Commit** ```bash python -m py_compile server/database.py server/api/servers.py && echo "OK" ``` ```bash git add server/database.py server/api/servers.py git commit -m "feat(presets): PasswordPreset 模型 + 4 个 CRUD/reveal 端点" ``` --- ### 任务 2:settings.php 密码预设管理面板 **文件:** `web/settings.php` - [ ] **步骤 1:在 settings.php 末尾(`` 前)添加预设管理 HTML + JS** 找到 settings.php 中「修改密码」section 之后,添加新 section: ```php

SSH 密码预设

保存常用 SSH 密码,新建服务器时快速选择

加载中...
``` - [ ] **步骤 2:Commit** ```bash git add web/settings.php git commit -m "feat(presets): settings.php 密码预设管理面板" ``` --- ### 任务 3:servers.php 预设下拉联动 **文件:** `web/servers.php` - [ ] **步骤 1:在密码字段上方添加预设下拉** 在 `passwordField` div 内部,密码 input 之前添加: ```php
``` - [ ] **步骤 2:添加 JS 加载预设列表并联动填充** 在现有 `