学生批量生成账号

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`, // 新增组织架构
updateOrg: `occupationlab/occupationlab/architecture/update`, // 编辑组织架构
deleteOrg: `occupationlab/occupationlab/architecture/delete`, // 删除组织架构
generate: `users/users/batchProcessing/users/generate`,
studentTemplate: `https://www.occupationlab.com/template/学生导入模板.xlsx`, // 学生导入模板
// 测评管理

@ -65,11 +65,12 @@
<div class="tool">
<ul class="filter">
<li>
<el-input style="width: 250px;" placeholder="请输入学生姓名/学号" prefix-icon="el-icon-search" v-model="keyWord"
clearable></el-input>
<el-input style="width: 400px;" placeholder="请输入学生姓名、学号、班级、账号、手机号、邮箱" prefix-icon="el-icon-search"
v-model="keyWord" clearable></el-input>
</li>
</ul>
<div>
<el-button type="info" @click="batchGenerate">一键批量生成账号</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="delAllSelection">批量删除</el-button>
@ -80,10 +81,13 @@
@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="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="workNumber" label="学生学号" align="center" min-width="100"></el-table-column>
<el-table-column prop="className" label="班级" align="center" min-width="200"
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">
<template slot-scope="scope">学生</template>
</el-table-column>
@ -112,12 +116,15 @@
<el-row :gutter="20">
<el-col :span="12">
<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 prop="userName" label="学生姓名">
<el-input v-model.trim="form.userName" placeholder="请输入学生姓名"></el-input>
</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>
@ -127,9 +134,6 @@
<el-form-item prop="email" label="邮箱">
<el-input v-model.trim="form.email" placeholder="可用于登录平台,以及找回密码"></el-input>
</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 :span="10">
<el-form-item prop="classId" label="所在班级">
@ -180,6 +184,22 @@
<el-button size="small" type="primary" @click="uploadSure"> </el-button>
</span>
</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>
</template>
@ -189,6 +209,7 @@ import Util from "@/libs/util";
import Setting from "@/setting";
import OrgTree from "@/components/org-tree/src/tree";
import { mapState } from "vuex";
import _ from 'lodash'
export default {
components: { OrgTree },
data () {
@ -266,7 +287,6 @@ export default {
}
],
workNumber: [
{ required: true, message: "请输入学号", trigger: 'blur' },
{
pattern: /^[A-Za-z0-9]*$/,
message: "请输入正确的学号",
@ -312,7 +332,21 @@ export default {
token: Util.local.get(Setting.tokenKey)
},
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: {
@ -652,6 +686,35 @@ export default {
}).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 () { //
this.isAdd = true;
this.showTree = true;
@ -667,54 +730,6 @@ export default {
this.originWorkNumber = data.workNumber
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 () {
let regex = /^1[3456789]\d{9}$/;
if (regex.test(this.form.phone)) {

@ -1,9 +1,7 @@
<template>
<div class="wrap">
<div class="side">
<org ref="org"
@getSingle="getSingle"
@getCheck="getCheck"></org>
<org ref="org" @getSingle="getSingle" @getCheck="getCheck"></org>
</div>
<div class="right">
@ -11,193 +9,95 @@
<div class="tool">
<ul class="filter">
<li>
<el-input placeholder="请输入教师姓名/工号"
prefix-icon="el-icon-search"
v-model.trim="keyword"
clearable></el-input>
<el-input placeholder="请输入教师姓名/工号" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input>
</li>
</ul>
<div>
<el-button v-auth="'教师管理:新增教师'"
type="info"
round
@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>
<el-button v-auth="'教师管理:新增教师'" type="info" round @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>
<el-table :data="listData"
class="table"
ref="table"
stripe
header-align="center"
@selection-change="handleSelectionChange">
<el-table-column type="selection"
width="55"
align="center"></el-table-column>
<el-table-column type="index"
label="序号"
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">
<el-table :data="listData" class="table" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column type="index" label="序号" 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">
<el-button v-auth="'教师管理:教师查看'"
type="text"
@click="showTeacher(scope.row)">查看</el-button>
<el-button v-auth="'教师管理:教师编辑'"
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>
<el-button v-auth="'教师管理:教师查看'" type="text" @click="showTeacher(scope.row)">查看</el-button>
<el-button v-auth="'教师管理:教师编辑'" 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>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
layout="total, prev, pager, next"
:current-page="page"
@current-change="handleCurrentChange"
:total="total"></el-pagination>
<el-pagination background layout="total, prev, pager, next" :current-page="page"
@current-change="handleCurrentChange" :total="total"></el-pagination>
</div>
</div>
<el-dialog :title="isDetail ? '查看教师' : (isAdd ? '新增教师' : '编辑教师')"
:visible.sync="teacherVisible"
width="30%"
@close="closeTeacher"
class="dialog"
:close-on-click-modal="false">
<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-dialog :title="isDetail ? '查看教师' : (isAdd ? '新增教师' : '编辑教师')" :visible.sync="teacherVisible" width="30%"
@close="closeTeacher" class="dialog" :close-on-click-modal="false">
<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 prop="userName"
label="用户姓名">
<el-input v-model.trim="form.userName"
placeholder="请输入教师姓名"></el-input>
<el-form-item prop="userName" label="用户姓名">
<el-input v-model.trim="form.userName" placeholder="请输入教师姓名"></el-input>
</el-form-item>
<el-form-item prop="roleValue"
label="账号角色">
<el-select v-model="form.roleValue"
@change="roleChange"
@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-form-item prop="roleValue" label="账号角色">
<el-select v-model="form.roleValue" @change="roleChange" @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-select>
</el-form-item>
<el-form-item prop="uniqueIdentification"
label="唯一标识">
<el-input disabled
v-model.trim="form.uniqueIdentification"
placeholder="请输入教师工号获取唯一标识"></el-input>
<el-form-item prop="uniqueIdentification" label="唯一标识">
<el-input disabled v-model.trim="form.uniqueIdentification" placeholder="请输入教师工号获取唯一标识"></el-input>
</el-form-item>
<el-form-item v-for="item in form.roleAndDeptList"
:label="`${item.roleName}所属部门`"
:rules="{
required: true, message: '请选择', trigger: 'change'
}">
<el-cascader v-model="item.cascaderValue"
:options="orgList"
:props="casProps"
style="width: 100%"></el-cascader>
<el-form-item v-for="item in form.roleAndDeptList" :label="`${item.roleName}所属部门`" :rules="{
required: true, message: '请选择', trigger: 'change'
}">
<el-cascader v-model="item.cascaderValue" :options="orgList" :props="casProps"
style="width: 100%"></el-cascader>
</el-form-item>
<el-form-item prop="phone"
label="手机号">
<el-input v-model.trim="form.phone"
placeholder="请输入手机号"
maxlength="11"></el-input>
<el-form-item prop="phone" label="手机号">
<el-input v-model.trim="form.phone" placeholder="请输入手机号" maxlength="11"></el-input>
</el-form-item>
<el-form-item prop="email"
label="邮箱">
<el-input v-model.trim="form.email"
placeholder="请输入邮箱"></el-input>
<el-form-item prop="email" label="邮箱">
<el-input v-model.trim="form.email" placeholder="请输入邮箱"></el-input>
</el-form-item>
</el-form>
<span slot="footer"
class="dialog-footer"
v-if="!isDetail">
<span slot="footer" class="dialog-footer" v-if="!isDetail">
<el-button @click="closeTeacher"> </el-button>
<el-button type="primary"
@click="saveSure('form')"> </el-button>
<el-button type="primary" @click="saveSure('form')"> </el-button>
</span>
</el-dialog>
<el-dialog title="批量导入"
:visible.sync="importVisible"
width="24%"
:close-on-click-modal="false">
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false">
<div style="text-align: center">
<div style="margin-bottom: 10px;">
<el-button type="primary"
@click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
<el-button type="primary" @click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
</div>
<el-upload name="file"
accept=".xls,.xlsx"
:on-remove="handleRemove"
:on-error="uploadError"
: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 name="file" accept=".xls,.xlsx" :on-remove="handleRemove" :on-error="uploadError"
: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-link v-if="uploadFaild"
type="primary"
@click="showFaild">部分数据导入失败查看失败原因</el-link>
<el-link v-if="uploadFaild" type="primary" @click="showFaild">部分数据导入失败查看失败原因</el-link>
</div>
<span slot="footer"
class="dialog-footer">
<span slot="footer" class="dialog-footer">
<el-button @click="importVisible = false"> </el-button>
<el-button type="primary"
@click="uploadSure"> </el-button>
<el-button type="primary" @click="uploadSure"> </el-button>
</span>
</el-dialog>
</div>
@ -657,20 +557,23 @@ export default {
</script>
<style lang="scss" scoped>
.wrap {
display: flex;
padding: 0 24px;
.side {
width: 300px;
padding: 24px 10px 24px 0;
margin-right: 24px;
border-right: 1px solid rgba(0, 0, 0, 0.06);
}
.right {
flex: 1;
padding: 24px 0;
}
display: flex;
padding: 0 24px;
.side {
width: 300px;
padding: 24px 10px 24px 0;
margin-right: 24px;
border-right: 1px solid rgba(0, 0, 0, 0.06);
}
.right {
flex: 1;
padding: 24px 0;
}
}
.el-input__inner {
height: 32px;
height: 32px;
}
</style>
Loading…
Cancel
Save