学生批量生成账号

dev_202412
yujialong 3 months ago
parent 2988ea46da
commit 10e03b909f
  1. 1
      src/api/index.js
  2. 129
      src/pages/student/list/index.vue
  3. 241
      src/pages/system/list/staff.vue

@ -79,6 +79,7 @@ export default {
saveOrg: `occupationlab/occupationlab/architecture/save`, // 新增组织架构 saveOrg: `occupationlab/occupationlab/architecture/save`, // 新增组织架构
updateOrg: `occupationlab/occupationlab/architecture/update`, // 编辑组织架构 updateOrg: `occupationlab/occupationlab/architecture/update`, // 编辑组织架构
deleteOrg: `occupationlab/occupationlab/architecture/delete`, // 删除组织架构 deleteOrg: `occupationlab/occupationlab/architecture/delete`, // 删除组织架构
generate: `users/users/batchProcessing/users/generate`,
studentTemplate: `https://www.occupationlab.com/template/学生导入模板.xlsx`, // 学生导入模板 studentTemplate: `https://www.occupationlab.com/template/学生导入模板.xlsx`, // 学生导入模板
// 测评管理 // 测评管理

@ -65,11 +65,12 @@
<div class="tool"> <div class="tool">
<ul class="filter"> <ul class="filter">
<li> <li>
<el-input style="width: 250px;" placeholder="请输入学生姓名/学号" prefix-icon="el-icon-search" v-model="keyWord" <el-input style="width: 400px;" placeholder="请输入学生姓名、学号、班级、账号、手机号、邮箱" prefix-icon="el-icon-search"
clearable></el-input> v-model="keyWord" clearable></el-input>
</li> </li>
</ul> </ul>
<div> <div>
<el-button type="info" @click="batchGenerate">一键批量生成账号</el-button>
<el-button type="info" v-auth @click="addStudent">新增学生</el-button> <el-button type="info" v-auth @click="addStudent">新增学生</el-button>
<el-button type="primary" v-auth @click="batchImport">批量导入</el-button> <el-button type="primary" v-auth @click="batchImport">批量导入</el-button>
<el-button type="primary" v-auth @click="delAllSelection">批量删除</el-button> <el-button type="primary" v-auth @click="delAllSelection">批量删除</el-button>
@ -80,10 +81,13 @@
@selection-change="handleSelectionChange" :row-key="getRowKeys"> @selection-change="handleSelectionChange" :row-key="getRowKeys">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="account" label="账号" align="center" min-width="130"></el-table-column>
<el-table-column prop="userName" label="学生姓名" align="center" min-width="100"></el-table-column> <el-table-column prop="userName" label="学生姓名" align="center" min-width="100"></el-table-column>
<el-table-column prop="workNumber" label="学生学号" align="center" min-width="100"></el-table-column> <el-table-column prop="workNumber" label="学生学号" align="center" min-width="100"></el-table-column>
<el-table-column prop="className" label="班级" align="center" min-width="200" <el-table-column prop="className" label="班级" align="center" min-width="200"
show-overflow-tooltip></el-table-column> show-overflow-tooltip></el-table-column>
<el-table-column prop="phone" label="手机号" align="center" width="100"></el-table-column>
<el-table-column prop="email" label="邮箱" align="center" min-width="100"></el-table-column>
<el-table-column prop="countries" label="账号角色" align="center" width="100"> <el-table-column prop="countries" label="账号角色" align="center" width="100">
<template slot-scope="scope">学生</template> <template slot-scope="scope">学生</template>
</el-table-column> </el-table-column>
@ -112,12 +116,15 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item prop="workNumber" label="学生学号"> <el-form-item prop="workNumber" label="学生学号">
<el-input v-model.trim="form.workNumber" placeholder="学生学号" @blur="workNumberChange"></el-input> <el-input v-model.trim="form.workNumber" placeholder="学生学号"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="userName" label="学生姓名"> <el-form-item prop="userName" label="学生姓名">
<el-input v-model.trim="form.userName" placeholder="请输入学生姓名"></el-input> <el-input v-model.trim="form.userName" placeholder="请输入学生姓名"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="roleId" label="账号角色"> <el-form-item v-if="form.accountId" label="账号">
{{ form.account }}
</el-form-item>
<el-form-item label="账号角色">
学生 学生
</el-form-item> </el-form-item>
@ -127,9 +134,6 @@
<el-form-item prop="email" label="邮箱"> <el-form-item prop="email" label="邮箱">
<el-input v-model.trim="form.email" placeholder="可用于登录平台,以及找回密码"></el-input> <el-input v-model.trim="form.email" placeholder="可用于登录平台,以及找回密码"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="uniqueIdentification" label="唯一标识">
<el-input disabled v-model="form.uniqueIdentification"></el-input>
</el-form-item>
</el-col> </el-col>
<el-col :span="10"> <el-col :span="10">
<el-form-item prop="classId" label="所在班级"> <el-form-item prop="classId" label="所在班级">
@ -180,6 +184,22 @@
<el-button size="small" type="primary" @click="uploadSure"> </el-button> <el-button size="small" type="primary" @click="uploadSure"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="一键批量生成账号" :visible.sync="generateVisible" :close-on-click-modal="false" width="400px">
<el-form ref="generateForm" :model="generateForm" :rules="generateRules" label-width="100px">
<el-form-item label="所属班级" prop="classId">
<el-cascader v-model="generateForm.classId" :props="cascaderProps" clearable style="width: 100%">
</el-cascader>
</el-form-item>
<el-form-item label="账号数" prop="numberOfUsers">
<el-input v-model.trim="generateForm.numberOfUsers" placeholder="请输入账号数"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="generateVisible = false"> </el-button>
<el-button type="primary" @click="generateSubmit"> </el-button>
</span>
</el-dialog>
</div> </div>
</div> </div>
</template> </template>
@ -189,6 +209,7 @@ import Util from "@/libs/util";
import Setting from "@/setting"; import Setting from "@/setting";
import OrgTree from "@/components/org-tree/src/tree"; import OrgTree from "@/components/org-tree/src/tree";
import { mapState } from "vuex"; import { mapState } from "vuex";
import _ from 'lodash'
export default { export default {
components: { OrgTree }, components: { OrgTree },
data () { data () {
@ -266,7 +287,6 @@ export default {
} }
], ],
workNumber: [ workNumber: [
{ required: true, message: "请输入学号", trigger: 'blur' },
{ {
pattern: /^[A-Za-z0-9]*$/, pattern: /^[A-Za-z0-9]*$/,
message: "请输入正确的学号", message: "请输入正确的学号",
@ -312,7 +332,21 @@ export default {
token: Util.local.get(Setting.tokenKey) token: Util.local.get(Setting.tokenKey)
}, },
disableds: false, disableds: false,
submiting: false // submiting: false, //
generateVisible: false,
generateForm: {
classId: [],
numberOfUsers: '',
},
generateRules: {
classId: [
{ required: true, message: '请选择所属班级', trigger: 'change' }
],
numberOfUsers: [
{ required: true, message: '请输入账号数', trigger: 'blur' }
],
},
}; };
}, },
computed: { computed: {
@ -652,6 +686,35 @@ export default {
}).catch(res => { }).catch(res => {
}); });
}, },
//
batchGenerate () {
this.generateForm = {
classId: [],
numberOfUsers: '',
}
this.generateVisible = true
},
//
generateSubmit () {
this.$refs.generateForm.validate(async (valid) => {
if (valid) {
const form = _.cloneDeep(this.generateForm)
const { classId } = form
if (classId && classId.length) form.classId = classId[classId.length - 1]
debugger
await this.$post(this.api.generate, {
...form,
platformId: Setting.platformId,
type: 1,
})
this.generateVisible = false
Util.successMsg('批量生成成功!')
this.initData()
} else {
return false;
}
})
},
addStudent () { // addStudent () { //
this.isAdd = true; this.isAdd = true;
this.showTree = true; this.showTree = true;
@ -667,54 +730,6 @@ export default {
this.originWorkNumber = data.workNumber this.originWorkNumber = data.workNumber
this.showTree = true this.showTree = true
}, },
//
renderAccount () {
const form = this.form
// id-id-schoolId-workNumber
form.account = `${Setting.platformId}-1-${this.schoolId}-${form.workNumber}`
},
async workNumberChange () {
const { form, isAdd, originWorkNumber: origin } = this
const { workNumber } = form
if (workNumber && /^[A-Za-z0-9]*$/.test(workNumber)) {
//
if (origin === workNumber && !isAdd) {
this.workNumberReapeat = false
} else {
const { data } = await this.$post(`${this.api.getDetailByAccount}?workNumber=${workNumber}&platformId=${Setting.platformId}&type=1`)
if (data) {
if (isAdd) {
this.showTree = true
const classId = data.classList.map(e => e.id).toString()
this.form = data
this.form.classId = classId
this.renderAccount()
// classId1
if (classId === '1') {
this.$refs.classTree.setCheckedKeys([])
} else {
this.defaultCheckedKeys = classId.split(",").map(i => Number(i))
}
this.$refs.form.clearValidate()
} else {
Util.errorMsg('该学生学号已存在')
this.workNumberReapeat = true
}
} else {
if (isAdd) {
//
this.form = JSON.parse(JSON.stringify(this.originForm))
this.form.workNumber = workNumber
this.renderAccount()
this.$refs.classTree.setCheckedKeys([])
}
this.workNumberReapeat = false
}
}
} else {
this.renderAccount()
}
},
phoneChange () { phoneChange () {
let regex = /^1[3456789]\d{9}$/; let regex = /^1[3456789]\d{9}$/;
if (regex.test(this.form.phone)) { if (regex.test(this.form.phone)) {

@ -1,9 +1,7 @@
<template> <template>
<div class="wrap"> <div class="wrap">
<div class="side"> <div class="side">
<org ref="org" <org ref="org" @getSingle="getSingle" @getCheck="getCheck"></org>
@getSingle="getSingle"
@getCheck="getCheck"></org>
</div> </div>
<div class="right"> <div class="right">
@ -11,193 +9,95 @@
<div class="tool"> <div class="tool">
<ul class="filter"> <ul class="filter">
<li> <li>
<el-input placeholder="请输入教师姓名/工号" <el-input placeholder="请输入教师姓名/工号" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input>
prefix-icon="el-icon-search"
v-model.trim="keyword"
clearable></el-input>
</li> </li>
</ul> </ul>
<div> <div>
<el-button v-auth="'教师管理:新增教师'" <el-button v-auth="'教师管理:新增教师'" type="info" round @click="addTeacher">新增教师</el-button>
type="info" <el-button v-auth="'教师管理:批量导入'" type="primary" round @click="batchImport">批量导入</el-button>
round <el-button v-auth="'教师管理:批量删除'" type="primary" round @click="delAllSelection">批量删除</el-button>
@click="addTeacher">新增教师</el-button>
<el-button v-auth="'教师管理:批量导入'"
type="primary"
round
@click="batchImport">批量导入</el-button>
<el-button v-auth="'教师管理:批量删除'"
type="primary"
round
@click="delAllSelection">批量删除</el-button>
</div> </div>
</div> </div>
<el-table :data="listData" <el-table :data="listData" class="table" ref="table" stripe header-align="center"
class="table" @selection-change="handleSelectionChange">
ref="table" <el-table-column type="selection" width="55" align="center"></el-table-column>
stripe <el-table-column type="index" label="序号" width="55" align="center"></el-table-column>
header-align="center" <el-table-column prop="userName" label="教师姓名" align="center"></el-table-column>
@selection-change="handleSelectionChange"> <el-table-column prop="workNumber" label="教师工号" align="center"></el-table-column>
<el-table-column type="selection" <el-table-column prop="dept" label="部门" align="center"></el-table-column>
width="55" <el-table-column prop="roleName" label="账号角色" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="logInNumber" label="登录次数" align="center"></el-table-column>
<el-table-column type="index" <el-table-column prop="lastLoginTime" label="上次登录时间" align="center"></el-table-column>
label="序号" <el-table-column label="操作" width="200" align="center">
width="55"
align="center"></el-table-column>
<el-table-column prop="userName"
label="教师姓名"
align="center"></el-table-column>
<el-table-column prop="workNumber"
label="教师工号"
align="center"></el-table-column>
<el-table-column prop="dept"
label="部门"
align="center"></el-table-column>
<el-table-column prop="roleName"
label="账号角色"
align="center"></el-table-column>
<el-table-column prop="logInNumber"
label="登录次数"
align="center"></el-table-column>
<el-table-column prop="lastLoginTime"
label="上次登录时间"
align="center"></el-table-column>
<el-table-column label="操作"
width="200"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-auth="'教师管理:教师查看'" <el-button v-auth="'教师管理:教师查看'" type="text" @click="showTeacher(scope.row)">查看</el-button>
type="text" <el-button v-auth="'教师管理:教师编辑'" type="text" @click="editTeacher(scope.row)">编辑</el-button>
@click="showTeacher(scope.row)">查看</el-button> <el-button v-auth="'教师管理:重置密码'" type="text" @click="resetPassword(scope.row)">重置密码</el-button>
<el-button v-auth="'教师管理:教师编辑'" <el-button v-auth="'教师管理:教师删除'" type="text" @click="delTeacher(scope.row)">删除</el-button>
type="text"
@click="editTeacher(scope.row)">编辑</el-button>
<el-button v-auth="'教师管理:重置密码'"
type="text"
@click="resetPassword(scope.row)">重置密码</el-button>
<el-button v-auth="'教师管理:教师删除'"
type="text"
@click="delTeacher(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" :current-page="page"
layout="total, prev, pager, next" @current-change="handleCurrentChange" :total="total"></el-pagination>
:current-page="page"
@current-change="handleCurrentChange"
:total="total"></el-pagination>
</div> </div>
</div> </div>
<el-dialog :title="isDetail ? '查看教师' : (isAdd ? '新增教师' : '编辑教师')" <el-dialog :title="isDetail ? '查看教师' : (isAdd ? '新增教师' : '编辑教师')" :visible.sync="teacherVisible" width="30%"
:visible.sync="teacherVisible" @close="closeTeacher" class="dialog" :close-on-click-modal="false">
width="30%" <el-form ref="form" :model="form" :rules="rules" label-width="150px" :disabled="isDetail"
@close="closeTeacher" style='margin-right: 80px;'>
class="dialog" <el-form-item prop="workNumber" label="工号">
:close-on-click-modal="false"> <el-input v-model.trim="form.workNumber" placeholder="请输入教师工号" @blur="workNumberChange"></el-input>
<el-form ref="form"
:model="form"
:rules="rules"
label-width="150px"
:disabled="isDetail"
style='margin-right: 80px;'>
<el-form-item prop="workNumber"
label="工号">
<el-input v-model.trim="form.workNumber"
placeholder="请输入教师工号"
@blur="workNumberChange"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="userName" <el-form-item prop="userName" label="用户姓名">
label="用户姓名"> <el-input v-model.trim="form.userName" placeholder="请输入教师姓名"></el-input>
<el-input v-model.trim="form.userName"
placeholder="请输入教师姓名"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="roleValue" <el-form-item prop="roleValue" label="账号角色">
label="账号角色"> <el-select v-model="form.roleValue" @change="roleChange" @remove-tag="roleRemove" multiple
<el-select v-model="form.roleValue" style="width: 100%;height: 32px">
@change="roleChange" <el-option v-for="item in roleList" :key="item.id" :label="item.roleName" :value="item.id">
@remove-tag="roleRemove"
multiple
style="width: 100%;height: 32px">
<el-option v-for="item in roleList"
:key="item.id"
:label="item.roleName"
:value="item.id">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="uniqueIdentification" <el-form-item prop="uniqueIdentification" label="唯一标识">
label="唯一标识"> <el-input disabled v-model.trim="form.uniqueIdentification" placeholder="请输入教师工号获取唯一标识"></el-input>
<el-input disabled
v-model.trim="form.uniqueIdentification"
placeholder="请输入教师工号获取唯一标识"></el-input>
</el-form-item> </el-form-item>
<el-form-item v-for="item in form.roleAndDeptList" <el-form-item v-for="item in form.roleAndDeptList" :label="`${item.roleName}所属部门`" :rules="{
:label="`${item.roleName}所属部门`" required: true, message: '请选择', trigger: 'change'
:rules="{ }">
required: true, message: '请选择', trigger: 'change' <el-cascader v-model="item.cascaderValue" :options="orgList" :props="casProps"
}"> style="width: 100%"></el-cascader>
<el-cascader v-model="item.cascaderValue"
:options="orgList"
:props="casProps"
style="width: 100%"></el-cascader>
</el-form-item> </el-form-item>
<el-form-item prop="phone" <el-form-item prop="phone" label="手机号">
label="手机号"> <el-input v-model.trim="form.phone" placeholder="请输入手机号" maxlength="11"></el-input>
<el-input v-model.trim="form.phone"
placeholder="请输入手机号"
maxlength="11"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="email" <el-form-item prop="email" label="邮箱">
label="邮箱"> <el-input v-model.trim="form.email" placeholder="请输入邮箱"></el-input>
<el-input v-model.trim="form.email"
placeholder="请输入邮箱"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer" v-if="!isDetail">
class="dialog-footer"
v-if="!isDetail">
<el-button @click="closeTeacher"> </el-button> <el-button @click="closeTeacher"> </el-button>
<el-button type="primary" <el-button type="primary" @click="saveSure('form')"> </el-button>
@click="saveSure('form')"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="批量导入" <el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false">
:visible.sync="importVisible"
width="24%"
:close-on-click-modal="false">
<div style="text-align: center"> <div style="text-align: center">
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">
<el-button type="primary" <el-button type="primary" @click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
@click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
</div> </div>
<el-upload name="file" <el-upload name="file" accept=".xls,.xlsx" :on-remove="handleRemove" :on-error="uploadError"
accept=".xls,.xlsx" :on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed"
:on-remove="handleRemove" :action="this.api.importStaff" :file-list="uploadList" :headers="headers">
:on-error="uploadError" <el-button type="primary" class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.importStaff"
:file-list="uploadList"
:headers="headers">
<el-button type="primary"
class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
</el-upload> </el-upload>
<el-link v-if="uploadFaild" <el-link v-if="uploadFaild" type="primary" @click="showFaild">部分数据导入失败查看失败原因</el-link>
type="primary"
@click="showFaild">部分数据导入失败查看失败原因</el-link>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="importVisible = false"> </el-button> <el-button @click="importVisible = false"> </el-button>
<el-button type="primary" <el-button type="primary" @click="uploadSure"> </el-button>
@click="uploadSure"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -657,20 +557,23 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.wrap { .wrap {
display: flex; display: flex;
padding: 0 24px; padding: 0 24px;
.side {
width: 300px; .side {
padding: 24px 10px 24px 0; width: 300px;
margin-right: 24px; padding: 24px 10px 24px 0;
border-right: 1px solid rgba(0, 0, 0, 0.06); margin-right: 24px;
} border-right: 1px solid rgba(0, 0, 0, 0.06);
.right { }
flex: 1;
padding: 24px 0; .right {
} flex: 1;
padding: 24px 0;
}
} }
.el-input__inner { .el-input__inner {
height: 32px; height: 32px;
} }
</style> </style>
Loading…
Cancel
Save