master
lion 1 day ago
parent 1115921d92
commit 7f6d57f8c3

@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue'
import { computed, ref, watch } from 'vue'
import TeacherPaperDialog from '@/components/TeacherPaperDialog.vue'
import {
approveTeacher,
@ -116,6 +116,11 @@ const directionOptions = computed(() =>
const universitySelectOptions = computed(() =>
universityOptions.value.map((u) => ({ value: u.id, label: u.name })),
)
const directionSelectOptions = computed(() =>
directionOptions.value.map((d) => ({ value: d.id, label: d.name })),
)
let hydrateSeq = 0
const starFollowRule = computed(() => {
const item = starOptions.value.find((s) => s.id === form.value.star_level_dict_item_id)
@ -367,68 +372,80 @@ async function openDemandRecords(row: DemandRow) {
demandRecordsVisible.value = true
}
function resetDialogState() {
hydrateSeq += 1
teacher.value = null
form.value = emptyForm()
papers.value = []
demands.value = []
loadedStarId.value = null
selectsReady.value = false
loading.value = false
}
function applyPreviewIfAny(id: number) {
const preview = props.previewTeacher
if (preview && Number(preview.id) === Number(id)) {
applyTeacherToForm(preview)
loading.value = false
return true
}
teacher.value = null
form.value = emptyForm()
loadedStarId.value = null
loading.value = true
return false
}
/** 弹窗已打开并完成入场后,再挂载大下拉并拉详情,避免点击后卡住 */
async function onDialogOpened() {
const requestId = props.teacherId
if (!requestId || !props.modelValue) return
const seq = ++hydrateSeq
//
await new Promise<void>((resolve) => {
requestAnimationFrame(() => resolve())
})
if (seq !== hydrateSeq || !props.modelValue || props.teacherId !== requestId) return
selectsReady.value = true
void ensureOptions()
try {
const detail = await fetchTeacher(requestId)
if (seq !== hydrateSeq || props.teacherId !== requestId || !props.modelValue) return
applyTeacherToForm(detail)
mergeTeacherDirectionOptions(detail)
loading.value = false
const [paperList, demandRes] = await Promise.all([
fetchTeacherPapers(requestId),
fetchDemandsList({ teacher_id: requestId, page: 1, page_size: 50 }),
])
if (seq !== hydrateSeq || props.teacherId !== requestId || !props.modelValue) return
papers.value = paperList
demands.value = demandRes.items
} finally {
if (seq === hydrateSeq && props.teacherId === requestId) {
loading.value = false
}
}
}
// await
watch(
() => [props.modelValue, props.teacherId] as const,
async ([open, id]) => {
([open, id]) => {
if (!open || !id) {
if (!open) {
teacher.value = null
form.value = emptyForm()
papers.value = []
demands.value = []
loadedStarId.value = null
selectsReady.value = false
}
if (!open) resetDialogState()
return
}
const requestId = id
papers.value = []
demands.value = []
selectsReady.value = false
//
if (props.previewTeacher && props.previewTeacher.id === id) {
applyTeacherToForm(props.previewTeacher)
loading.value = false
} else {
teacher.value = null
form.value = emptyForm()
loadedStarId.value = null
loading.value = true
}
//
await nextTick()
requestAnimationFrame(() => {
if (props.modelValue && props.teacherId === requestId) {
selectsReady.value = true
}
})
try {
const detailPromise = fetchTeacher(requestId)
void ensureOptions()
const detail = await detailPromise
if (props.teacherId !== requestId || !props.modelValue) return
applyTeacherToForm(detail)
mergeTeacherDirectionOptions(detail)
loading.value = false
const [paperList, demandRes] = await Promise.all([
fetchTeacherPapers(requestId),
fetchDemandsList({ teacher_id: requestId, page: 1, page_size: 50 }),
])
if (props.teacherId !== requestId || !props.modelValue) return
papers.value = paperList
demands.value = demandRes.items
} finally {
if (props.teacherId === requestId) {
loading.value = false
}
}
applyPreviewIfAny(id)
},
)
@ -445,6 +462,7 @@ watch(
width="960px"
top="4vh"
append-to-body
@opened="onDialogOpened"
@update:model-value="emit('update:modelValue', $event)"
>
<div v-loading="loading" class="detail-body">
@ -539,21 +557,17 @@ watch(
</el-col>
<el-col :xs="24" :md="8">
<el-form-item label="研究方向">
<el-select
<el-select-v2
v-if="selectsReady"
v-model="form.research_direction_values"
multiple
filterable
allow-create
default-first-option
collapse-tags
collapse-tags-tooltip
clearable
placeholder="可选,选择或输入研究方向"
style="width: 100%"
>
<el-option v-for="d in directionOptions" :key="d.id" :label="d.name" :value="d.id" />
</el-select>
:options="directionSelectOptions"
/>
<el-input v-else disabled model-value="" />
</el-form-item>
</el-col>

@ -270,6 +270,7 @@ async function batchApproveSelected() {
}
function goDetail(row: TeacherRow) {
// @opened
detailPreview.value = row
detailTeacherId.value = row.id
detailVisible.value = true

Loading…
Cancel
Save