Compare commits
4 Commits
f7e9d39bc2
...
016e070fb9
| Author | SHA1 | Date | |
|---|---|---|---|
| 016e070fb9 | |||
| 0ee8b0d6ea | |||
| 334b2d77b1 | |||
| b4bfc7706c |
@@ -1,6 +1,6 @@
|
|||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
import { router } from "./router"
|
import { router } from "./router"
|
||||||
import type { TutorialIn, ChallengeIn } from "./utils/type"
|
import type { TutorialIn, ChallengeIn, FlagType } from "./utils/type"
|
||||||
import { BASE_URL, STORAGE_KEY } from "./utils/const"
|
import { BASE_URL, STORAGE_KEY } from "./utils/const"
|
||||||
|
|
||||||
const http = axios.create({
|
const http = axios.create({
|
||||||
@@ -167,6 +167,11 @@ export const Submission = {
|
|||||||
const res = await http.put(`/submission/${id}/score`, { score })
|
const res = await http.put(`/submission/${id}/score`, { score })
|
||||||
return res.data
|
return res.data
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async updateFlag(id: string, flag: FlagType) {
|
||||||
|
const res = await http.put(`/submission/${id}/flag`, { flag })
|
||||||
|
return res.data
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Prompt = {
|
export const Prompt = {
|
||||||
|
|||||||
@@ -7,6 +7,18 @@
|
|||||||
返回首页
|
返回首页
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-flex align="center">
|
<n-flex align="center">
|
||||||
|
<n-select
|
||||||
|
v-model:value="query.flag"
|
||||||
|
style="width: 100px"
|
||||||
|
clearable
|
||||||
|
placeholder="标记"
|
||||||
|
:options="[
|
||||||
|
{ label: '红旗', value: 'red' },
|
||||||
|
{ label: '蓝旗', value: 'blue' },
|
||||||
|
{ label: '绿旗', value: 'green' },
|
||||||
|
{ label: '黄旗', value: 'yellow' },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
<div>
|
<div>
|
||||||
<n-input
|
<n-input
|
||||||
style="width: 120px"
|
style="width: 120px"
|
||||||
@@ -113,7 +125,7 @@
|
|||||||
</n-modal>
|
</n-modal>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NButton, type DataTableColumn } from "naive-ui"
|
import { NButton, NPopover, NSpace, type DataTableColumn } from "naive-ui"
|
||||||
import { computed, h, onMounted, onUnmounted, reactive, ref, watch } from "vue"
|
import { computed, h, onMounted, onUnmounted, reactive, ref, watch } from "vue"
|
||||||
import { Submission, Prompt } from "../api"
|
import { Submission, Prompt } from "../api"
|
||||||
import type { SubmissionOut } from "../utils/type"
|
import type { SubmissionOut } from "../utils/type"
|
||||||
@@ -128,6 +140,8 @@ import { step } from "../store/tutorial"
|
|||||||
import { html as eHtml, css as eCss, js as eJs } from "../store/editors"
|
import { html as eHtml, css as eCss, js as eJs } from "../store/editors"
|
||||||
import { TASK_TYPE } from "../utils/const"
|
import { TASK_TYPE } from "../utils/const"
|
||||||
import { goHome } from "../utils/helper"
|
import { goHome } from "../utils/helper"
|
||||||
|
import { roleAdmin, roleSuper } from "../store/user"
|
||||||
|
import type { FlagType } from "../utils/type"
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -137,6 +151,7 @@ const count = ref(0)
|
|||||||
const query = reactive({
|
const query = reactive({
|
||||||
page: Number(route.params.page),
|
page: Number(route.params.page),
|
||||||
username: route.query.username ?? "",
|
username: route.query.username ?? "",
|
||||||
|
flag: null as string | null,
|
||||||
})
|
})
|
||||||
|
|
||||||
const html = computed(() => submission.value.html)
|
const html = computed(() => submission.value.html)
|
||||||
@@ -149,6 +164,15 @@ const chainMessages = ref<{ id: number; role: string; content: string; code_html
|
|||||||
const chainLoading = ref(false)
|
const chainLoading = ref(false)
|
||||||
const selectedRound = ref(0)
|
const selectedRound = ref(0)
|
||||||
|
|
||||||
|
const FLAG_OPTIONS: { value: FlagType; color: string; label: string }[] = [
|
||||||
|
{ value: "red", color: "#e03030", label: "值得展示" },
|
||||||
|
{ value: "blue", color: "#2080f0", label: "需要讲解" },
|
||||||
|
{ value: "green", color: "#18a058", label: "优秀作品" },
|
||||||
|
{ value: "yellow", color: "#f0a020", label: "需要改进" },
|
||||||
|
]
|
||||||
|
|
||||||
|
const isAdmin = computed(() => roleAdmin.value || roleSuper.value)
|
||||||
|
|
||||||
const chainRounds = computed(() => {
|
const chainRounds = computed(() => {
|
||||||
const messages = chainMessages.value
|
const messages = chainMessages.value
|
||||||
const rounds: { question: string; html: string | null; css: string | null; js: string | null }[] = []
|
const rounds: { question: string; html: string | null; css: string | null; js: string | null }[] = []
|
||||||
@@ -177,6 +201,11 @@ const selectedPageHtml = computed(() => {
|
|||||||
return `<!DOCTYPE html><html><head><meta charset="utf-8">${style}</head><body>${round.html}${script}</body></html>`
|
return `<!DOCTYPE html><html><head><meta charset="utf-8">${style}</head><body>${round.html}${script}</body></html>`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
async function updateFlag(row: SubmissionOut, flag: FlagType) {
|
||||||
|
await Submission.updateFlag(row.id, flag)
|
||||||
|
row.flag = flag
|
||||||
|
}
|
||||||
|
|
||||||
async function showChain(conversationId: string) {
|
async function showChain(conversationId: string) {
|
||||||
chainLoading.value = true
|
chainLoading.value = true
|
||||||
chainModal.value = true
|
chainModal.value = true
|
||||||
@@ -191,6 +220,72 @@ async function showChain(conversationId: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const columns: DataTableColumn<SubmissionOut>[] = [
|
const columns: DataTableColumn<SubmissionOut>[] = [
|
||||||
|
{
|
||||||
|
title: "",
|
||||||
|
key: "flag",
|
||||||
|
width: 50,
|
||||||
|
render: (row) => {
|
||||||
|
const flagOption = FLAG_OPTIONS.find((f) => f.value === row.flag)
|
||||||
|
const flagIcon = h("span", {
|
||||||
|
style: {
|
||||||
|
display: "inline-block",
|
||||||
|
width: "12px",
|
||||||
|
height: "12px",
|
||||||
|
borderRadius: "50%",
|
||||||
|
backgroundColor: flagOption ? flagOption.color : "transparent",
|
||||||
|
border: flagOption ? "none" : "1px dashed #ccc",
|
||||||
|
cursor: isAdmin.value ? "pointer" : "default",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!isAdmin.value) return flagIcon
|
||||||
|
|
||||||
|
return h(
|
||||||
|
NPopover,
|
||||||
|
{ trigger: "click" },
|
||||||
|
{
|
||||||
|
trigger: () => flagIcon,
|
||||||
|
default: () =>
|
||||||
|
h(NSpace, { vertical: true, size: "small" }, () => [
|
||||||
|
...FLAG_OPTIONS.map((opt) =>
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
text: true,
|
||||||
|
onClick: () => updateFlag(row, opt.value),
|
||||||
|
},
|
||||||
|
() =>
|
||||||
|
h("span", { style: { display: "flex", alignItems: "center", gap: "6px" } }, [
|
||||||
|
h("span", {
|
||||||
|
style: {
|
||||||
|
display: "inline-block",
|
||||||
|
width: "10px",
|
||||||
|
height: "10px",
|
||||||
|
borderRadius: "50%",
|
||||||
|
backgroundColor: opt.color,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
opt.label,
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
row.flag
|
||||||
|
? h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
text: true,
|
||||||
|
block: true,
|
||||||
|
type: "error",
|
||||||
|
onClick: () => updateFlag(row, null),
|
||||||
|
},
|
||||||
|
() => "清除",
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "时间",
|
title: "时间",
|
||||||
key: "created",
|
key: "created",
|
||||||
@@ -291,6 +386,13 @@ watchDebounced(
|
|||||||
},
|
},
|
||||||
{ debounce: 500, maxWait: 1000 },
|
{ debounce: 500, maxWait: 1000 },
|
||||||
)
|
)
|
||||||
|
watch(
|
||||||
|
() => query.flag,
|
||||||
|
() => {
|
||||||
|
query.page = 1
|
||||||
|
init()
|
||||||
|
},
|
||||||
|
)
|
||||||
onMounted(init)
|
onMounted(init)
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
submission.value = {
|
submission.value = {
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ export function getRole(role: Role) {
|
|||||||
}[role]
|
}[role]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type FlagType = "red" | "blue" | "green" | "yellow" | null
|
||||||
|
|
||||||
export interface TutorialSlim {
|
export interface TutorialSlim {
|
||||||
display: number
|
display: number
|
||||||
title: string
|
title: string
|
||||||
@@ -64,6 +66,7 @@ export interface SubmissionOut {
|
|||||||
score: number
|
score: number
|
||||||
my_score: number
|
my_score: number
|
||||||
conversation_id?: string
|
conversation_id?: string
|
||||||
|
flag?: FlagType
|
||||||
created: Date
|
created: Date
|
||||||
modified: Date
|
modified: Date
|
||||||
}
|
}
|
||||||
@@ -78,6 +81,7 @@ export interface SubmissionAll {
|
|||||||
task_title: string
|
task_title: string
|
||||||
score: number
|
score: number
|
||||||
my_score: number
|
my_score: number
|
||||||
|
flag?: FlagType
|
||||||
html: ""
|
html: ""
|
||||||
css: ""
|
css: ""
|
||||||
js: ""
|
js: ""
|
||||||
|
|||||||
Reference in New Issue
Block a user