|
|
|
|
@ -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>
|
|
|
|
|
|