研学线路

master
lion 11 hours ago
parent 33fb1213ba
commit 20cf3c505a

@ -32,7 +32,7 @@ type StudyTour = {
org_name?: string
seasons?: string[]
suitable_count?: string
grade_levels?: string[]
suitable_audience?: string
duration?: string
contact_person?: string
contact_phones?: string
@ -54,13 +54,12 @@ const editId = ref<number | null>(null)
const rows = ref<StudyTour[]>([])
const venues = ref<Venue[]>([])
const seasonOptions = ref<DictOption[]>([])
const gradeOptions = ref<DictOption[]>([])
const currentUser = ref<{ role: string } | null>(null)
const filterKeyword = ref('')
const filterVenueId = ref<number | undefined>(undefined)
const filterOnShelf = ref<string | undefined>(undefined)
const filterSeason = ref<string | undefined>(undefined)
const filterGradeLevel = ref<string | undefined>(undefined)
const filterSuitableAudience = ref('')
const filterOrgName = ref('')
const listPagination = reactive({ current: 1, pageSize: 10 })
const MODAL_BODY_HEIGHT = '72vh'
@ -86,7 +85,7 @@ const form = reactive({
org_name: '',
seasons: [] as string[],
suitable_count: '',
grade_levels: [] as string[],
suitable_audience: '',
duration: '',
contact_person: '',
contact_phones: '',
@ -114,7 +113,7 @@ function formSignature() {
org_name: form.org_name,
seasons: form.seasons,
suitable_count: form.suitable_count,
grade_levels: form.grade_levels,
suitable_audience: form.suitable_audience,
duration: form.duration,
contact_person: form.contact_person,
contact_phones: form.contact_phones,
@ -288,6 +287,16 @@ const introEditorOptions = buildEditorOptions('请输入线路简介')
const feeEditorOptions = buildEditorOptions('请输入线路收费标准')
const implEditorOptions = buildEditorOptions('请输入线路计划实施情况')
function suitableAudienceFromRow(row: StudyTour): string {
const text = String(row.suitable_audience || '').trim()
if (text) return text
const legacy = (row as StudyTour & { grade_levels?: string[] }).grade_levels
if (Array.isArray(legacy) && legacy.length) {
return legacy.join('')
}
return ''
}
function resetForm() {
form.name = ''
form.tags = []
@ -295,7 +304,7 @@ function resetForm() {
form.org_name = ''
form.seasons = []
form.suitable_count = ''
form.grade_levels = []
form.suitable_audience = ''
form.duration = ''
form.contact_person = ''
form.contact_phones = ''
@ -321,7 +330,7 @@ function fillFormFromRow(row: StudyTour) {
form.org_name = row.org_name || ''
form.seasons = Array.isArray(row.seasons) ? [...row.seasons] : []
form.suitable_count = row.suitable_count || ''
form.grade_levels = Array.isArray(row.grade_levels) ? [...row.grade_levels] : []
form.suitable_audience = suitableAudienceFromRow(row)
form.duration = row.duration || ''
form.contact_person = row.contact_person || ''
form.contact_phones = row.contact_phones || ''
@ -537,12 +546,8 @@ function isVenueAdmin() {
}
async function loadDicts() {
const [seasonRes, gradeRes] = await Promise.all([
http.get('/dict-items', { params: { dict_type: 'study_tour_season', active_only: 1 } }),
http.get('/dict-items', { params: { dict_type: 'study_tour_grade_level', active_only: 1 } }),
])
const seasonRes = await http.get('/dict-items', { params: { dict_type: 'study_tour_season', active_only: 1 } })
seasonOptions.value = seasonRes.data || []
gradeOptions.value = gradeRes.data || []
}
async function loadMe() {
@ -559,7 +564,8 @@ async function loadData(keepCurrentPage = false) {
if (filterVenueId.value != null && filterVenueId.value > 0) params.venue_id = filterVenueId.value
if (filterOnShelf.value === '0' || filterOnShelf.value === '1') params.is_on_shelf = filterOnShelf.value
if (filterSeason.value) params.season = filterSeason.value
if (filterGradeLevel.value) params.grade_level = filterGradeLevel.value
const audience = filterSuitableAudience.value.trim()
if (audience) params.suitable_audience = audience
const org = filterOrgName.value.trim()
if (org) params.org_name = org
@ -723,7 +729,7 @@ function buildPayload() {
org_name: form.org_name.trim(),
seasons: [...form.seasons],
suitable_count: form.suitable_count.trim(),
grade_levels: [...form.grade_levels],
suitable_audience: form.suitable_audience.trim(),
duration: form.duration.trim(),
contact_person: form.contact_person.trim(),
contact_phones: form.contact_phones.trim(),
@ -852,9 +858,14 @@ onMounted(async () => {
<a-select v-model="filterSeason" placeholder="季节" allow-clear style="width: 120px" @change="loadData">
<a-option v-for="item in seasonOptions" :key="item.item_value" :value="item.item_value">{{ item.item_label }}</a-option>
</a-select>
<a-select v-model="filterGradeLevel" placeholder="学段" allow-clear style="width: 120px" @change="loadData">
<a-option v-for="item in gradeOptions" :key="item.item_value" :value="item.item_value">{{ item.item_label }}</a-option>
</a-select>
<a-input
v-model="filterSuitableAudience"
placeholder="适配人群"
style="width: 140px"
allow-clear
@press-enter="loadData"
@clear="loadData"
/>
<a-select v-model="filterOnShelf" placeholder="上架状态" allow-clear style="width: 120px" @change="loadData">
<a-option value="1">上架</a-option>
<a-option value="0">下架</a-option>
@ -963,10 +974,8 @@ onMounted(async () => {
<a-option v-for="item in seasonOptions" :key="item.item_value" :value="item.item_value">{{ item.item_label }}</a-option>
</a-select>
</a-form-item>
<a-form-item label="适配学段(多选)">
<a-select v-model="form.grade_levels" multiple allow-clear placeholder="请选择">
<a-option v-for="item in gradeOptions" :key="item.item_value" :value="item.item_value">{{ item.item_label }}</a-option>
</a-select>
<a-form-item label="适配人群">
<a-input v-model="form.suitable_audience" placeholder="如 小学,初中;多个以逗号分隔" />
</a-form-item>
<a-form-item label="研学时长"><a-input v-model="form.duration" placeholder="如 3天2晚、单日6小时" /></a-form-item>
<a-form-item label="线路联络人"><a-input v-model="form.contact_person" /></a-form-item>

Loading…
Cancel
Save