fix
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-11 21:08:35 -06:00
parent 3102e1178a
commit c12c77ac7e
3 changed files with 70 additions and 4 deletions

View File

@@ -27,6 +27,16 @@
<div v-if="pair.assistantMsg" class="message assistant">
<div class="message-role">AI</div>
<div class="message-content" v-html="renderContent(pair.assistantMsg)"></div>
<div v-if="hasCode(pair.assistantMsg)" class="message-actions">
<n-button
size="tiny"
:disabled="pair.assistantMsg.submitted"
:loading="submittingId === pair.assistantMsg.id"
@click="submitVersion(pair.assistantMsg)"
>
{{ pair.assistantMsg.submitted ? "已提交" : "提交此版本" }}
</n-button>
</div>
</div>
</div>
@@ -113,11 +123,12 @@ import {
stopPrompt,
currentTaskId,
removeMessagePair,
markMessageSubmitted,
} from "../../store/prompt"
import { Prompt } from "../../api"
import { Prompt, Submission } from "../../api"
import { renderMarkdown } from "../../utils/markdown"
const emit = defineEmits<{ deleted: [] }>()
const emit = defineEmits<{ deleted: []; submitted: [] }>()
const input = ref("")
const messagesRef = ref<HTMLElement>()
@@ -131,10 +142,18 @@ const modelOptions = [
const selectedModel = useStorage("prompt-model", "deepseek-v4-flash")
// Group messages into user+assistant pairs
const submittingId = ref<number | null>(null)
const pairs = computed(() => {
const result: Array<{
userMsg: { role: string; content: string; id?: number }
assistantMsg: { role: string; content: string; id?: number; code?: any } | null
assistantMsg: {
role: string
content: string
id?: number
code?: any
submitted?: boolean
} | null
index: number
}> = []
const msgs = messages.value
@@ -151,6 +170,37 @@ const pairs = computed(() => {
return result
})
function hasCode(msg: { code?: any } | null): boolean {
if (!msg?.code) return false
return !!(msg.code.html || msg.code.css || msg.code.js)
}
async function submitVersion(msg: {
id?: number
code?: { html: string | null; css: string | null; js: string | null }
}) {
if (!msg.id || !msg.code || !currentTaskId.value) return
submittingId.value = msg.id
try {
await Submission.create(
currentTaskId.value,
{
html: msg.code.html ?? "",
css: msg.code.css ?? "",
js: msg.code.js ?? "",
},
msg.id,
)
markMessageSubmitted(msg.id)
naiveMessage.success("提交成功")
emit("submitted")
} catch {
naiveMessage.error("提交失败,请重试")
} finally {
submittingId.value = null
}
}
async function deletePair(assistantMsgId: number) {
try {
await Prompt.deleteMessagePair(assistantMsgId)
@@ -240,6 +290,10 @@ watch([() => messages.value.length, streamingContent], () => {
font-size: 13px;
}
.message-actions {
margin-top: 6px;
}
@keyframes pulse {
0%,

View File

@@ -64,7 +64,10 @@
</div>
</n-tab-pane>
<n-tab-pane name="chat" tab="AI 对话" display-directive="show">
<PromptPanel @deleted="historyRefreshKey++" />
<PromptPanel
@deleted="historyRefreshKey++"
@submitted="historyRefreshKey++"
/>
</n-tab-pane>
<n-tab-pane name="external" tab="手动提交" display-directive="show">
<ExternalAIPanel :task-id="taskId" @submitted="historyRefreshKey++" />
@@ -158,6 +161,7 @@ import {
streaming,
setOnCodeComplete,
removeMessagePair,
markMessageSubmitted,
} from "../store/prompt"
const route = useRoute()
@@ -246,6 +250,7 @@ async function loadChallenge() {
},
messageId,
)
markMessageSubmitted(messageId)
historyRefreshKey.value++
message.success("已自动提交本次对话生成的代码")
} catch {

View File

@@ -7,6 +7,7 @@ export interface PromptMessage {
content: string
id?: number // assistant message backend pk (for deletion)
code?: { html: string | null; css: string | null; js: string | null }
submitted?: boolean // whether this assistant message's code has been submitted
created?: string
}
@@ -66,6 +67,7 @@ export function connectPrompt(taskId: number) {
content: streamingContent.value,
id: data.message_id,
code: data.code,
submitted: false,
})
streamingContent.value = ""
if (data.code) {
@@ -124,6 +126,11 @@ export function stopPrompt() {
}
}
export function markMessageSubmitted(assistantMsgId: number) {
const msg = messages.value.find((m) => m.id === assistantMsgId)
if (msg) msg.submitted = true
}
export function removeMessagePair(assistantMsgId: number) {
const idx = messages.value.findIndex((m) => m.id === assistantMsgId)
if (idx >= 1) {