Files
erp-ass/docs/superpowers/plans/2026-03-21-erp-ai-assistant-phase1.md
dazhuang acd73431ae feat: implement ERP AI Assistant Phase 1
Backend (FastAPI + SQLAlchemy + Claude API + RAG):
- Config management with Pydantic v2
- Database engine with connection pooling and SQL injection prevention
- AI engine with Claude API integration (support custom base URL)
- RAG engine with ChromaDB and sentence-transformers
- Requirement analysis service
- Config generation service
- Executor engine with SQL validation
- REST API endpoints: /analyze, /generate, /execute

Frontend (Vue 3 + Element Plus + Pinia):
- Complete 3-step workflow: analyze → generate → execute
- Step indicator with progress visualization
- Analysis result display with field table
- SQL preview with monospace font
- Execute confirmation dialog with safety warning
- Execution result display
- State management with Pinia
- API service integration

Security:
- SQL injection prevention with parameterized queries
- Dangerous SQL operation blocking
- Database password URL encoding
- Transaction auto-rollback
- Pydantic config validation

Features:
- Natural language requirement analysis
- Automated SQL configuration generation
- Safe execution with human review
- LAN access support
- Custom Claude API endpoint support

Documentation:
- README with quick start guide
- Quick start guide
- LAN access configuration
- Dependency fixes guide
- Claude API configuration
- Git operation guide
- Implementation report

Dependencies fixed:
- numpy<2.0.0 for chromadb compatibility
- sentence-transformers==2.7.0 for huggingface_hub compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 14:23:20 +00:00

59 KiB
Raw Permalink Blame History

ERP智能助手系统实施计划 (Phase 1)

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 构建一个可以通过自然语言或结构化表单配置ERP功能的Web应用实现需求解析、配置生成、审核确认、执行监控的完整流程。

Architecture: 单体内核架构Python FastAPI后端 + Vue 3前端。后端集成Claude API和RAG知识库通过SQL Server直连操作ERP配置表。采用TDD开发事务保护机制确保安全。

Tech Stack:

  • 后端: FastAPI, SQLAlchemy, pyodbc, Claude API, ChromaDB, sentence-transformers
  • 前端: Vue 3, Vite, Element Plus, Monaco Editor, Axios, Pinia
  • 数据库: SQL Server, ChromaDB

文件结构规划

后端文件职责划分

配置层

  • backend/app/config.py - 应用配置管理数据库、Claude API、知识库路径等

数据访问层

  • backend/app/core/db_engine.py - 数据库连接池、事务管理、SQL执行
  • backend/app/models/request.py - API请求模型Pydantic
  • backend/app/models/response.py - API响应模型
  • backend/app/models/database.py - 数据库表模型SQLAlchemy ORM如果需要

核心引擎层

  • backend/app/core/ai_engine.py - Claude API客户端、Prompt模板、JSON解析
  • backend/app/core/rag_engine.py - 知识库检索、文档向量化、元数据查询
  • backend/app/core/executor.py - 配置执行器、事务编排、回滚机制
  • backend/app/core/validator.py - SQL验证、风险检查、注入防护

业务逻辑层

  • backend/app/services/requirement_service.py - 需求解析服务调用AI引擎
  • backend/app/services/config_service.py - 配置生成服务
  • backend/app/services/execution_service.py - 执行服务

API层

  • backend/app/api/analyze.py - 需求解析API
  • backend/app/api/generate.py - 配置生成API
  • backend/app/api/execute.py - 执行配置API
  • backend/app/api/metadata.py - 数据库元数据API
  • backend/app/api/history.py - 历史记录API

入口文件

  • backend/app/main.py - FastAPI应用入口、中间件配置、路由注册

工具脚本

  • backend/scripts/init_knowledge.py - 初始化知识库
  • backend/scripts/import_docs.py - 导入文档到知识库

测试文件

  • backend/tests/test_db_engine.py - 数据库引擎测试
  • backend/tests/test_ai_engine.py - AI引擎测试
  • backend/tests/test_api.py - API集成测试

前端文件职责划分

页面组件

  • frontend/src/views/CreateFunction.vue - 新建功能主页面(包含步骤器)
  • frontend/src/views/History.vue - 历史记录页面
  • frontend/src/views/Settings.vue - 系统设置页面

可复用组件

  • frontend/src/components/RequirementInput.vue - 需求输入组件(自然语言+结构化表单)
  • frontend/src/components/ConfigPreview.vue - 配置预览组件SQL预览+风险提示)
  • frontend/src/components/ExecutionMonitor.vue - 执行监控组件(实时日志+进度条)

API调用

  • frontend/src/api/index.js - Axios实例、API方法封装

状态管理

  • frontend/src/store/index.js - Pinia store会话状态、执行状态

路由配置

  • frontend/src/router/index.js - Vue Router配置

任务分解

任务1: 项目初始化和配置管理

Files:

  • Create: backend/requirements.txt

  • Create: backend/.env.example

  • Create: backend/app/config.py

  • Create: backend/app/__init__.py

  • Step 1: 创建requirements.txt

fastapi==0.104.1
uvicorn[standard]==0.24.0
sqlalchemy==2.0.23
pyodbc==5.0.1
anthropic==0.18.1
chromadb==0.4.18
sentence-transformers==2.2.2
pydantic==2.5.0
pydantic-settings==2.1.0
python-dotenv==1.0.0
loguru==0.7.2
tenacity==8.2.3
python-jose[cryptography]==3.3.0
pytest==7.4.3
pytest-asyncio==0.21.1
httpx==0.25.2
  • Step 2: 创建.env.example
APP_NAME=ERP AI Assistant
APP_ENV=development
DEBUG=True
SECRET_KEY=change-this-in-production

# Database
DB_DRIVER=ODBC Driver 17 for SQL Server
DB_SERVER=192.168.120.19
DB_PORT=1433
DB_NAME=DMPF_HY
DB_USER=sa
DB_PASSWORD=your-password

# Claude API
ANTHROPIC_API_KEY=your-claude-api-key
CLAUDE_MODEL=claude-sonnet-4-6
CLAUDE_MAX_TOKENS=8192
CLAUDE_TEMPERATURE=0.7

# Knowledge Base
KNOWLEDGE_BASE_PATH=./knowledge_base
CHROMA_DB_PATH=./knowledge_base/chroma_db
EMBEDDING_MODEL=all-MiniLM-L6-v2
CHUNK_SIZE=500
CHUNK_OVERLAP=50
  • Step 3: 创建配置管理类

创建 backend/app/config.py:

from pydantic_settings import BaseSettings
from functools import lru_cache


class Settings(BaseSettings):
    # Application
    APP_NAME: str = "ERP AI Assistant"
    APP_ENV: str = "development"
    DEBUG: bool = True
    SECRET_KEY: str

    # Database
    DB_DRIVER: str
    DB_SERVER: str
    DB_PORT: int = 1433
    DB_NAME: str
    DB_USER: str
    DB_PASSWORD: str

    # Claude API
    ANTHROPIC_API_KEY: str
    CLAUDE_MODEL: str = "claude-sonnet-4-6"
    CLAUDE_MAX_TOKENS: int = 8192
    CLAUDE_TEMPERATURE: float = 0.7

    # Knowledge Base
    KNOWLEDGE_BASE_PATH: str = "./knowledge_base"
    CHROMA_DB_PATH: str = "./knowledge_base/chroma_db"
    EMBEDDING_MODEL: str = "all-MiniLM-L6-v2"
    CHUNK_SIZE: int = 500
    CHUNK_OVERLAP: int = 50

    @property
    def DATABASE_URL(self) -> str:
        """构建数据库连接URL"""
        return (
            f"mssql+pyodbc://{self.DB_USER}:{self.DB_PASSWORD}"
            f"@{self.DB_SERVER}:{self.DB_PORT}/{self.DB_NAME}"
            f"?driver={self.DB_DRIVER}"
        )

    class Config:
        env_file = ".env"
        case_sensitive = True


@lru_cache()
def get_settings() -> Settings:
    """获取配置单例"""
    return Settings()
  • Step 4: 创建__init__.py

创建 backend/app/__init__.py:

"""ERP AI Assistant Backend"""
__version__ = "1.0.0"
  • Step 5: 安装依赖并验证配置
cd backend
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -r requirements.txt

验证:

python -c "from app.config import get_settings; s = get_settings(); print(s.APP_NAME)"

Expected: 输出配置的APP_NAME或报错缺少必需的环境变量

  • Step 6: Commit
git add backend/
git commit -m "chore: initialize project with config management"

任务2: Pytest配置和测试基础设施

Files:

  • Create: backend/pytest.ini

  • Create: backend/tests/conftest.py

  • Update: backend/requirements.txt

  • Step 1: 更新requirements.txt添加测试依赖

backend/requirements.txt 末尾添加:

pytest-cov==4.1.0
pytest-mock==3.12.0
  • Step 2: 创建pytest.ini

创建 backend/pytest.ini:

[pytest]
asyncio_mode = auto
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -v --cov=app --cov-report=term-missing
  • Step 3: 创建conftest.py

创建 backend/tests/conftest.py:

import pytest
from app.config import get_settings


@pytest.fixture
def test_settings():
    """测试配置"""
    return get_settings()


@pytest.fixture
def mock_db_engine(mocker):
    """Mock数据库引擎"""
    from app.core.db_engine import DatabaseEngine
    return mocker.MagicMock(spec=DatabaseEngine)


@pytest.fixture
def mock_ai_engine(mocker):
    """Mock AI引擎"""
    from app.core.ai_engine import ClaudeEngine
    mock_engine = mocker.MagicMock(spec=ClaudeEngine)
    mock_engine.parse_json_response = lambda x: {"功能名称": "测试功能"}
    return mock_engine
  • Step 4: 验证pytest配置
cd backend
pytest --version

Expected: 显示pytest版本信息

  • Step 5: Commit
git add backend/pytest.ini backend/tests/conftest.py backend/requirements.txt
git commit -m "chore: add pytest configuration and test fixtures"

任务3: 数据库引擎实现

Files:

  • Create: backend/app/core/__init__.py

  • Create: backend/app/core/db_engine.py

  • Create: backend/tests/__init__.py

  • Create: backend/tests/test_db_engine.py

  • Step 1: 创建测试文件

创建 backend/tests/test_db_engine.py:

import pytest
from app.core.db_engine import DatabaseEngine


def test_database_engine_init():
    """测试数据库引擎初始化"""
    engine = DatabaseEngine()
    assert engine.engine is not None
    assert engine.Session is not None


def test_execute_sql_select():
    """测试执行SELECT查询"""
    engine = DatabaseEngine()
    result = engine.execute_sql("SELECT 1 AS test")
    assert result is not None
    assert len(result) > 0


def test_table_exists():
    """测试表存在性检查"""
    engine = DatabaseEngine()
    # 假设SYS_FORM表存在
    exists = engine.table_exists("SYS_FORM")
    assert exists is True
  • Step 2: 运行测试验证失败
cd backend
pytest tests/test_db_engine.py -v

Expected: FAIL - 模块不存在

  • Step 3: 实现数据库引擎

创建 backend/app/core/db_engine.py:

from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker
from contextlib import contextmanager
from loguru import logger
from app.config import get_settings


class DatabaseEngine:
    """数据库操作引擎"""

    def __init__(self):
        settings = get_settings()
        self.engine = create_engine(
            settings.DATABASE_URL,
            pool_size=20,
            max_overflow=10,
            pool_pre_ping=True,
            echo=settings.DEBUG
        )
        self.Session = sessionmaker(bind=self.engine)

    @contextmanager
    def get_session(self):
        """获取数据库会话(上下文管理器)"""
        session = self.Session()
        try:
            yield session
            session.commit()
        except Exception as e:
            session.rollback()
            logger.error(f"数据库操作失败: {e}")
            raise
        finally:
            session.close()

    def execute_sql(self, sql: str, params: dict = None):
        """执行单条SQL"""
        with self.get_session() as session:
            result = session.execute(text(sql), params or {})
            return result.fetchall()

    def execute_transaction(self, sql_list: list, params_list: list = None):
        """执行事务多条SQL"""
        params_list = params_list or [None] * len(sql_list)
        with self.get_session() as session:
            for sql, params in zip(sql_list, params_list):
                session.execute(text(sql), params or {})
        return True

    def get_table_structure(self, table_name: str):
        """获取表结构"""
        sql = f"""
        SELECT
            COLUMN_NAME,
            DATA_TYPE,
            CHARACTER_MAXIMUM_LENGTH,
            IS_NULLABLE,
            COLUMN_DEFAULT
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = '{table_name}'
        ORDER BY ORDINAL_POSITION
        """
        return self.execute_sql(sql)

    def table_exists(self, table_name: str) -> bool:
        """检查表是否存在"""
        sql = f"""
        SELECT COUNT(*)
        FROM INFORMATION_SCHEMA.TABLES
        WHERE TABLE_NAME = '{table_name}'
        """
        result = self.execute_sql(sql)
        return result[0][0] > 0
  • Step 4: 运行测试验证通过
cd backend
pytest tests/test_db_engine.py -v

Expected: PASS - 所有测试通过

  • Step 5: Commit
git add backend/app/core/ backend/tests/
git commit -m "feat: implement database engine with connection pooling"

任务3: AI引擎基础实现

Files:

  • Create: backend/app/core/ai_engine.py

  • Create: backend/tests/test_ai_engine.py

  • Step 1: 创建AI引擎测试

创建 backend/tests/test_ai_engine.py:

import pytest
from app.core.ai_engine import ClaudeEngine


def test_claude_engine_init():
    """测试Claude引擎初始化"""
    engine = ClaudeEngine()
    assert engine.client is not None
    assert engine.model == "claude-sonnet-4-6"


def test_parse_json_response():
    """测试JSON解析"""
    engine = ClaudeEngine()

    # 测试纯JSON
    json_str = '{"name": "test", "value": 123}'
    result = engine.parse_json_response(json_str)
    assert result["name"] == "test"
    assert result["value"] == 123

    # 测试markdown代码块
    md_str = '```json\n{"name": "test"}\n```'
    result = engine.parse_json_response(md_str)
    assert result["name"] == "test"
  • Step 2: 运行测试验证失败
pytest tests/test_ai_engine.py -v

Expected: FAIL - 模块不存在

  • Step 3: 实现AI引擎基础

创建 backend/app/core/ai_engine.py:

import anthropic
import json
import re
from loguru import logger
from app.config import get_settings


class ClaudeEngine:
    """Claude API调用引擎"""

    def __init__(self):
        settings = get_settings()
        self.client = anthropic.Anthropic(api_key=settings.ANTHROPIC_API_KEY)
        self.model = settings.CLAUDE_MODEL
        self.max_tokens = settings.CLAUDE_MAX_TOKENS
        self.temperature = settings.CLAUDE_TEMPERATURE

    def parse_json_response(self, content: str) -> dict:
        """解析Claude返回的JSON"""
        # 尝试直接解析
        try:
            return json.loads(content)
        except json.JSONDecodeError:
            pass

        # 尝试提取```json```块
        json_match = re.search(r'```json\s*(.*?)\s*```', content, re.DOTALL)
        if json_match:
            try:
                return json.loads(json_match.group(1))
            except json.JSONDecodeError:
                pass

        # 尝试提取{}块
        json_match = re.search(r'\{.*\}', content, re.DOTALL)
        if json_match:
            try:
                return json.loads(json_match.group(0))
            except json.JSONDecodeError:
                pass

        raise ValueError(f"无法解析Claude返回的JSON: {content[:100]}")

    async def call_claude(self, messages: list, temperature: float = None) -> str:
        """调用Claude API"""
        try:
            response = self.client.messages.create(
                model=self.model,
                max_tokens=self.max_tokens,
                temperature=temperature or self.temperature,
                messages=messages
            )
            return response.content[0].text
        except Exception as e:
            logger.error(f"Claude API调用失败: {e}")
            raise
  • Step 4: 运行测试验证通过
pytest tests/test_ai_engine.py -v

Expected: PASS

  • Step 5: Commit
git add backend/app/core/ai_engine.py backend/tests/test_ai_engine.py
git commit -m "feat: implement Claude API engine with JSON parsing"

任务4: Prompt模板设计

Files:

  • Create: backend/app/core/prompts.py

  • Create: backend/tests/test_prompts.py

  • Step 1: 创建Prompt测试

创建 backend/tests/test_prompts.py:

from app.core.prompts import SYSTEM_PROMPT, ANALYZE_PROMPT_TEMPLATE


def test_system_prompt_exists():
    """测试系统Prompt存在"""
    assert SYSTEM_PROMPT is not None
    assert len(SYSTEM_PROMPT) > 100
    assert "ERP平台配置专家" in SYSTEM_PROMPT


def test_analyze_prompt_template():
    """测试需求解析模板"""
    rendered = ANALYZE_PROMPT_TEMPLATE.format(
        user_input="创建销售订单",
        knowledge_context="测试知识",
        existing_tables="测试表"
    )
    assert "创建销售订单" in rendered
    assert "测试知识" in rendered
  • Step 2: 运行测试验证失败
pytest tests/test_prompts.py -v

Expected: FAIL

  • Step 3: 实现Prompt模板

创建 backend/app/core/prompts.py:

"""Prompt模板定义"""


SYSTEM_PROMPT = """你是一个ERP平台配置专家助手专门帮助开发人员配置一零软件结构化开发平台。

你的职责:
1. 理解用户的功能需求
2. 设计合理的数据库表结构
3. 生成符合平台规范的配置方案
4. 提供最佳实践建议

平台核心知识:
- 窗体类型0-普通、3-单树、4-树表、5-单据列表、11-一对多等
- 标准字段IKEY主键、COMPANYID、DOCCODE、DOCDATE、DOCSTATUS等
- 配置流程:建表 → 配置功能号 → 配置页面 → 配置菜单 → 配置IKEY
- 命名规范SA_销售、PU_采购、ST_库存、FI_财务

输出要求:
- 必须提供完整的SQL脚本
- 必须遵循平台配置规范
- 必须包含风险评估
- 使用JSON格式输出
"""


ANALYZE_PROMPT_TEMPLATE = """用户需求:{user_input}

参考知识:
{knowledge_context}

现有相关表:
{existing_tables}

请分析用户需求输出结构化需求文档JSON格式
{{
  "功能名称": "xxx",
  "功能号建议": "xx-xxx",
  "窗体类型": "x",
  "主表名建议": "XX_XXX",
  "从表名建议": "XX_XXX_DETAIL",
  "主表字段": [
    {{
      "字段名": "xxx",
      "字段类型": "xxx",
      "必填": true,
      "默认值": "xxx",
      "说明": "xxx"
    }}
  ],
  "从表字段": [],
  "业务需求": [],
  "关联表": [],
  "风险提示": []
}}
"""


GENERATE_PROMPT_TEMPLATE = """结构化需求:
{requirements}

平台配置规范:
{platform_rules}

相似案例:
{similar_cases}

请生成完整的配置方案,包括:
1. 建表SQL主表、从表、日志表
2. 功能号配置SQL
3. 页面配置SQL
4. 菜单配置SQL
5. IKEY配置SQL

输出JSON格式
{{
  "配置方案": {{
    "建表SQL": [
      {{
        "表名": "SA_ORDER",
        "类型": "主表",
        "SQL": "CREATE TABLE SA_ORDER (...)",
        "说明": "销售订单主表"
      }}
    ],
    "配置SQL": [
      {{
        "类型": "功能号配置",
        "SQL": "INSERT INTO SYS_FORM (...)",
        "说明": "配置功能号11-001"
      }}
    ]
  }},
  "风险评估": [],
  "建议后续操作": []
}}
"""
  • Step 4: 运行测试验证通过
pytest tests/test_prompts.py -v

Expected: PASS

  • Step 5: Commit
git add backend/app/core/prompts.py backend/tests/test_prompts.py
git commit -m "feat: add prompt templates for requirement analysis and config generation"

任务5: 知识库引擎基础实现

Files:

  • Create: backend/app/core/rag_engine.py

  • Create: backend/knowledge_base/documents/.gitkeep

  • Create: backend/scripts/init_knowledge.py

  • Step 1: 创建知识库目录结构

mkdir -p backend/knowledge_base/documents
touch backend/knowledge_base/documents/.gitkeep
  • Step 2: 实现RAG引擎基础

创建 backend/app/core/rag_engine.py:

import chromadb
from chromadb.config import Settings as ChromaSettings
from sentence_transformers import SentenceTransformer
from loguru import logger
from app.config import get_settings


class RAGEngine:
    """RAG检索引擎"""

    def __init__(self):
        settings = get_settings()

        # 初始化向量数据库
        self.chroma_client = chromadb.PersistentClient(
            path=settings.CHROMA_DB_PATH,
            settings=ChromaSettings(anonymized_telemetry=False)
        )

        # 初始化嵌入模型
        logger.info(f"加载嵌入模型: {settings.EMBEDDING_MODEL}")
        self.embedding_model = SentenceTransformer(settings.EMBEDDING_MODEL)

        # 获取或创建集合
        self.documents_collection = self.chroma_client.get_or_create_collection(
            name="documents"
        )

        self.chunk_size = settings.CHUNK_SIZE
        self.chunk_overlap = settings.CHUNK_OVERLAP

    def add_document(self, doc_id: str, content: str, metadata: dict = None):
        """添加文档到知识库"""
        # 分块
        chunks = self._split_text(content)

        # 生成嵌入
        embeddings = self.embedding_model.encode(chunks)

        # 添加到向量库
        ids = [f"{doc_id}_chunk_{i}" for i in range(len(chunks))]
        metadatas = [metadata or {} for _ in chunks]

        self.documents_collection.add(
            ids=ids,
            documents=chunks,
            embeddings=embeddings.tolist(),
            metadatas=metadatas
        )

        logger.info(f"添加文档 {doc_id},共 {len(chunks)} 个块")
        return len(chunks)

    def search(self, query: str, top_k: int = 3) -> list:
        """检索相关文档"""
        # 生成查询向量
        query_embedding = self.embedding_model.encode([query])

        # 检索
        results = self.documents_collection.query(
            query_embeddings=query_embedding.tolist(),
            n_results=top_k
        )

        return [
            {
                "content": doc,
                "metadata": meta,
                "distance": dist
            }
            for doc, meta, dist in zip(
                results["documents"][0],
                results["metadatas"][0],
                results["distances"][0]
            )
        ]

    def _split_text(self, text: str) -> list:
        """文本分块"""
        chunks = []
        start = 0

        while start < len(text):
            end = start + self.chunk_size
            chunk = text[start:end]
            chunks.append(chunk)
            start += self.chunk_size - self.chunk_overlap

        return chunks
  • Step 3: 创建知识库初始化脚本

创建 backend/scripts/init_knowledge.py:

#!/usr/bin/env python3
"""初始化知识库"""

import sys
import os

# 添加项目根目录到路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.core.rag_engine import RAGEngine
from loguru import logger


def init_knowledge_base():
    """初始化知识库"""
    logger.info("开始初始化知识库...")

    rag = RAGEngine()

    # 示例:添加平台基础知识
    sample_doc = """
    一零软件结构化开发平台配置指南

    窗体类型:
    - 0: 普通类型
    - 3: 单树类型
    - 4: 树表类型
    - 5: 单据列表类型
    - 11: 一对多的窗体类型

    标准字段:
    每张表都必须包含以下字段:
    - IKEY: 主键,自增
    - COMPANYID: 公司代码
    - CREATE_USER: 创建人
    - CREATE_DATE: 创建时间
    - UPDATE_USER: 更新人
    - UPDATE_DATE: 更新时间

    单据类型额外字段:
    - DOCCODE: 单据号
    - DOCDATE: 单据日期
    - DOCSTATUS: 单据状态

    配置流程:
    1. 在99-001创建功能号
    2. 在99-003配置页面
    3. 在99-002配置菜单
    4. 在99-006配置IKEY
    """

    rag.add_document(
        doc_id="platform_basics",
        content=sample_doc,
        metadata={"source": "platform_intro", "type": "guide"}
    )

    logger.success("知识库初始化完成!")


if __name__ == "__main__":
    init_knowledge_base()
  • Step 4: 测试知识库初始化
cd backend
python scripts/init_knowledge.py

Expected: 成功初始化并输出日志

  • Step 5: Commit
git add backend/app/core/rag_engine.py backend/scripts/ backend/knowledge_base/
git commit -m "feat: implement RAG engine with ChromaDB and sentence-transformers"

任务6: 需求解析服务实现

Files:

  • Create: backend/app/services/__init__.py

  • Create: backend/app/services/requirement_service.py

  • Create: backend/tests/test_requirement_service.py

  • Step 1: 创建需求解析服务测试

创建 backend/tests/test_requirement_service.py:

import pytest
from app.services.requirement_service import RequirementService


@pytest.mark.asyncio
async def test_analyze_requirement():
    """测试需求解析"""
    service = RequirementService()

    result = await service.analyze(
        user_input="创建一个销售订单管理页面",
        session_id="test-session"
    )

    assert result is not None
    assert "功能名称" in result
    assert result["功能名称"] != ""
  • Step 2: 运行测试验证失败
pytest tests/test_requirement_service.py -v

Expected: FAIL

  • Step 3: 实现需求解析服务

创建 backend/app/services/requirement_service.py:

from app.core.ai_engine import ClaudeEngine
from app.core.rag_engine import RAGEngine
from app.core.prompts import SYSTEM_PROMPT, ANALYZE_PROMPT_TEMPLATE
from app.core.db_engine import DatabaseEngine
from loguru import logger
import uuid


class RequirementService:
    """需求解析服务"""

    def __init__(self):
        self.ai_engine = ClaudeEngine()
        self.rag_engine = RAGEngine()
        self.db_engine = DatabaseEngine()

    async def analyze(self, user_input: str, session_id: str = None) -> dict:
        """分析用户需求

        Args:
            user_input: 用户输入的自然语言需求
            session_id: 会话ID用于上下文管理

        Returns:
            结构化需求文档
        """
        session_id = session_id or str(uuid.uuid4())
        logger.info(f"开始分析需求: {user_input[:50]}...")

        # 1. 检索相关知识
        knowledge_results = self.rag_engine.search(user_input, top_k=3)
        knowledge_context = "\n\n".join([
            f"【{r['metadata'].get('source', '文档')}\n{r['content']}"
            for r in knowledge_results
        ])

        # 2. 查询现有相关表
        existing_tables = self._get_existing_tables(user_input)

        # 3. 构建Prompt
        prompt = ANALYZE_PROMPT_TEMPLATE.format(
            user_input=user_input,
            knowledge_context=knowledge_context,
            existing_tables=existing_tables
        )

        messages = [
            {"role": "user", "content": SYSTEM_PROMPT},
            {"role": "assistant", "content": "我已了解平台配置规范,请告诉我您的需求。"},
            {"role": "user", "content": prompt}
        ]

        # 4. 调用Claude API
        response = await self.ai_engine.call_claude(messages, temperature=0.7)

        # 5. 解析结果
        result = self.ai_engine.parse_json_response(response)

        logger.success(f"需求分析完成: {result.get('功能名称', 'Unknown')}")
        return result

    def _get_existing_tables(self, user_input: str) -> str:
        """查询现有相关表"""
        # 简化版本:查询所有表
        try:
            sql = """
            SELECT TOP 10 TABLE_NAME
            FROM INFORMATION_SCHEMA.TABLES
            WHERE TABLE_TYPE = 'BASE TABLE'
            ORDER BY TABLE_NAME
            """
            tables = self.db_engine.execute_sql(sql)
            return "\n".join([f"- {t[0]}" for t in tables])
        except Exception as e:
            logger.warning(f"查询现有表失败: {e}")
            return "无法获取现有表信息"
  • Step 4: 运行测试验证通过
pytest tests/test_requirement_service.py -v

Expected: PASS需要配置Claude API Key

  • Step 5: Commit
git add backend/app/services/ backend/tests/test_requirement_service.py
git commit -m "feat: implement requirement analysis service with Claude API"

任务7: 执行引擎实现

Files:

  • Create: backend/app/core/executor.py

  • Create: backend/tests/test_executor.py

  • Step 1: 创建执行引擎测试

创建 backend/tests/test_executor.py:

import pytest
from app.core.executor import ConfigExecutor


def test_executor_init():
    """测试执行器初始化"""
    executor = ConfigExecutor()
    assert executor.db_engine is not None


def test_validate_sql():
    """测试SQL验证"""
    executor = ConfigExecutor()

    # 测试合法SQL
    is_valid, msg = executor.validate_sql("SELECT * FROM SYS_FORM")
    assert is_valid is True

    # 测试危险SQL
    is_valid, msg = executor.validate_sql("DROP DATABASE test")
    assert is_valid is False
    assert "危险操作" in msg
  • Step 2: 运行测试验证失败
pytest tests/test_executor.py -v

Expected: FAIL

  • Step 3: 实现执行引擎

创建 backend/app/core/executor.py:

import re
from typing import List, Tuple
from loguru import logger
from app.core.db_engine import DatabaseEngine


class ConfigExecutor:
    """配置执行器"""

    # 危险SQL关键词
    DANGEROUS_KEYWORDS = [
        "DROP DATABASE",
        "DROP TABLE",
        "TRUNCATE TABLE",
        "DELETE FROM",
        "UPDATE.*SET",
        "ALTER TABLE.*DROP"
    ]

    def __init__(self):
        self.db_engine = DatabaseEngine()

    def validate_sql(self, sql: str) -> Tuple[bool, str]:
        """验证SQL安全性

        Returns:
            (is_valid, message)
        """
        sql_upper = sql.upper()

        # 检查危险操作
        for keyword in self.DANGEROUS_KEYWORDS:
            if re.search(keyword, sql_upper):
                return False, f"危险操作被拦截: {keyword}"

        return True, "SQL验证通过"

    def execute_config(self, sql_list: List[str], session_id: str) -> dict:
        """执行配置SQL列表

        Args:
            sql_list: SQL列表
            session_id: 会话ID

        Returns:
            执行结果
        """
        logger.info(f"开始执行配置,共 {len(sql_list)} 条SQL")

        results = {
            "success": True,
            "executed": [],
            "failed": None,
            "message": ""
        }

        try:
            # 验证所有SQL
            for i, sql in enumerate(sql_list):
                is_valid, msg = self.validate_sql(sql)
                if not is_valid:
                    raise ValueError(f"SQL #{i+1} 验证失败: {msg}")

            # 执行事务
            self.db_engine.execute_transaction(sql_list)

            results["executed"] = sql_list
            results["message"] = f"成功执行 {len(sql_list)} 条SQL"
            logger.success(results["message"])

        except Exception as e:
            results["success"] = False
            results["failed"] = str(e)
            results["message"] = f"执行失败: {e}"
            logger.error(results["message"])

        return results

    def rollback(self, session_id: str):
        """回滚操作占位符实际需要记录逆向SQL"""
        logger.warning(f"回滚功能待实现: {session_id}")
        return {"success": False, "message": "回滚功能待实现"}
  • Step 4: 运行测试验证通过
pytest tests/test_executor.py -v

Expected: PASS

  • Step 5: Commit
git add backend/app/core/executor.py backend/tests/test_executor.py
git commit -m "feat: implement config executor with SQL validation"

任务8: API层实现 - 基础结构

Files:

  • Create: backend/app/models/__init__.py

  • Create: backend/app/models/request.py

  • Create: backend/app/models/response.py

  • Create: backend/app/api/__init__.py

  • Create: backend/app/main.py

  • Step 1: 创建请求/响应模型

创建 backend/app/models/request.py:

from pydantic import BaseModel, Field
from typing import Optional, List


class AnalyzeRequest(BaseModel):
    """需求解析请求"""
    input_type: str = Field(..., description="输入类型: natural_language | structured")
    content: str = Field(..., description="需求内容")
    session_id: Optional[str] = Field(None, description="会话ID")


class GenerateRequest(BaseModel):
    """配置生成请求"""
    session_id: str
    requirements: dict


class ExecuteRequest(BaseModel):
    """执行配置请求"""
    session_id: str
    confirmed: bool = Field(False, description="用户确认标识")
    backup_enabled: bool = Field(True, description="是否启用备份")

创建 backend/app/models/response.py:

from pydantic import BaseModel
from typing import Optional, Any, List


class AnalyzeResponse(BaseModel):
    """需求解析响应"""
    session_id: str
    status: str
    data: dict


class GenerateResponse(BaseModel):
    """配置生成响应"""
    session_id: str
    status: str
    data: dict


class ExecuteResponse(BaseModel):
    """执行配置响应"""
    execution_id: str
    status: str
    message: str


class ErrorResponse(BaseModel):
    """错误响应"""
    error: dict
  • Step 2: 创建FastAPI主应用

创建 backend/app/main.py:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config import get_settings

settings = get_settings()

app = FastAPI(
    title=settings.APP_NAME,
    version="1.0.0",
    debug=settings.DEBUG
)

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"],  # Vue开发服务器
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
async def root():
    """根路径"""
    return {
        "message": settings.APP_NAME,
        "version": "1.0.0",
        "status": "running"
    }


@app.get("/health")
async def health_check():
    """健康检查"""
    return {"status": "healthy"}


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
  • Step 3: 启动服务验证
cd backend
python -m app.main

访问 http://localhost:8000 验证返回JSON

  • Step 4: Commit
git add backend/app/models/ backend/app/api/ backend/app/main.py
git commit -m "feat: create FastAPI application with request/response models"

任务9: API层实现 - 需求解析API

Files:

  • Create: backend/app/api/analyze.py

  • Update: backend/app/main.py

  • Step 1: 创建需求解析API

创建 backend/app/api/analyze.py:

from fastapi import APIRouter, HTTPException
from app.models.request import AnalyzeRequest
from app.models.response import AnalyzeResponse
from app.services.requirement_service import RequirementService
import uuid

router = APIRouter()


@router.post("/analyze", response_model=AnalyzeResponse)
async def analyze_requirement(request: AnalyzeRequest):
    """需求解析API"""
    try:
        service = RequirementService()
        session_id = request.session_id or str(uuid.uuid4())

        result = await service.analyze(
            user_input=request.content,
            session_id=session_id
        )

        return AnalyzeResponse(
            session_id=session_id,
            status="success",
            data=result
        )

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
  • Step 2: 注册路由到main.py

更新 backend/app/main.py:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config import get_settings
from app.api import analyze  # 添加导入

settings = get_settings()

app = FastAPI(
    title=settings.APP_NAME,
    version="1.0.0",
    debug=settings.DEBUG
)

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由
app.include_router(analyze.router, prefix="/api/v1", tags=["分析"])


@app.get("/")
async def root():
    return {
        "message": settings.APP_NAME,
        "version": "1.0.0",
        "status": "running"
    }


@app.get("/health")
async def health_check():
    return {"status": "healthy"}


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
  • Step 3: 测试API
curl -X POST http://localhost:8000/api/v1/analyze \
  -H "Content-Type: application/json" \
  -d '{"input_type": "natural_language", "content": "创建销售订单管理页面"}'

Expected: 返回JSON响应

  • Step 4: Commit
git add backend/app/api/analyze.py backend/app/main.py
git commit -m "feat: implement analyze API endpoint"

任务10: 前端项目初始化

Files:

  • Create: frontend/package.json

  • Create: frontend/vite.config.js

  • Create: frontend/index.html

  • Create: frontend/src/main.js

  • Create: frontend/src/App.vue

  • Step 1: 初始化Vue项目

cd frontend
npm create vite@latest . -- --template vue
npm install
npm install vue-router@4 pinia axios element-plus monaco-editor sql-formatter
  • Step 2: 配置vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  server: {
    port: 5173,
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true
      }
    }
  }
})
  • Step 3: 创建基础App.vue
<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script setup>
</script>

<style>
#app {
  font-family: 'Microsoft YaHei', sans-serif;
  height: 100vh;
  margin: 0;
}
</style>
  • Step 4: 启动前端验证
npm run dev

访问 http://localhost:5173 验证Vue应用运行

  • Step 5: Commit
git add frontend/
git commit -m "chore: initialize Vue 3 frontend with Vite"

任务11: 前端路由和布局

Files:

  • Create: frontend/src/router/index.js

  • Create: frontend/src/views/Layout.vue

  • Update: frontend/src/main.js

  • Step 1: 创建路由配置

创建 frontend/src/router/index.js:

import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/',
    component: () => import('../views/Layout.vue'),
    children: [
      {
        path: '',
        redirect: '/create'
      },
      {
        path: 'create',
        name: 'CreateFunction',
        component: () => import('../views/CreateFunction.vue')
      },
      {
        path: 'history',
        name: 'History',
        component: () => import('../views/History.vue')
      }
    ]
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router
  • Step 2: 创建布局组件

创建 frontend/src/views/Layout.vue:

<template>
  <el-container class="layout-container">
    <el-header class="header">
      <div class="logo">ERP智能助手</div>
      <div class="user-info">用户: Admin</div>
    </el-header>

    <el-container>
      <el-aside width="200px" class="sidebar">
        <el-menu
          :default-active="$route.path"
          router
        >
          <el-menu-item index="/create">
            <el-icon><Edit /></el-icon>
            <span>新建功能</span>
          </el-menu-item>
          <el-menu-item index="/history">
            <el-icon><Document /></el-icon>
            <span>历史记录</span>
          </el-menu-item>
        </el-menu>
      </el-aside>

      <el-main class="main-content">
        <router-view />
      </el-main>
    </el-container>
  </el-container>
</template>

<script setup>
import { Edit, Document } from '@element-plus/icons-vue'
</script>

<style scoped>
.layout-container {
  height: 100vh;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #409EFF;
  color: white;
}

.logo {
  font-size: 20px;
  font-weight: bold;
}

.sidebar {
  background: #f5f7fa;
}

.main-content {
  background: #f0f2f5;
}
</style>
  • Step 3: 更新main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(ElementPlus)

app.mount('#app')
  • Step 4: 创建占位页面

创建 frontend/src/views/CreateFunction.vue:

<template>
  <div class="create-function">
    <h1>新建功能页面</h1>
    <p>开发中...</p>
  </div>
</template>

创建 frontend/src/views/History.vue:

<template>
  <div class="history">
    <h1>历史记录页面</h1>
    <p>开发中...</p>
  </div>
</template>
  • Step 5: 测试路由

访问 http://localhost:5173 验证布局和路由切换

  • Step 6: Commit
git add frontend/src/
git commit -m "feat: add frontend layout and routing"

任务12: 执行日志表和审计系统

Files:

  • Create: backend/scripts/create_log_table.sql

  • Create: backend/app/models/audit.py

  • Create: backend/app/services/audit_service.py

  • Step 1: 创建执行日志表SQL脚本

创建 backend/scripts/create_log_table.sql:

-- AI助手执行日志表
CREATE TABLE AI_ASSISTANT_LOG (
    LOG_ID INT IDENTITY(1,1) PRIMARY KEY,
    SESSION_ID VARCHAR(50) NOT NULL,
    EXECUTION_ID VARCHAR(50),
    USER_ID VARCHAR(50),
    ACTION_TYPE VARCHAR(50),
    SQL_CONTENT NVARCHAR(MAX),
    STATUS VARCHAR(20),
    ERROR_MESSAGE NVARCHAR(MAX),
    EXECUTION_TIME INT,
    CREATE_TIME DATETIME DEFAULT GETDATE(),
    INDEX IX_SESSION_ID (SESSION_ID),
    INDEX IX_CREATE_TIME (CREATE_TIME)
);

-- 创建索引
CREATE INDEX IX_EXECUTION_ID ON AI_ASSISTANT_LOG(EXECUTION_ID);
  • Step 2: 执行SQL创建表
# 使用sqlcmd或数据库管理工具执行
sqlcmd -S 192.168.120.19 -d DMPF_HY -U sa -P your-password -i backend/scripts/create_log_table.sql
  • Step 3: 创建审计模型

创建 backend/app/models/audit.py:

from pydantic import BaseModel
from datetime import datetime
from typing import Optional


class ExecutionLog(BaseModel):
    """执行日志模型"""
    log_id: Optional[int]
    session_id: str
    execution_id: Optional[str]
    user_id: Optional[str]
    action_type: str
    sql_content: str
    status: str
    error_message: Optional[str]
    execution_time: Optional[int]
    create_time: Optional[datetime] = None
  • Step 4: 创建审计服务

创建 backend/app/services/audit_service.py:

from app.core.db_engine import DatabaseEngine
from app.models.audit import ExecutionLog
from loguru import logger
import uuid


class AuditService:
    """审计服务"""

    def __init__(self):
        self.db_engine = DatabaseEngine()

    def log_execution(self, log: ExecutionLog) -> int:
        """记录执行日志"""
        sql = """
        INSERT INTO AI_ASSISTANT_LOG
        (SESSION_ID, EXECUTION_ID, USER_ID, ACTION_TYPE, SQL_CONTENT, STATUS, ERROR_MESSAGE, EXECUTION_TIME)
        VALUES
        (:session_id, :execution_id, :user_id, :action_type, :sql_content, :status, :error_message, :execution_time)
        """

        params = {
            "session_id": log.session_id,
            "execution_id": log.execution_id or str(uuid.uuid4()),
            "user_id": log.user_id or "system",
            "action_type": log.action_type,
            "sql_content": log.sql_content,
            "status": log.status,
            "error_message": log.error_message,
            "execution_time": log.execution_time
        }

        try:
            self.db_engine.execute_sql(sql, params)
            logger.info(f"记录执行日志: {log.action_type}")
            return 1
        except Exception as e:
            logger.error(f"记录执行日志失败: {e}")
            return 0

    def get_execution_history(self, session_id: str, limit: int = 100):
        """获取执行历史"""
        sql = f"""
        SELECT TOP {limit} *
        FROM AI_ASSISTANT_LOG
        WHERE SESSION_ID = '{session_id}'
        ORDER BY CREATE_TIME DESC
        """
        return self.db_engine.execute_sql(sql)
  • Step 5: 编写测试

创建 backend/tests/test_audit_service.py:

from app.services.audit_service import AuditService
from app.models.audit import ExecutionLog


def test_log_execution():
    """测试执行日志记录"""
    service = AuditService()

    log = ExecutionLog(
        session_id="test-session",
        action_type="TEST",
        sql_content="SELECT 1",
        status="SUCCESS"
    )

    result = service.log_execution(log)
    assert result == 1
  • Step 6: 运行测试
pytest tests/test_audit_service.py -v
  • Step 7: Commit
git add backend/scripts/create_log_table.sql backend/app/models/audit.py backend/app/services/audit_service.py backend/tests/test_audit_service.py
git commit -m "feat: add execution logging and audit system"

任务13: 配置生成服务

Files:

  • Create: backend/app/services/config_service.py

  • Create: backend/tests/test_config_service.py

  • Step 1: 创建配置生成服务测试

创建 backend/tests/test_config_service.py:

import pytest
from app.services.config_service import ConfigService


@pytest.mark.asyncio
async def test_generate_config():
    """测试配置生成"""
    service = ConfigService()

    requirements = {
        "功能名称": "销售订单",
        "功能号建议": "11-001",
        "窗体类型": "5",
        "主表名建议": "SA_ORDER",
        "主表字段": [
            {"字段名": "订单号", "字段类型": "varchar(50)", "必填": True}
        ]
    }

    result = await service.generate(requirements, "test-session")

    assert result is not None
    assert "配置方案" in result
  • Step 2: 运行测试验证失败
pytest tests/test_config_service.py -v

Expected: FAIL

  • Step 3: 实现配置生成服务

创建 backend/app/services/config_service.py:

from app.core.ai_engine import ClaudeEngine
from app.core.rag_engine import RAGEngine
from app.core.prompts import SYSTEM_PROMPT, GENERATE_PROMPT_TEMPLATE
from app.core.db_engine import DatabaseEngine
from loguru import logger


class ConfigService:
    """配置生成服务"""

    def __init__(self):
        self.ai_engine = ClaudeEngine()
        self.rag_engine = RAGEngine()
        self.db_engine = DatabaseEngine()

    async def generate(self, requirements: dict, session_id: str) -> dict:
        """生成配置方案

        Args:
            requirements: 结构化需求
            session_id: 会话ID

        Returns:
            配置方案包含SQL列表
        """
        logger.info(f"开始生成配置: {requirements.get('功能名称', 'Unknown')}")

        # 1. 检索相关知识
        platform_rules = self._get_platform_rules(requirements.get("窗体类型", "0"))
        similar_cases = self._get_similar_cases(requirements.get("功能名称", ""))

        # 2. 构建Prompt
        prompt = GENERATE_PROMPT_TEMPLATE.format(
            requirements=str(requirements),
            platform_rules=platform_rules,
            similar_cases=similar_cases
        )

        messages = [
            {"role": "user", "content": SYSTEM_PROMPT},
            {"role": "assistant", "content": "我已了解,请提供需求信息。"},
            {"role": "user", "content": prompt}
        ]

        # 3. 调用Claude API
        response = await self.ai_engine.call_claude(messages, temperature=0.5)

        # 4. 解析结果
        result = self.ai_engine.parse_json_response(response)

        logger.success(f"配置生成完成")
        return result

    def _get_platform_rules(self, form_type: str) -> str:
        """获取平台配置规则"""
        # 简化版本:从知识库检索
        results = self.rag_engine.search(f"窗体类型{form_type}配置规则", top_k=2)
        return "\n\n".join([r["content"] for r in results])

    def _get_similar_cases(self, keywords: str) -> str:
        """获取相似案例"""
        results = self.rag_engine.search(keywords, top_k=2)
        return "\n\n".join([r["content"] for r in results])
  • Step 4: 运行测试验证通过
pytest tests/test_config_service.py -v

Expected: PASS

  • Step 5: Commit
git add backend/app/services/config_service.py backend/tests/test_config_service.py
git commit -m "feat: implement config generation service"

任务14: 执行配置API

Files:

  • Create: backend/app/api/execute.py

  • Create: backend/app/api/generate.py

  • Update: backend/app/main.py

  • Step 1: 创建配置生成API

创建 backend/app/api/generate.py:

from fastapi import APIRouter, HTTPException
from app.models.request import GenerateRequest
from app.models.response import GenerateResponse
from app.services.config_service import ConfigService

router = APIRouter()


@router.post("/generate", response_model=GenerateResponse)
async def generate_config(request: GenerateRequest):
    """配置生成API"""
    try:
        service = ConfigService()
        result = await service.generate(
            requirements=request.requirements,
            session_id=request.session_id
        )

        return GenerateResponse(
            session_id=request.session_id,
            status="success",
            data=result
        )

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
  • Step 2: 创建执行配置API

创建 backend/app/api/execute.py:

from fastapi import APIRouter, HTTPException
from app.models.request import ExecuteRequest
from app.models.response import ExecuteResponse
from app.core.executor import ConfigExecutor
from app.services.audit_service import AuditService
from app.models.audit import ExecutionLog
import uuid

router = APIRouter()


@router.post("/execute", response_model=ExecuteResponse)
async def execute_config(request: ExecuteRequest):
    """执行配置API"""
    try:
        executor = ConfigExecutor()
        audit_service = AuditService()

        execution_id = str(uuid.uuid4())

        # TODO: 从session获取SQL列表实际应从数据库或缓存获取
        sql_list = []  # 占位符

        # 执行配置
        result = executor.execute_config(sql_list, request.session_id)

        # 记录日志
        for sql in sql_list:
            log = ExecutionLog(
                session_id=request.session_id,
                execution_id=execution_id,
                action_type="EXECUTE_SQL",
                sql_content=sql,
                status="SUCCESS" if result["success"] else "FAILED",
                error_message=result.get("failed")
            )
            audit_service.log_execution(log)

        return ExecuteResponse(
            execution_id=execution_id,
            status="success" if result["success"] else "failed",
            message=result["message"]
        )

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
  • Step 3: 更新main.py注册路由

backend/app/main.py 中添加路由:

from app.api import analyze, generate, execute

# ...existing code...

# 注册路由
app.include_router(analyze.router, prefix="/api/v1", tags=["分析"])
app.include_router(generate.router, prefix="/api/v1", tags=["生成"])
app.include_router(execute.router, prefix="/api/v1", tags=["执行"])
  • Step 4: 测试API
curl -X POST http://localhost:8000/api/v1/generate \
  -H "Content-Type: application/json" \
  -d '{"session_id": "test", "requirements": {"功能名称": "测试"}}'
  • Step 5: Commit
git add backend/app/api/generate.py backend/app/api/execute.py backend/app/main.py
git commit -m "feat: add generate and execute API endpoints"

任务15: 前端需求输入组件

Files:

  • Create: frontend/src/components/RequirementInput.vue

  • Create: frontend/src/api/index.js

  • Step 1: 创建API调用封装

创建 frontend/src/api/index.js:

import axios from 'axios'

const api = axios.create({
  baseURL: '/api/v1',
  timeout: 60000,
  headers: {
    'Content-Type': 'application/json'
  }
})

export default {
  async analyze(content, inputType = 'natural_language') {
    const response = await api.post('/analyze', {
      input_type: inputType,
      content
    })
    return response.data
  },

  async generate(sessionId, requirements) {
    const response = await api.post('/generate', {
      session_id: sessionId,
      requirements
    })
    return response.data
  },

  async execute(sessionId, confirmed = true) {
    const response = await api.post('/execute', {
      session_id: sessionId,
      confirmed,
      backup_enabled: true
    })
    return response.data
  }
}
  • Step 2: 创建需求输入组件

创建 frontend/src/components/RequirementInput.vue:

<template>
  <el-card class="requirement-input">
    <template #header>
      <div class="card-header">
        <span>需求输入</span>
        <el-radio-group v-model="inputMode" size="small">
          <el-radio-button label="natural">自然语言</el-radio-button>
          <el-radio-button label="structured">结构化表单</el-radio-button>
        </el-radio-group>
      </div>
    </template>

    <!-- 自然语言模式 -->
    <div v-if="inputMode === 'natural'" class="natural-input">
      <el-input
        v-model="naturalInput"
        type="textarea"
        :rows="6"
        placeholder="请描述您的需求,例如:创建一个销售订单管理页面,包含订单号、客户、金额等字段..."
      />
      <el-button type="primary" @click="submitNatural" :loading="loading" style="margin-top: 10px">
        提交需求
      </el-button>
    </div>

    <!-- 结构化表单模式 -->
    <div v-else class="structured-input">
      <el-form :model="formData" label-width="100px">
        <el-form-item label="功能名称">
          <el-input v-model="formData.functionName" />
        </el-form-item>

        <el-form-item label="窗体类型">
          <el-select v-model="formData.formType">
            <el-option label="普通类型" value="0" />
            <el-option label="单据列表" value="5" />
            <el-option label="一对多" value="11" />
          </el-select>
        </el-form-item>

        <el-divider>主表字段</el-divider>

        <el-table :data="formData.fields" style="width: 100%">
          <el-table-column prop="name" label="字段名">
            <template #default="{ row }">
              <el-input v-model="row.name" />
            </template>
          </el-table-column>
          <el-table-column prop="type" label="类型">
            <template #default="{ row }">
              <el-select v-model="row.type">
                <el-option label="varchar(50)" value="varchar(50)" />
                <el-option label="int" value="int" />
                <el-option label="decimal(18,2)" value="decimal(18,2)" />
                <el-option label="datetime" value="datetime" />
              </el-select>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template #default="{ $index }">
              <el-button type="danger" size="small" @click="removeField($index)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>

        <el-button type="primary" size="small" @click="addField" style="margin-top: 10px">
          添加字段
        </el-button>

        <el-button type="success" @click="submitStructured" :loading="loading" style="margin-top: 20px">
          生成配置
        </el-button>
      </el-form>
    </div>
  </el-card>
</template>

<script setup>
import { ref } from 'vue'
import api from '../api'
import { ElMessage } from 'element-plus'

const emit = defineEmits(['submitted'])

const inputMode = ref('natural')
const naturalInput = ref('')
const loading = ref(false)

const formData = ref({
  functionName: '',
  formType: '5',
  fields: [
    { name: '', type: 'varchar(50)' }
  ]
})

const addField = () => {
  formData.value.fields.push({ name: '', type: 'varchar(50)' })
}

const removeField = (index) => {
  formData.value.fields.splice(index, 1)
}

const submitNatural = async () => {
  if (!naturalInput.value.trim()) {
    ElMessage.warning('请输入需求描述')
    return
  }

  loading.value = true
  try {
    const result = await api.analyze(naturalInput.value)
    emit('submitted', result)
    ElMessage.success('需求解析成功')
  } catch (error) {
    ElMessage.error('需求解析失败:' + error.message)
  } finally {
    loading.value = false
  }
}

const submitStructured = async () => {
  loading.value = true
  try {
    // TODO: 转换formData为后端需要的格式
    const result = await api.analyze(JSON.stringify(formData.value), 'structured')
    emit('submitted', result)
    ElMessage.success('提交成功')
  } catch (error) {
    ElMessage.error('提交失败:' + error.message)
  } finally {
    loading.value = false
  }
}
</script>

<style scoped>
.requirement-input {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
  • Step 3: 更新CreateFunction.vue使用组件

更新 frontend/src/views/CreateFunction.vue:

<template>
  <div class="create-function">
    <el-steps :active="currentStep" finish-status="success">
      <el-step title="输入需求" />
      <el-step title="生成配置" />
      <el-step title="审核确认" />
      <el-step title="执行" />
      <el-step title="完成" />
    </el-steps>

    <div class="step-content" style="margin-top: 20px">
      <requirement-input v-if="currentStep === 0" @submitted="handleSubmitted" />
      <div v-else-if="currentStep === 1">生成配置中...</div>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import RequirementInput from '../components/RequirementInput.vue'

const currentStep = ref(0)

const handleSubmitted = (result) => {
  console.log('需求解析结果:', result)
  currentStep.value = 1
}
</script>
  • Step 4: 测试组件

访问 http://localhost:5173/create 验证组件显示和交互

  • Step 5: Commit
git add frontend/src/components/RequirementInput.vue frontend/src/api/index.js frontend/src/views/CreateFunction.vue
git commit -m "feat: add requirement input component with natural language and structured form"

剩余任务概要

由于篇幅限制,以下任务保持概要形式,将在执行过程中细化:

任务16: 配置预览组件

  • SQL预览Monaco Editor
  • 风险提示显示
  • 审核确认按钮

任务17: 执行监控组件

  • 实时日志显示
  • 进度条
  • WebSocket支持可选

任务18: 历史记录API和页面

  • 查询历史记录API
  • 历史记录列表页面
  • 详情查看

任务19: 数据库元数据API

  • 表列表查询
  • 表结构详情
  • 功能号列表

任务20: 知识库管理

  • 文档上传界面
  • 文档列表
  • 索引重建

任务21-25: 测试与部署

  • 单元测试完善
  • 集成测试
  • Docker配置
  • docker-compose编排
  • README文档

执行策略

推荐方式: 使用 superpowers:subagent-driven-development 技能

  • 每个任务由独立子代理执行
  • 任务间有明确的文件依赖
  • 每个任务完成后进行代码审查
  • 遵循TDD流程测试先行

关键检查点:

  1. 任务5后知识库可正常检索
  2. 任务9后API可通过Postman测试
  3. 任务11后前端可访问和导航
  4. 任务20后核心流程打通

风险与应对

  1. Claude API调用失败

    • 确保配置正确的API Key
    • 网络代理问题需提前解决
  2. 数据库连接失败

    • 检查SQL Server配置
    • 验证防火墙规则
    • 测试ODBC驱动安装
  3. 前后端联调问题

    • 使用浏览器开发者工具检查网络请求
    • 检查CORS配置

验收标准

  • 可以通过自然语言生成简单功能配置
  • 生成的SQL可以成功执行
  • 执行日志完整记录所有操作
  • 前端界面可用,流程完整
  • 核心API有单元测试覆盖
  • 代码已提交到Git仓库

计划创建时间: 2026-03-21 预计实施周期: Phase 1约4周 文档版本: 1.0