调整搜索框样式

This commit is contained in:
zhonghua 2026-03-12 11:15:12 +08:00
parent cfaca4a2aa
commit 254748302c
5 changed files with 131 additions and 355 deletions

View File

@ -774,10 +774,6 @@ onMounted(() => {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.search-box :deep(.ant-input-affix-wrapper) {
border-radius: 12px;
border: 2px solid #F0F0F0;
}
.search-box :deep(.ant-input-affix-wrapper:hover) {
border-color: #4facfe;

View File

@ -30,26 +30,16 @@
<div class="grade-tabs">
<span class="tab-label">年级筛选</span>
<div class="tab-buttons">
<div
v-for="grade in gradeOptions"
:key="grade.value"
class="grade-tab"
:class="{ active: selectedGrade === grade.value }"
@click="selectedGrade = grade.value"
>
<div v-for="grade in gradeOptions" :key="grade.value" class="grade-tab"
:class="{ active: selectedGrade === grade.value }" @click="selectedGrade = grade.value">
{{ grade.label }}
</div>
</div>
</div>
<div class="action-row">
<div class="search-box">
<a-input-search
v-model:value="searchKeyword"
placeholder="搜索课程名称"
style="width: 280px;"
@search="handleSearch"
allow-clear
>
<a-input-search v-model:value="searchKeyword" placeholder="搜索课程名称" style="width: 280px;"
@search="handleSearch" allow-clear>
<template #prefix>
<SearchOutlined style="color: #B2BEC3;" />
</template>
@ -64,12 +54,8 @@
<!-- 课程卡片网格 -->
<div class="course-grid" v-if="!loading && filteredCourses.length > 0">
<div
v-for="course in filteredCourses"
:key="course.id"
class="course-card"
:class="{ 'unauthorized': !course.authorized }"
>
<div v-for="course in filteredCourses" :key="course.id" class="course-card"
:class="{ 'unauthorized': !course.authorized }">
<div class="card-cover">
<div class="cover-placeholder" v-if="!course.pictureUrl">
<ReadOutlined class="cover-icon" />
@ -87,20 +73,12 @@
<p class="course-book">{{ course.pictureBookName }}</p>
<div class="course-tags">
<span
v-for="tag in course.gradeTags.slice(0, 2)"
:key="tag"
class="tag grade"
:style="getGradeTagStyle(translateGradeTag(tag))"
>
<span v-for="tag in course.gradeTags.slice(0, 2)" :key="tag" class="tag grade"
:style="getGradeTagStyle(translateGradeTag(tag))">
{{ translateGradeTag(tag) }}
</span>
<span
v-for="tag in course.domainTags.slice(0, 2)"
:key="tag"
class="tag domain"
:style="getDomainTagStyle(translateDomainTag(tag))"
>
<span v-for="tag in course.domainTags.slice(0, 2)" :key="tag" class="tag domain"
:style="getDomainTagStyle(translateDomainTag(tag))">
{{ translateDomainTag(tag) }}
</span>
</div>
@ -122,21 +100,12 @@
<FileTextOutlined />
详情
</a-button>
<a-button
v-if="!course.authorized"
type="link"
size="small"
class="auth-action"
@click="handleAuthorize(course)"
>
<a-button v-if="!course.authorized" type="link" size="small" class="auth-action"
@click="handleAuthorize(course)">
<StarFilled />
授权
</a-button>
<a-popconfirm
v-else
title="确定要取消授权吗?"
@confirm="handleRevoke(course)"
>
<a-popconfirm v-else title="确定要取消授权吗?" @confirm="handleRevoke(course)">
<a-button type="link" size="small" danger>
<StopOutlined />
取消
@ -164,13 +133,8 @@
</div>
<!-- 授权课程模态框 -->
<a-modal
v-model:open="authModalVisible"
width="800px"
class="auth-modal"
@ok="handleAuthModalOk"
@cancel="authModalVisible = false"
>
<a-modal v-model:open="authModalVisible" width="800px" class="auth-modal" @ok="handleAuthModalOk"
@cancel="authModalVisible = false">
<template #title>
<span class="modal-title">
<StarFilled class="modal-title-icon" />
@ -179,12 +143,7 @@
</template>
<div class="auth-content">
<div class="auth-search">
<a-input-search
v-model:value="searchKeyword"
placeholder="输入课程名称搜索..."
@search="searchCourses"
size="large"
>
<a-input-search v-model:value="searchKeyword" placeholder="输入课程名称搜索..." @search="searchCourses" size="large">
<template #prefix>
<SearchOutlined />
</template>
@ -192,13 +151,8 @@
</div>
<div class="available-courses" v-if="!authLoading && availableCourses.length > 0">
<div
v-for="course in availableCourses"
:key="course.id"
class="available-course-item"
:class="{ 'selected': selectedCourseIds.includes(course.id) }"
@click="toggleCourseSelection(course.id)"
>
<div v-for="course in availableCourses" :key="course.id" class="available-course-item"
:class="{ 'selected': selectedCourseIds.includes(course.id) }" @click="toggleCourseSelection(course.id)">
<div class="course-checkbox">
<CheckCircleOutlined v-if="selectedCourseIds.includes(course.id)" class="checkbox-check" />
</div>
@ -629,10 +583,6 @@ onMounted(() => {
gap: 12px;
}
.search-box :deep(.ant-input-affix-wrapper) {
border-radius: 12px;
border: 2px solid #F0F0F0;
}
.search-box :deep(.ant-input-affix-wrapper:hover) {
border-color: #43e97b;

View File

@ -28,13 +28,8 @@
<!-- 操作栏 -->
<div class="action-bar">
<div class="search-box">
<a-input-search
v-model:value="searchKeyword"
placeholder="搜索家长姓名/手机号/账号"
style="width: 280px;"
@search="handleSearch"
allow-clear
>
<a-input-search v-model:value="searchKeyword" placeholder="搜索家长姓名/手机号/账号" style="width: 280px;"
@search="handleSearch" allow-clear>
<template #prefix>
<SearchOutlined style="color: #B2BEC3;" />
</template>
@ -48,12 +43,8 @@
<!-- 家长卡片列表 -->
<div class="parent-grid" v-if="!loading && parents.length > 0">
<div
v-for="parent in parents"
:key="parent.id"
class="parent-card"
:class="{ 'inactive': parent.status !== 'ACTIVE' }"
>
<div v-for="parent in parents" :key="parent.id" class="parent-card"
:class="{ 'inactive': parent.status !== 'ACTIVE' }">
<div class="card-header">
<div class="parent-avatar">
<IdcardOutlined class="avatar-icon" />
@ -97,10 +88,7 @@
<a-button type="link" size="small" @click="handleResetPassword(parent)">
<KeyOutlined /> 重置
</a-button>
<a-popconfirm
title="确定要删除这位家长吗?"
@confirm="handleDelete(parent.id)"
>
<a-popconfirm title="确定要删除这位家长吗?" @confirm="handleDelete(parent.id)">
<a-button type="link" size="small" danger>
<DeleteOutlined /> 删除
</a-button>
@ -126,26 +114,14 @@
<!-- 分页 -->
<div class="pagination-wrapper" v-if="parents.length > 0">
<a-pagination
v-model:current="pagination.current"
v-model:pageSize="pagination.pageSize"
:total="pagination.total"
:show-size-changer="true"
:show-total="(total: number) => `共 ${total} 条`"
@change="handlePageChange"
/>
<a-pagination v-model:current="pagination.current" v-model:pageSize="pagination.pageSize"
:total="pagination.total" :show-size-changer="true" :show-total="(total: number) => `共 ${total} 条`"
@change="handlePageChange" />
</div>
<!-- 添加/编辑家长模态框 -->
<a-modal
v-model:open="modalVisible"
:title="isEdit ? '编辑家长' : '添加家长'"
@ok="handleModalOk"
@cancel="handleModalCancel"
:confirm-loading="submitting"
:width="520"
class="parent-modal"
>
<a-modal v-model:open="modalVisible" :title="isEdit ? '编辑家长' : '添加家长'" @ok="handleModalOk"
@cancel="handleModalCancel" :confirm-loading="submitting" :width="520" class="parent-modal">
<template #title>
<span class="modal-title">
<EditOutlined v-if="isEdit" class="modal-title-icon" />
@ -153,53 +129,47 @@
{{ isEdit ? '编辑家长' : '添加家长' }}
</span>
</template>
<a-form
ref="formRef"
:model="formState"
:rules="rules"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 16 }"
>
<a-form ref="formRef" :model="formState" :rules="rules" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
<a-form-item label="姓名" name="name">
<a-input v-model:value="formState.name" placeholder="请输入家长姓名">
<template #prefix><UserOutlined style="color: #B2BEC3;" /></template>
<template #prefix>
<UserOutlined style="color: #B2BEC3;" />
</template>
</a-input>
</a-form-item>
<a-form-item label="手机号" name="phone">
<a-input v-model:value="formState.phone" placeholder="请输入手机号">
<template #prefix><PhoneOutlined style="color: #B2BEC3;" /></template>
<template #prefix>
<PhoneOutlined style="color: #B2BEC3;" />
</template>
</a-input>
</a-form-item>
<a-form-item label="邮箱" name="email">
<a-input v-model:value="formState.email" placeholder="请输入邮箱(可选)">
<template #prefix><MailOutlined style="color: #B2BEC3;" /></template>
<template #prefix>
<MailOutlined style="color: #B2BEC3;" />
</template>
</a-input>
</a-form-item>
<a-form-item label="登录账号" name="loginAccount">
<a-input
v-model:value="formState.loginAccount"
placeholder="请输入登录账号"
:disabled="isEdit"
>
<template #prefix><KeyOutlined style="color: #B2BEC3;" /></template>
<a-input v-model:value="formState.loginAccount" placeholder="请输入登录账号" :disabled="isEdit">
<template #prefix>
<KeyOutlined style="color: #B2BEC3;" />
</template>
</a-input>
</a-form-item>
<a-form-item v-if="!isEdit" label="密码" name="password">
<a-input-password v-model:value="formState.password" placeholder="请输入密码默认123456">
<template #prefix><LockOutlined style="color: #B2BEC3;" /></template>
<template #prefix>
<LockOutlined style="color: #B2BEC3;" />
</template>
</a-input-password>
</a-form-item>
</a-form>
</a-modal>
<!-- 管理孩子模态框 -->
<a-modal
v-model:open="childrenModalVisible"
title="管理关联孩子"
:width="650"
:footer="null"
class="children-modal"
>
<a-modal v-model:open="childrenModalVisible" title="管理关联孩子" :width="650" :footer="null" class="children-modal">
<template #title>
<span class="modal-title">
<TeamOutlined class="modal-title-icon" />
@ -219,10 +189,7 @@
<div class="list-header">
<span>已关联孩子 ({{ parentChildren.length }})</span>
</div>
<a-list
:data-source="parentChildren"
:loading="childrenLoading"
>
<a-list :data-source="parentChildren" :loading="childrenLoading">
<template #renderItem="{ item }">
<a-list-item>
<a-list-item-meta>
@ -240,10 +207,7 @@
</template>
</a-list-item-meta>
<template #actions>
<a-popconfirm
title="确定要解除关联吗?"
@confirm="handleRemoveChild(item.id)"
>
<a-popconfirm title="确定要解除关联吗?" @confirm="handleRemoveChild(item.id)">
<a-button type="link" size="small" danger>
<DisconnectOutlined /> 解除
</a-button>
@ -259,13 +223,8 @@
</a-modal>
<!-- 选择学生弹窗 -->
<a-modal
v-model:open="selectStudentModalVisible"
title="选择孩子"
:width="800"
:footer="null"
class="select-student-modal"
>
<a-modal v-model:open="selectStudentModalVisible" title="选择孩子" :width="800" :footer="null"
class="select-student-modal">
<template #title>
<span class="modal-title">
<UserAddOutlined class="modal-title-icon" />
@ -275,20 +234,10 @@
<!-- 搜索和筛选 -->
<div class="select-search-bar">
<a-input-search
v-model:value="studentSearchKeyword"
placeholder="搜索学生姓名"
style="width: 240px;"
@search="handleStudentSearch"
allow-clear
/>
<a-select
v-model:value="studentClassFilter"
placeholder="按班级筛选"
style="width: 160px;"
allow-clear
@change="handleStudentSearch"
>
<a-input-search v-model:value="studentSearchKeyword" placeholder="搜索学生姓名" style="width: 240px;"
@search="handleStudentSearch" allow-clear />
<a-select v-model:value="studentClassFilter" placeholder="按班级筛选" style="width: 160px;" allow-clear
@change="handleStudentSearch">
<a-select-option v-for="cls in classOptions" :key="cls.id" :value="cls.id">
{{ cls.name }}
</a-select-option>
@ -296,17 +245,9 @@
</div>
<!-- 学生表格 -->
<a-table
:columns="studentTableColumns"
:data-source="studentTableData"
:loading="studentsLoading"
:pagination="studentPagination"
:row-selection="studentRowSelection"
row-key="id"
size="small"
@change="handleStudentTableChange"
style="margin-top: 16px;"
>
<a-table :columns="studentTableColumns" :data-source="studentTableData" :loading="studentsLoading"
:pagination="studentPagination" :row-selection="studentRowSelection" row-key="id" size="small"
@change="handleStudentTableChange" style="margin-top: 16px;">
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'gender'">
{{ record.gender === 'MALE' ? '男' : record.gender === 'FEMALE' ? '女' : '-' }}
@ -338,12 +279,7 @@
</a-modal>
<!-- 重置密码确认模态框 -->
<a-modal
v-model:open="resetPasswordVisible"
@ok="confirmResetPassword"
:confirm-loading="resetting"
:width="400"
>
<a-modal v-model:open="resetPasswordVisible" @ok="confirmResetPassword" :confirm-loading="resetting" :width="400">
<template #title>
<span class="modal-title">
<KeyOutlined class="modal-title-icon" />
@ -677,11 +613,11 @@ const loadStudentsForSelect = async () => {
studentsLoading.value = true;
try {
const result = await getStudents({
page: studentPagination.current,
pageSize: studentPagination.pageSize,
keyword: studentSearchKeyword.value || undefined,
classId: studentClassFilter.value || undefined,
});
page: studentPagination.current,
pageSize: studentPagination.pageSize,
keyword: studentSearchKeyword.value || undefined,
classId: studentClassFilter.value || undefined,
});
studentTableData.value = result.items;
studentPagination.total = result.total;
} catch (error) {
@ -836,11 +772,6 @@ onMounted(() => {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.search-box :deep(.ant-input-affix-wrapper) {
border-radius: 12px;
border: 2px solid #F0F0F0;
}
.search-box :deep(.ant-input-affix-wrapper:hover) {
border-color: #FF8C42;
}

View File

@ -38,24 +38,14 @@
<!-- 操作栏 -->
<div class="action-bar">
<div class="filters">
<a-select
v-model:value="selectedClassId"
placeholder="选择班级"
style="width: 150px;"
@change="handleClassChange"
allow-clear
>
<a-select v-model:value="selectedClassId" placeholder="选择班级" style="width: 150px;" @change="handleClassChange"
allow-clear>
<a-select-option v-for="cls in classes" :key="cls.id" :value="cls.id">
{{ cls.name }}
</a-select-option>
</a-select>
<a-input-search
v-model:value="searchKeyword"
placeholder="搜索学生姓名/家长"
style="width: 220px;"
@search="handleSearch"
allow-clear
>
<a-input-search v-model:value="searchKeyword" placeholder="搜索学生姓名/家长" style="width: 220px;"
@search="handleSearch" allow-clear>
<template #prefix>
<SearchOutlined style="color: #B2BEC3;" />
</template>
@ -75,11 +65,7 @@
<!-- 学生卡片网格 -->
<div class="student-grid" v-if="!loading && students.length > 0">
<div
v-for="student in students"
:key="student.id"
class="student-card"
>
<div v-for="student in students" :key="student.id" class="student-card">
<div class="card-header">
<div class="student-avatar" :class="normalizeGender(student.gender) === '男' ? 'boy' : 'girl'">
<UserOutlined class="avatar-icon" />
@ -93,7 +79,8 @@
<div class="card-body">
<div class="info-row">
<CalendarOutlined class="info-icon" />
<span class="info-value">{{ calculateAge(student.birthDate) || '--' }}{{ student.birthDate ? '岁' : '' }}</span>
<span class="info-value">{{ calculateAge(student.birthDate) || '--' }}{{ student.birthDate ? '岁' : ''
}}</span>
<span class="gender-tag" :class="normalizeGender(student.gender) === '男' ? 'boy' : 'girl'">
{{ normalizeGender(student.gender) }}
</span>
@ -119,10 +106,7 @@
<a-button type="link" size="small" @click="handleTransfer(student)">
<SwapOutlined /> 调班
</a-button>
<a-popconfirm
title="确定要删除这位学生吗?"
@confirm="handleDelete(student.id)"
>
<a-popconfirm title="确定要删除这位学生吗?" @confirm="handleDelete(student.id)">
<a-button type="link" size="small" danger>
<DeleteOutlined /> 删除
</a-button>
@ -150,37 +134,21 @@
<!-- 分页 -->
<div class="pagination-wrapper" v-if="students.length > 0">
<a-pagination
v-model:current="pagination.current"
v-model:pageSize="pagination.pageSize"
:total="pagination.total"
:show-size-changer="true"
:show-total="(total: number) => `共 ${total} 条`"
@change="handlePageChange"
/>
<a-pagination v-model:current="pagination.current" v-model:pageSize="pagination.pageSize"
:total="pagination.total" :show-size-changer="true" :show-total="(total: number) => `共 ${total} 条`"
@change="handlePageChange" />
</div>
<!-- 添加/编辑学生模态框 -->
<a-modal
v-model:open="modalVisible"
@ok="handleModalOk"
@cancel="handleModalCancel"
:confirm-loading="submitting"
:width="520"
>
<a-modal v-model:open="modalVisible" @ok="handleModalOk" @cancel="handleModalCancel" :confirm-loading="submitting"
:width="520">
<template #title>
<span class="modal-title">
<component :is="isEdit ? EditOutlined : PlusOutlined" class="modal-title-icon" />
{{ isEdit ? '编辑学生' : '添加学生' }}
</span>
</template>
<a-form
ref="formRef"
:model="formState"
:rules="rules"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 16 }"
>
<a-form ref="formRef" :model="formState" :rules="rules" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
<a-form-item label="姓名" name="name">
<a-input v-model:value="formState.name" placeholder="请输入学生姓名">
<template #prefix>
@ -190,17 +158,17 @@
</a-form-item>
<a-form-item label="性别" name="gender">
<a-radio-group v-model:value="formState.gender">
<a-radio value="男"><UserOutlined class="gender-icon boy" /> 男孩</a-radio>
<a-radio value="女"><UserOutlined class="gender-icon girl" /> 女孩</a-radio>
<a-radio value="男">
<UserOutlined class="gender-icon boy" /> 男孩
</a-radio>
<a-radio value="女">
<UserOutlined class="gender-icon girl" /> 女孩
</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="出生日期" name="birthDate">
<a-date-picker
v-model:value="formState.birthDate"
style="width: 100%;"
value-format="YYYY-MM-DD"
placeholder="选择出生日期"
/>
<a-date-picker v-model:value="formState.birthDate" style="width: 100%;" value-format="YYYY-MM-DD"
placeholder="选择出生日期" />
</a-form-item>
<a-form-item label="所在班级" name="classId">
<a-select v-model:value="formState.classId" placeholder="请选择班级" :loading="classesLoading">
@ -227,14 +195,8 @@
</a-modal>
<!-- 学生调班模态框 -->
<a-modal
v-model:open="transferModalVisible"
title="学生调班"
:confirm-loading="transferSubmitting"
@ok="handleTransferSubmit"
@cancel="transferModalVisible = false"
width="480px"
>
<a-modal v-model:open="transferModalVisible" title="学生调班" :confirm-loading="transferSubmitting"
@ok="handleTransferSubmit" @cancel="transferModalVisible = false" width="480px">
<div class="transfer-modal-content">
<div class="current-info">
<span>当前学生</span>
@ -243,22 +205,14 @@
</div>
<a-form layout="vertical">
<a-form-item label="目标班级" required>
<a-select
v-model:value="transferTargetClassId"
placeholder="请选择目标班级"
:loading="classesLoading"
>
<a-select v-model:value="transferTargetClassId" placeholder="请选择目标班级" :loading="classesLoading">
<a-select-option v-for="cls in classes" :key="cls.id" :value="cls.id">
{{ cls.name }} ({{ cls.grade }})
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="调班原因">
<a-textarea
v-model:value="transferReason"
placeholder="请输入调班原因(选填)"
:rows="3"
/>
<a-textarea v-model:value="transferReason" placeholder="请输入调班原因(选填)" :rows="3" />
</a-form-item>
</a-form>
@ -280,11 +234,7 @@
</a-modal>
<!-- 批量导入模态框 -->
<a-modal
v-model:open="importModalVisible"
:footer="null"
width="560px"
>
<a-modal v-model:open="importModalVisible" :footer="null" width="560px">
<template #title>
<span class="modal-title">
<DownloadOutlined class="modal-title-icon" />
@ -307,12 +257,8 @@
下载导入模板
</a-button>
<a-upload-dragger
:before-upload="beforeUpload"
:show-upload-list="false"
accept=".xlsx,.xls,.csv"
class="upload-area"
>
<a-upload-dragger :before-upload="beforeUpload" :show-upload-list="false" accept=".xlsx,.xls,.csv"
class="upload-area">
<div class="upload-content">
<FileAddOutlined class="upload-icon" />
<p class="upload-text">点击或拖拽文件到此区域上传</p>
@ -328,26 +274,15 @@
<div v-if="importFile" class="default-class-select">
<label>默认班级用于未指定班级的学生</label>
<a-select
v-model:value="importDefaultClassId"
placeholder="选择默认班级"
style="width: 100%;"
allow-clear
>
<a-select v-model:value="importDefaultClassId" placeholder="选择默认班级" style="width: 100%;" allow-clear>
<a-select-option v-for="cls in classes" :key="cls.id" :value="cls.id">
{{ cls.name }}
</a-select-option>
</a-select>
</div>
<a-button
type="primary"
:loading="importing"
:disabled="!importFile"
@click="handleImport"
block
class="import-submit-btn"
>
<a-button type="primary" :loading="importing" :disabled="!importFile" @click="handleImport" block
class="import-submit-btn">
<template v-if="!importing">
<RocketOutlined class="btn-icon" />
开始导入
@ -916,8 +851,7 @@ onMounted(() => {
gap: 12px;
}
.filters :deep(.ant-select-selector),
.filters :deep(.ant-input-affix-wrapper) {
.filters :deep(.ant-select-selector) {
border-radius: 12px;
border: 2px solid #F0F0F0;
}
@ -1390,7 +1324,8 @@ onMounted(() => {
gap: 12px;
}
.filters, .actions {
.filters,
.actions {
width: 100%;
flex-wrap: wrap;
}

View File

@ -28,13 +28,8 @@
<!-- 操作栏 -->
<div class="action-bar">
<div class="search-box">
<a-input-search
v-model:value="searchKeyword"
placeholder="搜索教师姓名/手机号/账号"
style="width: 280px;"
@search="handleSearch"
allow-clear
>
<a-input-search v-model:value="searchKeyword" placeholder="搜索教师姓名/手机号/账号" style="width: 280px;"
@search="handleSearch" allow-clear>
<template #prefix>
<SearchOutlined style="color: #B2BEC3;" />
</template>
@ -48,12 +43,8 @@
<!-- 教师卡片列表 -->
<div class="teacher-grid" v-if="!loading && teachers.length > 0">
<div
v-for="teacher in teachers"
:key="teacher.id"
class="teacher-card"
:class="{ 'inactive': teacher.status !== 'ACTIVE' }"
>
<div v-for="teacher in teachers" :key="teacher.id" class="teacher-card"
:class="{ 'inactive': teacher.status !== 'ACTIVE' }">
<div class="card-header">
<div class="teacher-avatar">
<SolutionOutlined class="avatar-icon" />
@ -79,9 +70,11 @@
<div class="info-row">
<BankOutlined class="info-icon" />
<span class="info-value classes-tag">
<span v-if="teacher.classNames && (Array.isArray(teacher.classNames) ? teacher.classNames.length > 0 : teacher.classNames)">
<span
v-if="teacher.classNames && (Array.isArray(teacher.classNames) ? teacher.classNames.length > 0 : teacher.classNames)">
{{ Array.isArray(teacher.classNames) ? teacher.classNames.slice(0, 2).join('、') : teacher.classNames }}
<span v-if="Array.isArray(teacher.classNames) && teacher.classNames.length > 2">{{ teacher.classNames.length }}个班级</span>
<span v-if="Array.isArray(teacher.classNames) && teacher.classNames.length > 2">{{
teacher.classNames.length }}个班级</span>
</span>
<span v-else class="no-class">未分配班级</span>
</span>
@ -99,10 +92,7 @@
<a-button type="link" size="small" @click="handleResetPassword(teacher)">
<KeyOutlined /> 重置密码
</a-button>
<a-popconfirm
title="确定要删除这位教师吗?"
@confirm="handleDelete(teacher.id)"
>
<a-popconfirm title="确定要删除这位教师吗?" @confirm="handleDelete(teacher.id)">
<a-button type="link" size="small" danger>
<DeleteOutlined /> 删除
</a-button>
@ -128,26 +118,14 @@
<!-- 分页 -->
<div class="pagination-wrapper" v-if="teachers.length > 0">
<a-pagination
v-model:current="pagination.current"
v-model:pageSize="pagination.pageSize"
:total="pagination.total"
:show-size-changer="true"
:show-total="(total: number) => `共 ${total} 条`"
@change="handlePageChange"
/>
<a-pagination v-model:current="pagination.current" v-model:pageSize="pagination.pageSize"
:total="pagination.total" :show-size-changer="true" :show-total="(total: number) => `共 ${total} 条`"
@change="handlePageChange" />
</div>
<!-- 添加/编辑教师模态框 -->
<a-modal
v-model:open="modalVisible"
:title="isEdit ? '编辑教师' : '添加教师'"
@ok="handleModalOk"
@cancel="handleModalCancel"
:confirm-loading="submitting"
:width="520"
class="teacher-modal"
>
<a-modal v-model:open="modalVisible" :title="isEdit ? '编辑教师' : '添加教师'" @ok="handleModalOk"
@cancel="handleModalCancel" :confirm-loading="submitting" :width="520" class="teacher-modal">
<template #title>
<span class="modal-title">
<EditOutlined v-if="isEdit" class="modal-title-icon" />
@ -155,49 +133,44 @@
{{ isEdit ? '编辑教师' : '添加教师' }}
</span>
</template>
<a-form
ref="formRef"
:model="formState"
:rules="rules"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 16 }"
>
<a-form ref="formRef" :model="formState" :rules="rules" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
<a-form-item label="姓名" name="name">
<a-input v-model:value="formState.name" placeholder="请输入教师姓名">
<template #prefix><UserOutlined style="color: #B2BEC3;" /></template>
<template #prefix>
<UserOutlined style="color: #B2BEC3;" />
</template>
</a-input>
</a-form-item>
<a-form-item label="手机号" name="phone">
<a-input v-model:value="formState.phone" placeholder="请输入手机号">
<template #prefix><PhoneOutlined style="color: #B2BEC3;" /></template>
<template #prefix>
<PhoneOutlined style="color: #B2BEC3;" />
</template>
</a-input>
</a-form-item>
<a-form-item label="邮箱" name="email">
<a-input v-model:value="formState.email" placeholder="请输入邮箱(可选)">
<template #prefix><MailOutlined style="color: #B2BEC3;" /></template>
<template #prefix>
<MailOutlined style="color: #B2BEC3;" />
</template>
</a-input>
</a-form-item>
<a-form-item label="登录账号" name="loginAccount">
<a-input
v-model:value="formState.loginAccount"
placeholder="请输入登录账号"
:disabled="isEdit"
>
<template #prefix><KeyOutlined style="color: #B2BEC3;" /></template>
<a-input v-model:value="formState.loginAccount" placeholder="请输入登录账号" :disabled="isEdit">
<template #prefix>
<KeyOutlined style="color: #B2BEC3;" />
</template>
</a-input>
</a-form-item>
<a-form-item v-if="!isEdit" label="密码" name="password">
<a-input-password v-model:value="formState.password" placeholder="请输入密码默认123456">
<template #prefix><LockOutlined style="color: #B2BEC3;" /></template>
<template #prefix>
<LockOutlined style="color: #B2BEC3;" />
</template>
</a-input-password>
</a-form-item>
<a-form-item label="负责班级" name="classIds">
<a-select
v-model:value="formState.classIds"
mode="multiple"
placeholder="请选择负责的班级"
:loading="classesLoading"
>
<a-select v-model:value="formState.classIds" mode="multiple" placeholder="请选择负责的班级" :loading="classesLoading">
<a-select-option v-for="cls in classes" :key="cls.id" :value="cls.id">
{{ cls.name }}
</a-select-option>
@ -207,12 +180,7 @@
</a-modal>
<!-- 重置密码确认模态框 -->
<a-modal
v-model:open="resetPasswordVisible"
@ok="confirmResetPassword"
:confirm-loading="resetting"
:width="400"
>
<a-modal v-model:open="resetPasswordVisible" @ok="confirmResetPassword" :confirm-loading="resetting" :width="400">
<template #title>
<span class="modal-title">
<KeyOutlined class="modal-title-icon" />
@ -557,10 +525,6 @@ onMounted(() => {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.search-box :deep(.ant-input-affix-wrapper) {
border-radius: 12px;
border: 2px solid #F0F0F0;
}
.search-box :deep(.ant-input-affix-wrapper:hover) {
border-color: #FF8C42;