- 新增试卷管理 Tab:列表展示、启用状态、题数/总分/通过分、目标权限标签、复制直链 - 新增试卷编辑弹窗:标题、描述、阅卷模式、通过分数、启用开关 - 目标权限多选、前置身份开关 + 判断方式(ANY/ALL)+ 权限多选 - 题目编辑:五种题型、上下移、删除、信息题、选答题、生死题、自动批复 - 选择题选项增删改、默认选项、正确选项、多选计分模式、选项得分/扣分 - 填空/简答作答字数上限与标准答案 - 查重开关与通过邮件配置(标题/正文/补充说明/附带邀请码) - 保存前校验:标题、题目、权限、通过分、邮件必填项 - 公开端审核类型改名 Public 前缀,避免与后台同名冲突 - 补充中英文 locale 共 37 个键
This commit is contained in:
1 parent
8d73689356
commit
7b3a5212e6
5 files changed
+1516
-183
No files matched your search
@@ -5,8 +5,8 @@ import { computed, onMounted, ref } from 'vue'
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
skinSiteReviewCatalog,
|
skinSiteReviewCatalog,
|
||||||
type SkinSiteReviewPaper,
|
type SkinSiteReviewPublicPaper,
|
||||||
type SkinSiteReviewQuestion,
|
type SkinSiteReviewPublicQuestion,
|
||||||
type SkinSiteReviewReceipt,
|
type SkinSiteReviewReceipt,
|
||||||
skinSiteSubmitReview,
|
skinSiteSubmitReview,
|
||||||
} from '@/helpers/skin-site-api'
|
} from '@/helpers/skin-site-api'
|
||||||
@@ -46,10 +46,10 @@ const messages = defineMessages({
|
|||||||
|
|
||||||
const emit = defineEmits<{ (e: 'back'): void }>()
|
const emit = defineEmits<{ (e: 'back'): void }>()
|
||||||
|
|
||||||
const papers = ref<SkinSiteReviewPaper[]>([])
|
const papers = ref<SkinSiteReviewPublicPaper[]>([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const failed = ref(false)
|
const failed = ref(false)
|
||||||
const activePaper = ref<SkinSiteReviewPaper | null>(null)
|
const activePaper = ref<SkinSiteReviewPublicPaper | null>(null)
|
||||||
const email = ref('')
|
const email = ref('')
|
||||||
const inviteCode = ref('')
|
const inviteCode = ref('')
|
||||||
const answers = ref<Record<string, string | string[]>>({})
|
const answers = ref<Record<string, string | string[]>>({})
|
||||||
@@ -70,7 +70,7 @@ const requiredAnswered = computed(() => {
|
|||||||
|
|
||||||
const canSubmit = computed(() => emailValid.value && requiredAnswered.value && !submitting.value)
|
const canSubmit = computed(() => emailValid.value && requiredAnswered.value && !submitting.value)
|
||||||
|
|
||||||
function defaultAnswer(q: SkinSiteReviewQuestion): string | string[] {
|
function defaultAnswer(q: SkinSiteReviewPublicQuestion): string | string[] {
|
||||||
if (q.type === 'MULTIPLE' || q.type === 'SINGLE') {
|
if (q.type === 'MULTIPLE' || q.type === 'SINGLE') {
|
||||||
const preset = (q.options ?? []).filter((o) => o.defaultSelected).map((o) => o.id)
|
const preset = (q.options ?? []).filter((o) => o.defaultSelected).map((o) => o.id)
|
||||||
return q.type === 'MULTIPLE' ? preset : (preset[0] ?? '')
|
return q.type === 'MULTIPLE' ? preset : (preset[0] ?? '')
|
||||||
@@ -78,7 +78,7 @@ function defaultAnswer(q: SkinSiteReviewQuestion): string | string[] {
|
|||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
function openPaper(paper: SkinSiteReviewPaper) {
|
function openPaper(paper: SkinSiteReviewPublicPaper) {
|
||||||
activePaper.value = paper
|
activePaper.value = paper
|
||||||
answers.value = {}
|
answers.value = {}
|
||||||
for (const q of paper.questions) answers.value[q.id] = defaultAnswer(q)
|
for (const q of paper.questions) answers.value[q.id] = defaultAnswer(q)
|
||||||
@@ -93,7 +93,7 @@ function closePaper() {
|
|||||||
receipt.value = null
|
receipt.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleMultiple(q: SkinSiteReviewQuestion, optionId: string, checked: boolean) {
|
function toggleMultiple(q: SkinSiteReviewPublicQuestion, optionId: string, checked: boolean) {
|
||||||
const current = Array.isArray(answers.value[q.id]) ? (answers.value[q.id] as string[]) : []
|
const current = Array.isArray(answers.value[q.id]) ? (answers.value[q.id] as string[]) : []
|
||||||
answers.value[q.id] = checked
|
answers.value[q.id] = checked
|
||||||
? [...current.filter((id) => id !== optionId), optionId]
|
? [...current.filter((id) => id !== optionId), optionId]
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -564,32 +564,32 @@ export function skinSitePublicMapServers(): Promise<SkinSiteResponse<SkinSitePub
|
|||||||
export type SkinSiteReviewQuestionType = 'SINGLE' | 'MULTIPLE' | 'TRUE_FALSE' | 'FILL' | 'ESSAY'
|
export type SkinSiteReviewQuestionType = 'SINGLE' | 'MULTIPLE' | 'TRUE_FALSE' | 'FILL' | 'ESSAY'
|
||||||
export type SkinSiteReviewResult = 'PENDING' | 'PASSED' | 'REJECTED'
|
export type SkinSiteReviewResult = 'PENDING' | 'PASSED' | 'REJECTED'
|
||||||
|
|
||||||
export interface SkinSiteReviewOption {
|
export interface SkinSiteReviewPublicOption {
|
||||||
id: string
|
id: string
|
||||||
description: string
|
description: string
|
||||||
correct?: boolean
|
correct?: boolean
|
||||||
defaultSelected?: boolean
|
defaultSelected?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SkinSiteReviewQuestion {
|
export interface SkinSiteReviewPublicQuestion {
|
||||||
id: string
|
id: string
|
||||||
type: SkinSiteReviewQuestionType
|
type: SkinSiteReviewPublicQuestionType
|
||||||
title: string
|
title: string
|
||||||
annotation?: string | null
|
annotation?: string | null
|
||||||
score?: number
|
score?: number
|
||||||
optional?: boolean
|
optional?: boolean
|
||||||
fatal?: boolean
|
fatal?: boolean
|
||||||
options?: SkinSiteReviewOption[]
|
options?: SkinSiteReviewPublicOption[]
|
||||||
answer?: string | null
|
answer?: string | null
|
||||||
maxLength?: number | null
|
maxLength?: number | null
|
||||||
informationQuestion?: boolean
|
informationQuestion?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SkinSiteReviewPaper {
|
export interface SkinSiteReviewPublicPaper {
|
||||||
id: string
|
id: string
|
||||||
title: string
|
title: string
|
||||||
description?: string
|
description?: string
|
||||||
questions: SkinSiteReviewQuestion[]
|
questions: SkinSiteReviewPublicQuestion[]
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1039,6 +1039,42 @@ export function skinSiteAdminUserFrequencyLimit(
|
|||||||
|
|
||||||
export type SkinSiteReviewMode = 'AUTO' | 'MANUAL'
|
export type SkinSiteReviewMode = 'AUTO' | 'MANUAL'
|
||||||
|
|
||||||
|
export type SkinSiteReviewQuestionType = 'SINGLE' | 'MULTIPLE' | 'TRUE_FALSE' | 'FILL' | 'ESSAY'
|
||||||
|
|
||||||
|
export interface SkinSiteReviewOption {
|
||||||
|
id: string
|
||||||
|
description: string
|
||||||
|
correct: boolean
|
||||||
|
defaultSelected: boolean
|
||||||
|
score: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SkinSiteReviewQuestion {
|
||||||
|
id: string
|
||||||
|
type: SkinSiteReviewQuestionType
|
||||||
|
title: string
|
||||||
|
annotation?: string | null
|
||||||
|
score: number
|
||||||
|
optional: boolean
|
||||||
|
fatal: boolean
|
||||||
|
autoReview: boolean
|
||||||
|
options: SkinSiteReviewOption[]
|
||||||
|
answer?: string | null
|
||||||
|
maxLength?: number | null
|
||||||
|
informationQuestion?: boolean
|
||||||
|
informationAlias?: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SkinSiteReviewPaper {
|
||||||
|
id: string
|
||||||
|
title: string
|
||||||
|
annotation?: string | null
|
||||||
|
mode: SkinSiteReviewMode
|
||||||
|
passScore: number
|
||||||
|
version: number
|
||||||
|
questions: SkinSiteReviewQuestion[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface SkinSiteReviewAnswer {
|
export interface SkinSiteReviewAnswer {
|
||||||
id: string
|
id: string
|
||||||
questionId?: string
|
questionId?: string
|
||||||
@@ -1069,6 +1105,7 @@ export interface SkinSiteReviewSubmission {
|
|||||||
createdAt: number
|
createdAt: number
|
||||||
reviewedAt?: number | null
|
reviewedAt?: number | null
|
||||||
answers: SkinSiteReviewAnswer[]
|
answers: SkinSiteReviewAnswer[]
|
||||||
|
paper: SkinSiteReviewPaper
|
||||||
decisionHistory?: Array<{
|
decisionHistory?: Array<{
|
||||||
previousResult: SkinSiteReviewResult
|
previousResult: SkinSiteReviewResult
|
||||||
result: SkinSiteReviewResult
|
result: SkinSiteReviewResult
|
||||||
@@ -1789,3 +1826,79 @@ export function skinSiteWikiUpdateSettings(
|
|||||||
body: settings,
|
body: settings,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface SkinSiteReviewPaperSummary {
|
||||||
|
id: string
|
||||||
|
enabled: boolean
|
||||||
|
title: string
|
||||||
|
annotation?: string | null
|
||||||
|
mode: SkinSiteReviewMode
|
||||||
|
passScore: number
|
||||||
|
targetPermissions: string[]
|
||||||
|
version: number
|
||||||
|
questionCount: number
|
||||||
|
totalScore: number
|
||||||
|
updatedAt: number
|
||||||
|
prerequisiteMode: 'ANY' | 'ALL'
|
||||||
|
prerequisitePermissions: string[]
|
||||||
|
eligible: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SkinSiteReviewMailConfig {
|
||||||
|
enabled: boolean
|
||||||
|
subject: string
|
||||||
|
message: string
|
||||||
|
includeInviteCode: boolean
|
||||||
|
extraText: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SkinSiteReviewConfigData {
|
||||||
|
preventDuplicate?: boolean
|
||||||
|
mail?: SkinSiteReviewMailConfig
|
||||||
|
id: string
|
||||||
|
enabled: boolean
|
||||||
|
title: string
|
||||||
|
annotation?: string | null
|
||||||
|
mode: SkinSiteReviewMode
|
||||||
|
passScore: number
|
||||||
|
targetPermissions: string[]
|
||||||
|
version: number
|
||||||
|
questions: SkinSiteReviewQuestion[]
|
||||||
|
updatedAt: number
|
||||||
|
prerequisiteMode: 'ANY' | 'ALL'
|
||||||
|
prerequisitePermissions: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function skinSiteReviewPaperList(): Promise<
|
||||||
|
SkinSiteResponse<SkinSiteReviewPaperSummary[]>
|
||||||
|
> {
|
||||||
|
return skinSiteRequest<SkinSiteReviewPaperSummary[]>('review/admin/papers')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function skinSiteReviewPaperAdmin(
|
||||||
|
paperId: string,
|
||||||
|
): Promise<SkinSiteResponse<SkinSiteReviewConfigData>> {
|
||||||
|
return skinSiteRequest<SkinSiteReviewConfigData>(
|
||||||
|
'review/admin/papers/' + encodeURIComponent(paperId),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function skinSiteCreateReviewPaperAdmin(
|
||||||
|
data: SkinSiteReviewConfigData,
|
||||||
|
): Promise<SkinSiteResponse<SkinSiteReviewConfigData>> {
|
||||||
|
return skinSiteRequest<SkinSiteReviewConfigData>('review/admin/papers', {
|
||||||
|
method: 'POST',
|
||||||
|
body: data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function skinSiteUpdateReviewPaperAdmin(
|
||||||
|
paperId: string,
|
||||||
|
data: SkinSiteReviewConfigData,
|
||||||
|
): Promise<SkinSiteResponse<SkinSiteReviewConfigData>> {
|
||||||
|
return skinSiteRequest<SkinSiteReviewConfigData>(
|
||||||
|
'review/admin/papers/' + encodeURIComponent(paperId),
|
||||||
|
{ method: 'PUT', body: data },
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -12141,5 +12141,42 @@
|
|||||||
"app.skin-site.admin.wiki.max-page-bytes": {"message": "Max page bytes"},
|
"app.skin-site.admin.wiki.max-page-bytes": {"message": "Max page bytes"},
|
||||||
"app.skin-site.admin.wiki.max-attachment-bytes": {"message": "Max attachment bytes"},
|
"app.skin-site.admin.wiki.max-attachment-bytes": {"message": "Max attachment bytes"},
|
||||||
"app.skin-site.admin.wiki.save-settings": {"message": "Save settings"},
|
"app.skin-site.admin.wiki.save-settings": {"message": "Save settings"},
|
||||||
"app.skin-site.admin.wiki.settings-saved": {"message": "Settings saved."}
|
"app.skin-site.admin.wiki.settings-saved": {"message": "Settings saved."},
|
||||||
|
"app.skin-site.admin.review.tab-list": {"message": "Submissions"},
|
||||||
|
"app.skin-site.admin.review.tab-papers": {"message": "Papers"},
|
||||||
|
"app.skin-site.admin.review.papers-empty": {"message": "No review papers yet."},
|
||||||
|
"app.skin-site.admin.review.new-paper": {"message": "New paper"},
|
||||||
|
"app.skin-site.admin.review.edit-paper": {"message": "Edit"},
|
||||||
|
"app.skin-site.admin.review.paper-title": {"message": "Title"},
|
||||||
|
"app.skin-site.admin.review.paper-annotation": {"message": "Description"},
|
||||||
|
"app.skin-site.admin.review.paper-enabled": {"message": "Enabled"},
|
||||||
|
"app.skin-site.admin.review.paper-mode": {"message": "Mode"},
|
||||||
|
"app.skin-site.admin.review.paper-pass-score": {"message": "Pass score"},
|
||||||
|
"app.skin-site.admin.review.paper-target-permissions": {"message": "Target permissions"},
|
||||||
|
"app.skin-site.admin.review.paper-questions": {"message": "Questions"},
|
||||||
|
"app.skin-site.admin.review.add-question": {"message": "Add question"},
|
||||||
|
"app.skin-site.admin.review.question-title": {"message": "Question title"},
|
||||||
|
"app.skin-site.admin.review.question-type": {"message": "Type"},
|
||||||
|
"app.skin-site.admin.review.question-score": {"message": "Score"},
|
||||||
|
"app.skin-site.admin.review.question-annotation": {"message": "Annotation"},
|
||||||
|
"app.skin-site.admin.review.add-option": {"message": "Add option"},
|
||||||
|
"app.skin-site.admin.review.option-description": {"message": "Option text"},
|
||||||
|
"app.skin-site.admin.review.option-correct": {"message": "Correct"},
|
||||||
|
"app.skin-site.admin.review.remove-question": {"message": "Remove"},
|
||||||
|
"app.skin-site.admin.review.question-no": {"message": "Question {n}"},
|
||||||
|
"app.skin-site.admin.review.paper-created": {"message": "Paper created."},
|
||||||
|
"app.skin-site.admin.review.paper-saved": {"message": "Paper saved."},
|
||||||
|
"app.skin-site.admin.review.mail-title": {"message": "Pass mail"},
|
||||||
|
"app.skin-site.admin.review.mail-enabled": {"message": "Send mail on pass"},
|
||||||
|
"app.skin-site.admin.review.mail-subject": {"message": "Subject"},
|
||||||
|
"app.skin-site.admin.review.mail-message": {"message": "Body"},
|
||||||
|
"app.skin-site.admin.review.mail-extra": {"message": "Extra text"},
|
||||||
|
"app.skin-site.admin.review.mail-include-invite": {"message": "Include invite code"},
|
||||||
|
"app.skin-site.admin.review.prevent-duplicate": {"message": "Reject duplicate submissions"},
|
||||||
|
"app.skin-site.admin.review.copy-link": {"message": "Copy link"},
|
||||||
|
"app.skin-site.admin.review.link-copied": {"message": "Link copied."},
|
||||||
|
"app.skin-site.admin.review.move-up": {"message": "Move up"},
|
||||||
|
"app.skin-site.admin.review.move-down": {"message": "Move down"},
|
||||||
|
"app.skin-site.admin.review.mail-subject-required": {"message": "Subject is required when mail is enabled."},
|
||||||
|
"app.skin-site.admin.review.mail-message-required": {"message": "Body is required when mail is enabled."}
|
||||||
}
|
}
|
||||||
@@ -11972,5 +11972,42 @@
|
|||||||
"app.skin-site.admin.wiki.max-page-bytes": {"message": "页面最大字节数"},
|
"app.skin-site.admin.wiki.max-page-bytes": {"message": "页面最大字节数"},
|
||||||
"app.skin-site.admin.wiki.max-attachment-bytes": {"message": "附件最大字节数"},
|
"app.skin-site.admin.wiki.max-attachment-bytes": {"message": "附件最大字节数"},
|
||||||
"app.skin-site.admin.wiki.save-settings": {"message": "保存设置"},
|
"app.skin-site.admin.wiki.save-settings": {"message": "保存设置"},
|
||||||
"app.skin-site.admin.wiki.settings-saved": {"message": "设置已保存。"}
|
"app.skin-site.admin.wiki.settings-saved": {"message": "设置已保存。"},
|
||||||
|
"app.skin-site.admin.review.tab-list": {"message": "申请列表"},
|
||||||
|
"app.skin-site.admin.review.tab-papers": {"message": "试卷管理"},
|
||||||
|
"app.skin-site.admin.review.papers-empty": {"message": "还没有审核试卷。"},
|
||||||
|
"app.skin-site.admin.review.new-paper": {"message": "新建试卷"},
|
||||||
|
"app.skin-site.admin.review.edit-paper": {"message": "编辑"},
|
||||||
|
"app.skin-site.admin.review.paper-title": {"message": "试卷标题"},
|
||||||
|
"app.skin-site.admin.review.paper-annotation": {"message": "描述"},
|
||||||
|
"app.skin-site.admin.review.paper-enabled": {"message": "启用"},
|
||||||
|
"app.skin-site.admin.review.paper-mode": {"message": "阅卷模式"},
|
||||||
|
"app.skin-site.admin.review.paper-pass-score": {"message": "通过分数"},
|
||||||
|
"app.skin-site.admin.review.paper-target-permissions": {"message": "通过后获得的身份"},
|
||||||
|
"app.skin-site.admin.review.paper-questions": {"message": "题目"},
|
||||||
|
"app.skin-site.admin.review.add-question": {"message": "添加题目"},
|
||||||
|
"app.skin-site.admin.review.question-title": {"message": "题目"},
|
||||||
|
"app.skin-site.admin.review.question-type": {"message": "题型"},
|
||||||
|
"app.skin-site.admin.review.question-score": {"message": "分数"},
|
||||||
|
"app.skin-site.admin.review.question-annotation": {"message": "题目注解"},
|
||||||
|
"app.skin-site.admin.review.add-option": {"message": "添加选项"},
|
||||||
|
"app.skin-site.admin.review.option-description": {"message": "选项文本"},
|
||||||
|
"app.skin-site.admin.review.option-correct": {"message": "正确"},
|
||||||
|
"app.skin-site.admin.review.remove-question": {"message": "删除"},
|
||||||
|
"app.skin-site.admin.review.question-no": {"message": "第 {n} 题"},
|
||||||
|
"app.skin-site.admin.review.paper-created": {"message": "试卷已创建。"},
|
||||||
|
"app.skin-site.admin.review.paper-saved": {"message": "试卷已保存。"},
|
||||||
|
"app.skin-site.admin.review.mail-title": {"message": "通过邮件"},
|
||||||
|
"app.skin-site.admin.review.mail-enabled": {"message": "审核通过后发送邮件"},
|
||||||
|
"app.skin-site.admin.review.mail-subject": {"message": "邮件标题"},
|
||||||
|
"app.skin-site.admin.review.mail-message": {"message": "邮件正文"},
|
||||||
|
"app.skin-site.admin.review.mail-extra": {"message": "邮件补充说明"},
|
||||||
|
"app.skin-site.admin.review.mail-include-invite": {"message": "附带邀请码"},
|
||||||
|
"app.skin-site.admin.review.prevent-duplicate": {"message": "禁止重复作答"},
|
||||||
|
"app.skin-site.admin.review.copy-link": {"message": "复制直链"},
|
||||||
|
"app.skin-site.admin.review.link-copied": {"message": "直链已复制。"},
|
||||||
|
"app.skin-site.admin.review.move-up": {"message": "上移"},
|
||||||
|
"app.skin-site.admin.review.move-down": {"message": "下移"},
|
||||||
|
"app.skin-site.admin.review.mail-subject-required": {"message": "开启邮件后必须填写邮件标题。"},
|
||||||
|
"app.skin-site.admin.review.mail-message-required": {"message": "开启邮件后必须填写邮件正文。"}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user