This commit is contained in:
lijing
2026-08-12 17:19:37 +08:00
commit e73d22744e
131 changed files with 66997 additions and 0 deletions
+786
View File
@@ -0,0 +1,786 @@
<template>
<div class="container-full-height">
<div class="layout-flex-row">
<!-- 左侧树形容器 高度撑满、内部滚动 -->
<div class="tree-wrap">
<my-tree :treeData="treeData" :selectId="selectnodeid" @on-tree-click="treeLink"></my-tree>
</div>
<!-- 右侧整体容器 高度撑满 -->
<div class="right-full-wrap">
<!-- 顶部按钮栏 固定高度不滚动 -->
<div class="top-btn-bar">
<Dropdown trigger="click" @on-click="changefieid">
<Button type="primary">
添加班级
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem name="openAddSingleClass">添加单个班级</DropdownItem>
<DropdownItem name="openMultiNumModal">添加多个班级</DropdownItem>
</DropdownMenu>
</Dropdown>
<Button type="success" style="margin-left:10px" @click="openImportModal">班级信息导入</Button>
</div>
<!-- 表格容器:填充剩余高度,纵向滚动 -->
<div class="table-auto-scroll">
<Table
border
stripe
:columns="tableColumns"
:data="tableData"
></Table>
</div>
</div>
</div>
<!-- 弹窗1:添加多个班级 设置数量 -->
<Modal v-model="multiClassModal" title="设置添加班级数量" width="400">
<div style="padding:16px 8px;">
<div style="display:flex;align-items:center;">
<span style="width:80px;">班级数</span>
<Input v-model.number="addClassCount" type="number" min="1" />
</div>
</div>
<div slot="footer" align="right">
<Button @click="multiClassModal = false">取消</Button>
<Button type="primary" @click="submitBatchAdd">提交</Button>
</div>
</Modal>
<!-- 弹窗2:班级信息导入 -->
<Modal v-model="importModal" title="班级信息导入" width="560">
<!-- <div style="padding:18px 10px;display:flex;align-items:center;gap:20px;">
<Upload action="" :before-upload="beforeUpload">
<Button>选择要上传的文件</Button>
</Upload>
<a href="javascript:;" style="color:#2d7ff9" @click="downloadTemplate">点击链接下载[用户导入模板.xls]</a>
</div>
<div slot="footer" align="right">
<Button @click="importModal = false">取消</Button>
<Button type="primary" @click="confirmImport">确定</Button>
</div> -->
<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>
<!-- 弹窗3:选择教师 -->
<Modal v-model="selectTeacherModal" title="选择教师" width="420">
<div style="padding:10px 5px;">
<div style="margin-bottom:16px;display:flex;align-items:center;">
<span style="width:75px;">科室</span>
<Select v-model="deptFilter" placeholder="按科室过滤" style="flex:1" @on-change="getteacherSelect" clearable>
<Option v-for="item in groupteacherSelectlist" :key="item.id" :value="item.id">{{ item.name }}</Option>
</Select>
</div>
<div style="display:flex;align-items:center;">
<span style="width:75px;">教师</span>
<Select v-model="selectedTeacher" style="flex:1" 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="selectTeacherModal = false">取消</Button>
<Button type="primary" @click="confirmSelectTeacher">提交</Button>
</div>
</Modal>
<!-- 弹窗5:选择校区 -->
<Modal v-model="selectCampusModal" title="选择校区" width="420">
<div style="padding:10px 5px;">
<div style="display:flex;align-items:center;">
<span style="width:75px;">校区</span>
<Select v-model="selectedCampus" style="flex:1" placeholder="请选择">
<Option v-for="item in campusselectlist" :key="item.id" :value="item.id">{{ item.name }}</Option>
</Select>
</div>
</div>
<div slot="footer" align="right">
<Button @click="selectCampusModal = false">取消</Button>
<Button type="primary" @click="confirmSelectCampus">提交</Button>
</div>
</Modal>
</div>
</template>
<script>
import myTree from "../../components/my_tree";
export default {
components: { myTree},
name: 'ClassHeightFullPage',
data() {
return {
schsystemId:'',
selectnodeid:'',
treeData: [],
selectedTreeNode: null,
selectGrade: '预备',
multiClassModal: false,
addClassCount: 2,
importModal: false,
spinShow:false,
selectTeacherModal: false,
editRowIndex: null,
editField: '',
deptFilter: '',
selectedTeacher: '',
selectCampusModal: false,
campusEditIndex: null,
selectedCampus: '',
tableColumns: [],
tableData: [],
campusselectlist:[],
groupteacherSelectlist:[],
teacherSelectlist:[],
UpParmas:{
fileName:'',
listData:{},
datapre:{},
actionUrl:APIConfig.BschClassSystem.schclassImport,
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.getGradeTree();
this.getgroupteacherSelect();
this.getteacherSelect();
this.getcampusselect();
this.initTableColumn();
},
mounted() {
},
methods: {
//获取年级树
getGradeTree:function(){
const _this = this;
var item={};
_this.$api.get(APIConfig.BschClassSystem.getGradeTree, item, resp => {
if(resp.code==0)
{
_this.treeData = resp.data;
if(resp.data.children.length>0){
// 起始节点为 data
const pathArr = _this.getFirstPath(resp.data);
_this.selectnodeid=pathArr[pathArr.length-1].id;
_this.schsystemId=pathArr[pathArr.length-1].schsystemId;
_this.getsearcBaseSchClass();
}
}else{
_this.treeData=[];
}
});
},
//获取最后一级的map
getFirstPath(rootNode) {
const path = [];
let cur = rootNode;
while (cur) {
// 存入当前层级关键信息
path.push({
id: cur.id,
name: cur.name,
type: cur.type,
schsystemId:cur.schsystemId,
gradeId:cur.gradeId,
classId:cur.classId,
});
// 有子节点就取第一个,没有就终止
if (cur.children && cur.children.length > 0) {
cur = cur.children[0];
} else {
cur = null;
}
}
return path;
},
//获取班级列表
getsearcBaseSchClass:function(){
const _this = this;
var item={
schsystemId:this.schsystemId,
gradeId:this.selectnodeid
};
_this.$api.get(APIConfig.BschClassSystem.getsearcBaseSchClass, item, resp => {
if(resp.code==0)
{
_this.tableData = resp.data;
}else{
_this.tableData=[];
}
});
},
//教师组下拉
getgroupteacherSelect:function(){
const _this = this;
var item={};
_this.$api.get(APIConfig.BschClassSystem.getgroupteacherSelect, item, resp => {
if(resp.code==0)
{
_this.groupteacherSelectlist= resp.data;
}else{
_this.groupteacherSelectlist=[];
}
});
},
//教师下拉
getteacherSelect:function(){
const _this = this;
var item={
groupId:_this.deptFilter
};
_this.$api.get(APIConfig.BschClassSystem.getteacherSelect, item, resp => {
if(resp.code==0)
{
_this.teacherSelectlist= resp.data;
}else{
_this.teacherSelectlist=[];
}
});
},
//校区下拉
getcampusselect:function(){
const _this = this;
var item={};
_this.$api.get(APIConfig.BschClassSystem.getcampusselect, item, resp => {
if(resp.code==0)
{
_this.campusselectlist= resp.data;
}else{
_this.campusselectlist=[];
}
});
},
//节点点击事件
treeLink(treeNode){
this.schsystemId=treeNode.schsystemId;
this.selectnodeid=treeNode.id;
this.getsearcBaseSchClass();
},
initTableColumn() {
this.tableColumns = [
{ title: '序号', type: 'index', align: 'center', width: 70 },
{ title: '班级名称', key: 'name', align: 'center', width: 100 },
{
title: '班级别名',
align: 'center',
render: (h, params) => {
return h('Input', {
props: { value: params.row.cname },
style: { width: '150px' },
on: {
input: (val) => {
this.$set(params.row, 'classAlias', val)
this.cellChange(params.index, 'classAlias', val)
}
}
})
}
},
{
title: '班主任',
align: 'center',
width: 160,
render: (h, params) => {
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.openTeacherSelect(params.index, 'headTeacher')
}
}, [
h('span', {
style: {
flex: 1,
textAlign: 'center',
fontSize: '14px',
paddingLeft: '6px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
}
}, params.row.firstTeacherName || ''),
params.row.firstTeacherName ? h('span', {
style: {
width: '22px',
height: '22px',
lineHeight: '22px',
textAlign: 'center',
color: 'red',
borderLeft: '1px solid #eee',
flexShrink: 0,
fontSize: '14px'
},
on: {
click: (e) => {
e.stopPropagation()
var item={
id:params.row.id,
firstTeacherId:null
};
let url=APIConfig.BschClassSystem.editClassFirstTeacher;
this.$api.post(url, item, resp => {
if(resp.code==0)
{
this.$Message.success(`设置教师成功`);
this.getsearcBaseSchClass();
}
});
}
}
}, '×') : null
])
}
},
{
title: '副班主任',
align: 'center',
width: 160,
render: (h, params) => {
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.openTeacherSelect(params.index, 'secondTeacherName')
}
}, [
h('span', {
style: {
flex: 1,
textAlign: 'center',
fontSize: '14px',
paddingLeft: '6px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
}
}, params.row.secondTeacherName || ''),
params.row.secondTeacherName ? h('span', {
style: {
width: '22px',
height: '22px',
lineHeight: '22px',
textAlign: 'center',
color: 'red',
borderLeft: '1px solid #eee',
flexShrink: 0,
fontSize: '14px'
},
on: {
click: (e) => {
e.stopPropagation()
var item={
id:params.row.id,
secondTeacherId:null
};
let url=APIConfig.BschClassSystem.editClassSecondTeacher;
this.$api.post(url, item, resp => {
if(resp.code==0)
{
this.$Message.success(`设置教师成功`);
this.getsearcBaseSchClass();
}
});
}
}
}, '×') : null
])
}
},
{
title: '校区',
align: 'center',
width: 160,
render: (h, params) => {
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.openCampusSelect(params.index)
}
}, [
h('span', {
style: {
flex: 1,
textAlign: 'center',
fontSize: '14px',
paddingLeft: '6px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
}
}, params.row.campusName || ''),
params.row.campusName ? h('span', {
style: {
width: '22px',
height: '22px',
lineHeight: '22px',
textAlign: 'center',
color: 'red',
borderLeft: '1px solid #eee',
flexShrink: 0,
fontSize: '14px'
},
on: {
click: (e) => {
e.stopPropagation()
var item={
id:params.row.id,
campusId:null
};
let url=APIConfig.BschClassSystem.editClassCampus;
this.$api.post(url, item, resp => {
if(resp.code==0)
{
this.$Message.success(`校区设置成功`);
this.getsearcBaseSchClass();
}
});
}
}
}, '×') : null
])
}
},
{
title: '操作',
align: 'center',
width: 100,
render: (h, params) => {
return h('div', { style: { display: 'flex', gap: '8px', justifyContent: 'center' } }, [
h('Button', {
props: { icon: 'ios-eye-outline', type: 'text', size: 'large' },
on: { click: () => this.viewDetail(params.row) }
}),
h('Button', {
props: { icon: 'ios-trash-outline', type: 'text', color: 'red', size: 'large',disabled:params.row.disableDel },
on: { click: () => this.deleteRow(params.index, params.row) }
})
])
}
}
]
},
loadTableData() {
console.log('当前筛选年级:', this.selectGrade)
// 替换后端请求
},
cellChange(rowIndex, field, value) {
var item={
id:this.tableData[rowIndex].id,
cname:value
};
this.$api.post(APIConfig.BschClassSystem.editClassName, item, resp => {
if(resp.code==0)
{
// this.$Message.success(`设置班级名称成功`);
this.getsearcBaseSchClass();
}
});
},
//自定义类型添加
changefieid:function(name){
var _this=this;
if(name=="openAddSingleClass")
{
var item={
gradeId:_this.selectnodeid,
number:1
};
_this.$api.post(APIConfig.BschClassSystem.addBaseSchClass, item, resp => {
if(resp.code==0)
{
this.$Message.success(`新增1个班级!`);
this.getsearcBaseSchClass();
}
});
}else if(name=="openMultiNumModal")
{
this.addClassCount = 2
this.multiClassModal = true
}
},
//批量增加班级
submitBatchAdd() {
if (this.addClassCount < 1) return this.$Message.warning('班级数量不能小于1');
var item={
gradeId:this.selectnodeid,
number:this.addClassCount
};
this.$api.post(APIConfig.BschClassSystem.addBaseSchClass, item, resp => {
if(resp.code==0)
{
this.$Message.success(`批量新增${this.addClassCount}个班级`);
this.getsearcBaseSchClass();
this.multiClassModal = false;
}
});
},
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.schclassdownloadTemplate+'?schId='+schId;
window.location.href=url;
}else{
this.$Message.info('获取不了学校!');
}
},
//附件上传模态框关闭事件
UpfileModalcloseclick:function(){
this.importModal=false;
this.UpParmas={
fileName:'',
listData:{},
datapre:{},
}
},
openTeacherSelect(index, field) {
this.editRowIndex = index
this.editField = field
this.deptFilter = ''
this.selectedTeacher =field=='headTeacher'? this.tableData[index].firstTeacherId:this.tableData[index].secondTeacherId;
this.selectTeacherModal = true
},
confirmSelectTeacher() {
if (!this.selectedTeacher) return this.$Message.warning('请选择教师');
var item={
id:this.tableData[this.editRowIndex].id
};
if(this.editField=='headTeacher'){
item.firstTeacherId=this.selectedTeacher;
}else{
item.secondTeacherId=this.selectedTeacher;
}
let url=this.editField=='headTeacher'?APIConfig.BschClassSystem.editClassFirstTeacher:APIConfig.BschClassSystem.editClassSecondTeacher;
this.$api.post(url, item, resp => {
if(resp.code==0)
{
this.$Message.success(`设置教师成功`);
this.getsearcBaseSchClass();
this.selectTeacherModal = false;
}
});
},
openCampusSelect(index) {
this.campusEditIndex = index
this.selectedCampus = this.tableData[index].campusId;
this.selectCampusModal = true
},
confirmSelectCampus() {
var item={
id:this.tableData[this.campusEditIndex].id,
campusId:this.selectedCampus
};
let url=APIConfig.BschClassSystem.editClassCampus;
this.$api.post(url, item, resp => {
if(resp.code==0)
{
this.$Message.success(`校区设置成功`);
this.getsearcBaseSchClass();
this.selectCampusModal = false;
}
});
},
viewDetail(row) {
this.$router.push('/ChristianityDetail?gradeId='+row.gradeId+'&classId='+row.classId+'&gradeclassName='+row.gradeName+row.name);
},
deleteRow(index, row) {
this.$Modal.confirm({
title: '确认删除',
content: `确定删除班级「${row.name}」吗?`,
onOk: () => {
var url=APIConfig.BschClassSystem.deleteBaseSchClass+this.tableData[index].id;
this.$api.post(url,{},(resp)=>{
this.$Message.success('删除成功!');
this.getsearcBaseSchClass();
});
}
})
}
}
}
</script>
<style scoped>
/* 根容器占满父高度 */
.container-full-height {
width: 100%;
height: 100%;
box-sizing: border-box;
border: 1px solid #e5e7eb;
border-radius: 6px;
padding: 12px;
background: #fff;
display: flex;
flex-direction: column;
}
.layout-flex-row {
display: flex;
flex: 1;
gap: 16px;
min-height: 0;
}
/* 左侧树形 压到底部、内部滚动 */
.tree-wrap {
width: 220px;
border: 1px solid #e8e8e8;
padding: 8px;
overflow-y: auto;
flex-shrink: 0;
}
/* 右侧整体容器 高度填充 */
.right-full-wrap {
flex: 1;
display: flex;
flex-direction: column;
min-width: 0;
min-height: 0;
}
/* 顶部按钮栏 固定不滚动 */
.top-btn-bar {
padding-bottom: 14px;
flex-shrink: 0;
}
/* 表格区域:自动填充剩余高度,纵向滚动 */
.table-auto-scroll {
flex: 1;
overflow: auto;
min-height: 0;
}
</style>
<style>
.ivu-alert-desc{
font-size: 12px;
}
</style>