Add ZSTD decompression for message_content field

Introduces ZSTD decompression for the message_content field in the message table when retrieving data, allowing compressed messages to be displayed as plain text. Also improves error handling for invalid time arguments in chatlog route and updates CSS for table list view layout.
This commit is contained in:
teest114514
2026-01-19 14:59:16 +08:00
parent b205c5386a
commit f87ec22251
3 changed files with 34 additions and 2 deletions

View File

@@ -118,6 +118,7 @@ func (s *Service) handleChatlog(c *gin.Context) {
start, end, ok := util.TimeRangeOf(q.Time)
if !ok {
errors.Err(c, errors.InvalidArg("time"))
return
}
if q.Limit < 0 {
q.Limit = 0

View File

@@ -291,7 +291,8 @@
.modal-view.active { display: flex; }
/* Browser View */
.db-table-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; overflow-y: auto; padding: 5px; }
#table-list-view { flex: 1; overflow: hidden; display: flex; flex-direction: column; }
.db-table-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; overflow-y: auto; padding: 5px; height: 100%; }
.db-table-item { padding: 15px; border: 1px solid var(--border); border-radius: 8px; cursor: pointer; text-align: center; background: white; transition: all 0.2s; box-shadow: 0 1px 2px rgba(0,0,0,0.05); }
.db-table-item:hover { background: #eff6ff; border-color: var(--primary); transform: translateY(-2px); box-shadow: 0 4px 6px rgba(0,0,0,0.05); }

View File

@@ -14,6 +14,7 @@ import (
"github.com/fsnotify/fsnotify"
_ "github.com/mattn/go-sqlite3"
"github.com/rs/zerolog/log"
"github.com/klauspost/compress/zstd"
"github.com/sjzar/chatlog/internal/errors"
"github.com/sjzar/chatlog/internal/model"
@@ -928,6 +929,13 @@ func (ds *DataSource) GetTableData(group, file, table string, limit, offset int,
return nil, err
}
// 为消息表创建 ZSTD 解码器(如果需要)
var zstdDecoder *zstd.Decoder
if group == "message" {
zstdDecoder, _ = zstd.NewReader(nil)
defer zstdDecoder.Close()
}
result := make([]map[string]interface{}, 0)
for rows.Next() {
values := make([]interface{}, len(resCols))
@@ -946,7 +954,29 @@ func (ds *DataSource) GetTableData(group, file, table string, limit, offset int,
val := values[i]
b, ok := val.([]byte)
if ok {
v = string(b)
// 特殊处理消息表的 message_content 字段
if group == "message" && col == "message_content" && len(b) > 0 {
// 检查是否是 ZSTD 压缩数据 (magic bytes: 0x28, 0xb5, 0x2f, 0xfd)
if len(b) >= 4 && b[0] == 0x28 && b[1] == 0xb5 && b[2] == 0x2f && b[3] == 0xfd {
// 尝试解压 ZSTD 数据
if zstdDecoder != nil {
decompressed, err := zstdDecoder.DecodeAll(b, nil)
if err == nil {
v = string(decompressed)
} else {
v = fmt.Sprintf("[Binary data: %d bytes, ZSTD decompress failed: %v]", len(b), err)
}
} else {
v = fmt.Sprintf("[Binary data: %d bytes, ZSTD decoder not available]", len(b))
}
} else {
// 不是 ZSTD 压缩数据,尝试作为普通文本显示
v = string(b)
}
} else {
// 其他字段,直接转换为字符串
v = string(b)
}
} else {
v = val
}