12 changed files with 704 additions and 967 deletions
@ -1,59 +0,0 @@ |
|||||
import request from '@/utils/request' |
|
||||
|
|
||||
// USER_CODE_BEGIN -- aaaaaaaaaaa
|
|
||||
/** |
|
||||
* 获取测试列表 |
|
||||
* @param params |
|
||||
* @returns |
|
||||
*/ |
|
||||
export function getAaaaaaaaaaaList(params: Record<string, any>) { |
|
||||
return request.get(`aaaaaaaaaaa/aaaaaaaaaaa`, { params }) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取测试详情 |
|
||||
* @param id 测试id |
|
||||
* @returns |
|
||||
*/ |
|
||||
export function getAaaaaaaaaaaInfo(id: number) { |
|
||||
return request.get(`aaaaaaaaaaa/aaaaaaaaaaa/${id}`) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 添加测试 |
|
||||
* @param params |
|
||||
* @returns |
|
||||
*/ |
|
||||
export function addAaaaaaaaaaa(params: Record<string, any>) { |
|
||||
return request.post('aaaaaaaaaaa/aaaaaaaaaaa', params, { |
|
||||
showErrorMessage: true, |
|
||||
showSuccessMessage: true, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 编辑测试 |
|
||||
* @param id |
|
||||
* @param params |
|
||||
* @returns |
|
||||
*/ |
|
||||
export function editAaaaaaaaaaa(params: Record<string, any>) { |
|
||||
return request.put(`aaaaaaaaaaa/aaaaaaaaaaa/${params.id}`, params, { |
|
||||
showErrorMessage: true, |
|
||||
showSuccessMessage: true, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除测试 |
|
||||
* @param id |
|
||||
* @returns |
|
||||
*/ |
|
||||
export function deleteAaaaaaaaaaa(id: number) { |
|
||||
return request.delete(`aaaaaaaaaaa/aaaaaaaaaaa/${id}`, { |
|
||||
showErrorMessage: true, |
|
||||
showSuccessMessage: true, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
// USER_CODE_END -- aaaaaaaaaaa
|
|
||||
@ -1,196 +0,0 @@ |
|||||
<template> |
|
||||
<div class="main-container"> |
|
||||
<el-card class="box-card !border-none" shadow="never"> |
|
||||
<div class="flex justify-between items-center"> |
|
||||
<span class="text-lg">{{ pageName }}</span> |
|
||||
<el-button type="primary" @click="addEvent"> |
|
||||
{{ t('addAaaaaaaaaaa') }} |
|
||||
</el-button> |
|
||||
</div> |
|
||||
|
|
||||
<el-card |
|
||||
class="box-card !border-none my-[10px] table-search-wrap" |
|
||||
shadow="never" |
|
||||
> |
|
||||
<el-form |
|
||||
:inline="true" |
|
||||
:model="aaaaaaaaaaaTable.searchParam" |
|
||||
ref="searchFormRef" |
|
||||
> |
|
||||
<el-form-item> |
|
||||
<el-button type="primary" @click="loadAaaaaaaaaaaList()">{{ |
|
||||
t('search') |
|
||||
}}</el-button> |
|
||||
<el-button @click="resetForm(searchFormRef)">{{ |
|
||||
t('reset') |
|
||||
}}</el-button> |
|
||||
</el-form-item> |
|
||||
</el-form> |
|
||||
</el-card> |
|
||||
|
|
||||
<div class="mt-[10px]"> |
|
||||
<el-table |
|
||||
:data="aaaaaaaaaaaTable.data" |
|
||||
size="large" |
|
||||
v-loading="aaaaaaaaaaaTable.loading" |
|
||||
> |
|
||||
<template #empty> |
|
||||
<span>{{ !aaaaaaaaaaaTable.loading ? t('emptyData') : '' }}</span> |
|
||||
</template> |
|
||||
<el-table-column :label="t('url1')" width="100" align="left"> |
|
||||
<template #default="{ row }"> |
|
||||
<el-avatar v-if="row.url1" :src="img(row.url1)" /> |
|
||||
<el-avatar v-else icon="UserFilled" /> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
<el-table-column |
|
||||
prop="url2" |
|
||||
:label="t('url2')" |
|
||||
min-width="120" |
|
||||
:show-overflow-tooltip="true" |
|
||||
/> |
|
||||
|
|
||||
<el-table-column |
|
||||
prop="url3" |
|
||||
:label="t('url3')" |
|
||||
min-width="120" |
|
||||
:show-overflow-tooltip="true" |
|
||||
/> |
|
||||
|
|
||||
<el-table-column |
|
||||
:label="t('operation')" |
|
||||
fixed="right" |
|
||||
min-width="120" |
|
||||
> |
|
||||
<template #default="{ row }"> |
|
||||
<el-button type="primary" link @click="editEvent(row)">{{ |
|
||||
t('edit') |
|
||||
}}</el-button> |
|
||||
<el-button type="primary" link @click="deleteEvent(row.id)">{{ |
|
||||
t('delete') |
|
||||
}}</el-button> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
</el-table> |
|
||||
<div class="mt-[16px] flex justify-end"> |
|
||||
<el-pagination |
|
||||
v-model:current-page="aaaaaaaaaaaTable.page" |
|
||||
v-model:page-size="aaaaaaaaaaaTable.limit" |
|
||||
layout="total, sizes, prev, pager, next, jumper" |
|
||||
:total="aaaaaaaaaaaTable.total" |
|
||||
@size-change="loadAaaaaaaaaaaList()" |
|
||||
@current-change="loadAaaaaaaaaaaList" |
|
||||
/> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<edit ref="editAaaaaaaaaaaDialog" @complete="loadAaaaaaaaaaaList" /> |
|
||||
</el-card> |
|
||||
</div> |
|
||||
</template> |
|
||||
|
|
||||
<script lang="ts" setup> |
|
||||
import { reactive, ref, watch } from 'vue' |
|
||||
import { t } from '@/lang' |
|
||||
import { useDictionary } from '@/app/api/dict' |
|
||||
import { getAaaaaaaaaaaList, deleteAaaaaaaaaaa } from '@/app/api/aaaaaaaaaaa' |
|
||||
import { img } from '@/utils/common' |
|
||||
import { ElMessageBox, FormInstance } from 'element-plus' |
|
||||
import Edit from '@/app/views/aaaaaaaaaaa/components/aaaaaaaaaaa-edit.vue' |
|
||||
import { useRoute } from 'vue-router' |
|
||||
const route = useRoute() |
|
||||
const pageName = route.meta.title |
|
||||
|
|
||||
let aaaaaaaaaaaTable = reactive({ |
|
||||
page: 1, |
|
||||
limit: 10, |
|
||||
total: 0, |
|
||||
loading: true, |
|
||||
data: [], |
|
||||
searchParam: {}, |
|
||||
}) |
|
||||
|
|
||||
const searchFormRef = ref<FormInstance>() |
|
||||
|
|
||||
// 选中数据 |
|
||||
const selectData = ref<any[]>([]) |
|
||||
|
|
||||
// 字典数据 |
|
||||
|
|
||||
/** |
|
||||
* 获取测试列表 |
|
||||
*/ |
|
||||
const loadAaaaaaaaaaaList = (page: number = 1) => { |
|
||||
aaaaaaaaaaaTable.loading = true |
|
||||
aaaaaaaaaaaTable.page = page |
|
||||
|
|
||||
getAaaaaaaaaaaList({ |
|
||||
page: aaaaaaaaaaaTable.page, |
|
||||
limit: aaaaaaaaaaaTable.limit, |
|
||||
...aaaaaaaaaaaTable.searchParam, |
|
||||
}) |
|
||||
.then((res) => { |
|
||||
aaaaaaaaaaaTable.loading = false |
|
||||
aaaaaaaaaaaTable.data = res.data.data |
|
||||
aaaaaaaaaaaTable.total = res.data.total |
|
||||
}) |
|
||||
.catch(() => { |
|
||||
aaaaaaaaaaaTable.loading = false |
|
||||
}) |
|
||||
} |
|
||||
loadAaaaaaaaaaaList() |
|
||||
|
|
||||
const editAaaaaaaaaaaDialog: Record<string, any> | null = ref(null) |
|
||||
|
|
||||
/** |
|
||||
* 添加测试 |
|
||||
*/ |
|
||||
const addEvent = () => { |
|
||||
editAaaaaaaaaaaDialog.value.setFormData() |
|
||||
editAaaaaaaaaaaDialog.value.showDialog = true |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 编辑测试 |
|
||||
* @param data |
|
||||
*/ |
|
||||
const editEvent = (data: any) => { |
|
||||
editAaaaaaaaaaaDialog.value.setFormData(data) |
|
||||
editAaaaaaaaaaaDialog.value.showDialog = true |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除测试 |
|
||||
*/ |
|
||||
const deleteEvent = (id: number) => { |
|
||||
ElMessageBox.confirm(t('aaaaaaaaaaaDeleteTips'), t('warning'), { |
|
||||
confirmButtonText: t('confirm'), |
|
||||
cancelButtonText: t('cancel'), |
|
||||
type: 'warning', |
|
||||
}).then(() => { |
|
||||
deleteAaaaaaaaaaa(id) |
|
||||
.then(() => { |
|
||||
loadAaaaaaaaaaaList() |
|
||||
}) |
|
||||
.catch(() => {}) |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
const resetForm = (formEl: FormInstance | undefined) => { |
|
||||
if (!formEl) return |
|
||||
formEl.resetFields() |
|
||||
loadAaaaaaaaaaaList() |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
/* 多行超出隐藏 */ |
|
||||
.multi-hidden { |
|
||||
word-break: break-all; |
|
||||
text-overflow: ellipsis; |
|
||||
overflow: hidden; |
|
||||
display: -webkit-box; |
|
||||
-webkit-line-clamp: 2; |
|
||||
-webkit-box-orient: vertical; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,176 +0,0 @@ |
|||||
<template> |
|
||||
<el-dialog |
|
||||
v-model="showDialog" |
|
||||
:title="formData.id ? t('updateAaaaaaaaaaa') : t('addAaaaaaaaaaa')" |
|
||||
width="50%" |
|
||||
class="diy-dialog-wrap" |
|
||||
:destroy-on-close="true" |
|
||||
> |
|
||||
<el-form |
|
||||
:model="formData" |
|
||||
label-width="120px" |
|
||||
ref="formRef" |
|
||||
:rules="formRules" |
|
||||
class="page-form" |
|
||||
v-loading="loading" |
|
||||
> |
|
||||
<el-form-item :label="t('url1')"> |
|
||||
<upload-image v-model="formData.url1" /> |
|
||||
</el-form-item> |
|
||||
|
|
||||
<el-form-item :label="t('url2')"> |
|
||||
<upload-file v-model="formData.url2" /> |
|
||||
</el-form-item> |
|
||||
|
|
||||
<el-form-item :label="t('url3')"> |
|
||||
<upload-video v-model="formData.url3" /> |
|
||||
</el-form-item> |
|
||||
</el-form> |
|
||||
|
|
||||
<template #footer> |
|
||||
<span class="dialog-footer"> |
|
||||
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> |
|
||||
<el-button |
|
||||
type="primary" |
|
||||
:loading="loading" |
|
||||
@click="confirm(formRef)" |
|
||||
>{{ t('confirm') }}</el-button |
|
||||
> |
|
||||
</span> |
|
||||
</template> |
|
||||
</el-dialog> |
|
||||
</template> |
|
||||
|
|
||||
<script lang="ts" setup> |
|
||||
import { ref, reactive, computed, watch } from 'vue' |
|
||||
import { useDictionary } from '@/app/api/dict' |
|
||||
import { t } from '@/lang' |
|
||||
import type { FormInstance } from 'element-plus' |
|
||||
import { |
|
||||
addAaaaaaaaaaa, |
|
||||
editAaaaaaaaaaa, |
|
||||
getAaaaaaaaaaaInfo, |
|
||||
} from '@/app/api/aaaaaaaaaaa' |
|
||||
|
|
||||
let showDialog = ref(false) |
|
||||
const loading = ref(false) |
|
||||
|
|
||||
/** |
|
||||
* 表单数据 |
|
||||
*/ |
|
||||
const initialFormData = { |
|
||||
id: '', |
|
||||
url1: '', |
|
||||
url2: '', |
|
||||
url3: '', |
|
||||
} |
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData }) |
|
||||
|
|
||||
const formRef = ref<FormInstance>() |
|
||||
|
|
||||
// 表单验证规则 |
|
||||
const formRules = computed(() => { |
|
||||
return { |
|
||||
url1: [{ required: true, message: t('url1Placeholder'), trigger: 'blur' }], |
|
||||
url2: [{ required: true, message: t('url2Placeholder'), trigger: 'blur' }], |
|
||||
url3: [{ required: true, message: t('url3Placeholder'), trigger: 'blur' }], |
|
||||
} |
|
||||
}) |
|
||||
|
|
||||
const emit = defineEmits(['complete']) |
|
||||
|
|
||||
/** |
|
||||
* 确认 |
|
||||
* @param formEl |
|
||||
*/ |
|
||||
const confirm = async (formEl: FormInstance | undefined) => { |
|
||||
if (loading.value || !formEl) return |
|
||||
let save = formData.id ? editAaaaaaaaaaa : addAaaaaaaaaaa |
|
||||
|
|
||||
await formEl.validate(async (valid) => { |
|
||||
if (valid) { |
|
||||
loading.value = true |
|
||||
|
|
||||
let data = formData |
|
||||
|
|
||||
save(data) |
|
||||
.then((res) => { |
|
||||
loading.value = false |
|
||||
showDialog.value = false |
|
||||
emit('complete') |
|
||||
}) |
|
||||
.catch((err) => { |
|
||||
loading.value = false |
|
||||
}) |
|
||||
} |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
// 获取字典数据 |
|
||||
|
|
||||
const setFormData = async (row: any = null) => { |
|
||||
Object.assign(formData, initialFormData) |
|
||||
loading.value = true |
|
||||
if (row) { |
|
||||
const data = await (await getAaaaaaaaaaaInfo(row.id)).data |
|
||||
if (data) |
|
||||
Object.keys(formData).forEach((key: string) => { |
|
||||
if (data[key] != undefined) formData[key] = data[key] |
|
||||
}) |
|
||||
} |
|
||||
loading.value = false |
|
||||
} |
|
||||
|
|
||||
// 验证手机号格式 |
|
||||
const mobileVerify = (rule: any, value: any, callback: any) => { |
|
||||
if (value && !/^1[3-9]\d{9}$/.test(value)) { |
|
||||
callback(new Error(t('generateMobile'))) |
|
||||
} else { |
|
||||
callback() |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 验证身份证号 |
|
||||
const idCardVerify = (rule: any, value: any, callback: any) => { |
|
||||
if ( |
|
||||
value && |
|
||||
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test( |
|
||||
value |
|
||||
) |
|
||||
) { |
|
||||
callback(new Error(t('generateIdCard'))) |
|
||||
} else { |
|
||||
callback() |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 验证邮箱号 |
|
||||
const emailVerify = (rule: any, value: any, callback: any) => { |
|
||||
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { |
|
||||
callback(new Error(t('generateEmail'))) |
|
||||
} else { |
|
||||
callback() |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 验证请输入整数 |
|
||||
const numberVerify = (rule: any, value: any, callback: any) => { |
|
||||
if (!Number.isInteger(value)) { |
|
||||
callback(new Error(t('generateNumber'))) |
|
||||
} else { |
|
||||
callback() |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
defineExpose({ |
|
||||
showDialog, |
|
||||
setFormData, |
|
||||
}) |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped></style> |
|
||||
<style lang="scss"> |
|
||||
.diy-dialog-wrap .el-form-item__label { |
|
||||
height: auto !important; |
|
||||
} |
|
||||
</style> |
|
||||
@ -0,0 +1,434 @@ |
|||||
|
<template> |
||||
|
<el-dialog v-model="dialogVisible" title="添加课程" width="600px"> |
||||
|
<el-form |
||||
|
ref="formRef" |
||||
|
:model="form" |
||||
|
:rules="rules" |
||||
|
label-width="120px" |
||||
|
> |
||||
|
<el-form-item label="校区" prop="campus_id"> |
||||
|
<el-select |
||||
|
v-model="form.campus_id" |
||||
|
placeholder="请选择校区" |
||||
|
@change="handleCampusChange" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in campusList" |
||||
|
:key="item.id" |
||||
|
:label="item.campus_name" |
||||
|
:value="item.id" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="场地" prop="venue_id"> |
||||
|
<el-select |
||||
|
v-model="form.venue_id" |
||||
|
placeholder="请选择场地" |
||||
|
@change="calculateAvailableCapacity" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in venueList" |
||||
|
:key="item.id" |
||||
|
:label="item.venue_name" |
||||
|
:value="item.id" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="上课日期" prop="course_date"> |
||||
|
<el-date-picker |
||||
|
v-model="form.course_date" |
||||
|
type="date" |
||||
|
placeholder="选择日期" |
||||
|
format="YYYY-MM-DD" |
||||
|
value-format="YYYY-MM-DD" |
||||
|
:disabled-date="disabledDate" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="上课时段" prop="time_slot"> |
||||
|
<el-select |
||||
|
v-model="form.time_slot" |
||||
|
placeholder="请选择上课时段" |
||||
|
@change="calculateAvailableCapacity" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(timeSlot, index) in timeSlotOptions" |
||||
|
:key="index" |
||||
|
:label="timeSlot" |
||||
|
:value="timeSlot" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="剩余空位" v-if="form.venue_id && form.time_slot"> |
||||
|
<span>{{ availableCapacity }}</span> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="上课类型" prop="course_type"> |
||||
|
<el-radio-group v-model="form.course_type" @change="handleCourseTypeChange"> |
||||
|
<el-radio label="class">班级</el-radio> |
||||
|
<el-radio label="student">学员</el-radio> |
||||
|
<el-radio label="trial">试课</el-radio> |
||||
|
</el-radio-group> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="班级" prop="class_ids" v-if="form.course_type === 'class'"> |
||||
|
<el-checkbox-group v-model="form.class_ids" @change="handleClassChange"> |
||||
|
<el-checkbox |
||||
|
v-for="item in classList" |
||||
|
:key="item.id" |
||||
|
:label="item.id" |
||||
|
> |
||||
|
{{ item.class_name }} |
||||
|
</el-checkbox> |
||||
|
</el-checkbox-group> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="学员" prop="student_ids" v-if="form.course_type === 'student' || form.course_type === 'trial'"> |
||||
|
<el-input |
||||
|
v-model="studentSearchKeyword" |
||||
|
placeholder="搜索学员名称" |
||||
|
@input="searchStudents" |
||||
|
/> |
||||
|
<div class="student-checkbox-list"> |
||||
|
<el-checkbox-group v-model="form.student_ids"> |
||||
|
<el-checkbox |
||||
|
v-for="item in filteredStudentList" |
||||
|
:key="item.id" |
||||
|
:label="item.id" |
||||
|
> |
||||
|
{{ item.name }} |
||||
|
</el-checkbox> |
||||
|
</el-checkbox-group> |
||||
|
</div> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="课程名称" prop="course_name"> |
||||
|
<el-input v-model="form.course_name" placeholder="请输入课程名称" /> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="上课教练" prop="coach_id"> |
||||
|
<el-select v-model="form.coach_id" placeholder="请选择教练"> |
||||
|
<el-option |
||||
|
v-for="item in coachList" |
||||
|
:key="item.id" |
||||
|
:label="item.name" |
||||
|
:value="item.id" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<template #footer> |
||||
|
<el-button @click="cancel">取消</el-button> |
||||
|
<el-button type="primary" @click="submit">确定</el-button> |
||||
|
</template> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref, defineProps, defineEmits, watch } from 'vue' |
||||
|
import {getAllVenueList, getVenueList} from '@/app/api/venue' |
||||
|
import { getClassroomList, getWithPersonnelList } from '@/app/api/classroom' |
||||
|
import { addCourseSchedule } from '@/app/api/course_schedule' |
||||
|
import { getTimetables } from '@/app/api/course_schedule' |
||||
|
import { ElMessage } from 'element-plus' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
visible: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
campusList: { |
||||
|
type: Array, |
||||
|
default: () => [] |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
const emit = defineEmits(['update:visible', 'success']) |
||||
|
|
||||
|
// 表单相关数据 |
||||
|
const dialogVisible = ref(false) |
||||
|
const formRef = ref(null) |
||||
|
const venueList = ref([]) |
||||
|
const classList = ref([]) |
||||
|
const studentList = ref([]) |
||||
|
const coachList = ref([]) |
||||
|
const timeSlotOptions = ref(['9:00-10:00', '10:00-11:00', '11:00-12:00', '14:00-15:00', '15:00-16:00', '16:00-17:00']) |
||||
|
const availableCapacity = ref(0) |
||||
|
const studentSearchKeyword = ref('') |
||||
|
const filteredStudentList = ref([]) |
||||
|
|
||||
|
// 监听visible属性变化 |
||||
|
watch(() => props.visible, (newVal) => { |
||||
|
dialogVisible.value = newVal |
||||
|
}) |
||||
|
|
||||
|
// 监听dialogVisible变化 |
||||
|
watch(dialogVisible, (newVal) => { |
||||
|
emit('update:visible', newVal) |
||||
|
if (newVal) { |
||||
|
// 打开弹窗时加载数据 |
||||
|
loadCoachList() |
||||
|
if (form.value.campus_id) { |
||||
|
handleCampusChange() |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
const form = ref({ |
||||
|
campus_id: '', |
||||
|
venue_id: '', |
||||
|
course_date: '', |
||||
|
time_slot: '', |
||||
|
course_type: 'class', |
||||
|
class_ids: [], |
||||
|
student_ids: [], |
||||
|
course_name: '', |
||||
|
coach_id: '' |
||||
|
}) |
||||
|
|
||||
|
const rules = { |
||||
|
campus_id: [{ required: true, message: '请选择校区', trigger: 'change' }], |
||||
|
venue_id: [{ required: true, message: '请选择场地', trigger: 'change' }], |
||||
|
course_date: [{ required: true, message: '请选择上课日期', trigger: 'change' }], |
||||
|
time_slot: [{ required: true, message: '请选择上课时段', trigger: 'change' }], |
||||
|
course_type: [{ required: true, message: '请选择上课类型', trigger: 'change' }], |
||||
|
coach_id: [{ required: true, message: '请选择上课教练', trigger: 'change' }], |
||||
|
course_name: [{ required: true, message: '请输入课程名称', trigger: 'blur' }] |
||||
|
} |
||||
|
|
||||
|
// 限制日期选择,只能选择当前及以后的日期 |
||||
|
const disabledDate = (time) => { |
||||
|
return time.getTime() < Date.now() - 8.64e7 // 禁用今天之前的日期 |
||||
|
} |
||||
|
|
||||
|
// 校区变化事件 |
||||
|
const handleCampusChange = async () => { |
||||
|
// 更新场地列表 |
||||
|
try { |
||||
|
const response = await getAllVenueList({ campus_id: form.value.campus_id }) |
||||
|
venueList.value = response.data |
||||
|
} catch (error) { |
||||
|
console.error('获取场地列表失败:', error) |
||||
|
} |
||||
|
|
||||
|
// 更新班级列表 |
||||
|
try { |
||||
|
const response = await getClassroomList({ campus_id: form.value.campus_id }) |
||||
|
if (response.data && response.data.list) { |
||||
|
classList.value = response.data.list |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.error('获取班级列表失败:', error) |
||||
|
} |
||||
|
|
||||
|
// 重置相关字段 |
||||
|
form.value.venue_id = '' |
||||
|
form.value.class_ids = [] |
||||
|
availableCapacity.value = 0 |
||||
|
} |
||||
|
|
||||
|
// 计算可用容量 |
||||
|
const calculateAvailableCapacity = async () => { |
||||
|
if (!form.value.venue_id || !form.value.time_slot) { |
||||
|
availableCapacity.value = 0 |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
// 获取场地容量 |
||||
|
const venueInfo = venueList.value.find(item => item.id === form.value.venue_id) |
||||
|
if (venueInfo) { |
||||
|
// 设置默认容量 |
||||
|
availableCapacity.value = venueInfo.capacity || 0 |
||||
|
|
||||
|
// 获取该时段已安排的课程占用情况 |
||||
|
if (form.value.course_date) { |
||||
|
const params = { |
||||
|
venue_id: form.value.venue_id, |
||||
|
course_date: form.value.course_date, |
||||
|
time_slot: form.value.time_slot |
||||
|
} |
||||
|
|
||||
|
const response = await getTimetables(params) |
||||
|
if (response.data && response.data.length > 0) { |
||||
|
// 查找对应场地和时间的课程 |
||||
|
const matchingDay = response.data.find(day => |
||||
|
day.date.includes(form.value.course_date) |
||||
|
) |
||||
|
|
||||
|
if (matchingDay) { |
||||
|
const matchingTimeSlot = matchingDay.timeSlots.find(slot => |
||||
|
slot.timeRange === form.value.time_slot |
||||
|
) |
||||
|
|
||||
|
if (matchingTimeSlot && matchingTimeSlot.course) { |
||||
|
// 更新可用容量 |
||||
|
availableCapacity.value = matchingTimeSlot.course.hasnumber |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.error('计算可用容量失败:', error) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 上课类型变化事件 |
||||
|
const handleCourseTypeChange = () => { |
||||
|
// 清空相关字段 |
||||
|
form.value.class_ids = [] |
||||
|
form.value.student_ids = [] |
||||
|
form.value.course_name = '' |
||||
|
|
||||
|
// 如果选择的是学员类型,加载学员列表 |
||||
|
if (form.value.course_type === 'student' || form.value.course_type === 'trial') { |
||||
|
loadStudentList() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 班级变化事件 |
||||
|
const handleClassChange = () => { |
||||
|
// 当选择班级时,设置课程名称为班级名称 |
||||
|
if (form.value.class_ids.length > 0) { |
||||
|
const selectedClass = classList.value.find(item => item.id === form.value.class_ids[0]) |
||||
|
if (selectedClass) { |
||||
|
form.value.course_name = selectedClass.class_name |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 加载学员列表 |
||||
|
const loadStudentList = async () => { |
||||
|
try { |
||||
|
// 这里应该调用获取学员列表的接口 |
||||
|
// 由于没有看到明确的接口,暂时使用模拟数据 |
||||
|
studentList.value = [ |
||||
|
{ id: 1, name: '学员1' }, |
||||
|
{ id: 2, name: '学员2' }, |
||||
|
{ id: 3, name: '学员3' } |
||||
|
] |
||||
|
filteredStudentList.value = [...studentList.value] |
||||
|
} catch (error) { |
||||
|
console.error('获取学员列表失败:', error) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 加载教练列表 |
||||
|
const loadCoachList = async () => { |
||||
|
try { |
||||
|
// 使用classroom的人员列表接口 |
||||
|
const response = await getWithPersonnelList({}) |
||||
|
if (response.data) { |
||||
|
coachList.value = response.data |
||||
|
} else { |
||||
|
// 模拟数据 |
||||
|
coachList.value = [ |
||||
|
{ id: 1, name: '教练1' }, |
||||
|
{ id: 2, name: '教练2' }, |
||||
|
{ id: 3, name: '教练3' } |
||||
|
] |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.error('获取教练列表失败:', error) |
||||
|
// 模拟数据 |
||||
|
coachList.value = [ |
||||
|
{ id: 1, name: '教练1' }, |
||||
|
{ id: 2, name: '教练2' }, |
||||
|
{ id: 3, name: '教练3' } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 搜索学员 |
||||
|
const searchStudents = () => { |
||||
|
if (!studentSearchKeyword.value) { |
||||
|
filteredStudentList.value = [...studentList.value] |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
filteredStudentList.value = studentList.value.filter(student => |
||||
|
student.name.includes(studentSearchKeyword.value) |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
// 取消 |
||||
|
const cancel = () => { |
||||
|
dialogVisible.value = false |
||||
|
} |
||||
|
|
||||
|
// 提交表单 |
||||
|
const submit = () => { |
||||
|
formRef.value.validate(async (valid) => { |
||||
|
if (!valid) return |
||||
|
|
||||
|
try { |
||||
|
const params = { |
||||
|
campus_id: form.value.campus_id, |
||||
|
venue_id: form.value.venue_id, |
||||
|
course_date: form.value.course_date, |
||||
|
time_slot: form.value.time_slot, |
||||
|
course_id: 0, // 这里可能需要根据实际情况创建课程 |
||||
|
coach_id: form.value.coach_id, |
||||
|
participants: form.value.course_type, |
||||
|
available_capacity: availableCapacity.value, |
||||
|
status: 'active', |
||||
|
} |
||||
|
|
||||
|
// 根据不同类型设置学员信息 |
||||
|
if (form.value.course_type === 'class') { |
||||
|
params.class_ids = form.value.class_ids |
||||
|
// 获取班级包含的学员 |
||||
|
const classStudents = [] |
||||
|
// 这里需要根据实际接口调整 |
||||
|
params.student_ids = classStudents |
||||
|
} else { |
||||
|
params.student_ids = form.value.student_ids |
||||
|
} |
||||
|
|
||||
|
const response = await addCourseSchedule(params) |
||||
|
if (response.code === 0) { |
||||
|
ElMessage.success('添加课程成功') |
||||
|
dialogVisible.value = false |
||||
|
emit('success') |
||||
|
resetForm() |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.error('添加课程失败:', error) |
||||
|
ElMessage.error('添加课程失败') |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 重置表单 |
||||
|
const resetForm = () => { |
||||
|
form.value = { |
||||
|
campus_id: '', |
||||
|
venue_id: '', |
||||
|
course_date: '', |
||||
|
time_slot: '', |
||||
|
course_type: 'class', |
||||
|
class_ids: [], |
||||
|
student_ids: [], |
||||
|
course_name: '', |
||||
|
coach_id: '' |
||||
|
} |
||||
|
if (formRef.value) { |
||||
|
formRef.value.resetFields() |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.student-checkbox-list { |
||||
|
max-height: 200px; |
||||
|
overflow-y: auto; |
||||
|
border: 1px solid #EBEEF5; |
||||
|
border-radius: 4px; |
||||
|
padding: 10px; |
||||
|
margin-top: 8px; |
||||
|
} |
||||
|
</style> |
||||
Loading…
Reference in new issue