作品管理与Phaser4客户端发布闭环
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m21s
Project CI / Backend tests (pull_request) Failing after 16s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m18s
Project CI / Frontend tests (pull_request) Successful in 2m8s
Project CI / Repository checks (pull_request) Failing after 16s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m56s
Project CI / Native shell tests (pull_request) Successful in 5m47s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled

补齐 Phaser4 客户端发布前校验、阶段进度与原生幂等账本

增加 Web 作者私有作品管理、资料编辑、版本历史与软删除

增加后台作品筛选、游标分页与删除治理

同步 SpacetimeDB schema、bindings、DTO、文档与定向测试
This commit is contained in:
2026-10-01 16:30:40 +08:00
parent 1f055e9902
commit a2b70d92b8
80 changed files with 5836 additions and 676 deletions
+50 -10
View File
@@ -1027,6 +1027,7 @@ function route(pathname, method, url) {
publicationRevision: versions[0]?.versionNumber ?? 0,
createdAt: iso(60 * 24 * 20),
updatedAt: iso(60 * 3),
deletedAt: null,
versions,
});
const version = (versionId, versionNumber, status, bytes) => ({
@@ -1041,17 +1042,56 @@ function route(pathname, method, url) {
reviewReason: null,
entryUrl: `https://games.example.com/${versionId}/index.html`,
});
const allGames = [
game('game_1001', '陶泥小世界', '阿陶', 'published', 345, [
version('ver_1001_7', 7, 'published', 18_400_000),
version('ver_1001_6', 6, 'published', 17_900_000),
]),
game('game_1002', '纸片拼图计划', '小满', 'suspended', 96, [
version('ver_1002_3', 3, 'suspended', 5_120_004),
]),
game('game_1003', '三消工坊', '老周', 'unpublished', 12, []),
{
...game('game_1004', '已删除的试作', '阿陶', 'unpublished', 4, []),
status: 'deleted',
deletedAt: iso(60 * 2),
},
];
const limit = Math.min(
Math.max(Number(url.searchParams.get('limit') ?? 50) || 50, 1),
200,
);
const keyword = (url.searchParams.get('keyword') ?? '')
.trim()
.toLowerCase();
const owner = (url.searchParams.get('owner') ?? '').trim();
const status = (url.searchParams.get('status') ?? '').trim();
const offset = Number(url.searchParams.get('cursor') ?? 0) || 0;
// 状态/关键词/作者过滤与游标语义跟服务端保持一致:默认排除已删除作品。
const filtered = allGames.filter((entry) => {
if (status === 'deleted') {
if (entry.status !== 'deleted') return false;
} else if (status) {
if (entry.status !== status || entry.deletedAt) return false;
} else if (entry.deletedAt) {
return false;
}
if (owner && entry.author.id !== owner) return false;
if (
keyword &&
!entry.title.toLowerCase().includes(keyword) &&
!entry.gameId.toLowerCase().includes(keyword) &&
!entry.author.id.toLowerCase().includes(keyword)
) {
return false;
}
return true;
});
const page = filtered.slice(offset, offset + limit);
const nextOffset = offset + page.length;
return {
games: [
game('game_1001', '陶泥小世界', '阿陶', 'published', 345, [
version('ver_1001_7', 7, 'published', 18_400_000),
version('ver_1001_6', 6, 'published', 17_900_000),
]),
game('game_1002', '纸片拼图计划', '小满', 'suspended', 96, [
version('ver_1002_3', 3, 'suspended', 5_120_004),
]),
game('game_1003', '三消工坊', '老周', 'unpublished', 12, []),
],
games: page,
nextCursor: nextOffset < filtered.length ? String(nextOffset) : null,
};
}
if (pathname === '/admin/api/editor-assets') {
@@ -41,6 +41,10 @@ const PAIRS = [
'GameDistributionCreateVersionRequest',
'GameDistributionCreateVersionRequest',
],
[
'GameDistributionUpdateGameMetadataRequest',
'GameDistributionUpdateGameMetadataRequest',
],
['GameDistributionPrivateVersion', 'GameDistributionPrivateVersion'],
];