- 构建:Vue CLI 4 → Vite 5,入口迁至根 index.html(含 env-config + 主题通道 loader)
- 技术栈:Vue 2.6 → Vue 3.4,view-design → view-ui-plus 1.3.24,vue-router 3 → 4(hash)
- 壳层重写:App.vue / components/layout.vue 对齐 Notice 骨架(logo-badge、icon-* 通道图标、resolveMenuPage、crumb-home 基线)
- 机械转换:具名 slot → template #x、.sync → v-model:、@click.native、$set、beforeDestroy、/deep/ → :deep()
- render:h('Button')/h('Input') → 真组件 + 扁平 props/onClick
- 组件适配:vuedraggable 4 的 #item 插槽;vue-treeselect → @zanmato/vue3-treeselect;Page 分页改 v-model + pageSize 显式回写
- 清理:删除 Vue2 死代码(layout_old/bak/child、App.Net、codeModal、未引用组件)
- 修复:深链接首次加载被重定向到首个模块(router.isReady)
验证:vite build 通过;headless CDP 全 15 路由无异常;教师列表 2 行渲染、操作列按钮点击弹窗正常。
338 lines
9.3 KiB
Vue
338 lines
9.3 KiB
Vue
<template>
|
||
<div class="student-move-wrap">
|
||
<!-- 顶部筛选栏 -->
|
||
<div class="top-filter-bar">
|
||
<div class="search-wrap" style="width:100%;">
|
||
<span>学校:</span>
|
||
<Select v-model="filterSchool" style="width: 200px" @on-change="getselectBySchId">
|
||
<Option value="-1">全部</Option>
|
||
<Option v-for="item in SchoolList" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
||
</Select>
|
||
<span style="margin-left: 16px">年级:</span>
|
||
<Select v-model="filterGrade" style="width: 140px" @on-change="getselectBySchIdAndGradeId">
|
||
<Option value="-1">全部</Option>
|
||
<Option v-for="item in gradeselectList" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
||
</Select>
|
||
<span style="margin-left: 16px">班级:</span>
|
||
<Select v-model="filterClass" style="width: 140px" @on-change="handleFilterChange">
|
||
<Option value="-1">全部</Option>
|
||
<Option v-for="item in schclassselectlist" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
||
</Select>
|
||
<span>
|
||
|
||
</span>
|
||
<Input
|
||
placeholder="请输入学生姓名"
|
||
search
|
||
@on-search="handleSearch"
|
||
suffix="ios-search"
|
||
class="fr"
|
||
style="width: 280px"
|
||
v-model="keyword"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 自适应滚动表格容器 -->
|
||
<div class="table-scroll-wrap">
|
||
<Table
|
||
stripe
|
||
:columns="tableColumns"
|
||
:data="tableData"
|
||
:height="useTableHeight()+32"
|
||
@on-selection-change="onSelectionChange"
|
||
></Table>
|
||
</div>
|
||
|
||
<!-- 底部栏:转入按钮 + 固定分页 -->
|
||
<div class="bottom-bar">
|
||
<!-- <Button type="default" status="danger" @click="openMoveModal">转入</Button> -->
|
||
<div> </div>
|
||
<div class="page-area">
|
||
<span style="margin-right: 12px">共 {{ total }} 条</span>
|
||
<Page
|
||
v-model="pageNum"
|
||
:page-size="pageSize"
|
||
:total="total"
|
||
:page-size-opts="[10,20,40]"
|
||
show-sizer
|
||
@on-change="pageChange"
|
||
@on-page-size-change="sizeChange"
|
||
></Page>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 弹窗:转至其他组 -->
|
||
<Modal v-model="moveModalVisible" title="转至其他组" width="540">
|
||
<div style="padding: 15px 10px;">
|
||
<div style="margin-bottom: 18px;display: flex;align-items: center;">
|
||
<span style="width: 105px;">待移动用户:</span>
|
||
<Input v-model="moveStuName" disabled style="flex:1;"></Input>
|
||
</div>
|
||
<div>
|
||
<span style="width: 105px;display: inline-block;margin-bottom: 10px;color:#f56c6c;font-weight:bold;">移动至:</span>
|
||
<my-tree :treeData="targetTreeData" @on-tree-click="treeLink"></my-tree>
|
||
</div>
|
||
</div>
|
||
<template #footer><div align="right">
|
||
<Button @click="moveModalVisible = false">取消</Button>
|
||
<Button type="primary" @click="submitMove">提交</Button>
|
||
</div></template>
|
||
</Modal>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { Button } from "view-ui-plus";
|
||
import myTree from "../../components/my_tree";
|
||
import { self_viewport } from "@/mixins/self_viewport";
|
||
export default {
|
||
name: 'StudentMovePage',
|
||
components: { myTree },
|
||
data() {
|
||
return {
|
||
// 筛选条件
|
||
filterSchool: '-1',
|
||
filterGrade: '-1',
|
||
filterClass: '-1',
|
||
keyword: '',
|
||
|
||
// 分页
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
total: 0,
|
||
selectedRows: [],
|
||
SchoolList:[],
|
||
gradeselectList:[],
|
||
schclassselectlist:[],
|
||
|
||
// 表格配置式列
|
||
tableColumns: [],
|
||
tableData: [],
|
||
|
||
// 转入弹窗
|
||
moveModalVisible: false,
|
||
moveStuName: '',
|
||
selectnodeid: 0,
|
||
// 目标学校年级树形
|
||
targetTreeData: []
|
||
}
|
||
},
|
||
mixins: [self_viewport],
|
||
created() {
|
||
this.getstudenttransferOutSchSelect();
|
||
this.initTableColumn();
|
||
this.loadTableData();
|
||
},
|
||
methods: {
|
||
//获取学校下拉
|
||
getstudenttransferOutSchSelect:function(){
|
||
const _this = this;
|
||
var item={};
|
||
_this.$api.get(APIConfig.BschClassSystem.studenttransferOutSchSelect, item, resp => {
|
||
if(resp.code==0)
|
||
{
|
||
_this.SchoolList = resp.data;
|
||
_this.handleFilterChange();
|
||
}else{
|
||
_this.SchoolList=[];
|
||
}
|
||
});
|
||
},
|
||
//获取年级
|
||
getselectBySchId:function(){
|
||
const _this = this;
|
||
var item={
|
||
schId:_this.filterSchool
|
||
};
|
||
_this.$api.get(APIConfig.BschClassSystem.getselectBySchId, item, resp => {
|
||
if(resp.code==0)
|
||
{
|
||
_this.gradeselectList = resp.data;
|
||
_this.handleFilterChange();
|
||
}else{
|
||
_this.gradeselectList=[];
|
||
}
|
||
});
|
||
},
|
||
//获取班级下拉
|
||
getselectBySchIdAndGradeId:function(){
|
||
const _this = this;
|
||
var item={
|
||
schId:_this.filterSchool,
|
||
gradeId:_this.filterGrade
|
||
};
|
||
_this.$api.get(APIConfig.BschClassSystem.getselectBySchIdAndGradeId, item, resp => {
|
||
if(resp.code==0)
|
||
{
|
||
this.schclassselectlist=resp.data;
|
||
}
|
||
});
|
||
},
|
||
// 初始化表格列
|
||
initTableColumn() {
|
||
this.tableColumns = [
|
||
// { type: 'selection', width: 55, align: 'center' },
|
||
{ title: '序号', type: 'index', align: 'center', width: 70 },
|
||
{ title: '学校', key: 'schName', align: 'center' },
|
||
{ title: '年级', key: 'gradeName', align: 'center', width: 110 },
|
||
{ title: '班级', key: 'className', align: 'center', width: 90 },
|
||
{ title: '姓名', key: 'name', align: 'center' },
|
||
{ title: '身份号', key: 'idCard', align: 'center' },
|
||
{
|
||
title: '操作',
|
||
align: 'center',
|
||
width: 100,
|
||
render: (h, params) => {
|
||
return h(Button, {type: 'text',
|
||
onClick: () => this.openMoveModal(params.row)},'转入')
|
||
}
|
||
}
|
||
]
|
||
},
|
||
|
||
// 多选勾选回调
|
||
onSelectionChange(rows) {
|
||
this.selectedRows = rows
|
||
},
|
||
|
||
// 加载列表数据
|
||
loadTableData() {
|
||
const _this = this;
|
||
var item = {
|
||
schId:_this.filterSchool=='-1'?'':_this.filterSchool,
|
||
gradeId:_this.filterGrade=='-1'?'':_this.filterGrade,
|
||
classId:_this.filterClass=='-1'?'':_this.filterClass,
|
||
keyword:_this.keyword,
|
||
page:_this.pageNum-1,
|
||
size:_this.pageSize
|
||
};
|
||
_this.$api.get(APIConfig.BschClassSystem.getstudentsearchTransferOut, item, resp => {
|
||
if (resp.code == 0) {
|
||
_this.tableData = resp.data.content;
|
||
_this.total=resp.data.total;
|
||
} else {
|
||
_this.tableData = [];
|
||
}
|
||
});
|
||
},
|
||
|
||
// 下拉筛选切换
|
||
handleFilterChange() {
|
||
this.pageNum = 1
|
||
this.loadTableData()
|
||
},
|
||
|
||
// 关键词搜索
|
||
handleSearch() {
|
||
this.pageNum = 1
|
||
this.loadTableData()
|
||
},
|
||
|
||
// 分页切换
|
||
pageChange(p) {
|
||
this.pageNum = p
|
||
this.loadTableData()
|
||
},
|
||
sizeChange(size) {
|
||
this.pageSize = size
|
||
this.pageNum = 1
|
||
this.loadTableData()
|
||
},
|
||
|
||
// 打开转入弹窗
|
||
openMoveModal(row) {
|
||
// if (!this.selectedRows.length) {
|
||
// return this.$Message.warning('请先勾选需要转入的学生')
|
||
// }
|
||
this.selectedRows=[row];
|
||
this.moveStuName = this.selectedRows.map(a=>a.name).join(',');
|
||
this.moveModalVisible = true;
|
||
this.getClassTree();
|
||
},
|
||
//获取班级树
|
||
getClassTree:function(){
|
||
const _this = this;
|
||
var item={};
|
||
_this.$api.get(APIConfig.BschClassSystem.getClassTree, item, resp => {
|
||
if(resp.code==0)
|
||
{
|
||
this.targetTreeData=resp.data;
|
||
}
|
||
});
|
||
},
|
||
// 树形选中切换
|
||
treeLink(treeNode) {
|
||
this.selectnodeid=treeNode.id;
|
||
},
|
||
// 提交迁移班级
|
||
submitMove() {
|
||
if (!this.selectnodeid) {
|
||
return this.$Message.warning('请选择目标年级节点')
|
||
}
|
||
const teacherIdArr = this.selectedRows.map(row => row.id);
|
||
let item={
|
||
stuId:teacherIdArr.join(','),
|
||
transferClassId:this.selectnodeid
|
||
};
|
||
const url = APIConfig.BschClassSystem.studentsetTransferIn;
|
||
this.$api.post(url,JSON.stringify(item), resp => {
|
||
if (resp.code == 0) {
|
||
this.$Message.success('学生转入分组成功!');
|
||
this.moveModalVisible = false
|
||
this.selectedRows = []
|
||
this.loadTableData()
|
||
} else if (resp.code == 4) {
|
||
this.$Message.info(resp.msg);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.student-move-wrap {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
box-sizing: border-box;
|
||
padding: 12px;
|
||
}
|
||
|
||
/* 顶部筛选栏 */
|
||
.top-filter-bar {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding-bottom: 14px;
|
||
flex-shrink: 0;
|
||
}
|
||
.filter-left {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
/* 表格自适应滚动容器 */
|
||
.table-scroll-wrap {
|
||
flex: 1;
|
||
min-height: 0;
|
||
}
|
||
.table-scroll-wrap :deep(.ivu-table) {
|
||
height: 100%;
|
||
}
|
||
|
||
/* 底部栏:分页固定底部 */
|
||
.bottom-bar {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding-top: 14px;
|
||
flex-shrink: 0;
|
||
}
|
||
.page-area {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
</style> |