b23ed28b88
- 标签约束 → 约束 - 用户自定义内容 → 自定义内容 - 片段内容 → 参考片段 - 片段: xxx → xxx(去掉前缀) - 智能建议补充 → 补充建议
241 lines
7.1 KiB
Go
241 lines
7.1 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"prompt-generator/internal/db"
|
|
"prompt-generator/internal/models"
|
|
)
|
|
|
|
func GetBuilderSessions(w http.ResponseWriter, r *http.Request) {
|
|
rows, err := db.DB.Query("SELECT id, title, project_name, final_prompt, claude_session_id, created_at, updated_at FROM builder_sessions ORDER BY updated_at DESC")
|
|
if err != nil {
|
|
fail(w, 500, "查询会话列表失败")
|
|
return
|
|
}
|
|
defer rows.Close()
|
|
|
|
var sessions []models.BuilderSession
|
|
for rows.Next() {
|
|
var s models.BuilderSession
|
|
if err := rows.Scan(&s.ID, &s.Title, &s.ProjectName, &s.FinalPrompt, &s.ClaudeSessionID, &s.CreatedAt, &s.UpdatedAt); err != nil {
|
|
continue
|
|
}
|
|
sessions = append(sessions, s)
|
|
}
|
|
if sessions == nil {
|
|
sessions = []models.BuilderSession{}
|
|
}
|
|
success(w, sessions)
|
|
}
|
|
|
|
func CreateBuilderSession(w http.ResponseWriter, r *http.Request) {
|
|
var req struct {
|
|
Title string `json:"title"`
|
|
ProjectName string `json:"project_name"`
|
|
FinalPrompt string `json:"final_prompt"`
|
|
ClaudeSessionID string `json:"claude_session_id"`
|
|
TagOptionIDs []struct {
|
|
TagID int64 `json:"tag_id"`
|
|
TagOptionID int64 `json:"tag_option_id"`
|
|
} `json:"tag_option_ids"`
|
|
SnippetIDs []struct {
|
|
SnippetID int64 `json:"snippet_id"`
|
|
SortOrder int `json:"sort_order"`
|
|
} `json:"snippet_ids"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
fail(w, 400, "请求格式错误")
|
|
return
|
|
}
|
|
|
|
var claudeID *string
|
|
if req.ClaudeSessionID != "" {
|
|
claudeID = &req.ClaudeSessionID
|
|
}
|
|
|
|
res, err := db.DB.Exec("INSERT INTO builder_sessions (title, project_name, final_prompt, claude_session_id) VALUES (?, ?, ?, ?)",
|
|
req.Title, req.ProjectName, req.FinalPrompt, claudeID)
|
|
if err != nil {
|
|
fail(w, 500, "创建会话失败")
|
|
return
|
|
}
|
|
|
|
sessionID, _ := res.LastInsertId()
|
|
|
|
// Insert tag associations
|
|
for _, t := range req.TagOptionIDs {
|
|
db.DB.Exec("INSERT INTO builder_session_tags (builder_session_id, tag_id, tag_option_id) VALUES (?, ?, ?)",
|
|
sessionID, t.TagID, t.TagOptionID)
|
|
}
|
|
|
|
// Insert snippet associations
|
|
for _, s := range req.SnippetIDs {
|
|
db.DB.Exec("INSERT INTO builder_session_snippets (builder_session_id, snippet_id, sort_order) VALUES (?, ?, ?)",
|
|
sessionID, s.SnippetID, s.SortOrder)
|
|
}
|
|
|
|
success(w, map[string]int64{"id": sessionID})
|
|
}
|
|
|
|
func GetBuilderSession(w http.ResponseWriter, r *http.Request) {
|
|
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
|
if err != nil {
|
|
fail(w, 400, "无效的 ID")
|
|
return
|
|
}
|
|
|
|
var s models.BuilderSession
|
|
err = db.DB.QueryRow("SELECT id, title, project_name, final_prompt, claude_session_id, created_at, updated_at FROM builder_sessions WHERE id=?", id).
|
|
Scan(&s.ID, &s.Title, &s.ProjectName, &s.FinalPrompt, &s.ClaudeSessionID, &s.CreatedAt, &s.UpdatedAt)
|
|
if err != nil {
|
|
fail(w, 404, "会话不存在")
|
|
return
|
|
}
|
|
|
|
// Load tags
|
|
tagRows, err := db.DB.Query("SELECT id, builder_session_id, tag_id, tag_option_id FROM builder_session_tags WHERE builder_session_id=?", id)
|
|
if err == nil {
|
|
for tagRows.Next() {
|
|
var t models.SessionTag
|
|
if err := tagRows.Scan(&t.ID, &t.BuilderSessionID, &t.TagID, &t.TagOptionID); err == nil {
|
|
s.Tags = append(s.Tags, t)
|
|
}
|
|
}
|
|
tagRows.Close()
|
|
}
|
|
|
|
// Load snippets
|
|
snippetRows, err := db.DB.Query("SELECT id, builder_session_id, snippet_id, sort_order FROM builder_session_snippets WHERE builder_session_id=? ORDER BY sort_order", id)
|
|
if err == nil {
|
|
for snippetRows.Next() {
|
|
var sn models.SessionSnippet
|
|
if err := snippetRows.Scan(&sn.ID, &sn.BuilderSessionID, &sn.SnippetID, &sn.SortOrder); err == nil {
|
|
s.Snippets = append(s.Snippets, sn)
|
|
}
|
|
}
|
|
snippetRows.Close()
|
|
}
|
|
|
|
if s.Tags == nil {
|
|
s.Tags = []models.SessionTag{}
|
|
}
|
|
if s.Snippets == nil {
|
|
s.Snippets = []models.SessionSnippet{}
|
|
}
|
|
|
|
success(w, s)
|
|
}
|
|
|
|
func UpdateBuilderSession(w http.ResponseWriter, r *http.Request) {
|
|
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
|
if err != nil {
|
|
fail(w, 400, "无效的 ID")
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
Title string `json:"title"`
|
|
ProjectName string `json:"project_name"`
|
|
FinalPrompt string `json:"final_prompt"`
|
|
ClaudeSessionID string `json:"claude_session_id"`
|
|
TagOptionIDs []struct {
|
|
TagID int64 `json:"tag_id"`
|
|
TagOptionID int64 `json:"tag_option_id"`
|
|
} `json:"tag_option_ids"`
|
|
SnippetIDs []struct {
|
|
SnippetID int64 `json:"snippet_id"`
|
|
SortOrder int `json:"sort_order"`
|
|
} `json:"snippet_ids"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
fail(w, 400, "请求格式错误")
|
|
return
|
|
}
|
|
|
|
var claudeID *string
|
|
if req.ClaudeSessionID != "" {
|
|
claudeID = &req.ClaudeSessionID
|
|
}
|
|
|
|
_, err = db.DB.Exec("UPDATE builder_sessions SET title=?, project_name=?, final_prompt=?, claude_session_id=? WHERE id=?",
|
|
req.Title, req.ProjectName, req.FinalPrompt, claudeID, id)
|
|
if err != nil {
|
|
fail(w, 500, "更新会话失败")
|
|
return
|
|
}
|
|
|
|
// Replace tags
|
|
db.DB.Exec("DELETE FROM builder_session_tags WHERE builder_session_id=?", id)
|
|
for _, t := range req.TagOptionIDs {
|
|
db.DB.Exec("INSERT INTO builder_session_tags (builder_session_id, tag_id, tag_option_id) VALUES (?, ?, ?)",
|
|
id, t.TagID, t.TagOptionID)
|
|
}
|
|
|
|
// Replace snippets
|
|
db.DB.Exec("DELETE FROM builder_session_snippets WHERE builder_session_id=?", id)
|
|
for _, s := range req.SnippetIDs {
|
|
db.DB.Exec("INSERT INTO builder_session_snippets (builder_session_id, snippet_id, sort_order) VALUES (?, ?, ?)",
|
|
id, s.SnippetID, s.SortOrder)
|
|
}
|
|
|
|
success(w, nil)
|
|
}
|
|
|
|
func DeleteBuilderSession(w http.ResponseWriter, r *http.Request) {
|
|
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
|
if err != nil {
|
|
fail(w, 400, "无效的 ID")
|
|
return
|
|
}
|
|
|
|
db.DB.Exec("DELETE FROM builder_session_tags WHERE builder_session_id=?", id)
|
|
db.DB.Exec("DELETE FROM builder_session_snippets WHERE builder_session_id=?", id)
|
|
db.DB.Exec("DELETE FROM builder_sessions WHERE id=?", id)
|
|
success(w, nil)
|
|
}
|
|
|
|
// AssemblePrompt 组装最终 Prompt
|
|
func AssemblePrompt(projectName string, customContent string, tagOptions []models.TagOption, snippets []models.Snippet, suggestions []string) string {
|
|
var parts []string
|
|
|
|
// Project context
|
|
if projectName != "" {
|
|
parts = append(parts, fmt.Sprintf("## 项目上下文\n\n项目名称: %s", projectName))
|
|
}
|
|
|
|
// Custom content
|
|
if customContent != "" {
|
|
parts = append(parts, fmt.Sprintf("## 自定义内容\n\n%s", customContent))
|
|
}
|
|
|
|
// Tag constraints
|
|
if len(tagOptions) > 0 {
|
|
var constraints []string
|
|
for _, opt := range tagOptions {
|
|
constraints = append(constraints, fmt.Sprintf("- %s", opt.ConstraintText))
|
|
}
|
|
parts = append(parts, fmt.Sprintf("## 约束\n\n%s", strings.Join(constraints, "\n")))
|
|
}
|
|
|
|
// Snippets
|
|
if len(snippets) > 0 {
|
|
var snippetParts []string
|
|
for _, s := range snippets {
|
|
snippetParts = append(snippetParts, fmt.Sprintf("--- %s ---\n%s", s.Name, s.Content))
|
|
}
|
|
parts = append(parts, fmt.Sprintf("## 参考片段\n\n%s", strings.Join(snippetParts, "\n\n")))
|
|
}
|
|
|
|
// Suggestions
|
|
if len(suggestions) > 0 {
|
|
parts = append(parts, fmt.Sprintf("## 补充建议\n\n%s", strings.Join(suggestions, "\n")))
|
|
}
|
|
|
|
return strings.Join(parts, "\n\n")
|
|
}
|