fix
This commit is contained in:
@@ -27,6 +27,16 @@
|
|||||||
<div v-if="pair.assistantMsg" class="message assistant">
|
<div v-if="pair.assistantMsg" class="message assistant">
|
||||||
<div class="message-role">AI</div>
|
<div class="message-role">AI</div>
|
||||||
<div class="message-content" v-html="renderContent(pair.assistantMsg)"></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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -113,11 +123,12 @@ import {
|
|||||||
stopPrompt,
|
stopPrompt,
|
||||||
currentTaskId,
|
currentTaskId,
|
||||||
removeMessagePair,
|
removeMessagePair,
|
||||||
|
markMessageSubmitted,
|
||||||
} from "../../store/prompt"
|
} from "../../store/prompt"
|
||||||
import { Prompt } from "../../api"
|
import { Prompt, Submission } from "../../api"
|
||||||
import { renderMarkdown } from "../../utils/markdown"
|
import { renderMarkdown } from "../../utils/markdown"
|
||||||
|
|
||||||
const emit = defineEmits<{ deleted: [] }>()
|
const emit = defineEmits<{ deleted: []; submitted: [] }>()
|
||||||
|
|
||||||
const input = ref("")
|
const input = ref("")
|
||||||
const messagesRef = ref<HTMLElement>()
|
const messagesRef = ref<HTMLElement>()
|
||||||
@@ -131,10 +142,18 @@ const modelOptions = [
|
|||||||
const selectedModel = useStorage("prompt-model", "deepseek-v4-flash")
|
const selectedModel = useStorage("prompt-model", "deepseek-v4-flash")
|
||||||
|
|
||||||
// Group messages into user+assistant pairs
|
// Group messages into user+assistant pairs
|
||||||
|
const submittingId = ref<number | null>(null)
|
||||||
|
|
||||||
const pairs = computed(() => {
|
const pairs = computed(() => {
|
||||||
const result: Array<{
|
const result: Array<{
|
||||||
userMsg: { role: string; content: string; id?: number }
|
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
|
index: number
|
||||||
}> = []
|
}> = []
|
||||||
const msgs = messages.value
|
const msgs = messages.value
|
||||||
@@ -151,6 +170,37 @@ const pairs = computed(() => {
|
|||||||
return result
|
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) {
|
async function deletePair(assistantMsgId: number) {
|
||||||
try {
|
try {
|
||||||
await Prompt.deleteMessagePair(assistantMsgId)
|
await Prompt.deleteMessagePair(assistantMsgId)
|
||||||
@@ -240,6 +290,10 @@ watch([() => messages.value.length, streamingContent], () => {
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-actions {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0%,
|
0%,
|
||||||
|
|||||||
@@ -64,7 +64,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
<n-tab-pane name="chat" tab="AI 对话" display-directive="show">
|
<n-tab-pane name="chat" tab="AI 对话" display-directive="show">
|
||||||
<PromptPanel @deleted="historyRefreshKey++" />
|
<PromptPanel
|
||||||
|
@deleted="historyRefreshKey++"
|
||||||
|
@submitted="historyRefreshKey++"
|
||||||
|
/>
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
<n-tab-pane name="external" tab="手动提交" display-directive="show">
|
<n-tab-pane name="external" tab="手动提交" display-directive="show">
|
||||||
<ExternalAIPanel :task-id="taskId" @submitted="historyRefreshKey++" />
|
<ExternalAIPanel :task-id="taskId" @submitted="historyRefreshKey++" />
|
||||||
@@ -158,6 +161,7 @@ import {
|
|||||||
streaming,
|
streaming,
|
||||||
setOnCodeComplete,
|
setOnCodeComplete,
|
||||||
removeMessagePair,
|
removeMessagePair,
|
||||||
|
markMessageSubmitted,
|
||||||
} from "../store/prompt"
|
} from "../store/prompt"
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -246,6 +250,7 @@ async function loadChallenge() {
|
|||||||
},
|
},
|
||||||
messageId,
|
messageId,
|
||||||
)
|
)
|
||||||
|
markMessageSubmitted(messageId)
|
||||||
historyRefreshKey.value++
|
historyRefreshKey.value++
|
||||||
message.success("已自动提交本次对话生成的代码")
|
message.success("已自动提交本次对话生成的代码")
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export interface PromptMessage {
|
|||||||
content: string
|
content: string
|
||||||
id?: number // assistant message backend pk (for deletion)
|
id?: number // assistant message backend pk (for deletion)
|
||||||
code?: { html: string | null; css: string | null; js: string | null }
|
code?: { html: string | null; css: string | null; js: string | null }
|
||||||
|
submitted?: boolean // whether this assistant message's code has been submitted
|
||||||
created?: string
|
created?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ export function connectPrompt(taskId: number) {
|
|||||||
content: streamingContent.value,
|
content: streamingContent.value,
|
||||||
id: data.message_id,
|
id: data.message_id,
|
||||||
code: data.code,
|
code: data.code,
|
||||||
|
submitted: false,
|
||||||
})
|
})
|
||||||
streamingContent.value = ""
|
streamingContent.value = ""
|
||||||
if (data.code) {
|
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) {
|
export function removeMessagePair(assistantMsgId: number) {
|
||||||
const idx = messages.value.findIndex((m) => m.id === assistantMsgId)
|
const idx = messages.value.findIndex((m) => m.id === assistantMsgId)
|
||||||
if (idx >= 1) {
|
if (idx >= 1) {
|
||||||
|
|||||||
Reference in New Issue
Block a user