13 changed files with 4472 additions and 4707 deletions
@ -1,280 +1,282 @@ |
|||||
<template> |
<template> |
||||
<div class="main-container"> |
<div class="main-container"> |
||||
<el-card class="box-card !border-none" shadow="never"> |
<el-card class="box-card !border-none" shadow="never"> |
||||
|
|
||||
<div class="flex justify-between items-center"> |
<div class="flex justify-between items-center"> |
||||
<span class="text-lg">{{pageName}}</span> |
<span class="text-lg">{{pageName}}</span> |
||||
<el-button type="primary" @click="addEvent"> |
<el-button type="primary" @click="addEvent"> |
||||
{{ t('addClassroom') }} |
{{ t('addClassroom') }} |
||||
</el-button> |
</el-button> |
||||
</div> |
</div> |
||||
|
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> |
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> |
||||
<el-form :inline="true" :model="classroomTable.searchParam" ref="searchFormRef"> |
<el-form :inline="true" :model="classroomTable.searchParam" ref="searchFormRef"> |
||||
|
|
||||
<el-form-item :label="t('campusId')" prop="campus_id"> |
<el-form-item :label="t('campusId')" prop="campus_id"> |
||||
<el-select class="w-[280px]" v-model="classroomTable.searchParam.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> |
<el-select class="w-[280px]" v-model="classroomTable.searchParam.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> |
||||
<el-option |
<el-option |
||||
v-for="(item, index) in campusIdList" |
v-for="(item, index) in campusIdList" |
||||
:key="index" |
:key="index" |
||||
:label="item['campus_name']" |
:label="item['campus_name']" |
||||
:value="item['id']" |
:value="item['id']" |
||||
/> |
/> |
||||
</el-select> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('className')" prop="class_name"> |
<el-form-item :label="t('className')" prop="class_name"> |
||||
<el-input v-model="classroomTable.searchParam.class_name" :placeholder="t('classNamePlaceholder')" /> |
<el-input v-model="classroomTable.searchParam.class_name" :placeholder="t('classNamePlaceholder')" /> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('headCoach')" prop="head_coach"> |
<el-form-item :label="t('headCoach')" prop="head_coach"> |
||||
<el-select class="w-[280px]" v-model="classroomTable.searchParam.head_coach" clearable :placeholder="t('headCoachPlaceholder')"> |
<el-select class="w-[280px]" v-model="classroomTable.searchParam.head_coach" clearable :placeholder="t('headCoachPlaceholder')"> |
||||
<el-option |
<el-option |
||||
v-for="(item, index) in headCoachList" |
v-for="(item, index) in headCoachList" |
||||
:key="index" |
:key="index" |
||||
:label="item['name']" |
:label="item['name']" |
||||
:value="item['id']" |
:value="item['id']" |
||||
/> |
/> |
||||
</el-select> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
|
|
||||
<el-form-item :label="t('classType')" prop="class_type"> |
<el-form-item :label="t('classType')" prop="class_type"> |
||||
<el-select class="w-[280px]" v-model="classroomTable.searchParam.class_type" clearable :placeholder="t('classTypePlaceholder')"> |
<el-select class="w-[280px]" v-model="classroomTable.searchParam.class_type" clearable :placeholder="t('classTypePlaceholder')"> |
||||
<el-option label="全部" value=""></el-option> |
<el-option label="全部" value=""></el-option> |
||||
<el-option |
<el-option |
||||
v-for="(item, index) in class_typeList" |
v-for="(item, index) in class_typeList" |
||||
:key="index" |
:key="index" |
||||
:label="item.name" |
:label="item.name" |
||||
:value="item.value" |
:value="item.value" |
||||
/> |
/> |
||||
</el-select> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
|
|
||||
<el-form-item :label="t('assistantCoach')" prop="assistant_coach"> |
<el-form-item :label="t('assistantCoach')" prop="assistant_coach"> |
||||
<el-select class="w-[280px]" v-model="classroomTable.searchParam.assistant_coach" clearable :placeholder="t('assistantCoachPlaceholder')"> |
<el-select class="w-[280px]" v-model="classroomTable.searchParam.assistant_coach" clearable :placeholder="t('assistantCoachPlaceholder')"> |
||||
<el-option |
<el-option |
||||
v-for="(item, index) in assistantCoachList" |
v-for="(item, index) in assistantCoachList" |
||||
:key="index" |
:key="index" |
||||
:label="item['name']" |
:label="item['name']" |
||||
:value="item['id']" |
:value="item['id']" |
||||
/> |
/> |
||||
</el-select> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('createdAt')" prop="created_at"> |
<el-form-item :label="t('createdAt')" prop="created_at"> |
||||
<el-input v-model="classroomTable.searchParam.created_at" :placeholder="t('createdAtPlaceholder')" /> |
<el-input v-model="classroomTable.searchParam.created_at" :placeholder="t('createdAtPlaceholder')" /> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('status')" prop="status"> |
<el-form-item :label="t('status')" prop="status"> |
||||
<el-select class="w-[280px]" v-model="classroomTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')"> |
<el-select class="w-[280px]" v-model="classroomTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')"> |
||||
<el-option label="全部" value=""></el-option> |
<el-option label="全部" value=""></el-option> |
||||
<el-option |
<el-option |
||||
v-for="(item, index) in statusList" |
v-for="(item, index) in statusList" |
||||
:key="index" |
:key="index" |
||||
:label="item.name" |
:label="item.name" |
||||
:value="item.value" |
:value="item.value" |
||||
/> |
/> |
||||
</el-select> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item> |
|
||||
<el-button type="primary" @click="loadClassroomList()">{{ t('search') }}</el-button> |
<el-form-item> |
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> |
<el-button type="primary" @click="loadClassroomList()">{{ t('search') }}</el-button> |
||||
</el-form-item> |
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> |
||||
</el-form> |
</el-form-item> |
||||
</el-card> |
</el-form> |
||||
|
</el-card> |
||||
<div class="mt-[10px]"> |
|
||||
<el-table :data="classroomTable.data" size="large" v-loading="classroomTable.loading"> |
<div class="mt-[10px]"> |
||||
<template #empty> |
<el-table :data="classroomTable.data" size="large" v-loading="classroomTable.loading"> |
||||
<span>{{ !classroomTable.loading ? t('emptyData') : '' }}</span> |
<template #empty> |
||||
</template> |
<span>{{ !classroomTable.loading ? t('emptyData') : '' }}</span> |
||||
<el-table-column prop="campus_id_name" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> |
</template> |
||||
|
<el-table-column prop="campus_id_name" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> |
||||
<el-table-column prop="class_name" :label="t('className')" min-width="120" :show-overflow-tooltip="true"/> |
|
||||
|
<el-table-column prop="class_name" :label="t('className')" min-width="120" :show-overflow-tooltip="true"/> |
||||
<el-table-column prop="head_coach_name" :label="t('headCoach')" min-width="120" :show-overflow-tooltip="true"/> |
|
||||
|
<el-table-column prop="head_coach_name" :label="t('headCoach')" min-width="120" :show-overflow-tooltip="true"/> |
||||
<el-table-column prop="age_group" :label="t('ageGroup')" min-width="120" :show-overflow-tooltip="true"/> |
|
||||
|
<el-table-column prop="age_group" :label="t('ageGroup')" min-width="120" :show-overflow-tooltip="true"/> |
||||
<el-table-column :label="t('classType')" min-width="180" align="center" :show-overflow-tooltip="true"> |
|
||||
<template #default="{ row }"> |
<el-table-column :label="t('classType')" min-width="180" align="center" :show-overflow-tooltip="true"> |
||||
<div v-for="(item, index) in class_typeList"> |
<template #default="{ row }"> |
||||
<div v-if="item.value == row.class_type">{{ item.name }}</div> |
<div v-for="(item, index) in class_typeList"> |
||||
</div> |
<div v-if="item.value == row.class_type">{{ item.name }}</div> |
||||
</template> |
</div> |
||||
</el-table-column> |
</template> |
||||
|
</el-table-column> |
||||
<el-table-column prop="assistant_coach_name" :label="t('assistantCoach')" min-width="120" :show-overflow-tooltip="true"/> |
|
||||
|
<el-table-column prop="assistant_coach_name" :label="t('assistantCoach')" min-width="120" :show-overflow-tooltip="true"/> |
||||
<el-table-column :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true"> |
|
||||
<template #default="{ row }"> |
<el-table-column :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true"> |
||||
<div v-for="(item, index) in statusList"> |
<template #default="{ row }"> |
||||
<div v-if="item.value == row.status">{{ item.name }}</div> |
<div v-for="(item, index) in statusList"> |
||||
</div> |
<div v-if="item.value == row.status">{{ item.name }}</div> |
||||
</template> |
</div> |
||||
</el-table-column> |
</template> |
||||
|
</el-table-column> |
||||
<el-table-column prop="sort_order" :label="t('sortOrder')" min-width="120" :show-overflow-tooltip="true"/> |
|
||||
|
<el-table-column prop="sort_order" :label="t('sortOrder')" 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-table-column :label="t('operation')" fixed="right" min-width="120"> |
||||
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> |
<template #default="{ row }"> |
||||
</template> |
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> |
||||
</el-table-column> |
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> |
||||
|
</template> |
||||
</el-table> |
</el-table-column> |
||||
<div class="mt-[16px] flex justify-end"> |
|
||||
<el-pagination v-model:current-page="classroomTable.page" v-model:page-size="classroomTable.limit" |
</el-table> |
||||
layout="total, sizes, prev, pager, next, jumper" :total="classroomTable.total" |
<div class="mt-[16px] flex justify-end"> |
||||
@size-change="loadClassroomList()" @current-change="loadClassroomList" /> |
<el-pagination v-model:current-page="classroomTable.page" v-model:page-size="classroomTable.limit" |
||||
</div> |
layout="total, sizes, prev, pager, next, jumper" :total="classroomTable.total" |
||||
</div> |
@size-change="loadClassroomList()" @current-change="loadClassroomList" /> |
||||
|
</div> |
||||
<edit ref="editClassroomDialog" @complete="loadClassroomList" /> |
</div> |
||||
</el-card> |
|
||||
</div> |
<edit ref="editClassroomDialog" @complete="loadClassroomList" /> |
||||
</template> |
</el-card> |
||||
|
</div> |
||||
<script lang="ts" setup> |
</template> |
||||
import { reactive, ref, watch } from 'vue' |
|
||||
import { t } from '@/lang' |
<script lang="ts" setup> |
||||
import { useDictionary } from '@/app/api/dict' |
import { reactive, ref, watch } from 'vue' |
||||
import { getClassroomList, deleteClassroom, getWithCampusList, getWithPersonnelList, getWithPersonnelList } from '@/app/api/classroom' |
import { t } from '@/lang' |
||||
import { img } from '@/utils/common' |
import { useDictionary } from '@/app/api/dict' |
||||
import { ElMessageBox,FormInstance } from 'element-plus' |
import { getClassroomList, deleteClassroom, getWithCampusList, getWithPersonnelList } from '@/app/api/classroom' |
||||
import Edit from '@/app/views/classroom/components/classroom-edit.vue' |
import { ElMessageBox,FormInstance } from 'element-plus' |
||||
import { useRoute } from 'vue-router' |
import Edit from '@/app/views/classroom/components/classroom-edit.vue' |
||||
const route = useRoute() |
import { useRoute } from 'vue-router' |
||||
const pageName = route.meta.title; |
const route = useRoute() |
||||
|
const pageName = route.meta.title; |
||||
let classroomTable = reactive({ |
|
||||
page: 1, |
let classroomTable = reactive({ |
||||
limit: 10, |
page: 1, |
||||
total: 0, |
limit: 10, |
||||
loading: true, |
total: 0, |
||||
data: [], |
loading: true, |
||||
searchParam:{ |
data: [], |
||||
"campus_id":"", |
searchParam:{ |
||||
"class_name":"", |
"campus_id":"", |
||||
"head_coach":"", |
"class_name":"", |
||||
"class_type":"", |
"head_coach":"", |
||||
"assistant_coach":"", |
"class_type":"", |
||||
"created_at":"", |
"assistant_coach":"", |
||||
"status":"" |
"created_at":"", |
||||
} |
"status":"" |
||||
}) |
} |
||||
|
}) |
||||
const searchFormRef = ref<FormInstance>() |
|
||||
|
const searchFormRef = ref<FormInstance>() |
||||
// 选中数据 |
|
||||
const selectData = ref<any[]>([]) |
// 选中数据 |
||||
|
const selectData = ref<any[]>([]) |
||||
// 字典数据 |
|
||||
const class_typeList = ref([] as any[]) |
// 字典数据 |
||||
const class_typeDictList = async () => { |
const class_typeList = ref([] as any[]) |
||||
class_typeList.value = await (await useDictionary('class_type')).data.dictionary |
const class_typeDictList = async () => { |
||||
} |
class_typeList.value = await (await useDictionary('class_type')).data.dictionary |
||||
class_typeDictList(); |
} |
||||
const statusList = ref([] as any[]) |
class_typeDictList(); |
||||
const statusDictList = async () => { |
const statusList = ref([] as any[]) |
||||
statusList.value = await (await useDictionary('SiteStatus')).data.dictionary |
const statusDictList = async () => { |
||||
} |
statusList.value = await (await useDictionary('SiteStatus')).data.dictionary |
||||
statusDictList(); |
} |
||||
|
statusDictList(); |
||||
/** |
|
||||
* 获取场地管理列表 |
|
||||
*/ |
/** |
||||
const loadClassroomList = (page: number = 1) => { |
* 获取场地管理列表 |
||||
classroomTable.loading = true |
*/ |
||||
classroomTable.page = page |
const loadClassroomList = (page: number = 1) => { |
||||
|
classroomTable.loading = true |
||||
getClassroomList({ |
classroomTable.page = page |
||||
page: classroomTable.page, |
|
||||
limit: classroomTable.limit, |
getClassroomList({ |
||||
...classroomTable.searchParam |
page: classroomTable.page, |
||||
}).then(res => { |
limit: classroomTable.limit, |
||||
classroomTable.loading = false |
...classroomTable.searchParam |
||||
classroomTable.data = res.data.data |
}).then(res => { |
||||
classroomTable.total = res.data.total |
classroomTable.loading = false |
||||
}).catch(() => { |
classroomTable.data = res.data.data |
||||
classroomTable.loading = false |
classroomTable.total = res.data.total |
||||
}) |
}).catch(() => { |
||||
} |
classroomTable.loading = false |
||||
loadClassroomList() |
}) |
||||
|
} |
||||
const editClassroomDialog: Record<string, any> | null = ref(null) |
loadClassroomList() |
||||
|
|
||||
/** |
const editClassroomDialog: Record<string, any> | null = ref(null) |
||||
* 添加场地管理 |
|
||||
*/ |
/** |
||||
const addEvent = () => { |
* 添加场地管理 |
||||
editClassroomDialog.value.setFormData() |
*/ |
||||
editClassroomDialog.value.showDialog = true |
const addEvent = () => { |
||||
} |
editClassroomDialog.value.setFormData() |
||||
|
editClassroomDialog.value.showDialog = true |
||||
/** |
} |
||||
* 编辑场地管理 |
|
||||
* @param data |
/** |
||||
*/ |
* 编辑场地管理 |
||||
const editEvent = (data: any) => { |
* @param data |
||||
editClassroomDialog.value.setFormData(data) |
*/ |
||||
editClassroomDialog.value.showDialog = true |
const editEvent = (data: any) => { |
||||
} |
editClassroomDialog.value.setFormData(data) |
||||
|
editClassroomDialog.value.showDialog = true |
||||
/** |
} |
||||
* 删除场地管理 |
|
||||
*/ |
/** |
||||
const deleteEvent = (id: number) => { |
* 删除场地管理 |
||||
ElMessageBox.confirm(t('classroomDeleteTips'), t('warning'), |
*/ |
||||
{ |
const deleteEvent = (id: number) => { |
||||
confirmButtonText: t('confirm'), |
ElMessageBox.confirm(t('classroomDeleteTips'), t('warning'), |
||||
cancelButtonText: t('cancel'), |
{ |
||||
type: 'warning', |
confirmButtonText: t('confirm'), |
||||
} |
cancelButtonText: t('cancel'), |
||||
).then(() => { |
type: 'warning', |
||||
deleteClassroom(id).then(() => { |
} |
||||
loadClassroomList() |
).then(() => { |
||||
}).catch(() => { |
deleteClassroom(id).then(() => { |
||||
}) |
loadClassroomList() |
||||
}) |
}).catch(() => { |
||||
} |
}) |
||||
|
}) |
||||
|
} |
||||
const campusIdList = ref([]) |
|
||||
const setCampusIdList = async () => { |
|
||||
campusIdList.value = await (await getWithCampusList({})).data |
const campusIdList = ref([]) |
||||
} |
const setCampusIdList = async () => { |
||||
setCampusIdList() |
campusIdList.value = await (await getWithCampusList({})).data |
||||
const headCoachList = ref([]) |
} |
||||
const setHeadCoachList = async () => { |
setCampusIdList() |
||||
headCoachList.value = await (await getWithPersonnelList({})).data |
const headCoachList = ref([]) |
||||
} |
const setHeadCoachList = async () => { |
||||
setHeadCoachList() |
headCoachList.value = await (await getWithPersonnelList({})).data |
||||
const assistantCoachList = ref([]) |
} |
||||
const setAssistantCoachList = async () => { |
setHeadCoachList() |
||||
assistantCoachList.value = await (await getWithPersonnelList({})).data |
const assistantCoachList = ref([]) |
||||
} |
const setAssistantCoachList = async () => { |
||||
setAssistantCoachList() |
assistantCoachList.value = await (await getWithPersonnelList({})).data |
||||
|
} |
||||
const resetForm = (formEl: FormInstance | undefined) => { |
setAssistantCoachList() |
||||
if (!formEl) return |
|
||||
formEl.resetFields() |
const resetForm = (formEl: FormInstance | undefined) => { |
||||
loadClassroomList() |
if (!formEl) return |
||||
} |
formEl.resetFields() |
||||
</script> |
loadClassroomList() |
||||
|
} |
||||
<style lang="scss" scoped> |
</script> |
||||
/* 多行超出隐藏 */ |
|
||||
.multi-hidden { |
<style lang="scss" scoped> |
||||
word-break: break-all; |
/* 多行超出隐藏 */ |
||||
text-overflow: ellipsis; |
.multi-hidden { |
||||
overflow: hidden; |
word-break: break-all; |
||||
display: -webkit-box; |
text-overflow: ellipsis; |
||||
-webkit-line-clamp: 2; |
overflow: hidden; |
||||
-webkit-box-orient: vertical; |
display: -webkit-box; |
||||
} |
-webkit-line-clamp: 2; |
||||
</style> |
-webkit-box-orient: vertical; |
||||
|
} |
||||
|
</style> |
||||
|
|||||
@ -1,287 +1,290 @@ |
|||||
<template> |
<template> |
||||
<el-dialog v-model="showDialog" :title="formData.id ? t('updateClassroom') : t('addClassroom')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> |
<el-dialog v-model="showDialog" :title="formData.id ? t('updateClassroom') : t('addClassroom')" 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 :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> |
||||
<el-form-item :label="t('campusId')" prop="campus_id"> |
<el-form-item :label="t('campusId')" prop="campus_id"> |
||||
<el-select class="input-width" v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> |
<el-select class="input-width" v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> |
||||
<el-option label="请选择" value=""></el-option> |
<el-option label="请选择" value=""></el-option> |
||||
<el-option |
<el-option |
||||
v-for="(item, index) in campusIdList" |
v-for="(item, index) in campusIdList" |
||||
:key="index" |
:key="index" |
||||
:label="item['campus_name']" |
:label="item['campus_name']" |
||||
:value="item['id']" |
:value="item['id']" |
||||
/> |
/> |
||||
</el-select> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('className')" prop="class_name"> |
<el-form-item :label="t('className')" prop="class_name"> |
||||
<el-input v-model="formData.class_name" clearable :placeholder="t('classNamePlaceholder')" class="input-width" /> |
<el-input v-model="formData.class_name" clearable :placeholder="t('classNamePlaceholder')" class="input-width" /> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('headCoach')" prop="head_coach"> |
<el-form-item :label="t('headCoach')" prop="head_coach"> |
||||
<el-select class="input-width" v-model="formData.head_coach" clearable :placeholder="t('headCoachPlaceholder')"> |
<el-select class="input-width" v-model="formData.head_coach" clearable :placeholder="t('headCoachPlaceholder')"> |
||||
<el-option label="请选择" value=""></el-option> |
<el-option label="请选择" value=""></el-option> |
||||
<el-option |
<el-option |
||||
v-for="(item, index) in headCoachList" |
v-for="(item, index) in headCoachList" |
||||
:key="index" |
:key="index" |
||||
:label="item['name']" |
:label="item['name']" |
||||
:value="item['id']" |
:value="item['id']" |
||||
/> |
/> |
||||
</el-select> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('ageGroup')" > |
<el-form-item :label="t('ageGroup')" > |
||||
<el-input v-model="formData.age_group" clearable :placeholder="t('ageGroupPlaceholder')" class="input-width" /> |
<el-input v-model="formData.age_group" clearable :placeholder="t('ageGroupPlaceholder')" class="input-width" /> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('classType')" prop="class_type"> |
<el-form-item :label="t('classType')" prop="class_type"> |
||||
<el-select class="input-width" v-model="formData.class_type" clearable :placeholder="t('classTypePlaceholder')"> |
<el-select class="input-width" v-model="formData.class_type" clearable :placeholder="t('classTypePlaceholder')"> |
||||
<el-option label="请选择" value=""></el-option> |
<el-option label="请选择" value=""></el-option> |
||||
<el-option |
<el-option |
||||
v-for="(item, index) in class_typeList" |
v-for="(item, index) in class_typeList" |
||||
:key="index" |
:key="index" |
||||
:label="item.name" |
:label="item.name" |
||||
:value="item.value" |
:value="item.value" |
||||
/> |
/> |
||||
</el-select> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('assistantCoach')" > |
<el-form-item :label="t('assistantCoach')" > |
||||
<el-select class="input-width" v-model="formData.assistant_coach" clearable :placeholder="t('assistantCoachPlaceholder')"> |
<el-select class="input-width" v-model="formData.assistant_coach" clearable :placeholder="t('assistantCoachPlaceholder')"> |
||||
<el-option label="请选择" value=""></el-option> |
<el-option label="请选择" value=""></el-option> |
||||
<el-option |
<el-option |
||||
v-for="(item, index) in assistantCoachList" |
v-for="(item, index) in assistantCoachList" |
||||
:key="index" |
:key="index" |
||||
:label="item['name']" |
:label="item['name']" |
||||
:value="item['id']" |
:value="item['id']" |
||||
/> |
/> |
||||
</el-select> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('status')" prop="status"> |
<el-form-item :label="t('status')" prop="status"> |
||||
<el-radio-group v-model="formData.status" :placeholder="t('statusPlaceholder')"> |
<el-radio-group v-model="formData.status" :placeholder="t('statusPlaceholder')"> |
||||
<el-radio |
<el-radio |
||||
v-for="(item, index) in statusList" |
v-for="(item, index) in statusList" |
||||
:key="index" :label="item.value"> |
:key="index" :label="item.value"> |
||||
{{ item.name }} |
{{ item.name }} |
||||
</el-radio> |
</el-radio> |
||||
</el-radio-group> |
</el-radio-group> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('sortOrder')" > |
<el-form-item :label="t('sortOrder')" > |
||||
<el-input v-model="formData.sort_order" clearable :placeholder="t('sortOrderPlaceholder')" class="input-width" /> |
<el-input v-model="formData.sort_order" clearable :placeholder="t('sortOrderPlaceholder')" class="input-width" /> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('remarks')" > |
<el-form-item :label="t('remarks')" > |
||||
<el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" /> |
<el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" /> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
</el-form> |
|
||||
|
</el-form> |
||||
<template #footer> |
|
||||
<span class="dialog-footer"> |
<template #footer> |
||||
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> |
<span class="dialog-footer"> |
||||
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ |
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> |
||||
t('confirm') |
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ |
||||
}}</el-button> |
t('confirm') |
||||
</span> |
}}</el-button> |
||||
</template> |
</span> |
||||
</el-dialog> |
</template> |
||||
</template> |
</el-dialog> |
||||
|
</template> |
||||
<script lang="ts" setup> |
|
||||
import { ref, reactive, computed, watch } from 'vue' |
<script lang="ts" setup> |
||||
import { useDictionary } from '@/app/api/dict' |
import { ref, reactive, computed, watch } from 'vue' |
||||
import { t } from '@/lang' |
import { useDictionary } from '@/app/api/dict' |
||||
import type { FormInstance } from 'element-plus' |
import { t } from '@/lang' |
||||
import { addClassroom, editClassroom, getClassroomInfo, getWithCampusList, getWithPersonnelList, getWithPersonnelList } from '@/app/api/classroom' |
import type { FormInstance } from 'element-plus' |
||||
|
import { addClassroom, editClassroom, getClassroomInfo, getWithCampusList, getWithPersonnelList } from '@/app/api/classroom' |
||||
let showDialog = ref(false) |
|
||||
const loading = ref(false) |
let showDialog = ref(false) |
||||
|
const loading = ref(false) |
||||
/** |
|
||||
* 表单数据 |
/** |
||||
*/ |
* 表单数据 |
||||
const initialFormData = { |
*/ |
||||
id: '', |
const initialFormData = { |
||||
campus_id: '', |
id: '', |
||||
class_name: '', |
campus_id: '', |
||||
head_coach: '', |
class_name: '', |
||||
age_group: '', |
head_coach: '', |
||||
class_type: '', |
age_group: '', |
||||
assistant_coach: '', |
class_type: '', |
||||
status: '', |
assistant_coach: '', |
||||
sort_order: '', |
status: '', |
||||
remarks: '', |
sort_order: '', |
||||
} |
remarks: '', |
||||
const formData: Record<string, any> = reactive({ ...initialFormData }) |
|
||||
|
} |
||||
const formRef = ref<FormInstance>() |
const formData: Record<string, any> = reactive({ ...initialFormData }) |
||||
|
|
||||
// 表单验证规则 |
const formRef = ref<FormInstance>() |
||||
const formRules = computed(() => { |
|
||||
return { |
// 表单验证规则 |
||||
campus_id: [ |
const formRules = computed(() => { |
||||
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, |
return { |
||||
|
campus_id: [ |
||||
] |
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, |
||||
, |
|
||||
class_name: [ |
] |
||||
{ required: true, message: t('classNamePlaceholder'), trigger: 'blur' }, |
, |
||||
|
class_name: [ |
||||
] |
{ required: true, message: t('classNamePlaceholder'), trigger: 'blur' }, |
||||
, |
|
||||
head_coach: [ |
] |
||||
{ required: true, message: t('headCoachPlaceholder'), trigger: 'blur' }, |
, |
||||
|
head_coach: [ |
||||
] |
{ required: true, message: t('headCoachPlaceholder'), trigger: 'blur' }, |
||||
, |
|
||||
age_group: [ |
] |
||||
{ required: true, message: t('ageGroupPlaceholder'), trigger: 'blur' }, |
, |
||||
|
age_group: [ |
||||
] |
{ required: true, message: t('ageGroupPlaceholder'), trigger: 'blur' }, |
||||
, |
|
||||
class_type: [ |
] |
||||
{ required: true, message: t('classTypePlaceholder'), trigger: 'blur' }, |
, |
||||
|
class_type: [ |
||||
] |
{ required: true, message: t('classTypePlaceholder'), trigger: 'blur' }, |
||||
, |
|
||||
assistant_coach: [ |
] |
||||
{ required: true, message: t('assistantCoachPlaceholder'), trigger: 'blur' }, |
, |
||||
|
assistant_coach: [ |
||||
] |
{ required: true, message: t('assistantCoachPlaceholder'), trigger: 'blur' }, |
||||
, |
|
||||
status: [ |
] |
||||
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' }, |
, |
||||
|
status: [ |
||||
] |
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' }, |
||||
, |
|
||||
sort_order: [ |
] |
||||
{ required: true, message: t('sortOrderPlaceholder'), trigger: 'blur' }, |
, |
||||
|
sort_order: [ |
||||
] |
{ required: true, message: t('sortOrderPlaceholder'), trigger: 'blur' }, |
||||
, |
|
||||
remarks: [ |
] |
||||
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' }, |
, |
||||
|
remarks: [ |
||||
] |
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' }, |
||||
, |
|
||||
} |
] |
||||
}) |
, |
||||
|
} |
||||
const emit = defineEmits(['complete']) |
}) |
||||
|
|
||||
/** |
const emit = defineEmits(['complete']) |
||||
* 确认 |
|
||||
* @param formEl |
/** |
||||
*/ |
* 确认 |
||||
const confirm = async (formEl: FormInstance | undefined) => { |
* @param formEl |
||||
if (loading.value || !formEl) return |
*/ |
||||
let save = formData.id ? editClassroom : addClassroom |
const confirm = async (formEl: FormInstance | undefined) => { |
||||
|
if (loading.value || !formEl) return |
||||
await formEl.validate(async (valid) => { |
let save = formData.id ? editClassroom : addClassroom |
||||
if (valid) { |
|
||||
loading.value = true |
await formEl.validate(async (valid) => { |
||||
|
if (valid) { |
||||
let data = formData |
loading.value = true |
||||
|
|
||||
save(data).then(res => { |
let data = formData |
||||
loading.value = false |
|
||||
showDialog.value = false |
save(data).then(res => { |
||||
emit('complete') |
loading.value = false |
||||
}).catch(err => { |
showDialog.value = false |
||||
loading.value = false |
emit('complete') |
||||
}) |
}).catch(err => { |
||||
} |
loading.value = false |
||||
}) |
}) |
||||
} |
} |
||||
|
}) |
||||
// 获取字典数据 |
} |
||||
let class_typeList = ref([]) |
|
||||
const class_typeDictList = async () => { |
// 获取字典数据 |
||||
class_typeList.value = await (await useDictionary('class_type')).data.dictionary |
let class_typeList = ref([]) |
||||
} |
const class_typeDictList = async () => { |
||||
class_typeDictList(); |
class_typeList.value = await (await useDictionary('class_type')).data.dictionary |
||||
watch(() => class_typeList.value, () => { formData.class_type = class_typeList.value[0].value }) |
} |
||||
let statusList = ref([]) |
class_typeDictList(); |
||||
const statusDictList = async () => { |
watch(() => class_typeList.value, () => { formData.class_type = class_typeList.value[0].value }) |
||||
statusList.value = await (await useDictionary('SiteStatus')).data.dictionary |
let statusList = ref([]) |
||||
} |
const statusDictList = async () => { |
||||
statusDictList(); |
statusList.value = await (await useDictionary('SiteStatus')).data.dictionary |
||||
watch(() => statusList.value, () => { formData.status = statusList.value[0].value }) |
} |
||||
|
statusDictList(); |
||||
|
watch(() => statusList.value, () => { formData.status = statusList.value[0].value }) |
||||
const campusIdList = ref([] as any[]) |
|
||||
const setCampusIdList = async () => { |
|
||||
campusIdList.value = await (await getWithCampusList({})).data |
|
||||
} |
const campusIdList = ref([] as any[]) |
||||
setCampusIdList() |
const setCampusIdList = async () => { |
||||
const headCoachList = ref([] as any[]) |
campusIdList.value = await (await getWithCampusList({})).data |
||||
const setHeadCoachList = async () => { |
} |
||||
headCoachList.value = await (await getWithPersonnelList({})).data |
setCampusIdList() |
||||
} |
const headCoachList = ref([] as any[]) |
||||
setHeadCoachList() |
const setHeadCoachList = async () => { |
||||
const assistantCoachList = ref([] as any[]) |
headCoachList.value = await (await getWithPersonnelList({})).data |
||||
const setAssistantCoachList = async () => { |
} |
||||
assistantCoachList.value = await (await getWithPersonnelList({})).data |
setHeadCoachList() |
||||
} |
const assistantCoachList = ref([] as any[]) |
||||
setAssistantCoachList() |
const setAssistantCoachList = async () => { |
||||
const setFormData = async (row: any = null) => { |
assistantCoachList.value = await (await getWithPersonnelList({})).data |
||||
Object.assign(formData, initialFormData) |
} |
||||
loading.value = true |
setAssistantCoachList() |
||||
if(row){ |
const setFormData = async (row: any = null) => { |
||||
const data = await (await getClassroomInfo(row.id)).data |
Object.assign(formData, initialFormData) |
||||
if (data) Object.keys(formData).forEach((key: string) => { |
loading.value = true |
||||
if (data[key] != undefined) formData[key] = data[key] |
if(row){ |
||||
}) |
const data = await (await getClassroomInfo(row.id)).data |
||||
} |
if (data) Object.keys(formData).forEach((key: string) => { |
||||
loading.value = false |
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 { |
const mobileVerify = (rule: any, value: any, callback: any) => { |
||||
callback() |
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 { |
const idCardVerify = (rule: any, value: any, callback: any) => { |
||||
callback() |
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 { |
const emailVerify = (rule: any, value: any, callback: any) => { |
||||
callback() |
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 { |
const numberVerify = (rule: any, value: any, callback: any) => { |
||||
callback() |
if (!Number.isInteger(value)) { |
||||
} |
callback(new Error(t('generateNumber'))) |
||||
} |
} else { |
||||
|
callback() |
||||
defineExpose({ |
} |
||||
showDialog, |
} |
||||
setFormData |
|
||||
}) |
defineExpose({ |
||||
</script> |
showDialog, |
||||
|
setFormData |
||||
<style lang="scss" scoped></style> |
}) |
||||
<style lang="scss"> |
</script> |
||||
.diy-dialog-wrap .el-form-item__label{ |
|
||||
height: auto !important; |
<style lang="scss" scoped></style> |
||||
} |
<style lang="scss"> |
||||
</style> |
.diy-dialog-wrap .el-form-item__label{ |
||||
|
height: auto !important; |
||||
|
} |
||||
|
</style> |
||||
|
|||||
@ -0,0 +1,127 @@ |
|||||
|
<template> |
||||
|
<div class="schedule-container"> |
||||
|
<!-- 周视图日历 --> |
||||
|
<FullCalendar |
||||
|
:options="calendarOptions" |
||||
|
ref="fullCalendar" |
||||
|
class="calendar" |
||||
|
/> |
||||
|
|
||||
|
<!-- 课程详情弹窗 --> |
||||
|
<el-dialog |
||||
|
v-model="dialogVisible" |
||||
|
title="课程人员安排" |
||||
|
width="30%" |
||||
|
:before-close="handleClose" |
||||
|
> |
||||
|
<div v-if="selectedEvent"> |
||||
|
<h3>{{ selectedEvent.title }}</h3> |
||||
|
<p>时间:{{ selectedEvent.time }}</p> |
||||
|
<h4>参与人员:</h4> |
||||
|
<ul> |
||||
|
<li v-for="person in selectedEvent.people" :key="person.id"> |
||||
|
{{ person.name }} - {{ person.role }} |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import {ref} from 'vue'; |
||||
|
import FullCalendar from '@fullcalendar/vue3'; |
||||
|
import dayGridPlugin from '@fullcalendar/daygrid'; |
||||
|
import timeGridPlugin from '@fullcalendar/timegrid'; |
||||
|
import interactionPlugin from '@fullcalendar/interaction'; // 新增此行 |
||||
|
import zhLocale from '@fullcalendar/core/locales/zh-cn'; |
||||
|
|
||||
|
// 模拟课程数据(替换为真实接口数据) |
||||
|
const courses = ref([ |
||||
|
{ |
||||
|
id: 1, |
||||
|
title: '数学课', |
||||
|
start: '2025-05-18 08:00:00', |
||||
|
end: '2025-05-18 09:00:00', |
||||
|
people: [ |
||||
|
{id: 1, name: '张老师', role: '主讲'}, |
||||
|
{id: 2, name: '李同学', role: '学生'} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
id: 2, |
||||
|
title: '英语课', |
||||
|
start: '2025-05-18 10:00:00', |
||||
|
end: '2025-05-18 11:00:00', |
||||
|
people: [ |
||||
|
{id: 3, name: '王老师', role: '主讲'} |
||||
|
] |
||||
|
} |
||||
|
]); |
||||
|
|
||||
|
// 弹窗相关 |
||||
|
const dialogVisible = ref(false); |
||||
|
const selectedEvent = ref(null); |
||||
|
|
||||
|
// FullCalendar 配置 |
||||
|
const calendarOptions = ref({ |
||||
|
locale: zhLocale, |
||||
|
plugins: [ |
||||
|
dayGridPlugin, |
||||
|
timeGridPlugin, |
||||
|
interactionPlugin // 新增此行 |
||||
|
], |
||||
|
initialView: 'timeGridWeek', // 周视图 |
||||
|
headerToolbar: { |
||||
|
left: 'prev,next today', |
||||
|
center: 'title', |
||||
|
right: 'timeGridWeek,timeGridDay' // 切换视图 |
||||
|
}, |
||||
|
events: courses.value, |
||||
|
eventClick: (info) => { |
||||
|
selectedEvent.value = { |
||||
|
title: info.event.title, |
||||
|
time: `${info.event.start.toLocaleTimeString()} - ${info.event.end.toLocaleTimeString()}`, |
||||
|
people: info.event.extendedProps.people |
||||
|
}; |
||||
|
dialogVisible.value = true; |
||||
|
}, |
||||
|
eventContent: (arg) => { |
||||
|
// 自定义事件内容(可选) |
||||
|
return {html: `<div class="fc-event-title">${arg.event.title}</div>`}; |
||||
|
}, |
||||
|
allDaySlot: false, // 隐藏全天时段 |
||||
|
slotDuration: '01:00', // 时间段间隔(1小时) |
||||
|
slotLabelFormat: { |
||||
|
hour: 'numeric', |
||||
|
minute: '2-digit', |
||||
|
omitZeroMinute: false, |
||||
|
meridiem: 'short' |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 关闭弹窗时重置数据 |
||||
|
const handleClose = () => { |
||||
|
dialogVisible.value = false; |
||||
|
selectedEvent.value = null; |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.schedule-container { |
||||
|
padding: 20px; |
||||
|
} |
||||
|
|
||||
|
.calendar { |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.fc-event-title { |
||||
|
white-space: normal !important; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
.fc-timegrid-event { |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
</style> |
||||
File diff suppressed because it is too large
Loading…
Reference in new issue