Files
prompt-generator/internal/handlers/builder.go
T
wonder b23ed28b88 fix: 优化生成 Prompt 的标题映射,移除技术术语
- 标签约束 → 约束
- 用户自定义内容 → 自定义内容
- 片段内容 → 参考片段
- 片段: xxx → xxx(去掉前缀)
- 智能建议补充 → 补充建议
2026-06-26 16:05:59 +08:00

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")
}