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-03-18 19:50:55 +08:00
parent 83cd62a110
commit 88d6ffaf53
15 changed files with 762 additions and 189 deletions

View File

@@ -7,10 +7,18 @@
@update:show="$emit('update:show', $event)"
>
<n-spin :show="loading">
<n-empty v-if="!loading && rounds.length === 0" description="暂无对话记录" />
<n-empty
v-if="!loading && rounds.length === 0"
description="暂无对话记录"
/>
<div
v-else
style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px; height: 75vh"
style="
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
height: 75vh;
"
>
<div
style="
@@ -25,26 +33,46 @@
<div
v-for="(round, index) in rounds"
:key="index"
style="display: flex; gap: 10px; align-items: flex-start; cursor: pointer"
style="
display: flex;
gap: 10px;
align-items: flex-start;
cursor: pointer;
"
@click="selectedRound = index"
>
<div
:style="{
flexShrink: 0, width: '22px', height: '22px', borderRadius: '50%',
flexShrink: 0,
width: '22px',
height: '22px',
borderRadius: '50%',
background: selectedRound === index ? '#2080f0' : '#c2d5fb',
color: '#fff', fontSize: '12px', fontWeight: 'bold',
display: 'flex', alignItems: 'center', justifyContent: 'center',
marginTop: '2px', transition: 'background 0.2s',
color: '#fff',
fontSize: '12px',
fontWeight: 'bold',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginTop: '2px',
transition: 'background 0.2s',
}"
>
{{ index + 1 }}
</div>
<div
:style="{
flex: 1, padding: '10px 14px', borderRadius: '8px',
flex: 1,
padding: '10px 14px',
borderRadius: '8px',
background: selectedRound === index ? '#e8f0fe' : '#f5f5f5',
border: selectedRound === index ? '1px solid #2080f0' : '1px solid #e0e0e0',
fontSize: '13px', lineHeight: '1.6', transition: 'all 0.2s',
border:
selectedRound === index
? '1px solid #2080f0'
: '1px solid #e0e0e0',
fontSize: '13px',
lineHeight: '1.6',
transition: 'all 0.2s',
}"
>
{{ round.question }}
@@ -60,7 +88,12 @@
:srcdoc="selectedPageHtml"
:key="selectedRound"
sandbox="allow-scripts"
style="flex: 1; border: 1px solid #e0e0e0; border-radius: 6px; background: #fff"
style="
flex: 1;
border: 1px solid #e0e0e0;
border-radius: 6px;
background: #fff;
"
/>
<n-empty v-else description="该轮无网页代码" style="margin: auto" />
</div>
@@ -86,10 +119,17 @@ const messages = ref<PromptMessage[]>([])
const selectedRound = ref(0)
const rounds = computed(() => {
const result: { question: string; html: string | null; css: string | null; js: string | null }[] = []
const result: {
question: string
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
let html: string | null = null,
css: string | null = null,
js: string | null = null
for (const reply of messages.value.slice(i + 1)) {
if (reply.role === "user") break
if (reply.role === "assistant" && reply.code_html) {

View File

@@ -1,9 +1,16 @@
<template>
<n-modal preset="card" :show="show" style="max-width: 60%" @update:show="$emit('update:show', $event)">
<n-modal
preset="card"
:show="show"
style="max-width: 60%"
@update:show="$emit('update:show', $event)"
>
<template #header>
<n-flex align="center">
<span>前端代码</span>
<n-button tertiary @click="$emit('copy-to-editor')">复制到编辑框</n-button>
<n-button tertiary @click="$emit('copy-to-editor')"
>复制到编辑框</n-button
>
</n-flex>
</template>
<n-tabs animated type="segment">

View File

@@ -14,7 +14,13 @@
<script setup lang="ts">
import { computed, h } from "vue"
import { NButton, NDataTable, NPopconfirm, NSpin, type DataTableColumn } from "naive-ui"
import {
NButton,
NDataTable,
NPopconfirm,
NSpin,
type DataTableColumn,
} from "naive-ui"
import type { SubmissionOut } from "../../utils/type"
import { TASK_TYPE } from "../../utils/const"
import { parseTime } from "../../utils/helper"
@@ -61,10 +67,14 @@ const subColumns = computed((): DataTableColumn<SubmissionOut>[] => [
render: (r) => {
const myScore = r.my_score > 0 ? String(r.my_score) : "-"
const avgScore = r.score > 0 ? r.score.toFixed(2) : "-"
return h("div", { style: { display: "flex", gap: "6px", alignItems: "baseline" } }, [
h("span", avgScore),
h("span", { style: { fontSize: "11px", color: "#999" } }, myScore),
])
return h(
"div",
{ style: { display: "flex", gap: "6px", alignItems: "baseline" } },
[
h("span", avgScore),
h("span", { style: { fontSize: "11px", color: "#999" } }, myScore),
],
)
},
},
{
@@ -73,55 +83,77 @@ const subColumns = computed((): DataTableColumn<SubmissionOut>[] => [
width: 60,
render: (r: SubmissionOut) => {
if (r.username !== user.username) {
return r.nominated ? h("span", { style: { color: "#f0a020" } }, "🏅") : null
return r.nominated
? h("span", { style: { color: "#f0a020" } }, "🏅")
: null
}
return h(
NButton,
{
text: true,
title: r.nominated ? "已参与排名点击可重新提名" : "参与排名",
onClick: (e: Event) => { e.stopPropagation(); emit("nominate", r) },
onClick: (e: Event) => {
e.stopPropagation()
emit("nominate", r)
},
},
() => (r.nominated ? "🏅" : ""),
)
},
},
...(isChallenge.value
? [{
title: "提示词",
key: "conversation_id",
width: 70,
render: (r: SubmissionOut) => {
if (!r.conversation_id) return "-"
return h(
NButton,
{ text: true, type: "primary", onClick: (e: Event) => { e.stopPropagation(); emit("show-chain", r.conversation_id!) } },
() => "查看",
)
},
} as DataTableColumn<SubmissionOut>]
? [
{
title: "提示词",
key: "conversation_id",
width: 70,
render: (r: SubmissionOut) => {
if (!r.conversation_id) return "-"
return h(
NButton,
{
text: true,
type: "primary",
onClick: (e: Event) => {
e.stopPropagation()
emit("show-chain", r.conversation_id!)
},
},
() => "查看",
)
},
} as DataTableColumn<SubmissionOut>,
]
: []),
...(!isChallenge.value
? [{
title: "操作",
key: "actions",
width: 60,
render: (r: SubmissionOut) => {
if (r.username !== user.username) return null
return h(
NPopconfirm,
{ onPositiveClick: () => emit("delete", r, props.row.id) },
{
trigger: () => h(
NButton,
{ text: true, type: "error", size: "small", onClick: (e: Event) => e.stopPropagation() },
() => "删除",
),
default: () => "确定删除这次提交",
},
)
},
} as DataTableColumn<SubmissionOut>]
? [
{
title: "操作",
key: "actions",
width: 60,
render: (r: SubmissionOut) => {
if (r.username !== user.username) return null
return h(
NPopconfirm,
{ onPositiveClick: () => emit("delete", r, props.row.id) },
{
trigger: () =>
h(
NButton,
{
text: true,
type: "error",
size: "small",
onClick: (e: Event) => e.stopPropagation(),
},
() => "删除",
),
default: () => "确定删除这次提交",
},
)
},
} as DataTableColumn<SubmissionOut>,
]
: []),
])
</script>

View File

@@ -13,14 +13,23 @@
<span style="display: flex; align-items: center; gap: 6px">
<span
:style="{
display: 'inline-block', width: '10px', height: '10px',
borderRadius: '50%', backgroundColor: opt.color,
display: 'inline-block',
width: '10px',
height: '10px',
borderRadius: '50%',
backgroundColor: opt.color,
}"
/>
{{ opt.label }}
</span>
</n-button>
<n-button v-if="flag" text block type="error" @click="$emit('update:flag', null)">
<n-button
v-if="flag"
text
block
type="error"
@click="$emit('update:flag', null)"
>
清除
</n-button>
</n-space>
@@ -32,7 +41,11 @@
import { computed } from "vue"
import type { FlagType } from "../../utils/type"
const FLAG_OPTIONS: { value: NonNullable<FlagType>; color: string; label: string }[] = [
const FLAG_OPTIONS: {
value: NonNullable<FlagType>
color: string
label: string
}[] = [
{ value: "red", color: "#e03030", label: "值得展示" },
{ value: "blue", color: "#2080f0", label: "需要讲解" },
{ value: "green", color: "#18a058", label: "优秀作品" },