- 新增移动端全屏对话框支持及标签宽度和位置动态调整,优化新增班级、年级和学生弹窗布局 - 所有对话框增加屏幕宽度监听,实现自动切换移动端和桌面端样式 - 表格组件增加移动端列表视图,隐藏侧边栏并改进分页和按钮自适应,提升小屏幕浏览体验 - Dialog及详情弹窗添加最大高度限制并启用滚动,防止移动端显示区域拥挤 - 登录页增加安全区域内边距,保证iOS等设备显示完整性 - 新增移动端菜单抽屉组件,支持手机端侧边栏交互显示 - 学生详情页调整词汇热力图列数,实现移动端更合理布局 - 表格和按钮统一增设触控友好大尺寸区域,提升移动端操作便利性 - 修正后端空词汇ID查询问题,避免空列表导致查询异常 - 统一隐藏小屏幕时的固定侧边栏,避免界面混乱和重复显示 - 搜索页和上传页表格添加移动端适配样式和展开收起逻辑,提升列表浏览灵活性
105 lines
2.9 KiB
Vue
105 lines
2.9 KiB
Vue
<template>
|
|
<el-dialog v-model="visible" title="新增班级" width="480px" :fullscreen="isMobile" :close-on-click-modal="false">
|
|
<div class="space-y-4" v-loading="loading">
|
|
<el-form :label-width="isMobile ? 0 : 80" :label-position="isMobile ? 'top' : 'right'">
|
|
<el-form-item label="班级名称">
|
|
<el-input v-model="name" placeholder="请输入班级名称,如:二班" clearable class="w-full" />
|
|
</el-form-item>
|
|
<el-form-item label="年级">
|
|
<el-select v-model="gradeId" placeholder="请选择年级" class="w-full sm:w-[260px]">
|
|
<el-option v-for="g in gradeOptions" :key="g.id" :label="g.title" :value="g.id" />
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
<template #footer>
|
|
<div class="footer-actions flex sm:justify-end gap-2 sm:flex-row flex-col">
|
|
<el-button class="w-full sm:w-auto touch-target" @click="visible = false">取消</el-button>
|
|
<el-button class="w-full sm:w-auto touch-target" type="primary" :disabled="!canSubmit" @click="handleSubmit">确定</el-button>
|
|
</div>
|
|
</template>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
|
|
import { getGradeList } from '@/api/grade'
|
|
import { addClass } from '@/api/class'
|
|
|
|
const props = defineProps({
|
|
modelValue: { type: Boolean, default: false },
|
|
defaultGradeId: { type: [Number, String], default: null }
|
|
})
|
|
const emit = defineEmits(['update:modelValue', 'success'])
|
|
|
|
const visible = computed({
|
|
get: () => props.modelValue,
|
|
set: (val) => emit('update:modelValue', val)
|
|
})
|
|
|
|
const loading = ref(false)
|
|
const name = ref('')
|
|
const gradeId = ref(null)
|
|
const gradeOptions = ref([])
|
|
const isMobile = ref(false)
|
|
|
|
const canSubmit = computed(() => name.value.trim().length > 0 && !!gradeId.value)
|
|
|
|
async function fetchGrades() {
|
|
loading.value = true
|
|
try {
|
|
const res = await getGradeList(1, 100)
|
|
const d = res?.data
|
|
gradeOptions.value = Array.isArray(d?.data) ? d.data : []
|
|
if (props.defaultGradeId && !gradeId.value) {
|
|
gradeId.value = Number(props.defaultGradeId)
|
|
}
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function handleSubmit() {
|
|
if (!canSubmit.value) return
|
|
loading.value = true
|
|
try {
|
|
await addClass(name.value.trim(), Number(gradeId.value))
|
|
ElMessage.success('新增班级成功')
|
|
emit('success')
|
|
visible.value = false
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
function updateIsMobile() {
|
|
isMobile.value = window.matchMedia('(max-width: 768px)').matches
|
|
}
|
|
|
|
watch(
|
|
() => props.modelValue,
|
|
(v) => {
|
|
if (v) {
|
|
name.value = ''
|
|
gradeId.value = props.defaultGradeId ? Number(props.defaultGradeId) : null
|
|
fetchGrades()
|
|
updateIsMobile()
|
|
}
|
|
}
|
|
)
|
|
|
|
onMounted(() => {
|
|
updateIsMobile()
|
|
window.addEventListener('resize', updateIsMobile)
|
|
})
|
|
onBeforeUnmount(() => {
|
|
window.removeEventListener('resize', updateIsMobile)
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.footer-actions :deep(.el-button + .el-button) {
|
|
margin-left: 0;
|
|
}
|
|
</style>
|