This commit is contained in:
zhouwentao 2026-02-01 17:41:57 +08:00
parent deb900da7b
commit f5b479468b
5 changed files with 149 additions and 8 deletions

View File

@ -183,7 +183,7 @@ onUnmounted(() => {
<input <input
v-model="searchQuery" v-model="searchQuery"
type="text" type="text"
class="h-9 w-50 rounded-l border border-gray-300 py-2 pl-9 pr-4 text-gray-700 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-200 dark:bg-slate-800 dark:border-slate-700 dark:text-slate-200 dark:placeholder-slate-500 dark:focus:ring-blue-900" class="h-9 w-50 rounded-l border border-gray-300 py-2 pl-9 pr-4 bg-white text-gray-700 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-200 dark:bg-slate-800 dark:border-slate-700 dark:text-slate-200 dark:placeholder-slate-500 dark:focus:ring-blue-900"
placeholder="输入院校名称" placeholder="输入院校名称"
> >
</div> </div>

View File

@ -42,6 +42,9 @@ const scores = ref({
english: '', // english: '', //
}) })
// Dynamic sub-major scores
const subMajorScores = ref<Record<string, string>>({})
// Errors state // Errors state
const errors = ref({ const errors = ref({
examType: '', examType: '',
@ -54,6 +57,7 @@ const errors = ref({
chinese: '', chinese: '',
english: '', english: '',
}, },
subMajorScores: {} as Record<string, string>,
}) })
// --- Computed Properties using Dict System --- // --- Computed Properties using Dict System ---
@ -85,15 +89,15 @@ function getSubMajorOptions() {
switch (majorCategory.value) { switch (majorCategory.value) {
case '表演类': case '表演类':
return [ return [
{ label: '服装表演', value: '服装表演' }, { label: '服装表演', value: '服装表演', formKey: '服装表演' },
{ label: '戏剧影视导演', value: '戏剧影视导演' }, { label: '戏剧影视导演', value: '戏剧影视导演', formKey: '戏剧影视导演' },
{ label: '戏剧影视表演', value: '戏剧影视表演' }, { label: '戏剧影视表演', value: '戏剧影视表演', formKey: '戏剧影视表演' },
] ]
case '音乐类': case '音乐类':
return [ return [
{ label: '音乐表演声乐', value: '音乐表演声乐', disabled: selectedSubMajors.value.includes('音乐表演器乐') }, { label: '音乐表演声乐', value: '音乐表演声乐', formKey: '音乐表演声乐', disabled: selectedSubMajors.value.includes('音乐表演器乐') },
{ label: '音乐表演器乐', value: '音乐表演器乐', disabled: selectedSubMajors.value.includes('音乐表演声乐') }, { label: '音乐表演器乐', value: '音乐表演器乐', formKey: '音乐表演器乐', disabled: selectedSubMajors.value.includes('音乐表演声乐') },
{ label: '音乐教育', value: '音乐教育' }, { label: '音乐教育', value: '音乐教育', formKey: '音乐教育' },
] ]
default: default:
return [] return []
@ -122,10 +126,35 @@ function handleMajorCategoryChange(val: any) {
errors.value.majorCategory = '' errors.value.majorCategory = ''
} }
function getSubMajorFormKey(subMajorValue: string): string {
const options = getSubMajorOptions()
const option = options.find(opt => opt.value === subMajorValue)
return option?.formKey || ''
}
function handleSubMajorChange(val: any) { function handleSubMajorChange(val: any) {
// //
console.warn(val) console.warn(val)
errors.value.subMajors = '' errors.value.subMajors = ''
//
const options = getSubMajorOptions()
const selectedOptions = options.filter(opt => val.includes(opt.value))
//
selectedOptions.forEach(opt => {
if (!subMajorScores.value[opt.formKey]) {
subMajorScores.value[opt.formKey] = ''
}
})
//
const currentFormKeys = selectedOptions.map(opt => opt.formKey)
Object.keys(subMajorScores.value).forEach(key => {
if (!currentFormKeys.includes(key)) {
delete subMajorScores.value[key]
}
})
} }
// --- Validation Logic --- // --- Validation Logic ---
@ -209,6 +238,11 @@ function validateForm() {
// --- Submit --- // --- Submit ---
async function handleSubmit() { async function handleSubmit() {
if (validateForm()) { if (validateForm()) {
if (getSubMajorOptions().length == 0){
selectedSubMajors.value = []
subMajorScores.value = {}
}
// //
const formData: ScoreFormData = { const formData: ScoreFormData = {
examType: examType.value, examType: examType.value,
@ -224,7 +258,7 @@ async function handleSubmit() {
subjectList: selectedElectives.value, subjectList: selectedElectives.value,
professionalCategory: majorCategory.value, professionalCategory: majorCategory.value,
professionalCategoryChildren: selectedSubMajors.value, professionalCategoryChildren: selectedSubMajors.value,
professionalCategoryChildrenScore: {}, professionalCategoryChildrenScore: subMajorScores.value,
professionalScore: Number(scores.value.unified) || 0, professionalScore: Number(scores.value.unified) || 0,
culturalScore: Number(scores.value.culture) || 0, culturalScore: Number(scores.value.culture) || 0,
englishScore: Number(scores.value.english) || 0, englishScore: Number(scores.value.english) || 0,
@ -262,6 +296,11 @@ function initForm() {
scores.value.culture = info.culturalScore?.toString() || '' scores.value.culture = info.culturalScore?.toString() || ''
scores.value.chinese = info.chineseScore?.toString() || '' scores.value.chinese = info.chineseScore?.toString() || ''
scores.value.english = info.englishScore?.toString() || '' scores.value.english = info.englishScore?.toString() || ''
//
if (info.professionalCategoryChildrenScore) {
subMajorScores.value = { ...info.professionalCategoryChildrenScore }
}
} }
} }
@ -297,6 +336,7 @@ defineExpose({
majorCategory.value = '' majorCategory.value = ''
selectedSubMajors.value = [] selectedSubMajors.value = []
scores.value = { unified: '', culture: '', chinese: '', english: '' } scores.value = { unified: '', culture: '', chinese: '', english: '' }
subMajorScores.value = {}
}, },
}) })
</script> </script>
@ -386,6 +426,30 @@ defineExpose({
成绩输入 成绩输入
</h3> </h3>
<!-- Dynamic Sub-Major Scores -->
<div v-if="selectedSubMajors.length > 0" class="mb-4">
<div class="grid grid-cols-2 gap-4">
<div
v-for="subMajor in selectedSubMajors"
:key="subMajor"
class="mb-4"
>
<label class="mb-2 block text-sm font-medium">{{ subMajor }}成绩</label>
<input
v-model="subMajorScores[getSubMajorFormKey(subMajor)]"
type="number"
min="0"
max="300"
placeholder="0-300"
class="w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<div v-if="errors.subMajorScores[getSubMajorFormKey(subMajor)]" class="mt-2 text-sm text-red-600">
{{ errors.subMajorScores[getSubMajorFormKey(subMajor)] }}
</div>
</div>
</div>
</div>
<!-- Unified Exam Score --> <!-- Unified Exam Score -->
<div class="grid grid-cols-2 gap-4"> <div class="grid grid-cols-2 gap-4">
<div class="mb-4"> <div class="mb-4">

View File

@ -0,0 +1,74 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
// --- ---
interface Ranking {
label: string
value: number
trend?: 'up' | 'down' | 'flat'
}
interface Major {
college: string
majors: string[]
}
// --- ---
const route = useRoute('/major/[majorCode]')
const majorCode = ref('')
onMounted(() => {
})
onUnmounted(() => {
})
watchEffect(() => {
majorCode.value = route.params.majorCode
})
useHead({
title: () => { return `${majorCode.value}|艺体志愿宝` },
})
</script>
<template>
<div class="mx-auto max-w-7xl min-h-screen bg-gray-50 px-4 transition-colors duration-300 dark:bg-slate-900 lg:px-8 sm:px-6">
<!-- 顶部导航 & Header sticky -->
<header class="top-0 z-50 shadow-sm">
</header>
<!-- 主要内容区域 -->
<!-- mx-auto max-w-7xl px-4 py-6 lg:px-8 sm:px-6 -->
<main class="mx-auto max-w-7xl">
</main>
</div>
</template>
<style scoped>
/* 隐藏滚动条但保留滚动功能 */
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
/* 自定义滚动条样式 */
.custom-scrollbar::-webkit-scrollbar {
width: 4px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: transparent;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 2px;
}
.dark .custom-scrollbar::-webkit-scrollbar-thumb {
background: #475569;
}
</style>

View File

@ -153,6 +153,7 @@ async function loadMore(reset = false) {
const res = await getUserMajorList({ const res = await getUserMajorList({
page: page.value, page: page.value,
size: size.value, size: size.value,
keyword: currentKeyword.value,
probability, probability,
batch: currentBatchTab.value, batch: currentBatchTab.value,
batch2: currentBatch2Tab.value, batch2: currentBatch2Tab.value,
@ -455,6 +456,7 @@ function handleDataChange(data: { keyword: string, filters: FilterState }) {
console.warn('发起请求:', data.keyword, data.filters) console.warn('发起请求:', data.keyword, data.filters)
currentKeyword.value = data.keyword currentKeyword.value = data.keyword
currentFilters.value = data.filters currentFilters.value = data.filters
loadMore(true)
} }
// //

View File

@ -26,6 +26,7 @@ declare module 'vue-router/auto-routes' {
'/demo/pop-confirm': RouteRecordInfo<'/demo/pop-confirm', '/demo/pop-confirm', Record<never, never>, Record<never, never>>, '/demo/pop-confirm': RouteRecordInfo<'/demo/pop-confirm', '/demo/pop-confirm', Record<never, never>, Record<never, never>>,
'/dict-demo': RouteRecordInfo<'/dict-demo', '/dict-demo', Record<never, never>, Record<never, never>>, '/dict-demo': RouteRecordInfo<'/dict-demo', '/dict-demo', Record<never, never>, Record<never, never>>,
'/hi/[name]': RouteRecordInfo<'/hi/[name]', '/hi/:name', { name: ParamValue<true> }, { name: ParamValue<false> }>, '/hi/[name]': RouteRecordInfo<'/hi/[name]', '/hi/:name', { name: ParamValue<true> }, { name: ParamValue<false> }>,
'/major/[majorCode]': RouteRecordInfo<'/major/[majorCode]', '/major/:majorCode', { majorCode: ParamValue<true> }, { majorCode: ParamValue<false> }>,
'/majors': RouteRecordInfo<'/majors', '/majors', Record<never, never>, Record<never, never>>, '/majors': RouteRecordInfo<'/majors', '/majors', Record<never, never>, Record<never, never>>,
'/privacy-policy': RouteRecordInfo<'/privacy-policy', '/privacy-policy', Record<never, never>, Record<never, never>>, '/privacy-policy': RouteRecordInfo<'/privacy-policy', '/privacy-policy', Record<never, never>, Record<never, never>>,
'/README': RouteRecordInfo<'/README', '/README', Record<never, never>, Record<never, never>>, '/README': RouteRecordInfo<'/README', '/README', Record<never, never>, Record<never, never>>,