feat: 重新设计作品展,点开能看大图、获奖和提示词

- 点作品不再跳到只有网页的全屏页,而是弹出大图:作者、题目、所获奖项、得分、浏览次数,
  有提示词的能看“是怎么问出来的”(作品展接口),← → 在同一奖项里切换
- 卡片缩略图改用 buildPreviewDocument,题目素材能加载;未评分的不显示星标
- 顶部加奖项跳转;标题和导航统一叫“作品展”
- 作品展接口返回 task_type(拼素材地址要用)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-27 11:59:56 +08:00
1 parent 3fb23dc3f3
commit 4c9617caf1
4 files changed
+391 -95

No files matched your search

+7 -3
View File
@@ -20,7 +20,7 @@ const ORDER_BY: Record<string, string> = {
const HAS_CHAIN = `EXISTS (SELECT 1 FROM prompt_message m WHERE m.submission_id = s.id) AS has_prompt_chain`
const ITEM_SELECT = `SELECT sa.id, sa.submission_id, sa.sort_order, sa.awarded_at, sa.is_stale,
u.username, t.title AS task_title, t.display AS task_display,
u.username, t.title AS task_title, t.display AS task_display, t.task_type,
s.score, s.view_count, s.html, s.css, s.js, ${HAS_CHAIN}
FROM submission_submissionaward sa
JOIN submission_submission s ON s.id = sa.submission_id
@@ -34,6 +34,7 @@ function itemManageOut(r: any) {
username: r.username,
task_title: r.task_title,
task_display: r.task_display,
task_type: r.task_type,
score: r.score,
view_count: r.view_count,
sort_order: r.sort_order,
@@ -104,6 +105,7 @@ router.get("/", (c) => {
username: r.username,
task_title: r.task_title,
task_display: r.task_display,
task_type: r.task_type,
score: r.score,
view_count: r.view_count,
html: r.html,
@@ -167,7 +169,7 @@ router.get("/manage/submissions/:submission_id", (c) => {
const id = uuidParam(c, "submission_id")
const s = orNotFound(
get(
`SELECT s.id, u.username, t.title AS task_title, t.display AS task_display,
`SELECT s.id, u.username, t.title AS task_title, t.display AS task_display, t.task_type,
s.score, s.view_count, ${HAS_CHAIN}
FROM submission_submission s
JOIN account_user u ON u.id = s.user_id
@@ -181,6 +183,7 @@ router.get("/manage/submissions/:submission_id", (c) => {
username: s.username,
task_title: s.task_title,
task_display: s.task_display,
task_type: s.task_type,
score: s.score,
view_count: s.view_count,
has_prompt_chain: bool(s.has_prompt_chain),
@@ -301,7 +304,7 @@ router.get("/:submission_id", (c) => {
assertAwarded(id)
const s = orNotFound(
get(
`SELECT s.id, u.username, t.title AS task_title, t.display AS task_display,
`SELECT s.id, u.username, t.title AS task_title, t.display AS task_display, t.task_type,
s.score, s.view_count, s.html, s.css, s.js, ${HAS_CHAIN}
FROM submission_submission s
JOIN account_user u ON u.id = s.user_id
@@ -320,6 +323,7 @@ router.get("/:submission_id", (c) => {
username: s.username,
task_title: s.task_title,
task_display: s.task_display,
task_type: s.task_type,
score: s.score,
view_count: s.view_count,
html: s.html,
+1 -1
View File
@@ -415,7 +415,7 @@ describe("作品展", () => {
const author1 = await client("author")
expect((await author1("GET", "/api/submission/showcase/")).json).toHaveLength(1)
expect((await author1("GET", `/api/submission/showcase/${uuid(sub)}/`)).json.awards).toEqual(["最佳"])
expect((await author1("GET", `/api/submission/showcase/${uuid(sub)}/`)).json).toMatchObject({ awards: ["最佳"], task_type: "challenge" })
await adm("PUT", `/api/submission/showcase/manage/awards/${award.id}`, { name: "最佳", is_active: false })
expect((await author1("GET", "/api/submission/showcase/")).json).toEqual([])