fix: 配置版本列表按 created_at 倒序展示

This commit is contained in:
ryan
2026-06-20 21:32:18 +08:00
parent 6fc39d9e80
commit b04a358e5e
5 changed files with 52 additions and 7 deletions
+2
View File
@@ -18,6 +18,8 @@ sidebar: false
### 修复 ### 修复
- 配置版本列表按 `created_at` 倒序展示,最新发布版本固定显示在列表顶部。
- 修复 WAF 规则组 PoW 策略发布后边缘不生效:统一 WAF 绑定站点名与 OpenResty 路由 `site_name` 解析逻辑,并为所有已启用网站生成 `site_rule_groups` 条目(含仅依赖全局规则组的站点)。 - 修复 WAF 规则组 PoW 策略发布后边缘不生效:统一 WAF 绑定站点名与 OpenResty 路由 `site_name` 解析逻辑,并为所有已启用网站生成 `site_rule_groups` 条目(含仅依赖全局规则组的站点)。
- 收敛子代理站点标识双轨逻辑:新增 `routeidentity` 统一包,`proxy_route`、`config_version`、`uptimekuma`、`flared` 与 OpenResty 渲染共用 `ResolveSiteName` / `DecodeDomains`;移除废弃 `RenderPoWConfig`;PoW Lua 与 WAF 一致仅依赖 `$openflare_waf_site`。 - 收敛子代理站点标识双轨逻辑:新增 `routeidentity` 统一包,`proxy_route`、`config_version`、`uptimekuma`、`flared` 与 OpenResty 渲染共用 `ResolveSiteName` / `DecodeDomains`;移除废弃 `RenderPoWConfig`;PoW Lua 与 WAF 一致仅依赖 `$openflare_waf_site`。
+11 -2
View File
@@ -80,6 +80,15 @@ export default function ConfigVersionsPage() {
[preview, diff], [preview, diff],
) )
const sortedVersions = useMemo(
() =>
[...versions].sort(
(left, right) =>
new Date(right.created_at).getTime() - new Date(left.created_at).getTime(),
),
[versions],
)
const fetchVersions = useCallback(async () => { const fetchVersions = useCallback(async () => {
setLoading(true) setLoading(true)
setError(null) setError(null)
@@ -240,7 +249,7 @@ export default function ConfigVersionsPage() {
<div className="border border-dashed shadow-none rounded-lg overflow-hidden bg-background"> <div className="border border-dashed shadow-none rounded-lg overflow-hidden bg-background">
{loading ? ( {loading ? (
<LoadingStateWithBorder /> <LoadingStateWithBorder />
) : versions.length === 0 ? ( ) : sortedVersions.length === 0 ? (
<EmptyStateWithBorder <EmptyStateWithBorder
title="暂无历史版本" title="暂无历史版本"
description="当前还没有可查看的发布记录,请先触发一次配置发布。" description="当前还没有可查看的发布记录,请先触发一次配置发布。"
@@ -258,7 +267,7 @@ export default function ConfigVersionsPage() {
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{versions.map((version) => ( {sortedVersions.map((version) => (
<TableRow <TableRow
key={version.id} key={version.id}
className="border-dashed hover:bg-muted/10 transition-colors" className="border-dashed hover:bg-muted/10 transition-colors"
@@ -7,6 +7,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"testing" "testing"
"time"
"github.com/Rain-kl/Wavelet/internal/apps/openflare/waf" "github.com/Rain-kl/Wavelet/internal/apps/openflare/waf"
"github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/db"
@@ -38,6 +39,40 @@ func setupConfigVersionTestDB(t *testing.T) func() {
} }
} }
func TestListConfigVersionsOrdersByCreatedAtDesc(t *testing.T) {
cleanup := setupConfigVersionTestDB(t)
defer cleanup()
ctx := context.Background()
conn := db.DB(ctx)
require.NotNil(t, conn)
newer := &model.ConfigVersion{
Version: "20260102-001",
SnapshotJSON: "{}",
RenderedConfig: "route {}",
Checksum: "checksum-newer",
CreatedBy: "tester",
CreatedAt: time.Date(2026, 1, 2, 12, 0, 0, 0, time.UTC),
}
older := &model.ConfigVersion{
Version: "20260101-001",
SnapshotJSON: "{}",
RenderedConfig: "route {}",
Checksum: "checksum-older",
CreatedBy: "tester",
CreatedAt: time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC),
}
require.NoError(t, conn.Create(newer).Error)
require.NoError(t, conn.Create(older).Error)
require.Greater(t, older.ID, newer.ID)
versions, err := ListConfigVersions(ctx)
require.NoError(t, err)
require.Len(t, versions, 2)
assert.Equal(t, newer.Version, versions[0].Version)
assert.Equal(t, older.Version, versions[1].Version)
}
func TestPublishConfigVersionCreatesVersion(t *testing.T) { func TestPublishConfigVersionCreatesVersion(t *testing.T) {
cleanup := setupConfigVersionTestDB(t) cleanup := setupConfigVersionTestDB(t)
defer cleanup() defer cleanup()
@@ -11,7 +11,6 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func handleLogicError(c *gin.Context, err error) bool { func handleLogicError(c *gin.Context, err error) bool {
if err == nil { if err == nil {
return false return false
@@ -21,7 +20,7 @@ func handleLogicError(c *gin.Context, err error) bool {
// ListConfigVersionsHandler lists config versions. // ListConfigVersionsHandler lists config versions.
// @Summary 获取配置版本列表 // @Summary 获取配置版本列表
// @Description 返回所有已发布的 OpenResty 配置版本摘要,需要管理员权限 // @Description 返回所有已发布的 OpenResty 配置版本摘要,按创建时间倒序排列,需要管理员权限
// @Tags openflare-config-version // @Tags openflare-config-version
// @Produce json // @Produce json
// @Security SessionCookie // @Security SessionCookie
+2 -2
View File
@@ -41,7 +41,7 @@ func (ConfigVersion) TableName() string {
return "of_config_versions" return "of_config_versions"
} }
// ListConfigVersionSummaries returns config version summaries ordered by id desc. // ListConfigVersionSummaries returns config version summaries ordered by created_at desc.
func ListConfigVersionSummaries(ctx context.Context) ([]*ConfigVersionSummary, error) { func ListConfigVersionSummaries(ctx context.Context) ([]*ConfigVersionSummary, error) {
conn := db.DB(ctx) conn := db.DB(ctx)
if conn == nil { if conn == nil {
@@ -50,7 +50,7 @@ func ListConfigVersionSummaries(ctx context.Context) ([]*ConfigVersionSummary, e
var versions []*ConfigVersionSummary var versions []*ConfigVersionSummary
err := conn.Model(&ConfigVersion{}). err := conn.Model(&ConfigVersion{}).
Select("id", "version", "checksum", "is_active", "created_by", "created_at"). Select("id", "version", "checksum", "is_active", "created_by", "created_at").
Order("id desc"). Order("created_at desc, id desc").
Find(&versions).Error Find(&versions).Error
return versions, err return versions, err
} }