Merge PR #18: delete traffic targets and LLM task conversations from UI (laohuan12138)

- Traffic 页:按 host 多选精确批量删 + 子串删 + 删后 _blobs 内容寻址块 GC 回收;新增 GET /api/traffic/hosts
- LLM 记录页:按 task_id 下拉选择 + 按任务删除
- 修复 host 选择器 Popover 高度渲染;.gitignore 加 /dist/
- 新增 traffic/traffic_test.go(DeleteHost/DeleteHostsExact/Hosts/GC 共 4 个测试)

本地已验证:go build/vet、traffic 测试、前端 tsc/build 均通过;与当前 main 无冲突。
This commit is contained in:
Autumn-27 committed 2026-08-11 09:38:12 -04:00
commit 052c35a954
12 files changed
+883 -20

No files matched your search

+42 -1
View File
@@ -152,7 +152,7 @@ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)`,
}
// ListLLMRecords returns paginated LLM records with optional filters.
func (d *DB) ListLLMRecords(model, session string, page, size int) ([]LLMRecord, int, error) {
func (d *DB) ListLLMRecords(model, session, task string, page, size int) ([]LLMRecord, int, error) {
if size <= 0 {
size = 50
}
@@ -174,6 +174,11 @@ func (d *DB) ListLLMRecords(model, session string, page, size int) ([]LLMRecord,
args = append(args, "%"+session+"%")
argN++
}
if task != "" {
where += fmt.Sprintf(` AND COALESCE(task_id,'') = $%d`, argN)
args = append(args, task)
argN++
}
var total int
if err := d.QueryRow(`SELECT COUNT(*) FROM llm_records `+where, args...).Scan(&total); err != nil {
@@ -204,6 +209,42 @@ func (d *DB) ListLLMRecords(model, session string, page, size int) ([]LLMRecord,
return out, total, rows.Err()
}
// LLMTask is one distinct task with its LLM-record count.
type LLMTask struct {
TaskID string `json:"task_id"`
Count int `json:"count"`
}
// LLMTasks returns distinct non-empty task_ids with record counts, most recent
// first — powers the LLM-records page's task picker.
func (d *DB) LLMTasks() ([]LLMTask, error) {
rows, err := d.Query(`SELECT task_id, COUNT(*) AS n FROM llm_records
WHERE COALESCE(task_id,'') <> '' GROUP BY task_id ORDER BY MAX(id) DESC`)
if err != nil {
return nil, err
}
defer rows.Close()
var out []LLMTask
for rows.Next() {
var t LLMTask
if err := rows.Scan(&t.TaskID, &t.Count); err != nil {
return nil, err
}
out = append(out, t)
}
return out, rows.Err()
}
// DeleteLLMRecords removes every LLM record for one exact task_id — the same
// match the page's task picker/filter uses. Returns rows deleted.
func (d *DB) DeleteLLMRecords(task string) (int64, error) {
res, err := d.Exec(`DELETE FROM llm_records WHERE COALESCE(task_id,'') = $1`, task)
if err != nil {
return 0, err
}
return res.RowsAffected()
}
// GetLLMRecord returns a single LLM record with full request/response bodies.
func (d *DB) GetLLMRecord(id int64) (*LLMRecord, error) {
var r LLMRecord