init
This commit is contained in:
@@ -0,0 +1,516 @@
|
||||
<template>
|
||||
<div class="group-manage-page">
|
||||
<!-- 顶部操作栏 -->
|
||||
<div class="top-header">
|
||||
<div class="left-btn-group">
|
||||
<Button type="primary" @click="openAddModal">添加</Button>
|
||||
<Button type="success" style="margin-left:10px" @click="openImportModal">批量导入</Button>
|
||||
</div>
|
||||
<div class="right-tab-group">
|
||||
<Button :type="activeType==='1'?'primary':'default'" @click="changeType('1')">年级组</Button>
|
||||
<Button :type="activeType==='2'?'primary':'default'" style="margin-left:6px" @click="changeType('2')">教研组</Button>
|
||||
<Button :type="activeType==='3'?'primary':'default'" style="margin-left:6px" @click="changeType('3')">备课组</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 三栏主体布局 -->
|
||||
<div class="three-col-container">
|
||||
<!-- 左侧:分组栏 -->
|
||||
<div class="col-wrap">
|
||||
<h3 class="col-title">组</h3>
|
||||
<div class="list-scroll-box">
|
||||
<div
|
||||
class="group-item"
|
||||
:class="{active: selectGroupIndex === index}"
|
||||
v-for="(item, index) in groupList"
|
||||
:key="index"
|
||||
@click="selectGroup(index)"
|
||||
>
|
||||
{{ item.cgName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-bottom-btns">
|
||||
<Button type="error" @click="delGroup">删除分组</Button>
|
||||
<Button style="margin-left:8px" @click="editGroup">编辑分组</Button>
|
||||
<Button type="primary">Primary</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中间:组员栏 -->
|
||||
<div class="col-wrap">
|
||||
<h3 class="col-title">组员</h3>
|
||||
<div class="list-scroll-box">
|
||||
<template v-if="groupList.length>0">
|
||||
<div class="member-item" v-for="(item, idx) in groupList[selectGroupIndex].cgMember" :key="idx">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="col-bottom-btns">
|
||||
<Button type="error" @click="openSetMember">设置组员</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:组长栏 -->
|
||||
<div class="col-wrap">
|
||||
<h3 class="col-title">组长</h3>
|
||||
<div class="list-scroll-box">
|
||||
<template v-if="groupList.length>0">
|
||||
<div class="leader-item" v-for="(item, idx) in groupList[selectGroupIndex].cgLeader" :key="idx">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="col-bottom-btns">
|
||||
<Button type="error" @click="openSetLeader">设置组长</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 弹窗1:添加学科 -->
|
||||
<Modal v-model="addModalVisible" :title="addFormData.id?'编辑组':'添加组'" width="520">
|
||||
<Form ref="addForm" :model="addFormData" label-width="90">
|
||||
<FormItem label="组名">
|
||||
<Input v-model="addFormData.groupName" maxlength="20" placeholder="最多可输入20个字符"/>
|
||||
</FormItem>
|
||||
<FormItem label="年级">
|
||||
<Select v-model="addFormData.gradeIds" placeholder="请选择" style="width:100%" multiple transfer>
|
||||
<Option v-for="(item,index) in gradeselectlist" :key="index" :value="item.id">{{ item.name }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label="学科">
|
||||
<Select v-model="addFormData.subjectIds" placeholder="请选择" style="width:100%" multiple transfer>
|
||||
<Option v-for="(item,index) in subjectselectlist" :key="index" :value="item.id">{{ item.name }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="addModalVisible = false">取消</Button>
|
||||
<Button type="primary" @click="submitAdd">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗2:教师批量导入 -->
|
||||
<Modal v-model="importModalVisible" title="批量导入分组信息" width="520">
|
||||
<div class="main-contents">
|
||||
<Form ref="UpParmas.datapre" :model="UpParmas.datapre" :label-width="100" inline>
|
||||
<FormItem label="Excel上传:" style="margin-bottom:10px;width:100%;">
|
||||
<i-input type="text" style="width:90%;" v-model="UpParmas.fileName" class="import-input" placeholder="未选中任何文件.." readonly></i-input>
|
||||
<Upload class="fr btn"
|
||||
:action="UpParmas.actionUrl"
|
||||
:data="UpParmas.datapre"
|
||||
:show-upload-list="false"
|
||||
:headers="uploadHeader"
|
||||
accept=".xls,.xlsx"
|
||||
:before-upload="handleUpload"
|
||||
:on-success="importFile"
|
||||
>
|
||||
<i-button icon="md-add"></i-button>
|
||||
</Upload>
|
||||
</FormItem>
|
||||
<FormItem v-if="UpParmas.listData.data!=null" style="margin-bottom:10px">
|
||||
<div v-if="UpParmas.listData.code==0" style="color:red">导入失败,请修改Excel文件中相关数据后再重新上传!</div>
|
||||
<div v-if="UpParmas.listData.code!=0" style="color:green">导入成功!</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
|
||||
<Alert show-icon>
|
||||
操作说明:
|
||||
<Icon type="ios-bulb-outline" slot="icon" size="20"></Icon>
|
||||
<template slot="desc" style="font-size: 12px;">
|
||||
请先上传EXCEL文件,若成功则显示导入成功数据,否则显示错误的数据及错误原因;<br>
|
||||
EXCEL文件的格式():工作表(WorkSheet)的名称应设为缺省的[Sheet1];<br>
|
||||
<a @click="MoBanExceldaochu" style="font-size:12px;">点击链接下载[分组导入模板.xls]</a>
|
||||
</template>
|
||||
</Alert>
|
||||
|
||||
<Table :columns="UpParmas.columns" :data="UpParmas.listData.data" v-if="UpParmas.listData.data"></Table>
|
||||
</div>
|
||||
<Spin fix v-if="spinShow">
|
||||
<Icon type="ios-loading" size=30 class="demo-spin-icon-load"></Icon>
|
||||
<div>上传中...</div>
|
||||
</Spin>
|
||||
<div slot="footer">
|
||||
<i-Button @click="UpfileModalcloseclick" style="margin-left: 8px">关闭</i-Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<user-check ref="userCheck" :treeData="treeData" v-model="userids" @on-submit="submit" :isDisabled="isAddto" />
|
||||
<user-check ref="userCheck2" :treeData="treeData" v-model="userids2" @on-submit="submit2" :isDisabled="isAddto" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import userCheck from "@/components/user_check.vue";
|
||||
export default {
|
||||
name: 'GroupTeacherManage',
|
||||
components: {userCheck},
|
||||
data() {
|
||||
return {
|
||||
// 顶部切换类型 grade年级组 / teach教研组 / prepare备课组
|
||||
activeType: '1',
|
||||
// 当前选中分组下标
|
||||
selectGroupIndex: 0,
|
||||
gradeselectlist:[],
|
||||
subjectselectlist:[],
|
||||
// 分组列表
|
||||
groupList: [],
|
||||
treeData: [],
|
||||
userids: [],
|
||||
userids2: [],
|
||||
userNames: [],
|
||||
isAddto: false,
|
||||
|
||||
// 添加分组弹窗
|
||||
addModalVisible: false,
|
||||
addFormData: {
|
||||
id:'',
|
||||
groupName: '',
|
||||
gradeIds: [],
|
||||
subjectIds: []
|
||||
},
|
||||
|
||||
// 批量导入弹窗
|
||||
importModalVisible: false,
|
||||
spinShow:false,
|
||||
UpParmas:{
|
||||
fileName:'',
|
||||
listData:{},
|
||||
datapre:{},
|
||||
actionUrl:APIConfig.BschClassSystem.importCustomGroup,
|
||||
columns:[
|
||||
{
|
||||
title: '行号',
|
||||
key: 'rows',
|
||||
align: 'center',
|
||||
width:'80'
|
||||
},
|
||||
{
|
||||
title: '内容',
|
||||
key: 'columnValue',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '错误详情',
|
||||
key: 'errorMsg',
|
||||
align: 'center',
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
uploadHeader() { //附件上传header
|
||||
let config = {};
|
||||
if (localStorage.getItem("currentRole")) {
|
||||
let currentRole = localStorage.getItem("currentRole");
|
||||
config["currentRole"] = currentRole;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
},
|
||||
created(){
|
||||
var _this=this;
|
||||
_this.treeData = [
|
||||
{
|
||||
name: "教师",
|
||||
data: [
|
||||
{
|
||||
name: "基础平台",
|
||||
data: _this.getTreeData2(),
|
||||
}
|
||||
],
|
||||
},
|
||||
];
|
||||
},
|
||||
mounted() {
|
||||
this.getgradeselect();
|
||||
this.getsubjectselect();
|
||||
this.getSchCustomGroup();
|
||||
},
|
||||
methods: {
|
||||
//获取年级下拉
|
||||
getgradeselect:function(){
|
||||
const _this = this;
|
||||
var item={};
|
||||
_this.$api.get(APIConfig.BschClassSystem.getgradeselect, item, resp => {
|
||||
if(resp.code==0)
|
||||
{
|
||||
this.gradeselectlist=resp.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
//获取学科下拉
|
||||
getsubjectselect:function(){
|
||||
const _this = this;
|
||||
var item={};
|
||||
_this.$api.get(APIConfig.BschClassSystem.getsubjectselect, item, resp => {
|
||||
if(resp.code==0)
|
||||
{
|
||||
this.subjectselectlist=resp.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取教师分组列表
|
||||
getSchCustomGroup() {
|
||||
const _this = this;
|
||||
let item={
|
||||
type:_this.activeType
|
||||
};
|
||||
_this.$api.get(APIConfig.BschClassSystem.getSchCustomGroup, item, resp => {
|
||||
if (resp.code == 0) {
|
||||
_this.groupList = resp.data;
|
||||
} else {
|
||||
_this.groupList = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
// 切换顶部分组类型
|
||||
changeType(type) {
|
||||
this.activeType = type;
|
||||
this.groupList=[];
|
||||
// 此处可请求接口重新加载对应分组数据
|
||||
this.getSchCustomGroup();
|
||||
},
|
||||
// 选中左侧分组
|
||||
selectGroup(index) {
|
||||
this.selectGroupIndex = index
|
||||
// 模拟切换分组加载组员、组长数据
|
||||
this.getSchCustomGroup();
|
||||
},
|
||||
|
||||
// 打开添加弹窗
|
||||
openAddModal() {
|
||||
this.addModalVisible = true
|
||||
this.addFormData = {id:'', groupName: '', grade: '', subject: '' }
|
||||
},
|
||||
// 提交新增分组
|
||||
submitAdd() {
|
||||
this.$refs.addForm.validate(valid => {
|
||||
if (!valid) return
|
||||
const newItem = {
|
||||
groupName:this.addFormData.groupName,
|
||||
groupType:this.activeType,
|
||||
gradeIds:this.addFormData.gradeIds,
|
||||
subjectIds:this.addFormData.subjectIds
|
||||
}
|
||||
if(this.addFormData.id){
|
||||
newItem.id=this.addFormData.id;
|
||||
}
|
||||
const url = APIConfig.BschClassSystem.saveSchCustomGroup;
|
||||
this.$api.post(url, JSON.stringify(newItem), resp => {
|
||||
if (resp.code == 0) {
|
||||
this.$Message.success(this.addFormData.id?"新增分组成功!":"保存分组成功!");
|
||||
this.addModalVisible = false;
|
||||
this.getSchCustomGroup();
|
||||
} else if (resp.code == 4) {
|
||||
this.$Message.info(resp.msg);
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
// 编辑分组
|
||||
editGroup() {
|
||||
this.addFormData.id=this.groupList[this.selectGroupIndex].cgId;
|
||||
this.addFormData.groupName=this.groupList[this.selectGroupIndex].cgName;
|
||||
this.addFormData.gradeIds=this.groupList[this.selectGroupIndex].gradeIds;
|
||||
this.addFormData.subjectIds=this.groupList[this.selectGroupIndex].subjectIds;
|
||||
this.addModalVisible=true;
|
||||
},
|
||||
// 删除分组
|
||||
delGroup() {
|
||||
this.$Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定删除该分组?删除后不可恢复',
|
||||
onOk: () => {
|
||||
let item={
|
||||
groupId:this.groupList[this.selectGroupIndex].cgId
|
||||
};
|
||||
var url=APIConfig.BschClassSystem.deleteSchCustomGroup;
|
||||
this.$api.post(url,item,(resp)=>{
|
||||
this.selectGroupIndex = 0
|
||||
this.$Message.success('删除成功!');
|
||||
this.getSchCustomGroup();
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 设置组员
|
||||
openSetMember() {
|
||||
this.userids=this.groupList[this.selectGroupIndex].cgMember.map(a=>a.id);
|
||||
this.$refs.userCheck.show();
|
||||
},
|
||||
// 设置组长
|
||||
openSetLeader() {
|
||||
this.userids2=this.groupList[this.selectGroupIndex].cgLeader.map(a=>a.id);
|
||||
this.$refs.userCheck2.show();
|
||||
},
|
||||
// 设置组员确认
|
||||
submit(arr) {
|
||||
// if(arr.length==0){
|
||||
// this.$Message.info('请选择组员!');
|
||||
// return;
|
||||
// }
|
||||
let teaIds = arr.map(x => x.id);
|
||||
let item={
|
||||
groupId:this.groupList[this.selectGroupIndex].cgId,
|
||||
teaIds:teaIds
|
||||
};
|
||||
var url=APIConfig.BschClassSystem.saveMembers;
|
||||
this.$api.post(url,JSON.stringify(item),(resp)=>{
|
||||
this.$Message.success('设置组员成功!');
|
||||
this.getSchCustomGroup();
|
||||
});
|
||||
},
|
||||
// 设置组长确认
|
||||
submit2(arr) {
|
||||
let teaIds = arr.map(x => x.id);
|
||||
let item={
|
||||
groupId:this.groupList[this.selectGroupIndex].cgId,
|
||||
leaderIds:teaIds
|
||||
};
|
||||
var url=APIConfig.BschClassSystem.setLeaders;
|
||||
this.$api.post(url,JSON.stringify(item),(resp)=>{
|
||||
this.$Message.success('设置组长成功!');
|
||||
this.getSchCustomGroup();
|
||||
});
|
||||
},
|
||||
getTreeData2() {
|
||||
return () =>
|
||||
new Promise((resolve, reject) => {
|
||||
this.$api.get(APIConfig.BschClassSystem.getTeacherTree, null, resp => {
|
||||
console.log("请求完成!");
|
||||
resolve([resp.data]);
|
||||
});
|
||||
});
|
||||
},
|
||||
// 批量导入相关
|
||||
openImportModal() {
|
||||
this.importModalVisible = true
|
||||
},
|
||||
//导入成功返回
|
||||
importFile(response, file, fileList){
|
||||
const _this=this;
|
||||
console.log(response);
|
||||
console.log(file);
|
||||
_this.spinShow=false;
|
||||
_this.UpParmas.fileName=file.name;
|
||||
_this.UpParmas.listData=response;
|
||||
if(response.State)
|
||||
{
|
||||
_this.$Message.info('导入成功!');
|
||||
_this.getteachssearch();
|
||||
}else{
|
||||
_this.$Message.info(response.Message);
|
||||
}
|
||||
},
|
||||
//附件上传之前的方法
|
||||
handleUpload:function(file){
|
||||
const _this=this;
|
||||
_this.spinShow=true;
|
||||
},
|
||||
//模版导出
|
||||
MoBanExceldaochu() {
|
||||
var _this = this;
|
||||
if (localStorage.getItem("currentRole")) {
|
||||
let currentRole = localStorage.getItem("currentRole");
|
||||
let { schId, roleId, userId, childId } = JSON.parse(decodeURIComponent(currentRole));
|
||||
let query='?schId='+schId;
|
||||
var url=APIConfig.BschClassSystem.GroupdownloadTemplate+query;
|
||||
window.location.href=url;
|
||||
}else{
|
||||
this.$Message.info('获取不了学校!');
|
||||
}
|
||||
},
|
||||
//附件上传模态框关闭事件
|
||||
UpfileModalcloseclick:function(){
|
||||
this.importModalVisible=false;
|
||||
this.UpParmas={
|
||||
fileName:'',
|
||||
listData:{},
|
||||
datapre:{},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.group-manage-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding: 12px;
|
||||
}
|
||||
/* 顶部栏 */
|
||||
.top-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 14px;
|
||||
background: #f7f7f7;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.left-btn-group, .right-tab-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 三栏容器 */
|
||||
.three-col-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 16px;
|
||||
min-height: 0;
|
||||
}
|
||||
.col-wrap {
|
||||
flex: 1;
|
||||
border: 1px solid #e5e7eb;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
.col-title {
|
||||
margin: 12px 14px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* 滚动列表区域 */
|
||||
.list-scroll-box {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
padding: 0 14px;
|
||||
}
|
||||
.group-item {
|
||||
padding: 8px 10px;
|
||||
margin: 4px 0;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.group-item.active {
|
||||
background: #9b77e9;
|
||||
color: #fff;
|
||||
}
|
||||
.member-item, .leader-item {
|
||||
padding: 6px 10px;
|
||||
margin: 3px 0;
|
||||
}
|
||||
/* 底部按钮 */
|
||||
.col-bottom-btns {
|
||||
padding: 12px 14px;
|
||||
border-top: 1px solid #eee;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.ivu-alert-desc{
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div class="page-wrap">
|
||||
<!-- 顶部搜索区域 -->
|
||||
<div class="top-search-bar">
|
||||
<div class="placeholder-left"></div>
|
||||
<Input
|
||||
v-model="searchKey"
|
||||
placeholder="账号、姓名、联系电话、变动详情"
|
||||
style="width: 360px"
|
||||
suffix="ios-search"
|
||||
@on-search="handleSearch"
|
||||
clearable
|
||||
></Input>
|
||||
</div>
|
||||
|
||||
<!-- 核心:表格自适应滚动容器 -->
|
||||
<div class="table-scroll-box">
|
||||
<Table
|
||||
border
|
||||
stripe
|
||||
:columns="tableColumns"
|
||||
:data="tableData"
|
||||
class="teacher-table"
|
||||
@on-selection-change="selectionChange"
|
||||
:height="useTableHeight()-12"
|
||||
></Table>
|
||||
</div>
|
||||
|
||||
<!-- 分页栏:固定在底部,不会滚动 -->
|
||||
<div class="page-fixed-bottom">
|
||||
<span class="total-text">共 {{ total }} 条</span>
|
||||
<Page
|
||||
:current.sync="pageNum"
|
||||
:total="total"
|
||||
:page-size="pageSize"
|
||||
:page-size-opts="[10,20,50]"
|
||||
show-sizer
|
||||
@on-change="pageChange"
|
||||
@on-page-size-change="sizeChange"
|
||||
></Page>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { self_viewport } from "@/mixins/self_viewport";
|
||||
export default {
|
||||
name: 'TeacherChangeRecord',
|
||||
data() {
|
||||
return {
|
||||
searchKey: '',
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
total: 52,
|
||||
selectedRows: [],
|
||||
|
||||
tableColumns: [
|
||||
{
|
||||
title: '序号',
|
||||
align: 'center',
|
||||
width: 70,
|
||||
render: (h, params) => {
|
||||
const num = (this.pageNum - 1) * this.pageSize + params.index + 1
|
||||
return h('span', num)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '教师账号',
|
||||
key: 'account',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '教师姓名',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '联系电话',
|
||||
key: 'phone',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '变动详情',
|
||||
key: 'changeInfo',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '变动日期',
|
||||
key: 'changeDate',
|
||||
align: 'center'
|
||||
}
|
||||
],
|
||||
|
||||
tableData: [
|
||||
{ account: '13761014664', name: '郭秀丽', phone: '13761014664', changeInfo: '从上海市进才中学北校转出', changeDate: '2020-04-01' },
|
||||
{ account: '13761040842', name: '刘莉', phone: '13761040842', changeInfo: '从上海市进才中学北校转出', changeDate: '2020-07-08' },
|
||||
{ account: '13482212686', name: '万凤翠', phone: '13482212686', changeInfo: '从上海市进才中学北校转出', changeDate: '2020-07-08' },
|
||||
{ account: '13681943351', name: '许娟', phone: '13681943351', changeInfo: '从上海市进才中学北校转出', changeDate: '2020-07-08' },
|
||||
{ account: '18816921752', name: '许曼', phone: '18816921752', changeInfo: '从上海市进才中学北校转出', changeDate: '2020-07-08' },
|
||||
{ account: '18017500305', name: '龚庆', phone: '18017500305', changeInfo: '从上海市进才中学北校转出', changeDate: '2020-07-08' },
|
||||
{ account: '13901923389', name: '俞胜', phone: '13901923389', changeInfo: '从上海市进才中学北校转出', changeDate: '2020-08-30' },
|
||||
{ account: '13371935731', name: '刘涵', phone: '13371935731', changeInfo: '从上海市进才中学北校教辅转出', changeDate: '2021-06-01' }
|
||||
]
|
||||
}
|
||||
},
|
||||
mixins: [self_viewport],
|
||||
mounted() {
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
selectionChange(rows) {
|
||||
this.selectedRows = rows
|
||||
},
|
||||
loadData() {
|
||||
console.log('分页参数', this.pageNum, this.pageSize, this.searchKey)
|
||||
// 接口请求示例
|
||||
// this.$axios.get('/api/teacher/changeList', { params: { pageNum, pageSize, keyword: searchKey } }).then(res => {
|
||||
// this.tableData = res.data.records
|
||||
// this.total = res.data.total
|
||||
// })
|
||||
},
|
||||
handleSearch() {
|
||||
this.pageNum = 1
|
||||
this.loadData()
|
||||
},
|
||||
pageChange(p) {
|
||||
this.pageNum = p
|
||||
this.loadData()
|
||||
},
|
||||
sizeChange(size) {
|
||||
this.pageSize = size
|
||||
this.pageNum = 1
|
||||
this.loadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 页面根容器:占满父高度,纵向弹性布局 */
|
||||
.page-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
/* 顶部搜索栏 固定高度不压缩 */
|
||||
.top-search-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 14px;
|
||||
background: #f7f7f7;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.placeholder-left {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 表格区域:自动填充剩余高度,内容超出滚动 */
|
||||
.table-scroll-box {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
.table-scroll-box >>> .teacher-table {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 分页容器:固定在底部,禁止被压缩、不会随表格滚动 */
|
||||
.page-fixed-bottom {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding-top: 12px;
|
||||
gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.total-text {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,945 @@
|
||||
<template>
|
||||
<div class="outer-wrap">
|
||||
<div class="page-flex-layout">
|
||||
<!-- 左侧分组树形栏 -->
|
||||
<div class="tree-sidebar">
|
||||
<div class="tree-op-buttons">
|
||||
<Tooltip content="添加子组" placement="top-start">
|
||||
<Button shape="circle" size="default" @click="openAddGroupModal" title="添加子组">
|
||||
<Icon type="ios-add"></Icon>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip content="修改子组" placement="top-start">
|
||||
<Button :disabled="selectnodetype==7" shape="circle" size="default" @click="openEditGroupModal" title="修改子组">
|
||||
<Icon type="ios-create-outline"></Icon>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip content="移动子组" placement="top-start">
|
||||
<Button :disabled="selectnodetype==7" shape="circle" size="default" @click="openMoveGroupModal" title="移动子组">
|
||||
<Icon type="ios-folder-open"></Icon>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip content="删除子组" placement="top-start">
|
||||
<Button :disabled="selectnodetype==7" shape="circle" size="default" @click="delCurrentGroup" title="删除子组">
|
||||
<Icon type="ios-trash"></Icon>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<my-tree :treeData="treeData" @on-tree-click="treeLink"></my-tree>
|
||||
</div>
|
||||
|
||||
<!-- 右侧教师主体区域 -->
|
||||
<div class="right-main">
|
||||
<!-- 顶部操作栏 -->
|
||||
<div class="top-tool-bar">
|
||||
<div class="left-btn-group">
|
||||
<Button :disabled="selectnodetype==7" type="primary" @click="openAddTeacherModal">添加教师</Button>
|
||||
<Button type="success" style="margin-left:10px" @click="openImportModal">教师导入</Button>
|
||||
</div>
|
||||
<div class="search-wrap">
|
||||
<Input
|
||||
class="fr"
|
||||
v-model="searchKeyword"
|
||||
placeholder="请输入教师名字或教师账号"
|
||||
search
|
||||
style="width:260px"
|
||||
@on-search="searchTeacher"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 【修复重点容器】表格自适应区域 -->
|
||||
<div class="table-adapt-wrap">
|
||||
<div class="table-scroll">
|
||||
<Table
|
||||
border
|
||||
stripe
|
||||
:columns="tableColumns"
|
||||
:data="tableData"
|
||||
class="teacher-table"
|
||||
@on-selection-change="selectionChange"
|
||||
:height="useTableHeight({ isSearch: true, isOperat: true })-22"
|
||||
></Table>
|
||||
</div>
|
||||
<!-- 分页栏:永远固定在表格底部,不跟随滚动 -->
|
||||
<div class="bottom-bar">
|
||||
<div class="batch-btn-group">
|
||||
<Button type="error" @click="batchDeleteTeacher">删除教师</Button>
|
||||
<Button style="margin-left:8px" @click="batchTransferTeacher">转出教师</Button>
|
||||
<Button style="margin-left:8px" @click="openBatchMoveTeacherModal">移动教师</Button>
|
||||
<Button style="margin-left:8px" @click="openSetStatusModal">设置状态</Button>
|
||||
</div>
|
||||
<div class="pagination-wrap">
|
||||
<Page
|
||||
:current.sync="pageNum"
|
||||
:total="total"
|
||||
:page-size="pageSize"
|
||||
:page-size-opts="[10,20,50]"
|
||||
show-sizer
|
||||
show-total
|
||||
@on-change="pageChange"
|
||||
@on-page-size-change="sizeChange"
|
||||
></Page>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 弹窗1:添加教师 -->
|
||||
<Modal v-model="addTeacherModal" title="添加教师" width="540">
|
||||
<Form ref="addTeacherForm" :model="addTeacherFormData" :rules="addTeacherRules" label-width="110">
|
||||
<FormItem label="教师姓名" prop="teacherName">
|
||||
<Input v-model="addTeacherFormData.teacherName" placeholder="请输入老师姓名"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="用户名" prop="account">
|
||||
<Input v-model="addTeacherFormData.account" placeholder="请输入用户名"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="密码" prop="password">
|
||||
<Input v-model="addTeacherFormData.password" placeholder="请输入密码" type="password"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="身份证号" prop="idCard">
|
||||
<Input v-model="addTeacherFormData.idCard" placeholder="请输入身份证号"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="手机号" prop="phone">
|
||||
<Input v-model="addTeacherFormData.phone" placeholder="请输入手机号"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="性别" prop="gender">
|
||||
<Select v-model="addTeacherFormData.gender" style="width:100%" transfer>
|
||||
<Option value="1">男</Option>
|
||||
<Option value="0">女</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="addTeacherModal = false" style="margin-right:10px">取消</Button>
|
||||
<Button type="primary" @click="submitAddTeacher">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗2:编辑教师 -->
|
||||
<Modal v-model="editTeacherModal" title="编辑教师" width="540">
|
||||
<Form ref="editTeacherForm" :model="editTeacherFormData" :rules="editTeacherRules" label-width="110">
|
||||
<FormItem label="教师姓名" prop="teacherName">
|
||||
<Input v-model="editTeacherFormData.teacherName"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="用户名" prop="account">
|
||||
<Input v-model="editTeacherFormData.account"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="身份证号" prop="idCard">
|
||||
<Input v-model="editTeacherFormData.idCard"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="手机号" prop="phone">
|
||||
<Input v-model="editTeacherFormData.phone"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="性别" prop="gender">
|
||||
<Select v-model="editTeacherFormData.gender" style="width:100%" transfer>
|
||||
<Option value="1">男</Option>
|
||||
<Option value="0">女</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="editTeacherModal = false" style="margin-right:10px">取消</Button>
|
||||
<Button type="primary" @click="submitEditTeacher">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗3:教师导入 -->
|
||||
<Modal v-model="importModal" title="教师导入" width="460">
|
||||
<div class="main-contents">
|
||||
<Form ref="UpParmas.datapre" :model="UpParmas.datapre" :label-width="100" inline>
|
||||
<FormItem label="Excel上传:" style="margin-bottom:10px;width:100%;">
|
||||
<i-input type="text" style="width:90%;" v-model="UpParmas.fileName" class="import-input" placeholder="未选中任何文件.." readonly></i-input>
|
||||
<Upload class="fr btn"
|
||||
:action="UpParmas.actionUrl"
|
||||
:data="UpParmas.datapre"
|
||||
:show-upload-list="false"
|
||||
:headers="uploadHeader"
|
||||
accept=".xls,.xlsx"
|
||||
:before-upload="handleUpload"
|
||||
:on-success="importFile"
|
||||
>
|
||||
<i-button icon="md-add"></i-button>
|
||||
</Upload>
|
||||
</FormItem>
|
||||
<FormItem v-if="UpParmas.listData.data!=null" style="margin-bottom:10px">
|
||||
<div v-if="UpParmas.listData.code==0" style="color:red">导入失败,请修改Excel文件中相关数据后再重新上传!</div>
|
||||
<div v-if="UpParmas.listData.code!=0" style="color:green">导入成功!</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
|
||||
<Alert show-icon>
|
||||
操作说明:
|
||||
<Icon type="ios-bulb-outline" slot="icon" size="20"></Icon>
|
||||
<template slot="desc" style="font-size: 12px;">
|
||||
请先上传EXCEL文件,若成功则显示导入成功数据,否则显示错误的数据及错误原因;<br>
|
||||
EXCEL文件的格式():工作表(WorkSheet)的名称应设为缺省的[Sheet1];<br>
|
||||
<a @click="MoBanExceldaochu" style="font-size:12px;">点击链接下载[教师导入模板.xls]</a>
|
||||
</template>
|
||||
</Alert>
|
||||
|
||||
<Table :columns="UpParmas.columns" :data="UpParmas.listData.data" v-if="UpParmas.listData.data"></Table>
|
||||
</div>
|
||||
<Spin fix v-if="spinShow">
|
||||
<Icon type="ios-loading" size=30 class="demo-spin-icon-load"></Icon>
|
||||
<div>上传中...</div>
|
||||
</Spin>
|
||||
<div slot="footer">
|
||||
<i-Button @click="UpfileModalcloseclick" style="margin-left: 8px">关闭</i-Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗4:添加子组 -->
|
||||
<Modal v-model="addGroupModal" title="添加子组" width="420">
|
||||
<Form ref="addGroupForm" :model="addGroupFormData" :rules="addGroupRules" label-width="90">
|
||||
<FormItem label="组名称">
|
||||
<Input v-model="addGroupFormData.parentGroupName" disabled></Input>
|
||||
</FormItem>
|
||||
<FormItem label="子组名称" prop="groupName">
|
||||
<Input v-model="addGroupFormData.groupName" placeholder="请输入组名称"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="子组排序">
|
||||
<Input v-model="addGroupFormData.sort"></Input>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="addGroupModal = false" style="margin-right:10px">取消</Button>
|
||||
<Button type="primary" @click="submitAddGroup">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗5:修改子组 -->
|
||||
<Modal v-model="editGroupModal" title="修改子组" width="420">
|
||||
<Form ref="editGroupForm" :model="editGroupFormData" :rules="editGroupRules" label-width="90">
|
||||
<FormItem label="子组名称" prop="groupName">
|
||||
<Input v-model="editGroupFormData.groupName"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="子组排序">
|
||||
<Input v-model="editGroupFormData.sort"></Input>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="editGroupModal = false" style="margin-right:10px">取消</Button>
|
||||
<Button type="primary" @click="submitEditGroup">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗6:移动子组 -->
|
||||
<Modal v-model="moveGroupModal" title="移动子组" width="440">
|
||||
<div style="margin-bottom:12px">
|
||||
<span>待移动组:</span>
|
||||
<Input v-model="moveGroupTargetName" disabled style="width:280px;display:inline-block;margin-left:6px"></Input>
|
||||
</div>
|
||||
<div style="margin-top:10px">
|
||||
<span>移动至:</span>
|
||||
<Tree :data="treeData" ref="moveGroupTreeRef"></Tree>
|
||||
</div>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="moveGroupModal = false" style="margin-right:10px">取消</Button>
|
||||
<Button type="primary" @click="confirmMoveGroup">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗7:批量删除确认 -->
|
||||
<Modal v-model="batchDeleteModal" title="删除" width="400">
|
||||
<Alert type="warning" show-icon>
|
||||
确定是否删除教师?<br/>删除后将不可恢复。
|
||||
</Alert>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="batchDeleteModal = false" style="margin-right:10px">取消</Button>
|
||||
<Button type="error" @click="confirmBatchDelete">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗8:移动教师弹窗 -->
|
||||
<!-- 弹窗8:移动教师弹窗(无箭头,勾选自动进右侧,右侧删除自动取消左侧勾选) -->
|
||||
<Modal v-model="moveTeacherModal" title="移动教师" width="680">
|
||||
<div style="margin-bottom:16px;display:flex;align-items:center;">
|
||||
<span style="white-space:nowrap;margin-right:10px;">待移动教师:</span>
|
||||
<Input v-model="moveTeacherName" disabled style="flex:1" />
|
||||
</div>
|
||||
<div style="display:flex;align-items:stretch;gap:12px;">
|
||||
<!-- 左侧:选择组 zTree勾选树 -->
|
||||
<div style="flex:1;border:1px solid #dcdcdc;display:flex;flex-direction:column;">
|
||||
<div style="background:#3377dd;color:#fff;padding:8px 12px;text-align:center;font-weight:bold;">选择组</div>
|
||||
<div style="flex:1;overflow:auto;padding:8px;">
|
||||
<my-tree
|
||||
ref="moveTeacherLeftTree"
|
||||
:treeData="treeData"
|
||||
:setting="treeSetting"
|
||||
@on-tree-Check="checkedtreeLink"
|
||||
></my-tree>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 中间箭头区域直接删除,不再需要 -->
|
||||
<!-- 右侧:移动至组 已选列表 带单条删除 -->
|
||||
<div style="flex:1;border:1px solid #dcdcdc;display:flex;flex-direction:column;">
|
||||
<div style="background:#3377dd;color:#fff;padding:8px 12px;text-align:center;font-weight:bold;">移动至组</div>
|
||||
<div style="flex:1;overflow:auto;padding:8px;">
|
||||
<div
|
||||
v-for="(item,idx) in targetGroupList"
|
||||
:key="item.id"
|
||||
style="padding:4px 0;display:flex;align-items:center;gap:6px;justify-content:space-between;"
|
||||
>
|
||||
<div style="display:flex;align-items:center;gap:6px;">
|
||||
<Icon type="ios-checkbox-outline"></Icon>
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
<Icon
|
||||
type="ios-close"
|
||||
style="color:#f56c6c;cursor:pointer;font-size:16px;"
|
||||
@click="handleDeleteRightItem(item, idx)"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="targetGroupList.length === 0" style="color:#999;text-align:center;padding:20px 0;">暂无选中分组</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="moveTeacherModal = false" style="margin-right:10px">取消</Button>
|
||||
<Button type="primary" @click="submitMoveTeacher">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗9:【设置教师的状态】 匹配设计图 -->
|
||||
<Modal v-model="setStatusModal" title="设置教师的状态" width="380">
|
||||
<Form ref="statusForm" :model="statusFormData" label-width="120">
|
||||
<FormItem label="选择设置状态">
|
||||
<RadioGroup v-model="statusFormData.status">
|
||||
<Radio label="1">正常</Radio>
|
||||
<Radio label="0">禁用</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="setStatusModal = false" style="margin-right:10px">取消</Button>
|
||||
<Button type="primary" @click="submitSetStatus">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 弹窗10:转出教师弹窗 -->
|
||||
<Modal v-model="transferTeacherModal" title="转出教师" width="420">
|
||||
<p>确认将选中教师做转出操作?转出后不在本校编制内</p>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="transferTeacherModal = false" style="margin-right:10px">取消</Button>
|
||||
<Button type="primary" @click="confirmTransferTeacher">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import myTree from "../../components/my_tree";
|
||||
import { self_viewport } from "@/mixins/self_viewport";
|
||||
export default {
|
||||
name: 'TeacherInfoManage',
|
||||
components: { myTree },
|
||||
data() {
|
||||
return {
|
||||
selectnodeid:'',
|
||||
selectnodetitle: '',
|
||||
selectnodetype:7,
|
||||
searchKeyword: '',
|
||||
selectedRows: [],
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
|
||||
treeData: [],
|
||||
// 移动教师弹窗穿梭框
|
||||
checkedTreeNodes: [], // 左侧树形勾选的节点
|
||||
targetGroupList: [], // 右侧移入的目标分组数组
|
||||
treeSetting:{
|
||||
view: {
|
||||
dblClickExpand: false,
|
||||
showIcon: false,
|
||||
},
|
||||
check: {
|
||||
enable: true,
|
||||
// 核心两项配置
|
||||
chkboxType: {
|
||||
"Y": "", // 勾选父节点 【不会】向下联动勾选子节点
|
||||
"N": "" // 取消父节点 【不会】向下联动取消子节点
|
||||
},
|
||||
autoCheckTrigger: false
|
||||
},
|
||||
callback: {}
|
||||
},
|
||||
|
||||
tableColumns: [
|
||||
{ type: 'selection', width: 50 },
|
||||
{ title: '序号', type: 'index', align: 'center', width: 70 },
|
||||
{ title: '教师账号', key: 'account', align: 'center' },
|
||||
{ title: '教师姓名', key: 'name', align: 'center' },
|
||||
{
|
||||
title: '教师组',
|
||||
key: 'groupName',
|
||||
align: 'center',
|
||||
render: (h, params) => {
|
||||
return h('div', [
|
||||
params.row.groupList.map(a=>a.name).join(',')
|
||||
]);
|
||||
},
|
||||
},
|
||||
{ title: '联系电话', key: 'tel', align: 'center' },
|
||||
{
|
||||
title: '性别',
|
||||
key: 'gender',
|
||||
align: 'center',
|
||||
width: 70,
|
||||
render: (h, params) => {
|
||||
return h('div', [
|
||||
params.row.gender==0?'女':params.row.gender==1?'男':''
|
||||
]);
|
||||
},
|
||||
},
|
||||
{ title: '状态', key: 'statusName', align: 'center', width: 80 },
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 90,
|
||||
render: (h, params) => {
|
||||
return h('Button', {
|
||||
props: { type: 'text', icon: 'md-create', size: 'large' },
|
||||
on: { click: () => this.editSingleTeacher(params.row, params.index) }
|
||||
})
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
tableData: [],
|
||||
spinShow:false,
|
||||
UpParmas:{
|
||||
fileName:'',
|
||||
listData:{},
|
||||
datapre:{},
|
||||
actionUrl:APIConfig.BschClassSystem.teacherImport,
|
||||
columns:[
|
||||
{
|
||||
title: '行号',
|
||||
key: 'rows',
|
||||
align: 'center',
|
||||
width:'80'
|
||||
},
|
||||
{
|
||||
title: '内容',
|
||||
key: 'columnValue',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '错误详情',
|
||||
key: 'errorMsg',
|
||||
align: 'center',
|
||||
}
|
||||
],
|
||||
},
|
||||
|
||||
addTeacherModal: false,
|
||||
editTeacherModal: false,
|
||||
importModal: false,
|
||||
addGroupModal: false,
|
||||
editGroupModal: false,
|
||||
moveGroupModal: false,
|
||||
batchDeleteModal: false,
|
||||
moveTeacherModal: false,
|
||||
setStatusModal: false,
|
||||
transferTeacherModal: false,
|
||||
|
||||
addTeacherFormData: { teacherName: '', account: '', password: '', idCard: '', phone: '', gender: '0' },
|
||||
addTeacherRules: {
|
||||
teacherName: [{ required: true, message: '请输入教师姓名', trigger: 'blur' }],
|
||||
account: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
||||
gender: [{ required: true, message: '请选择性别', trigger: 'change' }]
|
||||
},
|
||||
|
||||
editTeacherIndex: null,
|
||||
editTeacherFormData: {id:null, teacherName: '', account: '', idCard: '', phone: '', gender: '0',teaId:0,status:1 },
|
||||
editTeacherRules: {
|
||||
teacherName: [{ required: true, message: '请输入教师姓名', trigger: 'blur' }],
|
||||
account: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||||
gender: [{ required: true, message: '请选择性别', trigger: 'change' }]
|
||||
},
|
||||
|
||||
addGroupFormData: { parentGroupName: '', groupName: '', sort: '' },
|
||||
addGroupRules: { groupName: [{ required: true, message: '请输入子组名称', trigger: 'blur' }] },
|
||||
|
||||
editGroupIndex: null,
|
||||
editGroupFormData: { groupName: '', sort: '' },
|
||||
editGroupRules: { groupName: [{ required: true, message: '请输入子组名称', trigger: 'blur' }] },
|
||||
|
||||
moveGroupTargetName: '',
|
||||
moveTeacherName: '',
|
||||
statusFormData: { status: '1' }
|
||||
}
|
||||
},
|
||||
mixins: [self_viewport],
|
||||
computed: {
|
||||
uploadHeader() { //附件上传header
|
||||
let config = {};
|
||||
if (localStorage.getItem("currentRole")) {
|
||||
let currentRole = localStorage.getItem("currentRole");
|
||||
config["currentRole"] = currentRole;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getTeaTree();
|
||||
},
|
||||
methods: {
|
||||
//获取教师树
|
||||
getTeaTree:function(){
|
||||
const _this = this;
|
||||
var item={};
|
||||
_this.$api.get(APIConfig.BschClassSystem.getTeaTree, item, resp => {
|
||||
if(resp.code==0)
|
||||
{
|
||||
_this.treeData=resp.data;
|
||||
_this.selectnodeid=resp.data.id;
|
||||
_this.selectnodetitle=resp.data.name;
|
||||
_this.selectnodetype=resp.data.type;
|
||||
_this.loadData();
|
||||
}
|
||||
});
|
||||
},
|
||||
// 树形选中切换
|
||||
treeLink(treeNode) {
|
||||
this.selectnodeid=treeNode.id;
|
||||
this.selectnodetitle=treeNode.name;
|
||||
this.selectnodetype=treeNode.type;
|
||||
this.pageNum = 1
|
||||
this.loadData()
|
||||
},
|
||||
// 移动教师树形复选框勾选回调(接收my-tree抛出的zTree选中数组)移动教师树形选中切换
|
||||
checkedtreeLink(allCheckedList){
|
||||
this.checkedTreeNodes = [...allCheckedList]
|
||||
// 右侧列表 = 只保留当前左侧还在勾选的条目,自动过滤取消勾选项
|
||||
this.targetGroupList = this.targetGroupList.filter(rightItem => {
|
||||
return allCheckedList.some(leftItem => leftItem.id === rightItem.id)
|
||||
})
|
||||
// 新增左侧新勾选的节点,去重加入右侧
|
||||
allCheckedList.forEach(node => {
|
||||
const exist = this.targetGroupList.some(item => item.id === node.id)
|
||||
if (!exist) {
|
||||
this.targetGroupList.push({
|
||||
id: node.id,
|
||||
name: node.name
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 加载列表数据
|
||||
loadData() {
|
||||
const _this = this;
|
||||
var item = {
|
||||
groupId:_this.selectnodeid,
|
||||
keyword:_this.searchKeyword,
|
||||
page:_this.pageNum-1,
|
||||
size:_this.pageSize
|
||||
};
|
||||
_this.$api.get(APIConfig.BschClassSystem.getteachersearch, item, resp => {
|
||||
if (resp.code == 0) {
|
||||
_this.tableData = resp.data.content;
|
||||
_this.total=resp.data.total;
|
||||
} else {
|
||||
_this.tableData = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
selectionChange(rows) {
|
||||
this.selectedRows = rows
|
||||
},
|
||||
searchTeacher() {
|
||||
this.pageNum = 1;
|
||||
this.loadData();
|
||||
},
|
||||
pageChange(p) { this.pageNum = p;this.loadData(); },
|
||||
sizeChange(s) { this.pageSize = s; this.pageNum = 1;this.loadData(); },
|
||||
|
||||
openAddTeacherModal() {
|
||||
this.addTeacherFormData = { teacherName: '', account: '', password: '', idCard: '', phone: '', gender: '0' }
|
||||
this.addTeacherModal = true
|
||||
},
|
||||
submitAddTeacher() {
|
||||
this.$refs.addTeacherForm.validate(valid => {
|
||||
if (!valid) return
|
||||
// 新增
|
||||
const newItem = {
|
||||
groupId:this.selectnodeid,
|
||||
name:this.addTeacherFormData.teacherName,
|
||||
account:this.addTeacherFormData.account,
|
||||
pwd:this.addTeacherFormData.password,
|
||||
idCard:this.addTeacherFormData.idCard,
|
||||
tel:this.addTeacherFormData.phone,
|
||||
gender:this.addTeacherFormData.gender,
|
||||
teaId:0,
|
||||
status:1
|
||||
}
|
||||
const url = APIConfig.BschClassSystem.teachersave;
|
||||
this.$api.post(url, JSON.stringify(newItem), resp => {
|
||||
if (resp.code == 0) {
|
||||
this.$Message.success("新增教师成功!");
|
||||
this.addTeacherModal = false
|
||||
this.loadData();
|
||||
} else if (resp.code == 4) {
|
||||
this.$Message.info(resp.msg);
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
editSingleTeacher(row, idx) {
|
||||
this.editTeacherIndex = idx;
|
||||
this.editTeacherFormData = {
|
||||
id:row.id,
|
||||
teacherName: row.name,
|
||||
account: row.account,
|
||||
idCard: row.idCard || '',
|
||||
phone: row.tel,
|
||||
gender: row.gender+'',
|
||||
teaId:row.teaId,
|
||||
status:row.status
|
||||
};
|
||||
this.editTeacherModal = true;
|
||||
},
|
||||
submitEditTeacher() {
|
||||
this.$refs.editTeacherForm.validate(valid => {
|
||||
if (!valid) return
|
||||
// 编辑
|
||||
const newItem = {
|
||||
id:this.editTeacherFormData.id,
|
||||
groupId:this.selectnodeid,
|
||||
name:this.editTeacherFormData.teacherName,
|
||||
account:this.editTeacherFormData.account,
|
||||
idCard:this.editTeacherFormData.idCard,
|
||||
tel:this.editTeacherFormData.phone,
|
||||
gender:this.editTeacherFormData.gender,
|
||||
teaId:this.editTeacherFormData.teaId,
|
||||
status:this.editTeacherFormData.status
|
||||
}
|
||||
const url = APIConfig.BschClassSystem.teachersave;
|
||||
this.$api.post(url, JSON.stringify(newItem), resp => {
|
||||
if (resp.code == 0) {
|
||||
this.$Message.success("编辑教师成功!");
|
||||
this.editTeacherModal = false
|
||||
this.loadData();
|
||||
} else if (resp.code == 4) {
|
||||
this.$Message.info(resp.msg);
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
openImportModal() { this.importModal = true },
|
||||
//导入成功返回
|
||||
importFile(response, file, fileList){
|
||||
const _this=this;
|
||||
console.log(response);
|
||||
console.log(file);
|
||||
_this.spinShow=false;
|
||||
_this.UpParmas.fileName=file.name;
|
||||
_this.UpParmas.listData=response;
|
||||
if(response.State)
|
||||
{
|
||||
_this.$Message.info('导入成功!');
|
||||
_this.getsearcBaseSchClass();
|
||||
}else{
|
||||
_this.$Message.info(response.Message);
|
||||
}
|
||||
},
|
||||
//附件上传之前的方法
|
||||
handleUpload:function(file){
|
||||
const _this=this;
|
||||
_this.spinShow=true;
|
||||
},
|
||||
MoBanExceldaochu() {
|
||||
var _this = this;
|
||||
if (localStorage.getItem("currentRole")) {
|
||||
let currentRole = localStorage.getItem("currentRole");
|
||||
let { schId, roleId, userId, childId } = JSON.parse(decodeURIComponent(currentRole));
|
||||
var url=APIConfig.BschClassSystem.teacherdownloadTemplate+'?schId='+schId;
|
||||
window.location.href=url;
|
||||
}else{
|
||||
this.$Message.info('获取不了学校!');
|
||||
}
|
||||
},
|
||||
//附件上传模态框关闭事件
|
||||
UpfileModalcloseclick:function(){
|
||||
this.importModal=false;
|
||||
this.UpParmas={
|
||||
fileName:'',
|
||||
listData:{},
|
||||
datapre:{},
|
||||
}
|
||||
},
|
||||
|
||||
batchDeleteTeacher() {
|
||||
if (!this.selectedRows.length) return this.$Message.warning('请先勾选教师')
|
||||
this.batchDeleteModal = true
|
||||
},
|
||||
confirmBatchDelete() {
|
||||
const idlist = this.selectedRows.map(i => i.id);
|
||||
const url = APIConfig.BschClassSystem.teacherdelete+idlist.join(',');
|
||||
this.$api.post(url,{}, resp => {
|
||||
if (resp.code == 0) {
|
||||
this.$Message.success("删除成功!");
|
||||
this.selectedRows = [];
|
||||
this.batchDeleteModal = false;
|
||||
this.loadData();
|
||||
} else if (resp.code == 4) {
|
||||
this.$Message.info(resp.msg);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 弹窗打开初始化
|
||||
openBatchMoveTeacherModal() {
|
||||
if (!this.selectedRows.length) return this.$Message.warning('请先勾选教师')
|
||||
this.moveTeacherName = this.selectedRows.map(i => i.name).join('、')
|
||||
// 清空数据
|
||||
this.checkedTreeNodes = []
|
||||
this.targetGroupList = []
|
||||
this.$nextTick(() => {
|
||||
// 清空整棵树所有勾选
|
||||
const ztree = this.$refs.moveTeacherLeftTree.getZtreeInstance()
|
||||
ztree.checkAllNodes(false)
|
||||
})
|
||||
this.moveTeacherModal = true
|
||||
},
|
||||
// 右侧点击X删除单条 → 反向取消左侧树勾选
|
||||
handleDeleteRightItem(delItem, index) {
|
||||
// 删除右侧数组
|
||||
this.targetGroupList.splice(index, 1)
|
||||
// 获取树实例,取消对应节点复选框
|
||||
const ztree = this.$refs.moveTeacherLeftTree.getZtreeInstance()
|
||||
const targetNode = ztree.getNodeByParam('id', delItem.id)
|
||||
if (targetNode) {
|
||||
ztree.checkNode(targetNode, false, false)
|
||||
}
|
||||
},
|
||||
|
||||
// 确定按钮 直接提交
|
||||
submitMoveTeacher() {
|
||||
if (this.targetGroupList.length === 0) {
|
||||
return this.$Message.warning('请至少选择一个目标分组')
|
||||
}
|
||||
const teacherIdArr = this.selectedRows.map(row => row.id)
|
||||
const groupIdArr = this.targetGroupList.map(item => item.id)
|
||||
|
||||
// console.log('待移动教师ID', teacherIdArr)
|
||||
// console.log('目标分组ID', groupIdArr)
|
||||
let item={
|
||||
ids:teacherIdArr,
|
||||
transferGroupIds:groupIdArr
|
||||
};
|
||||
const url = APIConfig.BschClassSystem.moveGroup;
|
||||
this.$api.post(url,JSON.stringify(item), resp => {
|
||||
if (resp.code == 0) {
|
||||
this.$Message.success('教师移动分组成功');
|
||||
this.moveTeacherModal = false;
|
||||
// 清空选择缓存
|
||||
this.selectedRows = [];
|
||||
this.targetGroupList = [];
|
||||
this.checkedTreeNodes = [];
|
||||
// 刷新表格数据
|
||||
this.loadData();
|
||||
} else if (resp.code == 4) {
|
||||
this.$Message.info(resp.msg);
|
||||
}
|
||||
});
|
||||
},
|
||||
batchTransferTeacher() {
|
||||
if (!this.selectedRows.length) return this.$Message.warning('请先勾选教师')
|
||||
this.transferTeacherModal = true
|
||||
},
|
||||
//转出事件
|
||||
confirmTransferTeacher() {
|
||||
const idlist = this.selectedRows.map(i => i.id);
|
||||
const url = APIConfig.BschClassSystem.transferOut+idlist.join(',');
|
||||
this.$api.post(url,{}, resp => {
|
||||
if (resp.code == 0) {
|
||||
this.$Message.success("转出操作完成!");
|
||||
this.selectedRows = [];
|
||||
this.transferTeacherModal = false;
|
||||
this.loadData();
|
||||
} else if (resp.code == 4) {
|
||||
this.$Message.info(resp.msg);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
openBatchMoveTeacherModal() {
|
||||
if (!this.selectedRows.length) return this.$Message.warning('请先勾选教师')
|
||||
this.moveTeacherName = this.selectedRows.map(i => i.name).join('、')
|
||||
this.moveTeacherModal = true
|
||||
},
|
||||
confirmMoveTeacher() {
|
||||
this.moveTeacherModal = false
|
||||
this.$Message.success('移动教师成功')
|
||||
},
|
||||
|
||||
openSetStatusModal() {
|
||||
if (!this.selectedRows.length) return this.$Message.warning('请先勾选教师')
|
||||
this.statusFormData.status = '1'
|
||||
this.setStatusModal = true
|
||||
},
|
||||
submitSetStatus() {
|
||||
const idlist = this.selectedRows.map(i => i.id);
|
||||
let item={
|
||||
ids:idlist.join(','),
|
||||
status:this.statusFormData.status
|
||||
};
|
||||
const url = APIConfig.BschClassSystem.teachersetStatus;
|
||||
this.$api.post(url,item, resp => {
|
||||
if (resp.code == 0) {
|
||||
this.$Message.success("状态修改成功!");
|
||||
this.selectedRows = [];
|
||||
this.setStatusModal = false;
|
||||
this.loadData();
|
||||
} else if (resp.code == 4) {
|
||||
this.$Message.info(resp.msg);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
openAddGroupModal() {
|
||||
if (!this.selectnodeid) return this.$Message.warning('请先选择父分组')
|
||||
this.addGroupFormData.parentGroupName = this.selectnodetitle
|
||||
this.addGroupFormData.groupName = ''
|
||||
this.addGroupFormData.sort = ''
|
||||
this.addGroupModal = true
|
||||
},
|
||||
submitAddGroup() {
|
||||
this.$refs.addGroupForm.validate(valid => {
|
||||
if (!valid) return;
|
||||
this.$Message.success('新增分组成功');
|
||||
this.addGroupModal = false;
|
||||
})
|
||||
},
|
||||
|
||||
openEditGroupModal() {
|
||||
if (!this.selectnodeid) return this.$Message.warning('请先选择分组')
|
||||
this.editGroupIndex = this.selectnodeid;
|
||||
this.editGroupFormData.groupName = this.selectnodetitle;
|
||||
this.editGroupFormData.sort = '';
|
||||
this.editGroupModal = true;
|
||||
},
|
||||
submitEditGroup() {
|
||||
this.$refs.editGroupForm.validate(valid => {
|
||||
if (!valid) return
|
||||
this.selectedTreeNode.title = this.editGroupFormData.groupName
|
||||
this.editGroupModal = false
|
||||
this.$Message.success('修改分组成功')
|
||||
})
|
||||
},
|
||||
|
||||
openMoveGroupModal() {
|
||||
if (!this.selectnodeid) return this.$Message.warning('请先选择分组')
|
||||
this.moveGroupTargetName = this.selectnodetitle
|
||||
this.moveGroupModal = true
|
||||
},
|
||||
confirmMoveGroup() {
|
||||
this.moveGroupModal = false
|
||||
this.$Message.success('移动分组成功')
|
||||
},
|
||||
|
||||
delCurrentGroup() {
|
||||
if (!this.selectnodeid) return this.$Message.warning('请先选择分组')
|
||||
this.$Modal.confirm({
|
||||
title: '提示',
|
||||
content: `确定删除分组【${this.selectedTreeNode.title}】?`,
|
||||
onOk: () => {
|
||||
this.$Message.success('删除分组成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 全局布局逐级修复高度 + min-height:0 解决flex塌陷 */
|
||||
.outer-wrap {
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.page-flex-layout {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 16px;
|
||||
min-height: 0; /* 第一层修复 */
|
||||
}
|
||||
.tree-sidebar {
|
||||
width: 250px;
|
||||
border: 1px solid #e8e8e8;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
.tree-op-buttons {
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.tree-sidebar >>> .ivu-tree {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 8px;
|
||||
}
|
||||
.right-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0; /* 第二层修复 */
|
||||
}
|
||||
.top-tool-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0px 16px;
|
||||
background: #f7f7f7;
|
||||
margin-bottom: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.table-adapt-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0; /* 第三层核心修复 */
|
||||
}
|
||||
.table-scroll {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
.teacher-table {
|
||||
height: 100%;
|
||||
}
|
||||
/* 分页固定底部,永远不参与滚动 */
|
||||
.bottom-bar {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.total-text {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-right: 12px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.ivu-alert-desc{
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,537 @@
|
||||
<template>
|
||||
<div class="teach-manage-page">
|
||||
<!-- 顶部筛选栏 -->
|
||||
<div class="top-filter-bar">
|
||||
<div class="filter-left">
|
||||
<Select v-model="majorVal" placeholder="选择学制" style="width: 220px" @on-change="getselectBySchsystemId">
|
||||
<Option v-for="(item,index) in schsystemselectlist" :key="index" :value="item.id">{{ item.name }}</Option>
|
||||
</Select>
|
||||
<Select v-model="gradeVal" placeholder="选择年级" style="width: 180px; margin-left: 12px" @on-change="handleGradeChange">
|
||||
<Option v-for="(item,index) in selectBySchsystemIdlist" :key="index" :value="item.id">{{ item.name }}</Option>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="btn-group-right">
|
||||
<Button type="success" @click="handleBatchImport">批量导入</Button>
|
||||
<Button type="success" style="margin-left: 10px" @click="handleExport">任教导出</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 关键外层嵌套:强制横向溢出滚动 -->
|
||||
<div class="table-outer">
|
||||
<Table
|
||||
border
|
||||
stripe
|
||||
:columns="tableColumns"
|
||||
:data="tableData"
|
||||
:height="useTableHeight()+48"
|
||||
></Table>
|
||||
</div>
|
||||
|
||||
<!-- 选择教师弹窗 -->
|
||||
<Modal v-model="teacherModalVisible" title="选择教师" width="420" @on-cancel="resetModal">
|
||||
<div style="padding:10px 20px;">
|
||||
<div style="margin-bottom:18px;">
|
||||
<span style="display:inline-block;width:60px;">科室</span>
|
||||
<Select v-model="selectDept" placeholder="按科室过滤" style="width:280px" @on-change="getteacherSelect" clearable>
|
||||
<Option v-for="item in groupteacherSelectlist" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<span style="display:inline-block;width:60px;">教师</span>
|
||||
<Select v-model="selectTeacher" placeholder="请选择" style="width:280px" filterable>
|
||||
<Option v-for="item in teacherSelectlist" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" align="right">
|
||||
<Button @click="teacherModalVisible = false">取消</Button>
|
||||
<Button type="primary" @click="submitSelectTeacher">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 批量导入弹窗 -->
|
||||
<Modal v-model="importModalVisible" title="批量导入任教信息" width="520">
|
||||
<div class="main-contents">
|
||||
<Form ref="UpParmas.datapre" :model="UpParmas.datapre" :label-width="100" inline>
|
||||
<FormItem label="Excel上传:" style="margin-bottom:10px;width:100%;">
|
||||
<i-input type="text" style="width:90%;" v-model="UpParmas.fileName" class="import-input" placeholder="未选中任何文件.." readonly></i-input>
|
||||
<Upload class="fr btn"
|
||||
:action="UpParmas.actionUrl"
|
||||
:data="UpParmas.datapre"
|
||||
:show-upload-list="false"
|
||||
:headers="uploadHeader"
|
||||
accept=".xls,.xlsx"
|
||||
:before-upload="handleUpload"
|
||||
:on-success="importFile"
|
||||
>
|
||||
<i-button icon="md-add"></i-button>
|
||||
</Upload>
|
||||
</FormItem>
|
||||
<FormItem v-if="UpParmas.listData.data!=null" style="margin-bottom:10px">
|
||||
<div v-if="UpParmas.listData.code==0" style="color:red">导入失败,请修改Excel文件中相关数据后再重新上传!</div>
|
||||
<div v-if="UpParmas.listData.code!=0" style="color:green">导入成功!</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
|
||||
<Alert show-icon>
|
||||
操作说明:
|
||||
<Icon type="ios-bulb-outline" slot="icon" size="20"></Icon>
|
||||
<template slot="desc" style="font-size: 12px;">
|
||||
请先上传EXCEL文件,若成功则显示导入成功数据,否则显示错误的数据及错误原因;<br>
|
||||
EXCEL文件的格式():工作表(WorkSheet)的名称应设为缺省的[Sheet1];<br>
|
||||
<a @click="MoBanExceldaochu" style="font-size:12px;">点击链接下载[任教导入模板.xls]</a>
|
||||
</template>
|
||||
</Alert>
|
||||
|
||||
<Table :columns="UpParmas.columns" :data="UpParmas.listData.data" v-if="UpParmas.listData.data"></Table>
|
||||
</div>
|
||||
<Spin fix v-if="spinShow">
|
||||
<Icon type="ios-loading" size=30 class="demo-spin-icon-load"></Icon>
|
||||
<div>上传中...</div>
|
||||
</Spin>
|
||||
<div slot="footer">
|
||||
<i-Button @click="UpfileModalcloseclick" style="margin-left: 8px">关闭</i-Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { self_viewport } from "@/mixins/self_viewport";
|
||||
export default {
|
||||
name: 'TeachManage',
|
||||
mixins: [self_viewport],
|
||||
data() {
|
||||
return {
|
||||
majorVal: '',
|
||||
gradeVal: '',
|
||||
importModalVisible: false,
|
||||
schsystemselectlist: [],
|
||||
selectBySchsystemIdlist: [],
|
||||
|
||||
// 后端原始数据源
|
||||
subjectList: [],
|
||||
classList: [],
|
||||
teachList: [],
|
||||
|
||||
tableColumns: [],
|
||||
tableData: [],
|
||||
|
||||
teacherModalVisible: false,
|
||||
currentRowIndex: null,
|
||||
currentSubId: '',
|
||||
currentClassId: null,
|
||||
oldTeacherId: null,
|
||||
detailId: null, // 任教明细主键id
|
||||
|
||||
selectDept: '',
|
||||
selectTeacher: '',
|
||||
groupteacherSelectlist: [],
|
||||
teacherSelectlist: [],
|
||||
spinShow:false,
|
||||
UpParmas:{
|
||||
fileName:'',
|
||||
listData:{},
|
||||
datapre:{},
|
||||
actionUrl:APIConfig.BschClassSystem.teacherImport,
|
||||
columns:[
|
||||
{
|
||||
title: '行号',
|
||||
key: 'rows',
|
||||
align: 'center',
|
||||
width:'80'
|
||||
},
|
||||
{
|
||||
title: '内容',
|
||||
key: 'columnValue',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '错误详情',
|
||||
key: 'errorMsg',
|
||||
align: 'center',
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
uploadHeader() { //附件上传header
|
||||
let config = {};
|
||||
if (localStorage.getItem("currentRole")) {
|
||||
let currentRole = localStorage.getItem("currentRole");
|
||||
config["currentRole"] = currentRole;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getschsystemselect();
|
||||
this.getgroupteacherSelect();
|
||||
this.getteacherSelect();
|
||||
},
|
||||
methods: {
|
||||
// 学制下拉
|
||||
getschsystemselect() {
|
||||
const _this = this;
|
||||
_this.$api.get(APIConfig.BschClassSystem.getschsystemselect, {}, resp => {
|
||||
if (resp.code == 0) {
|
||||
_this.schsystemselectlist = resp.data;
|
||||
if (_this.schsystemselectlist.length > 0) {
|
||||
_this.majorVal = _this.schsystemselectlist[0].id;
|
||||
_this.getselectBySchsystemId();
|
||||
}
|
||||
} else {
|
||||
_this.schsystemselectlist = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
// 通过学制ID获取年级下拉
|
||||
getselectBySchsystemId() {
|
||||
const _this = this;
|
||||
const item = { schsystemId: _this.majorVal };
|
||||
_this.$api.get(APIConfig.BschClassSystem.getselectBySchsystemId, item, resp => {
|
||||
if (resp.code == 0) {
|
||||
_this.selectBySchsystemIdlist = resp.data;
|
||||
_this.getteachssearch();
|
||||
} else {
|
||||
_this.selectBySchsystemIdlist = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
// 教师组下拉
|
||||
getgroupteacherSelect() {
|
||||
const _this = this;
|
||||
_this.$api.get(APIConfig.BschClassSystem.getgroupteacherSelect, {}, resp => {
|
||||
if (resp.code == 0) {
|
||||
_this.groupteacherSelectlist = resp.data;
|
||||
} else {
|
||||
_this.groupteacherSelectlist = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
// 教师下拉
|
||||
getteacherSelect() {
|
||||
const _this = this;
|
||||
const item = { groupId: _this.selectDept };
|
||||
_this.$api.get(APIConfig.BschClassSystem.getteacherSelect, item, resp => {
|
||||
if (resp.code == 0) {
|
||||
_this.teacherSelectlist = resp.data;
|
||||
if (_this.oldTeacherId) {
|
||||
const findT = _this.teacherSelectlist.find(t => t.id === _this.oldTeacherId);
|
||||
if (findT) {
|
||||
_this.selectTeacher = findT.id;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_this.teacherSelectlist = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
// 打开弹窗并回显原有教师+明细ID
|
||||
openTeacherModal(rowIdx, rowData, subId) {
|
||||
this.resetModal();
|
||||
this.currentRowIndex = rowIdx;
|
||||
this.currentSubId = subId;
|
||||
this.currentClassId = rowData.classId;
|
||||
this.detailId = null;
|
||||
|
||||
const classTeach = this.teachList.find(item => item.classId === this.currentClassId);
|
||||
if (classTeach) {
|
||||
const subItem = classTeach.teachSubjectList.find(s => s.subId === subId);
|
||||
if (subItem) {
|
||||
this.oldTeacherId = subItem.teacherId || null;
|
||||
this.detailId = subItem.id;
|
||||
}
|
||||
}
|
||||
|
||||
this.teacherModalVisible = true;
|
||||
this.getteacherSelect();
|
||||
},
|
||||
// 核心:获取任教列表并格式化表格数据 + 自动生成表头
|
||||
getteachssearch() {
|
||||
const _this = this;
|
||||
const item = {
|
||||
schsystemId: this.majorVal,
|
||||
gradeId: this.gradeVal
|
||||
};
|
||||
_this.$api.get(APIConfig.BschClassSystem.getteachssearch, item, resp => {
|
||||
if (resp.code !== 0) {
|
||||
_this.subjectList = [];
|
||||
_this.classList = [];
|
||||
_this.teachList = [];
|
||||
_this.tableData = [];
|
||||
_this.tableColumns = [];
|
||||
return;
|
||||
}
|
||||
const { subjectList, classList, teachList } = resp.data;
|
||||
_this.subjectList = subjectList;
|
||||
_this.classList = classList;
|
||||
_this.teachList = teachList;
|
||||
|
||||
// 组装表格行数据:一行一个班级,key=subId
|
||||
_this.tableData = _this.classList.map(classItem => {
|
||||
const matchTeach = _this.teachList.find(t => t.classId === classItem.classId);
|
||||
const row = {
|
||||
gradeId:classItem.gradeId,
|
||||
grade: classItem.gradeName,
|
||||
className: classItem.name,
|
||||
classId: classItem.classId
|
||||
};
|
||||
if (matchTeach && Array.isArray(matchTeach.teachSubjectList)) {
|
||||
matchTeach.teachSubjectList.forEach(subItem => {
|
||||
row[subItem.subId] = subItem.teacherName || '';
|
||||
});
|
||||
}
|
||||
return row;
|
||||
});
|
||||
|
||||
// 动态构建列
|
||||
_this.buildTableColumns();
|
||||
});
|
||||
},
|
||||
// 动态生成表格列(完全基于后端subjectList,无硬编码科目)
|
||||
buildTableColumns() {
|
||||
// 左侧固定列
|
||||
const baseColumns = [
|
||||
{ title: '年级', key: 'grade', fixed: 'left', width: 110, align: 'center' },
|
||||
{ title: '班级', key: 'className', fixed: 'left', width: 110, align: 'center' }
|
||||
];
|
||||
|
||||
// 科目动态列
|
||||
const subjectColumns = this.subjectList.map(subItem => {
|
||||
const subId = subItem.id;
|
||||
const subName = subItem.name;
|
||||
return {
|
||||
title: subName,
|
||||
key: subId,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
render: (h, params) => {
|
||||
const val = params.row[subId];
|
||||
return h('div', {
|
||||
style: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
width: '140px',
|
||||
height: '34px',
|
||||
border: '1px solid #dcdcdc',
|
||||
borderRadius: '4px',
|
||||
cursor: 'pointer',
|
||||
margin: '0 auto'
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.openTeacherModal(params.index, params.row, subId)
|
||||
}
|
||||
}
|
||||
}, [
|
||||
h('span', {
|
||||
style: {
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
fontSize: '14px',
|
||||
paddingLeft: '6px',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap'
|
||||
}
|
||||
}, val || '点击选择'),
|
||||
val ? h('span', {
|
||||
style: {
|
||||
width: '22px',
|
||||
height: '22px',
|
||||
lineHeight: '22px',
|
||||
textAlign: 'center',
|
||||
color: 'red',
|
||||
borderLeft: '1px solid #eee',
|
||||
flexShrink: 0,
|
||||
fontSize: '14px',
|
||||
cursor: 'pointer'
|
||||
},
|
||||
on: {
|
||||
click: (e) => {
|
||||
e.stopPropagation();
|
||||
const row = params.row;
|
||||
let delId = null;
|
||||
const classTeach = this.teachList.find(t => t.classId === row.classId);
|
||||
if (classTeach) {
|
||||
const target = classTeach.teachSubjectList.find(s => s.subId === subId);
|
||||
delId = target?.id;
|
||||
}
|
||||
this.$api.post(APIConfig.BschClassSystem.teachsdelete+delId, {}, res => {
|
||||
if (res.code === 0) {
|
||||
this.$Message.success('移除教师成功');
|
||||
this.getteachssearch();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, '×') : null
|
||||
]);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// 右侧操作列
|
||||
const actionColumn = [{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
render: (h, params) => {
|
||||
return h('Button', {
|
||||
props: { type: 'text', icon: 'ios-refresh', size: 'large' },
|
||||
attrs: { title: '重置本行所有任教' },
|
||||
on: { click: () => this.handleResetRow(params.index) }
|
||||
})
|
||||
}
|
||||
}];
|
||||
|
||||
this.tableColumns = [...baseColumns, ...subjectColumns, ...actionColumn];
|
||||
},
|
||||
// 弹窗提交分配教师
|
||||
submitSelectTeacher() {
|
||||
if (!this.selectTeacher) {
|
||||
this.$Message.warning('请选择教师');
|
||||
return;
|
||||
}
|
||||
const row = this.tableData[this.currentRowIndex];
|
||||
const params = {
|
||||
id: this.detailId,
|
||||
gradeId:row.gradeId,
|
||||
classId: row.classId,
|
||||
subId: this.currentSubId,
|
||||
teaId: this.selectTeacher
|
||||
};
|
||||
this.$api.post(APIConfig.BschClassSystem.teachssave, JSON.stringify(params), res => {
|
||||
if (res.code === 0) {
|
||||
this.$Message.success('分配教师成功');
|
||||
this.teacherModalVisible = false;
|
||||
this.getteachssearch();
|
||||
}
|
||||
});
|
||||
},
|
||||
// 关闭弹窗重置变量
|
||||
resetModal() {
|
||||
this.selectDept = '';
|
||||
this.selectTeacher = '';
|
||||
this.currentRowIndex = null;
|
||||
this.currentSubId = '';
|
||||
this.currentClassId = null;
|
||||
this.oldTeacherId = null;
|
||||
this.detailId = null;
|
||||
},
|
||||
// 整行重置清空所有科目教师
|
||||
handleResetRow(index) {
|
||||
this.$Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定清空该班级所有学科任教教师?',
|
||||
onOk: () => {
|
||||
const row = this.tableData[index];
|
||||
const params = {
|
||||
classId: row.classId
|
||||
};
|
||||
this.$api.post(APIConfig.BschClassSystem.delClassTeach, params, res => {
|
||||
if (res.code === 0) {
|
||||
this.getteachssearch();
|
||||
this.$Message.success('重置完成');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
handleGradeChange() {
|
||||
this.getteachssearch();
|
||||
},
|
||||
handleBatchImport() {
|
||||
this.importModalVisible = true;
|
||||
},
|
||||
//导入成功返回
|
||||
importFile(response, file, fileList){
|
||||
const _this=this;
|
||||
console.log(response);
|
||||
console.log(file);
|
||||
_this.spinShow=false;
|
||||
_this.UpParmas.fileName=file.name;
|
||||
_this.UpParmas.listData=response;
|
||||
if(response.State)
|
||||
{
|
||||
_this.$Message.info('导入成功!');
|
||||
_this.getteachssearch();
|
||||
}else{
|
||||
_this.$Message.info(response.Message);
|
||||
}
|
||||
},
|
||||
//附件上传之前的方法
|
||||
handleUpload:function(file){
|
||||
const _this=this;
|
||||
_this.spinShow=true;
|
||||
},
|
||||
MoBanExceldaochu() {
|
||||
var _this = this;
|
||||
if (localStorage.getItem("currentRole")) {
|
||||
let currentRole = localStorage.getItem("currentRole");
|
||||
let { schId, roleId, userId, childId } = JSON.parse(decodeURIComponent(currentRole));
|
||||
let query=this.gradeVal?'?schId='+schId+'&schsystemId='+this.majorVal+'&gradeId='+this.gradeVal:'?schId='+schId+'&schsystemId='+this.majorVal;
|
||||
var url=APIConfig.BschClassSystem.TeachdownloadTemplate+query;
|
||||
window.location.href=url;
|
||||
}else{
|
||||
this.$Message.info('获取不了学校!');
|
||||
}
|
||||
},
|
||||
//附件上传模态框关闭事件
|
||||
UpfileModalcloseclick:function(){
|
||||
this.importModalVisible=false;
|
||||
this.UpParmas={
|
||||
fileName:'',
|
||||
listData:{},
|
||||
datapre:{},
|
||||
}
|
||||
},
|
||||
handleExport() {
|
||||
var _this = this;
|
||||
if (localStorage.getItem("currentRole")) {
|
||||
let currentRole = localStorage.getItem("currentRole");
|
||||
let { schId, roleId, userId, childId } = JSON.parse(decodeURIComponent(currentRole));
|
||||
let query=this.gradeVal?'?schId='+schId+'&schsystemId='+this.majorVal+'&gradeId='+this.gradeVal:'?schId='+schId+'&schsystemId='+this.majorVal;
|
||||
var url=APIConfig.BschClassSystem.teachsexport+query;
|
||||
window.location.href=url;
|
||||
}else{
|
||||
this.$Message.info('获取不了学校!');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.teach-manage-page {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.top-filter-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
background-color: #f7f7f7;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.filter-left, .btn-group-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.table-outer {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.ivu-alert-desc{
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user