2020-12-31 09:32:25 +08:00
|
|
|
<template>
|
2020-12-31 16:40:13 +08:00
|
|
|
<div>
|
2021-01-05 13:56:51 +08:00
|
|
|
<div class="back_box">
|
2021-01-07 15:14:58 +08:00
|
|
|
<el-button v-if="companyAdmin" :loading="loadingStudentInfo" type="text" class="uploadDemo" style="margin-top: 10px;">
|
2021-01-06 13:23:16 +08:00
|
|
|
<input
|
|
|
|
id="importResults"
|
|
|
|
ref="files"
|
|
|
|
type="file"
|
|
|
|
class="file_box"
|
|
|
|
accept=".json, application/json, .csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
|
|
|
@change="importResults"
|
|
|
|
>
|
|
|
|
导入学生信息
|
|
|
|
</el-button>
|
2021-01-08 17:48:25 +08:00
|
|
|
<el-button type="text" @click="exportTemplate">学生信息导入模板</el-button>
|
2021-01-05 13:56:51 +08:00
|
|
|
<el-button type="text" @click="goBack">返回</el-button>
|
|
|
|
</div>
|
2021-01-07 15:14:58 +08:00
|
|
|
<el-tabs v-model="activeName" type="card">
|
2021-01-05 13:56:51 +08:00
|
|
|
<el-tab-pane label="部门管理" name="first">
|
2021-01-07 15:14:58 +08:00
|
|
|
<div style="font-size: 22px;text-align: center;">{{ $store.state.user.companyName }}</div>
|
|
|
|
<div style="position: relative;transform: translateX(-50%);left: 50%;padding: 20px;width: 500px;">
|
|
|
|
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick">
|
|
|
|
<div slot-scope="{ node, data }" style="display: flex;justify-content: space-between;align-items: center;width: 100%;">
|
|
|
|
<div>{{ data.name }}</div>
|
|
|
|
<div>
|
|
|
|
<el-button type="text" @click="() => editDept(data)">编辑</el-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</el-tree>
|
|
|
|
</div>
|
2021-01-05 13:56:51 +08:00
|
|
|
</el-tab-pane>
|
|
|
|
<el-tab-pane label="成员管理" name="second">
|
2021-01-07 15:14:58 +08:00
|
|
|
<el-row>
|
|
|
|
<el-col :span="21" :offset="1">
|
|
|
|
<span>班级</span>
|
|
|
|
<el-select v-model="classId" size="small" placeholder="班级">
|
|
|
|
<el-option
|
|
|
|
v-for="item in classList"
|
|
|
|
:key="item.departmentId"
|
|
|
|
:label="item.departmentName"
|
|
|
|
:value="item.departmentId"
|
|
|
|
/>
|
|
|
|
</el-select>
|
|
|
|
</el-col>
|
|
|
|
<el-col :span="2">
|
|
|
|
<el-button type="primary" size="small" @click="onSubmit">查询</el-button>
|
|
|
|
</el-col>
|
|
|
|
</el-row>
|
|
|
|
<el-table :data="tableData" border style="width: 100%;margin-top: 10px;" :max-height="height">
|
|
|
|
<el-table-column prop="account" label="学号" />
|
2021-01-06 13:23:16 +08:00
|
|
|
<el-table-column prop="name" label="姓名" />
|
2021-01-07 15:14:58 +08:00
|
|
|
<el-table-column prop="companyName" label="组织" />
|
|
|
|
<el-table-column prop="departmentName" label="班级" />
|
|
|
|
<el-table-column label="操作">
|
|
|
|
<template slot-scope="scope">
|
2021-01-08 17:55:42 +08:00
|
|
|
<el-button type="text" @click="handleDelete(scope.$index, scope.row)">移出班级</el-button>
|
2021-01-07 15:14:58 +08:00
|
|
|
</template>
|
|
|
|
</el-table-column>
|
2021-01-06 13:23:16 +08:00
|
|
|
</el-table>
|
2021-01-07 15:14:58 +08:00
|
|
|
<div style="text-align: center;padding: 10px;">
|
2021-01-06 13:23:16 +08:00
|
|
|
<el-pagination
|
|
|
|
:current-page="currentPage"
|
|
|
|
:page-sizes="[10, 20, 30, 50, 100]"
|
|
|
|
:page-size="pageSize"
|
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
:total="totalNum"
|
|
|
|
@size-change="handleSizeChange"
|
|
|
|
@current-change="handleCurrentChange"
|
|
|
|
/>
|
|
|
|
</div>
|
2021-01-05 13:56:51 +08:00
|
|
|
</el-tab-pane>
|
2021-01-08 17:27:25 +08:00
|
|
|
<el-tab-pane label="成绩导出" name="third">
|
|
|
|
<grade-export refs="gradeExport" :class-list="classList" :height="height" />
|
|
|
|
</el-tab-pane>
|
2020-12-31 09:32:25 +08:00
|
|
|
</el-tabs>
|
2021-01-07 15:14:58 +08:00
|
|
|
<el-dialog
|
|
|
|
title="修改部门名称"
|
|
|
|
:visible.sync="dialogVisible"
|
|
|
|
width="30%"
|
|
|
|
>
|
|
|
|
<el-input v-model="newDeptName" />
|
|
|
|
<span slot="footer" class="dialog-footer">
|
|
|
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
|
|
|
<el-button type="primary" @click="updateDeptName">确 定</el-button>
|
|
|
|
</span>
|
|
|
|
</el-dialog>
|
2020-12-31 16:40:13 +08:00
|
|
|
</div>
|
2020-12-31 09:32:25 +08:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2021-01-07 15:14:58 +08:00
|
|
|
import { getCompanyDeptInfo, importCompanyMember, queryDeptInfoPaging, getAllDeptTree, deleteDepartUserRelation, updateDeptInfo } from '@/api/company';
|
2021-01-06 13:23:16 +08:00
|
|
|
import { convertSheetToList } from '@/utils/runPlan';
|
|
|
|
import XLSX from 'xlsx';
|
2021-01-08 17:27:25 +08:00
|
|
|
import GradeExport from './gradeExport';
|
2021-01-06 13:23:16 +08:00
|
|
|
|
2020-12-31 09:32:25 +08:00
|
|
|
export default {
|
|
|
|
name: 'Organization',
|
2021-01-08 17:27:25 +08:00
|
|
|
components:{
|
|
|
|
GradeExport
|
|
|
|
},
|
2020-12-31 09:32:25 +08:00
|
|
|
data() {
|
|
|
|
return {
|
2021-01-07 15:14:58 +08:00
|
|
|
activeName: 'second',
|
|
|
|
defaultProps: {
|
|
|
|
children: 'childDept',
|
|
|
|
label: 'name'
|
|
|
|
},
|
2021-01-06 13:23:16 +08:00
|
|
|
currentPage: 1,
|
|
|
|
totalNum: 0,
|
|
|
|
pageSize: 10,
|
|
|
|
data: [],
|
|
|
|
tableData: [],
|
|
|
|
loadingStudentInfo: false,
|
2021-01-07 15:14:58 +08:00
|
|
|
classId: '',
|
2021-01-06 13:23:16 +08:00
|
|
|
classList: [],
|
2021-01-07 15:14:58 +08:00
|
|
|
dialogVisible:false,
|
|
|
|
editDeptInfo: '',
|
|
|
|
newDeptName: ''
|
2020-12-31 09:32:25 +08:00
|
|
|
};
|
|
|
|
},
|
2021-01-06 13:23:16 +08:00
|
|
|
computed: {
|
|
|
|
companyId() {
|
|
|
|
return this.$store.state.user.companyId;
|
2021-01-07 15:14:58 +08:00
|
|
|
},
|
|
|
|
companyAdmin() {
|
|
|
|
return this.$store.state.user.companyAdmin;
|
|
|
|
},
|
|
|
|
height() {
|
|
|
|
return this.$store.state.app.height - 240;
|
2021-01-06 13:23:16 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {
|
2021-01-07 15:14:58 +08:00
|
|
|
this.classList = [];
|
|
|
|
this.data = [];
|
|
|
|
this.getCompanyDept();
|
|
|
|
this.getDeptTree();
|
2021-01-06 13:23:16 +08:00
|
|
|
},
|
2020-12-31 09:32:25 +08:00
|
|
|
methods: {
|
2021-01-06 13:23:16 +08:00
|
|
|
onSubmit() {
|
2021-01-07 15:14:58 +08:00
|
|
|
if (this.classId) {
|
|
|
|
const params = { deptId: this.classId, pageSize: this.pageSize, pageNum: this.currentPage };
|
|
|
|
queryDeptInfoPaging(params).then(resp => {
|
|
|
|
this.pageSize = resp.data.pageSize;
|
|
|
|
this.currentPage = resp.data.pageNum;
|
|
|
|
this.totalNum = resp.data.total;
|
|
|
|
this.tableData = resp.data.list;
|
|
|
|
}).catch(error => {
|
|
|
|
console.error(error);
|
|
|
|
this.$message.error('查询学生信息失败!');
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.$message.error('请选择班级!');
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getCompanyDept() {
|
|
|
|
getCompanyDeptInfo(this.companyId).then(resp => {
|
|
|
|
this.classList = resp.data;
|
|
|
|
if (!this.classId && this.classList && this.classList.length) {
|
|
|
|
this.classId = this.classList[0].departmentId;
|
|
|
|
this.onSubmit();
|
|
|
|
}
|
|
|
|
}).catch(error => {
|
|
|
|
console.error(error);
|
|
|
|
this.$message.error('查询部门信息失败!');
|
|
|
|
});
|
|
|
|
},
|
|
|
|
getDeptTree() {
|
|
|
|
if (this.companyAdmin) {
|
|
|
|
getAllDeptTree(this.companyId).then(resp => {
|
|
|
|
this.data = resp.data;
|
|
|
|
}).catch(error => {
|
|
|
|
console.error(error);
|
|
|
|
this.$message.error('获取部门树信息失败!');
|
|
|
|
});
|
|
|
|
}
|
2021-01-06 13:23:16 +08:00
|
|
|
},
|
|
|
|
handleSizeChange(val) {
|
2021-01-07 15:14:58 +08:00
|
|
|
console.log(val);
|
|
|
|
this.pageSize = val;
|
|
|
|
this.onSubmit();
|
2021-01-06 13:23:16 +08:00
|
|
|
},
|
|
|
|
handleCurrentChange(val) {
|
2021-01-07 15:14:58 +08:00
|
|
|
console.log(val);
|
|
|
|
this.currentPage = val;
|
|
|
|
this.onSubmit();
|
2021-01-06 13:23:16 +08:00
|
|
|
},
|
|
|
|
importResults(e) {
|
|
|
|
const obj = this.$refs.files;
|
|
|
|
if (obj.files) {
|
|
|
|
const file = obj.files[0];
|
|
|
|
this.handleImportResults(file);
|
|
|
|
obj.value = '';
|
|
|
|
}
|
|
|
|
},
|
2021-01-07 15:14:58 +08:00
|
|
|
editDept(data) {
|
|
|
|
this.editDeptInfo = data;
|
|
|
|
this.newDeptName = data.name;
|
|
|
|
this.dialogVisible = true;
|
|
|
|
},
|
|
|
|
updateDeptName() {
|
|
|
|
updateDeptInfo(this.editDeptInfo.id, {name: this.newDeptName}).then(resp => {
|
|
|
|
this.dialogVisible = false;
|
|
|
|
this.getDeptTree();
|
|
|
|
this.getCompanyDept();
|
|
|
|
}).catch(() => {
|
|
|
|
this.$message.error('更新部门信息失败!');
|
|
|
|
});
|
|
|
|
},
|
|
|
|
handleDelete(index, row) {
|
|
|
|
const _that = this;
|
|
|
|
const data = { userId:row.userId, departmentId:row.departmentId };
|
|
|
|
this.$confirm('是否确认删除成员部门关系?', this.$t('tip.hint'), {
|
|
|
|
confirmButtonText: '确认',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
deleteDepartUserRelation(data).then(response => {
|
|
|
|
_that.onSubmit();
|
|
|
|
}).catch(() => {
|
|
|
|
_that.$message.error('删除成员部门关系失败!');
|
|
|
|
});
|
|
|
|
}).catch(() => {
|
|
|
|
});
|
|
|
|
},
|
2021-01-06 13:23:16 +08:00
|
|
|
handleImportResults(file) {
|
|
|
|
const studentData = { depart: '', parentDepart: '', companyUsers:[] };
|
|
|
|
if (file) {
|
|
|
|
setTimeout(() => {
|
|
|
|
const that = this;
|
|
|
|
const reader = new FileReader();
|
|
|
|
if (reader) {
|
|
|
|
reader.onload = function (e) {
|
|
|
|
let wb;
|
|
|
|
const data = e.target.result;
|
|
|
|
if (that.rABS) {
|
|
|
|
wb = XLSX.read(btoa(that.fixdata(data)), { // 手动转化
|
|
|
|
type: 'base64'
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
wb = XLSX.read(data, {
|
|
|
|
type: 'binary'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (wb) {
|
|
|
|
try {
|
|
|
|
const students = [];
|
|
|
|
for (const index in wb.Sheets) {
|
|
|
|
const dataList = convertSheetToList(wb.Sheets[index], true);
|
|
|
|
if (dataList.length) {
|
|
|
|
const depart = dataList[2][0].trim();
|
|
|
|
const parentDepart = dataList[1][0].trim();
|
|
|
|
studentData.depart = depart;
|
|
|
|
studentData.parentDepart = parentDepart;
|
|
|
|
for ( let i = 2; i <= dataList[0].length; i++) {
|
|
|
|
if (dataList[2][i] && dataList[1][i]) {
|
|
|
|
students.push({account:dataList[1][i], name: dataList[2][i]});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
studentData.companyUsers = students;
|
|
|
|
}
|
|
|
|
that.loadingStudentInfo = true;
|
|
|
|
importCompanyMember(that.companyId, studentData).then(resp => {
|
2021-01-07 15:14:58 +08:00
|
|
|
that.$message.success('学生信息导入成功!');
|
2021-01-08 17:53:04 +08:00
|
|
|
that.loadingStudentInfo = false;
|
2021-01-07 15:14:58 +08:00
|
|
|
that.getCompanyDept();
|
|
|
|
that.getDeptTree();
|
2021-01-06 13:23:16 +08:00
|
|
|
}).catch((error) => {
|
|
|
|
that.$message.error('学生信息导入失败:' + error.message);
|
|
|
|
that.loadingStudentInfo = false;
|
|
|
|
});
|
|
|
|
} catch (error) {
|
2021-01-07 15:14:58 +08:00
|
|
|
that.$message.warning(`解析学生信息表失败:${error}`);
|
2021-01-06 13:23:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
if (that.rABS) {
|
|
|
|
reader.readAsArrayBuffer(file);
|
|
|
|
} else {
|
|
|
|
reader.readAsBinaryString(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 200);
|
|
|
|
}
|
|
|
|
},
|
2021-01-05 13:56:51 +08:00
|
|
|
goBack() {
|
|
|
|
this.$router.go(-1);
|
|
|
|
},
|
2021-01-08 17:27:25 +08:00
|
|
|
exportTemplate() {
|
|
|
|
const wb = XLSX.utils.book_new();
|
|
|
|
const data1 = [{A: '', B: '年级一', C:'班级二'}];
|
|
|
|
const data2 = [{A: '序号', B: '学号', C:'姓名'}];
|
|
|
|
const data3 = [{A: '1', B: '00001', C:'张三'}];
|
|
|
|
const data4 = [{A: '2', B: '00002', C:'李四'}];
|
|
|
|
const data = [...data1, ...data2, ...data3, ...data4];
|
|
|
|
const ws = XLSX.utils.json_to_sheet(data, {skipHeader:true});
|
|
|
|
ws['!cols'] = [
|
|
|
|
{width: 15},
|
|
|
|
{width: 15},
|
|
|
|
{width: 15}
|
|
|
|
];
|
|
|
|
XLSX.utils.book_append_sheet(wb, ws, 'file');
|
|
|
|
XLSX.writeFile(wb, '学生信息模板' + '.xlsx');
|
2021-01-05 13:56:51 +08:00
|
|
|
},
|
|
|
|
handleNodeClick(e) {
|
2020-12-31 09:32:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
2021-01-05 13:56:51 +08:00
|
|
|
.back_box {
|
|
|
|
float: right;
|
|
|
|
padding-right: 20px;
|
|
|
|
height: 40px;
|
|
|
|
z-index: 36;
|
2021-01-08 17:53:04 +08:00
|
|
|
width: 320px;
|
2021-01-05 13:56:51 +08:00
|
|
|
text-align: center;
|
|
|
|
position: absolute;
|
|
|
|
right: 0;
|
|
|
|
}
|
2021-01-06 13:23:16 +08:00
|
|
|
.file_box {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
position: absolute;
|
|
|
|
left: 0;
|
|
|
|
top: 0;
|
|
|
|
opacity: 0;
|
|
|
|
cursor: pointer;
|
|
|
|
z-index: 100;
|
|
|
|
}
|
|
|
|
.uploadDemo {
|
|
|
|
position: relative;
|
|
|
|
overflow: hidden;
|
|
|
|
margin-right: 3px;
|
|
|
|
cursor: pointer;
|
|
|
|
padding: 0 15px;
|
|
|
|
height: 28px;
|
|
|
|
}
|
2020-12-31 09:32:25 +08:00
|
|
|
</style>
|