check if stable
Some checks failed
Deploy / deploy (build, debian, 22) (push) Has been cancelled
Deploy / deploy (build:staging, school, 8822) (push) Has been cancelled

This commit is contained in:
2026-06-07 05:05:52 -06:00
parent 1566a4e275
commit 4b32330b60
3 changed files with 70 additions and 12 deletions

View File

@@ -421,6 +421,13 @@ export const Showcase = {
return res.data return res.data
}, },
async refreshAwardItem(itemId: number): Promise<AwardItemManageOut> {
const res = await http.put(
`/submission/showcase/manage/items/${itemId}/refresh`,
)
return res.data
},
async getDetail(submissionId: string): Promise<ShowcaseDetail> { async getDetail(submissionId: string): Promise<ShowcaseDetail> {
const res = await http.get(`/submission/showcase/${submissionId}/`) const res = await http.get(`/submission/showcase/${submissionId}/`)
return res.data return res.data

View File

@@ -242,6 +242,7 @@
import { computed, h, onMounted, reactive, ref } from "vue" import { computed, h, onMounted, reactive, ref } from "vue"
import { import {
NButton, NButton,
NButtonGroup,
NInputNumber, NInputNumber,
NTag, NTag,
useMessage, useMessage,
@@ -268,6 +269,7 @@ const itemsLoading = ref(false)
const savingAward = ref(false) const savingAward = ref(false)
const deletingAward = ref(false) const deletingAward = ref(false)
const updatingItemIds = ref(new Set<number>()) const updatingItemIds = ref(new Set<number>())
const refreshingItemIds = ref(new Set<number>())
const addWorkModalVisible = ref(false) const addWorkModalVisible = ref(false)
const lookupSubmissionId = ref("") const lookupSubmissionId = ref("")
const lookupLoading = ref(false) const lookupLoading = ref(false)
@@ -347,22 +349,49 @@ const itemColumns: DataTableColumn<AwardItemManageOut>[] = [
{ default: () => (row.has_prompt_chain ? "" : "") }, { default: () => (row.has_prompt_chain ? "" : "") },
), ),
}, },
{
title: "状态",
key: "is_stale",
width: 96,
render: (row) =>
row.is_stale
? h(NTag, { size: "small", type: "warning" }, { default: () => "有新提交" })
: null,
},
{ {
title: "", title: "",
key: "actions", key: "actions",
width: 54, width: 100,
render: (row) => render: (row) =>
h( h(NButtonGroup, { size: "small" }, {
NButton, default: () => [
{ row.is_stale
size: "small", ? h(
tertiary: true, NButton,
type: "error", {
title: "移除", size: "small",
onClick: () => removeAwardItem(row), secondary: true,
}, type: "warning",
{ icon: () => h(Icon, { icon: "lucide:trash-2", width: 15 }) }, title: "切换到最新提交",
), loading: refreshingItemIds.value.has(row.id),
onClick: () => refreshAwardItem(row),
},
{ icon: () => h(Icon, { icon: "lucide:refresh-cw", width: 14 }) },
)
: null,
h(
NButton,
{
size: "small",
tertiary: true,
type: "error",
title: "移除",
onClick: () => removeAwardItem(row),
},
{ icon: () => h(Icon, { icon: "lucide:trash-2", width: 15 }) },
),
],
}),
}, },
] ]
@@ -470,6 +499,27 @@ function setUpdatingItem(id: number, loading: boolean) {
updatingItemIds.value = next updatingItemIds.value = next
} }
function setRefreshingItem(id: number, loading: boolean) {
const next = new Set(refreshingItemIds.value)
if (loading) next.add(id)
else next.delete(id)
refreshingItemIds.value = next
}
async function refreshAwardItem(row: AwardItemManageOut) {
setRefreshingItem(row.id, true)
try {
const updated = await Showcase.refreshAwardItem(row.id)
const idx = awardItems.value.findIndex((item) => item.id === row.id)
if (idx !== -1) awardItems.value[idx] = updated
message.success("已切换到最新提交")
} catch (err: any) {
message.error(err.response?.data?.detail ?? "切换失败")
} finally {
setRefreshingItem(row.id, false)
}
}
async function updateItemOrder(row: AwardItemManageOut, sortOrder: number) { async function updateItemOrder(row: AwardItemManageOut, sortOrder: number) {
if (row.sort_order === sortOrder) return if (row.sort_order === sortOrder) return
row.sort_order = sortOrder row.sort_order = sortOrder

View File

@@ -293,6 +293,7 @@ export interface AwardItemManageOut {
sort_order: number sort_order: number
awarded_at: string awarded_at: string
has_prompt_chain: boolean has_prompt_chain: boolean
is_stale: boolean
} }
export interface ShowcaseDetail { export interface ShowcaseDetail {