diff --git a/src/api.ts b/src/api.ts index 662fbdb..e861974 100644 --- a/src/api.ts +++ b/src/api.ts @@ -209,6 +209,11 @@ export const Submission = { return res.data }, + async getPromptChain(id: string): Promise { + const res = await http.get(`/submission/${id}/prompt-chain`) + return res.data + }, + async delete(id: string) { const res = await http.delete("/submission/" + id) return res.data diff --git a/src/components/submissions/ChainModal.vue b/src/components/submissions/ChainModal.vue index 4ec4b4a..3a07298 100644 --- a/src/components/submissions/ChainModal.vue +++ b/src/components/submissions/ChainModal.vue @@ -203,14 +203,13 @@ import { computed, ref, watch } from "vue" import { NPopconfirm, NButton } from "naive-ui" import { Icon } from "@iconify/vue" -import { Prompt } from "../../api" -import type { PromptMessage } from "../../utils/type" +import { Prompt, Submission } from "../../api" +import type { PromptRound } from "../../utils/type" import { user, roleSuper } from "../../store/user" const props = defineProps<{ show: boolean - userId: number - taskId: number + submissionId: string username?: string }>() @@ -219,49 +218,12 @@ const canDelete = computed(() => roleSuper.value || (!!props.username && props.u defineEmits<{ "update:show": [value: boolean] }>() const loading = ref(false) -const messages = ref([]) const selectedRound = ref(0) - -const rounds = computed(() => { - const result: { - question: string - source: string | null - prompt_level: number | null - assistantMsgId: number | null - html: string | null - css: string | null - js: string | null - }[] = [] - for (const [i, msg] of messages.value.entries()) { - if (msg.role !== "user") continue - let html: string | null = null, - css: string | null = null, - js: string | null = null, - assistantMsgId: number | null = null - for (const reply of messages.value.slice(i + 1)) { - if (reply.role === "user") break - if (reply.role === "assistant") { - assistantMsgId = reply.id - if (reply.code_html) { - html = reply.code_html - css = reply.code_css - js = reply.code_js - } - break - } - } - result.push({ - question: msg.content, - source: msg.source ?? null, - prompt_level: msg.prompt_level ?? null, - assistantMsgId, - html, - css, - js, - }) - } - return result -}) +type ChainRound = Omit & { + source: string | null + assistantMsgId: number | null +} +const rounds = ref([]) async function deleteRound(index: number) { const round = rounds.value[index] @@ -291,24 +253,28 @@ const selectedPageHtml = computed(() => { }) async function loadMessages() { - if (!props.userId || !props.taskId) return + if (!props.submissionId) return loading.value = true - messages.value = [] + rounds.value = [] selectedRound.value = 0 try { - messages.value = await Prompt.getMessagesByUserTask( - props.taskId, - props.userId, - ) + const data = await Submission.getPromptChain(props.submissionId) + rounds.value = data.map((round) => ({ + ...round, + source: round.source ?? null, + assistantMsgId: round.assistant_msg_id ?? null, + })) const last = rounds.value.length - 1 if (last >= 0) selectedRound.value = last + } catch { + rounds.value = [] } finally { loading.value = false } } watch( - () => [props.show, props.userId, props.taskId] as const, + () => [props.show, props.submissionId] as const, ([visible]) => { if (visible) loadMessages() }, diff --git a/src/components/submissions/ExpandedSubTable.vue b/src/components/submissions/ExpandedSubTable.vue index 7a37a04..3d7cba6 100644 --- a/src/components/submissions/ExpandedSubTable.vue +++ b/src/components/submissions/ExpandedSubTable.vue @@ -36,7 +36,7 @@ const props = defineProps<{ const emit = defineEmits<{ select: [id: string] delete: [row: SubmissionOut, parentId: string] - "show-chain": [userId: number, taskId: number, username: string] + "show-chain": [submissionId: string, username: string] }>() const isChallenge = computed(() => props.row.task_type === TASK_TYPE.Challenge) @@ -91,7 +91,7 @@ const subColumns = computed((): DataTableColumn[] => [ type: "primary", onClick: (e: Event) => { e.stopPropagation() - emit("show-chain", r.userid, r.task_id, r.username) + emit("show-chain", r.id, r.username) }, }, () => "查看", diff --git a/src/pages/Submissions.vue b/src/pages/Submissions.vue index b77dac6..8d5524a 100644 --- a/src/pages/Submissions.vue +++ b/src/pages/Submissions.vue @@ -105,8 +105,7 @@ @@ -159,8 +158,7 @@ const js = computed(() => submission.value.js) // Modal 状态 const codeModal = ref(false) const chainModal = ref(false) -const chainUserId = ref(0) -const chainTaskId = ref(0) +const chainSubmissionId = ref("") const chainUsername = ref("") // 展开行 @@ -203,9 +201,8 @@ async function clearAllFlags() { query.flag = null } -function showChain(userId: number, taskId: number, username: string) { - chainUserId.value = userId - chainTaskId.value = taskId +function showChain(submissionId: string, username: string) { + chainSubmissionId.value = submissionId chainUsername.value = username chainModal.value = true } @@ -222,7 +219,8 @@ const columns: DataTableColumn[] = [ loading: expandedLoading.has(row.id), onSelect: (id) => getSubmissionByID(id), onDelete: (r, parentId) => handleDelete(r, parentId), - "onShow-chain": (userId, taskId, username) => showChain(userId, taskId, username), + "onShow-chain": (submissionId, username) => + showChain(submissionId, username), }), }, { diff --git a/src/router.ts b/src/router.ts index 2b0d588..40c83a8 100644 --- a/src/router.ts +++ b/src/router.ts @@ -68,12 +68,10 @@ export const router = createRouter({ routes, }) -router.beforeEach((to, from, next) => { +router.beforeEach((to) => { const isLoggedIn = localStorage.getItem(STORAGE_KEY.LOGIN) === "true" if (to.meta.auth && !isLoggedIn) { loginModal.value = true - next(false) - } else { - next() + return false } }) diff --git a/src/utils/type.ts b/src/utils/type.ts index eab317f..3152fea 100644 --- a/src/utils/type.ts +++ b/src/utils/type.ts @@ -200,6 +200,7 @@ export interface PromptRound { question: string source: string prompt_level: number | null + assistant_msg_id?: number | null html: string | null css: string | null js: string | null