feat(HTML Export): Export static HTML

This commit is contained in:
Symb0x76
2025-09-15 21:18:19 +08:00
parent 594b50d616
commit 4bda962a2f
4 changed files with 70 additions and 1 deletions
+18
View File
@@ -71,6 +71,8 @@ func (s *Service) initAPIRouter() {
api.GET("/chatroom", s.handleChatRooms)
api.GET("/session", s.handleSessions)
api.GET("/diary", s.handleDiary)
// 导出为静态HTML
api.GET("/export/chatlog", s.handleExportChatlogHTML)
}
}
@@ -209,6 +211,22 @@ func (s *Service) handleChatlog(c *gin.Context) {
}
}
// handleExportChatlogHTML 导出查询结果为静态HTML文件
// GET /api/v1/export/chatlog?time=...&talker=...&sender=...&keyword=...&limit=...&offset=...
// 行为与 handleChatlog?format=html 类似,但会下发附件下载头,便于保存为静态HTML。
func (s *Service) handleExportChatlogHTML(c *gin.Context) {
// 复用 handleChatlog 的查询参数与渲染逻辑,只是强制设置 format=html,并附加下载头
q := c.Request.URL.Query()
q.Set("format", "html")
// 默认文件名:chatlog_YYYY-MM-DD_HH-mm-SS.html
now := time.Now().Format("2006-01-02_15-04-05")
filename := fmt.Sprintf("chatlog_%s.html", now)
c.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
// 变更 Request 的 RawQuery 后复用现有处理函数
c.Request.URL.RawQuery = q.Encode()
s.handleChatlog(c)
}
func (s *Service) handleContacts(c *gin.Context) {
q := struct {
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+52 -1
View File
@@ -597,7 +597,15 @@
</div>
</div>
<button id="test-api">执行查询</button>
<div style="display: flex; gap: 10px; align-items: center">
<button id="test-api">执行查询</button>
<button
id="export-html"
title="按当前聊天记录查询参数导出为静态HTML"
>
导出HTML
</button>
</div>
<div
id="result-wrapper"
@@ -884,6 +892,49 @@
}
});
// 导出静态HTML(仅在“聊天记录”标签生效)
document
.getElementById("export-html")
.addEventListener("click", function () {
const activeTab = document
.querySelector(".tab.active")
.getAttribute("data-tab");
if (activeTab !== "chatlog") {
const em = document.getElementById("error-message");
em.textContent =
"导出仅支持‘聊天记录’标签。请切换到‘聊天记录’并设置查询条件。";
em.style.display = "block";
return;
}
const time = document.getElementById("time").value;
if (!time) {
const em = document.getElementById("error-message");
em.textContent = "错误: 时间范围为必填项!";
em.style.display = "block";
return;
}
const talker = document.getElementById("talker").value;
const sender = document.getElementById("sender").value;
const keyword = document.getElementById("keyword").value;
const limit = document.getElementById("limit").value;
const offset = document.getElementById("offset").value;
const params = new URLSearchParams();
params.append("time", time);
if (talker) params.append("talker", talker);
if (sender) params.append("sender", sender);
if (keyword) params.append("keyword", keyword);
if (limit) params.append("limit", limit);
if (offset) params.append("offset", offset);
const url = "/api/v1/export/chatlog?" + params.toString();
// 触发下载
const a = document.createElement("a");
a.href = url;
a.download = "";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
// 复制结果功能
document
.getElementById("copy-result")