修复:webapp 翻页逻辑和编译错误
前端改进: - 添加 direction 追踪翻页方向(forward/backward) - 使用 startIndex/endIndex 追踪当前显示范围 - topics 列表自动排序 - 移除 currentCenterIndex,改用更清晰的边界索引 后端改进: - 支持 direction 参数控制查询方向 - backward:从 startIndex 向前查询(更早的记录) - forward:从 endIndex 向后查询(更新的记录) - 修复 QueryNewest/QueryOldest 返回值处理 - 正确计算 startRecordIndex(基于查询结果) 修复编译错误: - example/index/main.go:修正 QueryNewest/QueryOldest 返回值数量 - example/webapp/main.go:修正变量重复定义和未定义错误 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -348,6 +348,9 @@ func handleIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
<script>
|
<script>
|
||||||
let currentTopic = null;
|
let currentTopic = null;
|
||||||
let currentCenterIndex = null; // 追踪当前中心索引位置
|
let currentCenterIndex = null; // 追踪当前中心索引位置
|
||||||
|
let direction = 'forward'; // 默认方向为向前翻页
|
||||||
|
let startIndex = null;
|
||||||
|
let endIndex = null;
|
||||||
|
|
||||||
// 加载 topics
|
// 加载 topics
|
||||||
async function loadTopics() {
|
async function loadTopics() {
|
||||||
@@ -355,7 +358,7 @@ func handleIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
const topics = await response.json();
|
const topics = await response.json();
|
||||||
|
|
||||||
const list = document.getElementById('topicList');
|
const list = document.getElementById('topicList');
|
||||||
list.innerHTML = topics.map(topic =>
|
list.innerHTML = topics.sort().map(topic =>
|
||||||
'<li class="topic-item" onclick="selectTopic(\'' + topic + '\')">' + topic + '</li>'
|
'<li class="topic-item" onclick="selectTopic(\'' + topic + '\')">' + topic + '</li>'
|
||||||
).join('');
|
).join('');
|
||||||
}
|
}
|
||||||
@@ -363,7 +366,9 @@ func handleIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
// 选择 topic
|
// 选择 topic
|
||||||
function selectTopic(topic) {
|
function selectTopic(topic) {
|
||||||
currentTopic = topic;
|
currentTopic = topic;
|
||||||
currentCenterIndex = null; // 切换 topic 时重置索引
|
direction = 'forward'; // 切换 topic 时重置方向
|
||||||
|
startIndex = null;
|
||||||
|
endIndex = null;
|
||||||
|
|
||||||
// 更新选中状态
|
// 更新选中状态
|
||||||
document.querySelectorAll('.topic-item').forEach(item => {
|
document.querySelectorAll('.topic-item').forEach(item => {
|
||||||
@@ -393,7 +398,7 @@ func handleIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 加载日志
|
// 加载日志
|
||||||
async function loadLogs(index) {
|
async function loadLogs() {
|
||||||
if (!currentTopic) return;
|
if (!currentTopic) return;
|
||||||
|
|
||||||
const backward = document.getElementById('backwardCount').value;
|
const backward = document.getElementById('backwardCount').value;
|
||||||
@@ -401,19 +406,18 @@ func handleIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 构建查询 URL
|
// 构建查询 URL
|
||||||
let url = '/api/query?topic=' + currentTopic +
|
let url = '/api/query?topic=' + currentTopic +
|
||||||
'&backward=' + backward + '&forward=' + forward;
|
'&backward=' + backward + '&forward=' + forward +
|
||||||
|
'&direction=' + direction;
|
||||||
|
|
||||||
// 如果指定了索引,添加到查询参数
|
if (direction === 'backward' && startIndex != null) {
|
||||||
if (index !== undefined && index !== null) {
|
url += '&index=' + startIndex;
|
||||||
url += '&index=' + index;
|
} else if (direction === 'forward' && endIndex != null) {
|
||||||
|
url += '&index=' + endIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
// 更新当前中心索引
|
|
||||||
currentCenterIndex = data.centerIndex;
|
|
||||||
|
|
||||||
const container = document.getElementById('logContainer');
|
const container = document.getElementById('logContainer');
|
||||||
|
|
||||||
if (data.records.length === 0) {
|
if (data.records.length === 0) {
|
||||||
@@ -444,35 +448,25 @@ func handleIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
'</div>';
|
'</div>';
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
|
if (data.records.length > 0) {
|
||||||
|
startIndex = data.records[0].index;
|
||||||
|
endIndex = data.records[data.records.length - 1].index;
|
||||||
|
} else {
|
||||||
|
startIndex = null;
|
||||||
|
endIndex = null;
|
||||||
|
}
|
||||||
|
|
||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function queryBackward() {
|
function queryBackward() {
|
||||||
if (currentCenterIndex === null || currentCenterIndex === undefined) {
|
direction = 'backward';
|
||||||
loadLogs();
|
loadLogs();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const backward = parseInt(document.getElementById('backwardCount').value);
|
|
||||||
const forward = parseInt(document.getElementById('forwardCount').value);
|
|
||||||
|
|
||||||
// 向前翻页:中心索引向前移动(backward + forward + 1)个位置
|
|
||||||
const newIndex = currentCenterIndex - (backward + forward + 1);
|
|
||||||
loadLogs(newIndex >= 0 ? newIndex : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function queryForward() {
|
function queryForward() {
|
||||||
if (currentCenterIndex === null || currentCenterIndex === undefined) {
|
direction = 'forward';
|
||||||
loadLogs();
|
loadLogs();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const backward = parseInt(document.getElementById('backwardCount').value);
|
|
||||||
const forward = parseInt(document.getElementById('forwardCount').value);
|
|
||||||
|
|
||||||
// 向后翻页:中心索引向后移动(backward + forward + 1)个位置
|
|
||||||
const newIndex = currentCenterIndex + (backward + forward + 1);
|
|
||||||
loadLogs(newIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatBytes(bytes) {
|
function formatBytes(bytes) {
|
||||||
@@ -483,6 +477,7 @@ func handleIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
loadTopics();
|
loadTopics();
|
||||||
|
|
||||||
// 只自动刷新统计信息,不刷新日志
|
// 只自动刷新统计信息,不刷新日志
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (currentTopic) {
|
if (currentTopic) {
|
||||||
@@ -530,6 +525,7 @@ func handleQuery(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 获取查询参数
|
// 获取查询参数
|
||||||
indexParam := r.URL.Query().Get("index")
|
indexParam := r.URL.Query().Get("index")
|
||||||
|
direction := r.URL.Query().Get("direction")
|
||||||
backward, _ := strconv.Atoi(r.URL.Query().Get("backward"))
|
backward, _ := strconv.Atoi(r.URL.Query().Get("backward"))
|
||||||
forward, _ := strconv.Atoi(r.URL.Query().Get("forward"))
|
forward, _ := strconv.Atoi(r.URL.Query().Get("forward"))
|
||||||
|
|
||||||
@@ -550,50 +546,55 @@ func handleQuery(w http.ResponseWriter, r *http.Request) {
|
|||||||
// 获取记录总数
|
// 获取记录总数
|
||||||
totalCount := processor.GetRecordCount()
|
totalCount := processor.GetRecordCount()
|
||||||
|
|
||||||
// 确定查询中心索引
|
|
||||||
var centerIndex int
|
|
||||||
if indexParam == "" {
|
|
||||||
// 如果没有指定索引,使用当前处理位置
|
|
||||||
centerIndex = seq.GetProcessingIndex(topic)
|
|
||||||
} else {
|
|
||||||
centerIndex, _ = strconv.Atoi(indexParam)
|
|
||||||
// 限制索引范围
|
|
||||||
if centerIndex < 0 {
|
|
||||||
centerIndex = 0
|
|
||||||
}
|
|
||||||
if centerIndex >= totalCount {
|
|
||||||
centerIndex = totalCount - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前处理索引和读取索引(用于状态判断)
|
// 获取当前处理索引和读取索引(用于状态判断)
|
||||||
startIdx := seq.GetProcessingIndex(topic)
|
startIdx := seq.GetProcessingIndex(topic)
|
||||||
endIdx := seq.GetReadIndex(topic)
|
endIdx := seq.GetReadIndex(topic)
|
||||||
|
|
||||||
// 合并查询结果:向后 + 当前 + 向前
|
// 执行查询
|
||||||
var results []*seqlog.RecordWithStatus
|
var results []*seqlog.RecordWithStatus
|
||||||
|
var startRecordIndex int
|
||||||
|
|
||||||
// 向后查询(查询更早的记录)
|
if direction == "backward" {
|
||||||
if backward > 0 && centerIndex > 0 {
|
// 向前翻页:查询更早的记录
|
||||||
backResults, err := processor.QueryNewest(centerIndex-1, backward)
|
var index int
|
||||||
if err == nil {
|
if indexParam == "" {
|
||||||
results = append(results, backResults...)
|
index = startIdx
|
||||||
}
|
} else {
|
||||||
|
index, _ = strconv.Atoi(indexParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前位置的记录
|
if index > 0 {
|
||||||
if centerIndex >= 0 && centerIndex < totalCount {
|
var queryErr error
|
||||||
currentResults, err := processor.QueryOldest(centerIndex, 1)
|
results, queryErr = processor.QueryNewest(index-1, backward)
|
||||||
if err == nil {
|
if queryErr != nil {
|
||||||
results = append(results, currentResults...)
|
http.Error(w, queryErr.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if len(results) > 0 {
|
||||||
|
// QueryNewest 返回的结果按索引递增排列
|
||||||
|
startRecordIndex = index - len(results)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 向后翻页:查询更新的记录
|
||||||
|
var index int
|
||||||
|
if indexParam == "" {
|
||||||
|
index = startIdx
|
||||||
|
} else {
|
||||||
|
index, _ = strconv.Atoi(indexParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 向前查询(查询更新的记录)
|
if index < totalCount {
|
||||||
if forward > 0 && centerIndex+1 < totalCount {
|
var queryErr error
|
||||||
forwardResults, err := processor.QueryOldest(centerIndex+1, forward)
|
results, queryErr = processor.QueryOldest(index, forward)
|
||||||
if err == nil {
|
if queryErr != nil {
|
||||||
results = append(results, forwardResults...)
|
http.Error(w, queryErr.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(results) > 0 {
|
||||||
|
// QueryOldest 返回的结果按索引递增排列
|
||||||
|
startRecordIndex = index
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,12 +604,6 @@ func handleQuery(w http.ResponseWriter, r *http.Request) {
|
|||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算每条记录的实际索引位置
|
|
||||||
startRecordIndex := centerIndex - backward
|
|
||||||
if startRecordIndex < 0 {
|
|
||||||
startRecordIndex = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
records := make([]Record, len(results))
|
records := make([]Record, len(results))
|
||||||
for i, r := range results {
|
for i, r := range results {
|
||||||
records[i] = Record{
|
records[i] = Record{
|
||||||
@@ -621,7 +616,6 @@ func handleQuery(w http.ResponseWriter, r *http.Request) {
|
|||||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
"records": records,
|
"records": records,
|
||||||
"total": len(records),
|
"total": len(records),
|
||||||
"centerIndex": centerIndex,
|
|
||||||
"totalCount": totalCount,
|
"totalCount": totalCount,
|
||||||
"processingIndex": startIdx,
|
"processingIndex": startIdx,
|
||||||
"readIndex": endIdx,
|
"readIndex": endIdx,
|
||||||
|
|||||||
Reference in New Issue
Block a user