Files
education/frontend/src/views/teachOffice/teacher/index.vue
T
2026-09-02 15:00:12 +08:00

1079 lines
44 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="app-container teacher-page">
<!-- 查询条件 -->
<el-card shadow="never" class="search-card">
<el-form :model="searchForm" label-width="90px" class="search-form" @submit.native.prevent>
<el-row :gutter="0">
<el-col :span="6">
<el-form-item label="教员姓名">
<el-input v-model="searchForm.jyxm" placeholder="请输入" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="教研室代号">
<el-input v-model="searchForm.jysdh" placeholder="请输入" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="职称">
<el-input v-model="searchForm.zc" placeholder="请输入" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="教员类别">
<el-input v-model="searchForm.jylb" placeholder="请输入" clearable />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="search-actions">
<el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button>
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
</div>
</el-card>
<!-- 教员列表 -->
<div class="list-title">教员列表</div>
<div class="list-toolbar">
<div class="left-group">
<el-button type="primary" icon="el-icon-plus" @click="handleNew">新建</el-button>
<el-button type="danger" plain icon="el-icon-delete" @click="handleDeleteSelected">删除所选</el-button>
</div>
</div>
<el-card shadow="never" class="table-card">
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="jybh" label="教员工号" width="110" align="center" />
<el-table-column prop="jyxm" label="教员姓名" width="90" align="center" />
<el-table-column label="性别" width="60" align="center">
<template slot-scope="{ row }">{{ fmtGender(row.xb) }}</template>
</el-table-column>
<el-table-column prop="jysmc" label="教研室名称" width="200" show-overflow-tooltip align="center"/>
<el-table-column prop="zc" label="职称" width="120" align="center" />
<el-table-column prop="xl" label="学历" width="120" align="center" />
<el-table-column prop="xw" label="学位" width="120" align="center" />
<el-table-column label="出生时间" width="110" align="center">
<template slot-scope="{ row }">{{ fmtDateTime(row.cssj) || '-' }}</template>
</el-table-column>
<el-table-column label="入伍工作时间" width="120" align="center">
<template slot-scope="{ row }">{{ fmtDateTime(row.rwgzsj) || '-' }}</template>
</el-table-column>
<el-table-column prop="sjh" label="联系方式" width="110" align="center" />
<el-table-column label="虚实类型" width="80" align="center">
<template slot-scope="{ row }">{{ fmtXslx(row.xslx) }}</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right">
<template slot-scope="{ row }">
<el-button type="text" size="small" icon="el-icon-view" @click="handleViewAttribute(row)">查看属性</el-button>
<el-button type="text" size="small" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" size="small" class="danger-text" @click="handleDisable(row)">离职</el-button>
</template>
</el-table-column>
</el-table>
<el-empty v-if="!loading && tableData.length === 0" description="暂无教员数据" :image-size="60" />
<div class="pagination-wrap">
<el-pagination
:current-page="pagination.pageNum"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新建教员对话框 -->
<el-dialog
:visible="addDialogVisible"
title="新建教员"
width="820px"
:close-on-click-modal="false"
@update:visible="val => addDialogVisible = val"
>
<el-form ref="addFormRef" :model="addForm" :rules="addRules" label-width="160px" class="add-form">
<el-divider content-position="left">教员基本信息</el-divider>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教员姓名" prop="teacher.jyxm"><el-input v-model="addForm.teacher.jyxm" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="性别" prop="teacher.xb">
<el-select v-model="addForm.teacher.xb" style="width:100%">
<el-option :value="1" label="男" /><el-option :value="0" label="女" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="序号" prop="teacher.xh"><el-input v-model="addForm.teacher.xh" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="身份证号" prop="teacher.sfzh"><el-input v-model="addForm.teacher.sfzh" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="专业技术职务等级" prop="teacher.zyjszwdj">
<el-select v-model="addForm.teacher.zyjszwdj" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in zyjszwdjOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="虚实类型" prop="teacher.xslx">
<el-radio-group v-model="addForm.teacher.xslx">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教员类别" prop="teacher.jylb">
<el-select v-model="addForm.teacher.jylb" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jylbOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="在职类别" prop="teacher.zzlb">
<el-select v-model="addForm.teacher.zzlb" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in zzlbOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="导师类别" prop="teacher.dslb">
<el-select v-model="addForm.teacher.dslb" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in dslbOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学缘" prop="teacher.xy"><el-input v-model="addForm.teacher.xy" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="额外允许开班数" prop="teacher.ewyxkbs">
<el-input-number v-model="addForm.teacher.ewyxkbs" :min="0" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="外训教员" prop="teacher.wxjy">
<el-radio-group v-model="addForm.teacher.wxjy">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="外训译员" prop="teacher.wxyy">
<el-radio-group v-model="addForm.teacher.wxyy">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="政治类教员" prop="teacher.zzljy">
<el-radio-group v-model="addForm.teacher.zzljy">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="职称"><el-input v-model="addForm.teacher.zc" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号"><el-input v-model="addForm.teacher.sjh" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="卡号"><el-input v-model="addForm.teacher.kh" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="拼音"><el-input v-model="addForm.teacher.py" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="专业技术职务等级时间">
<el-date-picker v-model="addForm.teacher.zyjszwdjsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职称时间">
<el-date-picker v-model="addForm.teacher.zcsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="备注"><el-input v-model="addForm.teacher.bz" type="textarea" :rows="2" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-divider content-position="left">教员属性</el-divider>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="学历"><el-input v-model="addForm.attributes.xl" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学位"><el-input v-model="addForm.attributes.xw" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教龄"><el-input-number v-model="addForm.attributes.jl" :min="0" style="width:100%" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教龄计算日期">
<el-date-picker v-model="addForm.attributes.jljsrq" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="主任">
<el-radio-group v-model="addForm.attributes.zr">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职务"><el-input v-model="addForm.attributes.zw" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="职务时间">
<el-date-picker v-model="addForm.attributes.zwsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="技术职务"><el-input v-model="addForm.attributes.jszw" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="技术职务时间">
<el-date-picker v-model="addForm.attributes.jszwsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="技术等级"><el-input v-model="addForm.attributes.jsdj" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="技术等级时间">
<el-date-picker v-model="addForm.attributes.jsdjsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="军衔文职"><el-input v-model="addForm.attributes.jxwz" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="军衔文职时间">
<el-date-picker v-model="addForm.attributes.jxwzsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出生时间">
<el-date-picker v-model="addForm.attributes.cssj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="入伍工作时间">
<el-date-picker v-model="addForm.attributes.rwgzsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="任代职经历"><el-input v-model="addForm.attributes.rdzjl" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="发表论文"><el-input v-model="addForm.attributes.fblw" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer">
<el-button @click="addDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="addSaving" @click="handleAddConfirm">确定</el-button>
</div>
</el-dialog>
<!-- 编辑教员基本信息对话框 -->
<el-dialog
:visible="editDialogVisible"
title="编辑教员信息"
width="780px"
:close-on-click-modal="false"
@update:visible="val => editDialogVisible = val"
>
<div v-loading="editLoading">
<el-form ref="editFormRef" :model="editForm" :rules="editRules" label-width="140px" class="add-form">
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教员编号"><el-input v-model="editForm.jybh" disabled /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教员姓名" prop="jyxm"><el-input v-model="editForm.jyxm" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教研室代号" prop="jysdh"><el-input v-model="editForm.jysdh" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="序号"><el-input v-model="editForm.xh" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="性别" prop="xb">
<el-select v-model="editForm.xb" style="width:100%">
<el-option :value="1" label="男" /><el-option :value="0" label="女" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="身份证号" prop="sfzh"><el-input v-model="editForm.sfzh" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="专业技术职务等级" prop="zyjszwdj"><el-input v-model="editForm.zyjszwdj" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="虚实类型" prop="xslx">
<el-radio-group v-model="editForm.xslx">
<el-radio :label="1">实教</el-radio>
<el-radio :label="0">非实教</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教员类别" prop="jylb"><el-input v-model="editForm.jylb" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="在职类别" prop="zzlb"><el-input v-model="editForm.zzlb" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="导师类别" prop="dslb"><el-input v-model="editForm.dslb" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学缘" prop="xy"><el-input v-model="editForm.xy" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="额外允许开班数" prop="ewyxkbs">
<el-input-number v-model="editForm.ewyxkbs" :min="0" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="外训教员" prop="wxjy">
<el-radio-group v-model="editForm.wxjy">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="外训译员" prop="wxyy">
<el-radio-group v-model="editForm.wxyy">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="政治类教员" prop="zzljy">
<el-radio-group v-model="editForm.zzljy">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="职称"><el-input v-model="editForm.zc" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号"><el-input v-model="editForm.sjh" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="卡号"><el-input v-model="editForm.kh" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="拼音"><el-input v-model="editForm.py" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="备注"><el-input v-model="editForm.bz" type="textarea" :rows="2" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div slot="footer">
<el-button @click="editDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="editSaving" @click="handleEditConfirm">保存</el-button>
</div>
</el-dialog>
<!-- 教员属性详情/编辑对话框 -->
<el-dialog
:visible="attributeVisible"
:title="attributeMode === 'view' ? '教员属性' : '编辑教员属性'"
width="720px"
:close-on-click-modal="false"
@update:visible="val => attributeVisible = val"
>
<div v-loading="attributeLoading || attributeSaving">
<template v-if="attributeMode === 'view'">
<el-descriptions :column="2" border size="medium">
<el-descriptions-item label="教员编号">{{ attributeData.jybh || '-' }}</el-descriptions-item>
<el-descriptions-item label="主任">{{ fmtFlag(attributeData.zr, '是', '否') }}</el-descriptions-item>
<el-descriptions-item label="职务">{{ attributeData.zw || '-' }}</el-descriptions-item>
<el-descriptions-item label="职务时间">{{ fmtDateTime(attributeData.zwsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="技术职务">{{ attributeData.jszw || '-' }}</el-descriptions-item>
<el-descriptions-item label="技术职务时间">{{ fmtDateTime(attributeData.jszwsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="技术等级">{{ attributeData.jsdj || '-' }}</el-descriptions-item>
<el-descriptions-item label="技术等级时间">{{ fmtDateTime(attributeData.jsdjsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="军衔文职">{{ attributeData.jxwz || '-' }}</el-descriptions-item>
<el-descriptions-item label="军衔文职时间">{{ fmtDateTime(attributeData.jxwzsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="出生时间">{{ fmtDateTime(attributeData.cssj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="学历">{{ attributeData.xl || '-' }}</el-descriptions-item>
<el-descriptions-item label="学位">{{ attributeData.xw || '-' }}</el-descriptions-item>
<el-descriptions-item label="入伍工作时间">{{ fmtDateTime(attributeData.rwgzsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="任代职经历">{{ attributeData.rdzjl || '-' }}</el-descriptions-item>
<el-descriptions-item label="发表论文">{{ attributeData.fblw || '-' }}</el-descriptions-item>
<el-descriptions-item label="教龄">{{ fmtVal(attributeData.jl) }}</el-descriptions-item>
<el-descriptions-item label="教龄计算日期">{{ fmtDateTime(attributeData.jljsrq) || '-' }}</el-descriptions-item>
</el-descriptions>
<div slot="footer" class="dialog-footer">
<el-button @click="attributeVisible = false">关闭</el-button>
<el-button type="primary" @click="handleStartEditAttribute">编辑</el-button>
</div>
</template>
<template v-else>
<el-form ref="attributeFormRef" :model="attributeForm" label-width="140px" class="add-form">
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教员编号"><el-input v-model="attributeForm.jybh" disabled /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="主任">
<el-radio-group v-model="attributeForm.zr">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="职务"><el-input v-model="attributeForm.zw" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职务时间">
<el-date-picker v-model="attributeForm.zwsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="技术职务"><el-input v-model="attributeForm.jszw" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="技术职务时间">
<el-date-picker v-model="attributeForm.jszwsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="技术等级"><el-input v-model="attributeForm.jsdj" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="技术等级时间">
<el-date-picker v-model="attributeForm.jsdjsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="军衔文职"><el-input v-model="attributeForm.jxwz" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="军衔文职时间">
<el-date-picker v-model="attributeForm.jxwzsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="出生时间">
<el-date-picker v-model="attributeForm.cssj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学历"><el-input v-model="attributeForm.xl" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="学位"><el-input v-model="attributeForm.xw" placeholder="选填" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="入伍工作时间">
<el-date-picker v-model="attributeForm.rwgzsj" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教龄"><el-input-number v-model="attributeForm.jl" :min="0" style="width:100%" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教龄计算日期">
<el-date-picker v-model="attributeForm.jljsrq" type="datetime" value-format="yyyy-MM-ddTHH:mm:ss" placeholder="选填" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="任代职经历"><el-input v-model="attributeForm.rdzjl" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="发表论文"><el-input v-model="attributeForm.fblw" placeholder="选填" /></el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleCancelEditAttribute">取消</el-button>
<el-button type="primary" :loading="attributeSaving" @click="handleSaveAttribute">保存</el-button>
</div>
</template>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listTeacher,
getTeacher,
addTeacher,
updateTeacher,
disableTeacher,
getTeacherAttribute,
updateTeacherAttribute
} from '@/api/teachOffice/teacher'
import { getDicts } from '@/api/system/dict/data'
export default {
name: 'Teacher',
data() {
return {
// 查询条件(仅后端 JYBMapper.xml 支持的字段:jyxm 模糊 / jysdh 等值 / zc 模糊 / jylb 等值)
searchForm: { jyxm: '', jysdh: '', zc: '', jylb: '' },
// 列表
loading: false,
tableData: [],
selectedRows: [],
pagination: { pageNum: 1, pageSize: 20, total: 0 },
// 新建
addDialogVisible: false,
addSaving: false,
addForm: this.createEmptyAddForm(),
addRules: {
'teacher.jyxm': [{ required: true, message: '请输入教员姓名', trigger: 'blur' }],
'teacher.xh': [{ required: true, message: '请输入序号', trigger: 'blur' }],
'teacher.zyjszwdj': [{ required: true, message: '请输入专业技术职务等级', trigger: 'blur' }],
'teacher.xslx': [{ required: true, message: '请选择虚实类型', trigger: 'change' }],
'teacher.jylb': [{ required: true, message: '请选择教员类别', trigger: 'change' }],
'teacher.zzlb': [{ required: true, message: '请选择在职类别', trigger: 'change' }],
'teacher.ewyxkbs': [{ required: true, message: '请输入额外允许开班数', trigger: 'change' }],
'teacher.dslb': [{ required: true, message: '请选择导师类别', trigger: 'change' }],
'teacher.xy': [{ required: true, message: '请输入学缘', trigger: 'blur' }],
'teacher.sfzh': [{ required: true, message: '请输入身份证号', trigger: 'blur' }],
'teacher.xb': [{ required: true, message: '请选择性别', trigger: 'change' }],
'teacher.wxjy': [{ required: true, message: '请选择外训教员', trigger: 'change' }],
'teacher.wxyy': [{ required: true, message: '请选择外训译员', trigger: 'change' }],
'teacher.zzljy': [{ required: true, message: '请选择政治类教员', trigger: 'change' }]
},
// 编辑
editDialogVisible: false,
editLoading: false,
editSaving: false,
editForm: {},
editRules: {
jyxm: [{ required: true, message: '请输入教员姓名', trigger: 'blur' }],
jysdh: [{ required: true, message: '请输入教研室代号', trigger: 'blur' }],
xb: [{ required: true, message: '请选择性别', trigger: 'change' }],
sfzh: [{ required: true, message: '请输入身份证号', trigger: 'blur' }],
zyjszwdj: [{ required: true, message: '请输入专业技术职务等级', trigger: 'blur' }],
xslx: [{ required: true, message: '请选择虚实类型', trigger: 'change' }],
jylb: [{ required: true, message: '请输入教员类别', trigger: 'blur' }],
zzlb: [{ required: true, message: '请输入在职类别', trigger: 'blur' }],
dslb: [{ required: true, message: '请输入导师类别', trigger: 'blur' }],
xy: [{ required: true, message: '请输入学缘', trigger: 'blur' }],
ewyxkbs: [{ required: true, message: '请输入额外允许开班数', trigger: 'change' }],
wxjy: [{ required: true, message: '请选择外训教员', trigger: 'change' }],
wxyy: [{ required: true, message: '请选择外训译员', trigger: 'change' }],
zzljy: [{ required: true, message: '请选择政治类教员', trigger: 'change' }]
},
// 教员属性
attributeVisible: false,
attributeMode: 'view',
attributeData: {},
attributeForm: {},
attributeLoading: false,
attributeSaving: false,
attributeJybh: '',
// 字典选项
zyjszwdjOptions: [],
jylbOptions: [],
zzlbOptions: [],
dslbOptions: []
}
},
mounted() {
this.fetchList()
this.loadDicts()
},
methods: {
/** 统一格式化后端 LocalDateTime(去除 T、截断到秒) */
fmtDateTime(val) {
if (val === null || val === undefined || val === '') return ''
return String(val).replace('T', ' ').slice(0, 19)
},
/** 空值显示为 '-' */
fmtVal(val) {
return (val === null || val === undefined || val === '') ? '-' : val
},
/** 性别:1-男 0-女(与后端 TeacherListVO 注释及学员页约定一致) */
fmtGender(val) {
if (val === null || val === undefined || val === '') return '-'
return Number(val) === 1 ? '男' : Number(val) === 0 ? '女' : String(val)
},
/** 虚实类型:1-实教 0-非实教(项目约定 1-实 0-虚) */
fmtXslx(val) {
if (val === null || val === undefined || val === '') return '-'
return Number(val) === 1 ? '实教' : Number(val) === 0 ? '非实教' : String(val)
},
/** 0/1 标志位格式化 */
fmtFlag(val, yesLabel, noLabel) {
if (val === null || val === undefined || val === '') return '-'
return Number(val) === 1 ? yesLabel : Number(val) === 0 ? noLabel : String(val)
},
/** 移除空值 */
loadDicts() {
getDicts('teacher_zyjszwdj').then(res => { this.zyjszwdjOptions = res.data || [] }).catch(() => {})
getDicts('teacher_jylb').then(res => { this.jylbOptions = res.data || [] }).catch(() => {})
getDicts('teacher_zzlb').then(res => { this.zzlbOptions = res.data || [] }).catch(() => {})
getDicts('teacher_dslb').then(res => { this.dslbOptions = res.data || [] }).catch(() => {})
},
cleanPayload(obj) {
const payload = {}
Object.keys(obj).forEach(key => {
const value = obj[key]
if (value !== '' && value !== null && value !== undefined) {
payload[key] = value
}
})
return payload
},
/** 创建空白新增表单 */
createEmptyAddForm() {
return {
teacher: {
jybh: '', jyxm: '', jysdh: '', xh: '', zyjszwdj: '', zyjszwdjsj: '',
xslx: 1, jylb: '', zzlb: '', dslb: '', xy: '', sfzh: '', xb: 1,
wxjy: 0, wxyy: 0, zzljy: 0, ewyxkbs: 0, zc: '', sjh: '', kh: '', py: '',
zcsj: '', bz: ''
},
attributes: {
xl: '', xw: '', jl: 0, jljsrq: '', zr: 0, zw: '', zwsj: '', jszw: '',
jszwsj: '', jsdj: '', jsdjsj: '', jxwz: '', jxwzsj: '', cssj: '',
rwgzsj: '', rdzjl: '', fblw: ''
}
}
},
// ==================== 列表 ====================
buildQuery() {
const params = {}
;['jyxm', 'jysdh', 'zc', 'jylb'].forEach(key => {
const value = this.searchForm[key]
if (value !== '' && value !== null && value !== undefined) {
params[key] = String(value).trim()
}
})
return params
},
fetchList() {
this.loading = true
const params = {
pageNum: this.pagination.pageNum,
pageSize: this.pagination.pageSize,
...this.buildQuery()
}
listTeacher(params).then(response => {
const data = response.data || {}
this.tableData = data.records || []
this.pagination.total = data.total || 0
this.loading = false
}).catch(() => {
this.tableData = []
this.pagination.total = 0
this.loading = false
})
},
handleSearch() {
this.pagination.pageNum = 1
this.fetchList()
},
handleReset() {
this.searchForm = { jyxm: '', jysdh: '', zc: '', jylb: '' }
this.pagination.pageNum = 1
this.fetchList()
},
handleSizeChange(size) {
this.pagination.pageSize = size
this.pagination.pageNum = 1
this.fetchList()
},
handleCurrentChange(page) {
this.pagination.pageNum = page
this.fetchList()
},
handleSelectionChange(rows) {
this.selectedRows = rows
},
// ==================== 无后端接口的操作 ====================
handleDeleteSelected() {
this.$message.info('后端暂未提供该接口')
},
// ==================== 新增 ====================
handleNew() {
this.addForm = this.createEmptyAddForm()
this.$nextTick(() => {
this.$refs.addFormRef && this.$refs.addFormRef.clearValidate()
})
this.addDialogVisible = true
},
handleAddConfirm() {
this.$refs.addFormRef.validate(valid => {
if (!valid) return
const dto = {
teacher: this.buildTeacherPayload(this.addForm.teacher),
attributes: this.buildAttributePayload(this.addForm.attributes)
}
this.addSaving = true
addTeacher(dto).then(() => {
this.$message.success('新增成功')
this.addDialogVisible = false
this.fetchList()
}).catch(() => {
}).finally(() => {
this.addSaving = false
})
})
},
/** 组装 JYB 请求体(lzzt 不传,后端自动置 0) */
buildTeacherPayload(t) {
const payload = this.cleanPayload({
jybh: t.jybh,
jyxm: t.jyxm,
jysdh: t.jysdh,
bz: t.bz,
zc: t.zc,
xh: t.xh,
zyjszwdj: t.zyjszwdj,
xslx: t.xslx,
jylb: t.jylb,
kh: t.kh,
py: t.py,
zzlb: t.zzlb,
ewyxkbs: t.ewyxkbs,
dslb: t.dslb,
xy: t.xy,
sfzh: t.sfzh,
xb: t.xb,
wxjy: t.wxjy,
wxyy: t.wxyy,
zzljy: t.zzljy,
sjh: t.sjh
})
// 整数/标志字段转 Number
;['xb', 'xslx', 'ewyxkbs', 'wxjy', 'wxyy', 'zzljy'].forEach(key => {
if (payload[key] !== undefined) payload[key] = Number(payload[key])
})
// 时间字段已由 date-picker 输出 ISO 格式
;['zyjszwdjsj', 'zcsj'].forEach(key => {
if (t[key]) payload[key] = t[key]
})
return payload
},
/** 组装 JYSX 请求体(仅非空字段) */
buildAttributePayload(a) {
const payload = this.cleanPayload({
xl: a.xl,
xw: a.xw,
jl: a.jl,
jljsrq: a.jljsrq,
zr: a.zr,
zw: a.zw,
zwsj: a.zwsj,
jszw: a.jszw,
jszwsj: a.jszwsj,
jsdj: a.jsdj,
jsdjsj: a.jsdjsj,
jxwz: a.jxwz,
jxwzsj: a.jxwzsj,
cssj: a.cssj,
rwgzsj: a.rwgzsj,
rdzjl: a.rdzjl,
fblw: a.fblw
})
if (payload.zr !== undefined) payload.zr = Number(payload.zr)
if (payload.jl !== undefined) payload.jl = Number(payload.jl)
return payload
},
// ==================== 编辑 ====================
handleEdit(row) {
this.editDialogVisible = true
this.editLoading = true
getTeacher(row.jybh).then(response => {
const data = response.data || {}
const form = this.createEmptyAddForm().teacher
Object.keys(form).forEach(key => {
if (data[key] !== undefined && data[key] !== null) form[key] = data[key]
})
this.editForm = form
this.editLoading = false
}).catch(() => {
this.editDialogVisible = false
this.editLoading = false
})
},
handleEditConfirm() {
this.$refs.editFormRef.validate(valid => {
if (!valid) return
if (!this.editForm.jybh) {
this.$message.warning('缺少教员编号,无法保存')
return
}
const payload = this.buildTeacherPayload(this.editForm)
payload.jybh = this.editForm.jybh
this.editSaving = true
updateTeacher(payload).then(() => {
this.$message.success('保存成功')
this.editDialogVisible = false
this.fetchList()
}).catch(() => {
}).finally(() => {
this.editSaving = false
})
})
},
// ==================== 离职(逻辑删除) ====================
handleDisable(row) {
if (!row.jybh) {
this.$message.warning('当前行缺少教员编号')
return
}
this.$confirm(`确定要办理教员「${row.jyxm || row.jybh}」离职吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
disableTeacher(row.jybh).then(() => {
this.$message.success('已办理离职')
this.fetchList()
}).catch(() => {})
}).catch(() => {})
},
// ==================== 教员属性 ====================
handleViewAttribute(row) {
this.attributeMode = 'view'
this.attributeJybh = row.jybh
this.attributeData = {}
this.attributeVisible = true
this.attributeLoading = true
getTeacherAttribute(row.jybh).then(response => {
this.attributeData = response.data || {}
this.attributeLoading = false
}).catch(() => {
this.attributeVisible = false
this.attributeLoading = false
})
},
handleStartEditAttribute() {
this.attributeForm = this.createEmptyAddForm().attributes
Object.keys(this.attributeForm).forEach(key => {
if (this.attributeData[key] !== undefined && this.attributeData[key] !== null) {
this.attributeForm[key] = this.attributeData[key]
}
})
this.attributeForm.jybh = this.attributeJybh
this.attributeMode = 'edit'
},
handleCancelEditAttribute() {
this.attributeMode = 'view'
},
handleSaveAttribute() {
const payload = this.buildAttributePayload(this.attributeForm)
payload.jybh = this.attributeJybh
this.attributeSaving = true
updateTeacherAttribute(payload).then(() => {
this.$message.success('保存成功')
this.attributeMode = 'view'
this.handleViewAttribute({ jybh: this.attributeJybh })
}).catch(() => {
}).finally(() => {
this.attributeSaving = false
})
}
}
}
</script>
<style scoped lang="scss">
.teacher-page {
.search-card {
margin-bottom: 16px;
.search-form {
.el-form-item {
margin-bottom: 0;
padding: 10px 12px;
}
}
.search-actions {
display: flex;
justify-content: flex-end;
padding: 12px;
border-top: 1px solid #ebeef5;
}
}
.list-title {
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 12px;
}
.list-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
margin-bottom: 16px;
.left-group,
.right-group {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
}
.table-card {
margin-bottom: 16px;
::v-deep(.el-table) {
width: 100%;
}
.pagination-wrap {
display: flex;
justify-content: flex-end;
margin-top: 16px;
}
}
.danger-text {
color: #f56c6c;
}
}
</style>