|
@@ -0,0 +1,1666 @@
|
|
|
+<script setup>
|
|
|
+import { computed, onMounted, onUnmounted, watch, ref } from "vue";
|
|
|
+import { useRouter } from 'vue-router';
|
|
|
+import { Search } from '@element-plus/icons-vue';
|
|
|
+import { ElMessage } from 'element-plus';
|
|
|
+const router = useRouter();
|
|
|
+
|
|
|
+import { schoolTree, schoolAdd, schoolItem, schoolUpdate, schoolDelete } from "@/api/admin/school";
|
|
|
+import { userList, userAdd, userDetail, userUpdate, userDelete } from "@/api/admin/user";
|
|
|
+
|
|
|
+// let state = ref({
|
|
|
+// optionUserType: [],
|
|
|
+// listParams: {
|
|
|
+// keyword: '',
|
|
|
+// page: 1,
|
|
|
+// limit: 5,
|
|
|
+// },
|
|
|
+// list: [],
|
|
|
+// total: 0,
|
|
|
+// showDialog: false,
|
|
|
+// ids: [],
|
|
|
+// showDel: false,
|
|
|
+// });
|
|
|
+
|
|
|
+let state = ref({
|
|
|
+ // 用户类型
|
|
|
+ "optionUserType": [
|
|
|
+ {
|
|
|
+ "name": "老师",
|
|
|
+ "value" : 0,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "学生",
|
|
|
+ "value" : 1,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ // 用户提交分页查询数据
|
|
|
+ "listParams": {
|
|
|
+ // 搜索的内容 账号
|
|
|
+ "keyword": "",
|
|
|
+ // 搜索姓名
|
|
|
+ "nickName": "",
|
|
|
+ // 用户类型 0 - 老师, 1 - 学生
|
|
|
+ "userType": 1,
|
|
|
+ // 第几页
|
|
|
+ "page": 1,
|
|
|
+ // 每页显示多少数据
|
|
|
+ "limit": 5
|
|
|
+ },
|
|
|
+ // 具体分页的数据
|
|
|
+ "list": [
|
|
|
+ // {
|
|
|
+ // "id": 661434193309765,
|
|
|
+ // "level": 0,
|
|
|
+ // "orgName": "信息论与编码基础教研组",
|
|
|
+ // "zoneName": null,
|
|
|
+ // "rolesName": [
|
|
|
+ // "教师"
|
|
|
+ // ],
|
|
|
+ // "createTime": "2025-04-03 10:42:39",
|
|
|
+ // "name": "教师测试账号",
|
|
|
+ // "code": null,
|
|
|
+ // "username": "teacher",
|
|
|
+ // "phone": null,
|
|
|
+ // "duty": null,
|
|
|
+ // "photo": null,
|
|
|
+ // "orgId": 656844968038469,
|
|
|
+ // "roles": [
|
|
|
+ // 661429664665669
|
|
|
+ // ],
|
|
|
+ // "email": null,
|
|
|
+ // "status": 1,
|
|
|
+ // "type": 1
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // "id": 668917601919045,
|
|
|
+ // "level": 0,
|
|
|
+ // "orgName": "2025级通讯班",
|
|
|
+ // "zoneName": null,
|
|
|
+ // "rolesName": [
|
|
|
+ // "学生"
|
|
|
+ // ],
|
|
|
+ // "createTime": "2025-04-24 14:12:43",
|
|
|
+ // "name": "刘瑾见",
|
|
|
+ // "code": "110220",
|
|
|
+ // "username": "14367845673",
|
|
|
+ // "phone": null,
|
|
|
+ // "duty": null,
|
|
|
+ // "photo": null,
|
|
|
+ // "orgId": 656845035987013,
|
|
|
+ // "roles": [
|
|
|
+ // 661441664479301
|
|
|
+ // ],
|
|
|
+ // "email": null,
|
|
|
+ // "status": 1,
|
|
|
+ // "type": 0
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // "id": 668916601290821,
|
|
|
+ // "level": 0,
|
|
|
+ // "orgName": "2025级通讯班",
|
|
|
+ // "zoneName": null,
|
|
|
+ // "rolesName": [
|
|
|
+ // "学生"
|
|
|
+ // ],
|
|
|
+ // "createTime": "2025-04-24 14:08:39",
|
|
|
+ // "name": "王伟",
|
|
|
+ // "code": "1234525",
|
|
|
+ // "username": "13234367546",
|
|
|
+ // "phone": null,
|
|
|
+ // "duty": null,
|
|
|
+ // "photo": null,
|
|
|
+ // "orgId": 656845035987013,
|
|
|
+ // "roles": [
|
|
|
+ // 661441664479301
|
|
|
+ // ],
|
|
|
+ // "email": null,
|
|
|
+ // "status": 1,
|
|
|
+ // "type": 0
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // "id": 668923933716550,
|
|
|
+ // "level": 0,
|
|
|
+ // "orgName": "2025级通讯班",
|
|
|
+ // "zoneName": null,
|
|
|
+ // "rolesName": [
|
|
|
+ // "学生"
|
|
|
+ // ],
|
|
|
+ // "createTime": "2025-04-24 14:38:29",
|
|
|
+ // "name": "威威",
|
|
|
+ // "code": "25242345",
|
|
|
+ // "username": "1431163",
|
|
|
+ // "phone": null,
|
|
|
+ // "duty": null,
|
|
|
+ // "photo": null,
|
|
|
+ // "orgId": 656845035987013,
|
|
|
+ // "roles": [
|
|
|
+ // 661441664479301
|
|
|
+ // ],
|
|
|
+ // "email": null,
|
|
|
+ // "status": 1,
|
|
|
+ // "type": 0
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // "id": 661442553135174,
|
|
|
+ // "level": 0,
|
|
|
+ // "orgName": "2025级通讯班",
|
|
|
+ // "zoneName": null,
|
|
|
+ // "rolesName": [
|
|
|
+ // "学生"
|
|
|
+ // ],
|
|
|
+ // "createTime": "2025-04-03 11:16:40",
|
|
|
+ // "name": "学生测试账号",
|
|
|
+ // "code": null,
|
|
|
+ // "username": "student",
|
|
|
+ // "phone": null,
|
|
|
+ // "duty": null,
|
|
|
+ // "photo": {
|
|
|
+ // "name": "sl.jpg",
|
|
|
+ // "url": "/upload/Files/2025/04/28/0b326e2784ba73f56ef9f40aae86695c.jpg"
|
|
|
+ // },
|
|
|
+ // "orgId": 656845035987013,
|
|
|
+ // "roles": [
|
|
|
+ // 661441664479301
|
|
|
+ // ],
|
|
|
+ // "email": null,
|
|
|
+ // "status": 1,
|
|
|
+ // "type": 2
|
|
|
+ // }
|
|
|
+ ],
|
|
|
+ // 用户总数量
|
|
|
+ "total": 0,
|
|
|
+ // 是否弹出添加UI
|
|
|
+ "showDialog": false,
|
|
|
+ // 当前分页列表,多选的数据
|
|
|
+ "ids": [],
|
|
|
+ // 批量删除模态框
|
|
|
+ "showDel": false,
|
|
|
+ // 详情模态框
|
|
|
+ "showDetails": false,
|
|
|
+ // 更新密码模态框
|
|
|
+ "showUpdatePwd": false,
|
|
|
+});
|
|
|
+
|
|
|
+// 父子级的学校到班级的数据参数
|
|
|
+let options = [
|
|
|
+ // {
|
|
|
+ // id: 1,
|
|
|
+ // name: 'Asia',
|
|
|
+ // children: [
|
|
|
+ // {
|
|
|
+ // id: 2,
|
|
|
+ // name: 'China',
|
|
|
+ // children: [
|
|
|
+ // { id: 3, name: 'Beijing' },
|
|
|
+ // { id: 4, name: 'Shanghai' },
|
|
|
+ // { id: 5, name: 'Hangzhou' },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // id: 6,
|
|
|
+ // name: 'Japan',
|
|
|
+ // children: [
|
|
|
+ // { id: 7, name: 'Tokyo' },
|
|
|
+ // { id: 8, name: 'Osaka' },
|
|
|
+ // { id: 9, name: 'Kyoto' },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // id: 10,
|
|
|
+ // name: 'Korea',
|
|
|
+ // children: [
|
|
|
+ // { id: 11, name: 'Seoul' },
|
|
|
+ // { id: 12, name: 'Busan' },
|
|
|
+ // { id: 13, name: 'Taegu' },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // id: 14,
|
|
|
+ // name: 'Europe',
|
|
|
+ // children: [
|
|
|
+ // {
|
|
|
+ // id: 15,
|
|
|
+ // name: 'France',
|
|
|
+ // children: [
|
|
|
+ // { id: 16, name: 'Paris' },
|
|
|
+ // { id: 17, name: 'Marseille' },
|
|
|
+ // { id: 18, name: 'Lyon' },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // id: 19,
|
|
|
+ // name: 'UK',
|
|
|
+ // children: [
|
|
|
+ // { id: 20, name: 'London' },
|
|
|
+ // { id: 21, name: 'Birmingham' },
|
|
|
+ // { id: 22, name: 'Manchester' },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // id: 23,
|
|
|
+ // name: 'North America',
|
|
|
+ // children: [
|
|
|
+ // {
|
|
|
+ // id: 24,
|
|
|
+ // name: 'US',
|
|
|
+ // children: [
|
|
|
+ // { id: 25, name: 'New York' },
|
|
|
+ // { id: 26, name: 'Los Angeles' },
|
|
|
+ // { id: 27, name: 'Washington' },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // id: 28,
|
|
|
+ // name: 'Canada',
|
|
|
+ // children: [
|
|
|
+ // { id: 29, name: 'Toronto' },
|
|
|
+ // { id: 30, name: 'Montreal' },
|
|
|
+ // { id: 31, name: 'Ottawa' },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+]
|
|
|
+
|
|
|
+// 用于表单验证规则必须要的对象
|
|
|
+let ruleFormRef = ref();
|
|
|
+
|
|
|
+/**
|
|
|
+ * 添加,最后提交的数据
|
|
|
+ */
|
|
|
+let addParams = ref({
|
|
|
+ // 账号
|
|
|
+ "userName": null,
|
|
|
+ // 0 表示教师,1表示学生
|
|
|
+ "userType": 1,
|
|
|
+ // 昵称
|
|
|
+ "nickName": null,
|
|
|
+ // 用户分配到的班级数组,可以是多个
|
|
|
+ "classInfo": [],
|
|
|
+ // 密码
|
|
|
+ "password": null,
|
|
|
+ // 确认密码
|
|
|
+ "password2": null
|
|
|
+});
|
|
|
+
|
|
|
+/**
|
|
|
+ * 添加,字段相关验证规则
|
|
|
+ */
|
|
|
+let addRules = ref({
|
|
|
+ userName: [{ required: true, message: '请填写账号', trigger: 'blur' }],
|
|
|
+ nickName: [{ required: true, message: '请填写姓名', trigger: 'blur' }],
|
|
|
+ userType: [{ required: true, message: '请选择账号类型', trigger: 'change', }],
|
|
|
+ classInfo: [{ required: true, message: '请选择班级', trigger: 'change', }],
|
|
|
+ password: [{ required: true, message: '请填写密码', trigger: 'blur' }],
|
|
|
+ password2: [{ required: true, message: '请填写确认密码', trigger: 'blur' }],
|
|
|
+});
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 详情数据
|
|
|
+ */
|
|
|
+let detailsDb = ref({
|
|
|
+ "id": null,
|
|
|
+ // 账号
|
|
|
+ "userName": null,
|
|
|
+ // 0 表示教师,1表示学生
|
|
|
+ "userType": 1,
|
|
|
+ // 昵称
|
|
|
+ "nickName": null,
|
|
|
+ // 用户分配到的班级数组,可以是多个
|
|
|
+ "classInfo": [],
|
|
|
+});
|
|
|
+
|
|
|
+// 用于表单验证规则必须要的对象
|
|
|
+let ruleFormRefUpdatePwd = ref();
|
|
|
+
|
|
|
+/**
|
|
|
+ * 用于更新密码的时候,会用到的参数数据
|
|
|
+ */
|
|
|
+let updatePwdDb = ref({
|
|
|
+ "id": null,
|
|
|
+ // 账号
|
|
|
+ "userName": null,
|
|
|
+ // 0 表示教师,1表示学生
|
|
|
+ "userType": null,
|
|
|
+ // 昵称
|
|
|
+ "nickName": null,
|
|
|
+ // 用户分配到的班级数组,可以是多个
|
|
|
+ "classInfo": [],
|
|
|
+ // 密码
|
|
|
+ "password": null,
|
|
|
+ // 确认密码
|
|
|
+ "password2": null
|
|
|
+});
|
|
|
+
|
|
|
+/**
|
|
|
+ * 因为这里的接口返回的不是分页的接口,是全部数据,所以这里就记录全部数据
|
|
|
+ * 后面通过逻辑,来控制分页的显示
|
|
|
+ */
|
|
|
+let pageDb = [];
|
|
|
+
|
|
|
+/**
|
|
|
+ * 查找分页数据
|
|
|
+ */
|
|
|
+const pageUpdateEvent = () => {
|
|
|
+
|
|
|
+ console.log(
|
|
|
+ "查找分页数据 pageUpdateEvent", state.value.listParams
|
|
|
+ );
|
|
|
+
|
|
|
+ let keyword = state.value.listParams.keyword;
|
|
|
+ let pageNum = state.value.listParams.page;
|
|
|
+ let pageSize = state.value.listParams.limit;
|
|
|
+ let userType = state.value.listParams.userType;
|
|
|
+ let nickName = state.value.listParams.nickName;
|
|
|
+
|
|
|
+ let submit = {
|
|
|
+ // 第几页
|
|
|
+ "pageNum": pageNum,
|
|
|
+ // 每页显示多少数据
|
|
|
+ "pageSize": pageSize,
|
|
|
+ // 0 - 老师, 1 - 学生
|
|
|
+ "userType" : userType,
|
|
|
+ // 昵称
|
|
|
+ // "nickName" : "",
|
|
|
+ "nickName" : nickName,
|
|
|
+ // 账号
|
|
|
+ "userName": keyword,
|
|
|
+ };
|
|
|
+
|
|
|
+ userList(submit)
|
|
|
+ .then(response => {
|
|
|
+
|
|
|
+ let dataOld = response?.data?.data;
|
|
|
+ let data = dataOld?.list;
|
|
|
+ state.value.total = dataOld.total;
|
|
|
+
|
|
|
+ let newList = [];
|
|
|
+ // 循环数组,一些特殊字段进行处理
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ let thisData = data[i];
|
|
|
+ let newType = thisData["userType"] == 0 ? "老师" : "学生";
|
|
|
+ thisData["newType"] = newType;
|
|
|
+ newList.push(thisData);
|
|
|
+ }
|
|
|
+
|
|
|
+ state.value.list = newList;
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "userListEvent response", response, data
|
|
|
+ // );
|
|
|
+
|
|
|
+ // pageDb = [];
|
|
|
+ // pageDb = data;
|
|
|
+
|
|
|
+ // pageDbUpdateEvent();
|
|
|
+
|
|
|
+ }).catch(error => {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// /**
|
|
|
+// * 因为接口不是标准的分页接口,是直接返回所有数据的
|
|
|
+// * 这里进行单独处理,来展示第几页的数据
|
|
|
+// */
|
|
|
+// const pageDbUpdateEvent = () => {
|
|
|
+
|
|
|
+// // console.log(
|
|
|
+// // "查找分页数据 pageDbUpdateEvent", state.value.listParams, pageDb
|
|
|
+// // );
|
|
|
+
|
|
|
+// state.value.total = pageDb.length;
|
|
|
+// state.value.list = [];
|
|
|
+
|
|
|
+// let page = state.value.listParams.page;
|
|
|
+// let limit = state.value.listParams.limit;
|
|
|
+// let keyword = state.value.listParams.keyword;
|
|
|
+
|
|
|
+// // 从第几个数组下标开始
|
|
|
+// let indexStart = (page - 1) * limit;
|
|
|
+// // 到第几个数组下标结束
|
|
|
+// let indexEnd = indexStart + limit - 1;
|
|
|
+
|
|
|
+// for (let i = 0; i < pageDb.length; i++) {
|
|
|
+
|
|
|
+// // 在范围内
|
|
|
+// if (i >= indexStart && i <= indexEnd) {
|
|
|
+// let thisPageDb = pageDb[i];
|
|
|
+// state.value.list.push(thisPageDb);
|
|
|
+
|
|
|
+// }
|
|
|
+
|
|
|
+// }
|
|
|
+
|
|
|
+// }
|
|
|
+
|
|
|
+/**
|
|
|
+ * 弹出添加UI
|
|
|
+ */
|
|
|
+const btnAddStudent = (formEl) => {
|
|
|
+
|
|
|
+ state.value.showDialog = true;
|
|
|
+ if (!formEl) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ formEl.resetFields();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 触发搜索逻辑
|
|
|
+ */
|
|
|
+const btnSearchName = () => {
|
|
|
+ state.value.listParams.page = 1;
|
|
|
+ pageUpdateEvent();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 更新选中的班级逻辑
|
|
|
+ * @param val
|
|
|
+ */
|
|
|
+const classChange = (val) => {
|
|
|
+ state.value.listParams.page = 1;
|
|
|
+ pageUpdateEvent();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 上一页,下一页改变
|
|
|
+ */
|
|
|
+const handleSizeChange = (val) => {
|
|
|
+ // 重新查找分页数据
|
|
|
+ pageUpdateEvent();
|
|
|
+}
|
|
|
+/**
|
|
|
+ * 上一页,下一页改变
|
|
|
+ */
|
|
|
+const handleCurrentChange = (val) => {
|
|
|
+ // 重新查找分页数据
|
|
|
+ pageUpdateEvent();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 分页多选,更新多选的相关数据
|
|
|
+ * @param res
|
|
|
+ */
|
|
|
+const selectionChange = (res) => {
|
|
|
+ state.value.ids = [];
|
|
|
+ res.forEach((item) => {
|
|
|
+ // state.value.ids.push(item.id);
|
|
|
+ state.value.ids.push(item);
|
|
|
+ });
|
|
|
+ console.log("分页多选,更新多选的相关数据", state.value.ids);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 添加 点击提交
|
|
|
+ * @param formEl
|
|
|
+ */
|
|
|
+const submitForm = async (formEl) => {
|
|
|
+ if (!formEl) return
|
|
|
+ await formEl.validate((valid, fields) => {
|
|
|
+ if (valid) {
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "addParams", addParams.value
|
|
|
+ // );
|
|
|
+
|
|
|
+ let classInfoArray = [];
|
|
|
+ if (addParams.value.classInfo != null && addParams.value.classInfo != undefined) {
|
|
|
+ for (let i = 0; i < addParams.value.classInfo.length; i++) {
|
|
|
+ let thisClassInfo = addParams.value.classInfo[i];
|
|
|
+ let schoolIdJson = getSchoolIdJson(thisClassInfo);
|
|
|
+ if (schoolIdJson != null && schoolIdJson != undefined) {
|
|
|
+ // console.log( "schoolIdJson", schoolIdJson );
|
|
|
+ // 特殊处理,必须选中的是班级
|
|
|
+ if (schoolIdJson.type == 3) {
|
|
|
+ let addJson = {
|
|
|
+ "id": schoolIdJson.id,
|
|
|
+ "name": schoolIdJson.name,
|
|
|
+ "remark": schoolIdJson.remark,
|
|
|
+ "schoolId": schoolIdJson.schoolId,
|
|
|
+ };
|
|
|
+ classInfoArray.push(addJson);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let submit = {
|
|
|
+ // 账号
|
|
|
+ "userName": addParams.value.userName,
|
|
|
+ // 0 表示教师,1表示学生
|
|
|
+ "userType": addParams.value.userType,
|
|
|
+ // 昵称
|
|
|
+ "nickName": addParams.value.nickName,
|
|
|
+ // 用户分配到的班级数组,可以是多个
|
|
|
+ // "classInfo": [
|
|
|
+ // // {
|
|
|
+ // // "id": 0,
|
|
|
+ // // "name": "",
|
|
|
+ // // "remark": "",
|
|
|
+ // // "schoolId": 0
|
|
|
+ // // }
|
|
|
+ // ],
|
|
|
+ "classInfo": classInfoArray,
|
|
|
+ // 密码
|
|
|
+ "password": addParams.value.password,
|
|
|
+ // 确认密码
|
|
|
+ "password2": addParams.value.password2
|
|
|
+ };
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "添加账号的相关数据 submit", submit
|
|
|
+ // );
|
|
|
+
|
|
|
+ userAdd(submit)
|
|
|
+ .then(response => {
|
|
|
+
|
|
|
+ let data = response?.data?.data;
|
|
|
+ // console.log(
|
|
|
+ // "userAddEvent response", response, data
|
|
|
+ // );
|
|
|
+
|
|
|
+ // 重新查找分页数据
|
|
|
+ pageUpdateEvent();
|
|
|
+ // 接口请求完成,隐藏模态框
|
|
|
+ state.value.showDialog = false;
|
|
|
+
|
|
|
+ }).catch(error => {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // console.log('error submit!', fields)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 更新
|
|
|
+ * @param formEl
|
|
|
+ */
|
|
|
+const updateForm = async (formEl) => {
|
|
|
+ if (!formEl) return
|
|
|
+ await formEl.validate((valid, fields) => {
|
|
|
+ if (valid) {
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "detailsDb", detailsDb.value
|
|
|
+ // );
|
|
|
+
|
|
|
+ let classInfoArray = [];
|
|
|
+ if (detailsDb.value.classInfo != null && detailsDb.value.classInfo != undefined) {
|
|
|
+ for (let i = 0; i < detailsDb.value.classInfo.length; i++) {
|
|
|
+ let thisClassInfo = detailsDb.value.classInfo[i];
|
|
|
+ let schoolIdJson = getSchoolIdJson(thisClassInfo);
|
|
|
+ if (schoolIdJson != null && schoolIdJson != undefined) {
|
|
|
+ // console.log( "schoolIdJson", schoolIdJson );
|
|
|
+ // 特殊处理,必须选中的是班级
|
|
|
+ if (schoolIdJson.type == 3) {
|
|
|
+ let addJson = {
|
|
|
+ "id": schoolIdJson.id,
|
|
|
+ "name": schoolIdJson.name,
|
|
|
+ "remark": schoolIdJson.remark,
|
|
|
+ "schoolId": schoolIdJson.schoolId,
|
|
|
+ };
|
|
|
+ classInfoArray.push(addJson);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let submit = {
|
|
|
+ "id": detailsDb.value.id,
|
|
|
+ // 账号
|
|
|
+ "userName": detailsDb.value.userName,
|
|
|
+ // 0 表示教师,1表示学生
|
|
|
+ "userType": detailsDb.value.userType,
|
|
|
+ // 昵称
|
|
|
+ "nickName": detailsDb.value.nickName,
|
|
|
+ // 用户分配到的班级数组,可以是多个【通过测试,班级不可以减少,但是新增多个,则会新增】
|
|
|
+ "classInfo": classInfoArray,
|
|
|
+ };
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "submit", submit
|
|
|
+ // );
|
|
|
+
|
|
|
+ userUpdate(submit)
|
|
|
+ .then(response => {
|
|
|
+
|
|
|
+ // let data = response?.data?.data;
|
|
|
+ // console.log(
|
|
|
+ // "userUpdateEvent response", response, data
|
|
|
+ // );
|
|
|
+
|
|
|
+ // 重新查找分页数据
|
|
|
+ pageUpdateEvent();
|
|
|
+ // 接口请求完成,隐藏模态框
|
|
|
+ state.value.showDetails = false;
|
|
|
+
|
|
|
+ }).catch(error => {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // console.log('error submit!', fields)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 更新密码
|
|
|
+ * @param formEl
|
|
|
+ */
|
|
|
+const updatePwdForm = async (formEl) => {
|
|
|
+ if (!formEl) return
|
|
|
+ await formEl.validate((valid, fields) => {
|
|
|
+ if (valid) {
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "updatePwdDb", updatePwdDb.value
|
|
|
+ // );
|
|
|
+
|
|
|
+ let classInfoArray = [];
|
|
|
+ if (updatePwdDb.value.classInfo != null && updatePwdDb.value.classInfo != undefined) {
|
|
|
+ for (let i = 0; i < updatePwdDb.value.classInfo.length; i++) {
|
|
|
+ let thisClassInfo = updatePwdDb.value.classInfo[i];
|
|
|
+ let schoolIdJson = getSchoolIdJson(thisClassInfo);
|
|
|
+ if (schoolIdJson != null && schoolIdJson != undefined) {
|
|
|
+ // console.log( "schoolIdJson", schoolIdJson );
|
|
|
+ // 特殊处理,必须选中的是班级
|
|
|
+ if (schoolIdJson.type == 3) {
|
|
|
+ let addJson = {
|
|
|
+ "id": schoolIdJson.id,
|
|
|
+ "name": schoolIdJson.name,
|
|
|
+ "remark": schoolIdJson.remark,
|
|
|
+ "schoolId": schoolIdJson.schoolId,
|
|
|
+ };
|
|
|
+ classInfoArray.push(addJson);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let password = updatePwdDb.value.password;
|
|
|
+ let password2 = updatePwdDb.value.password2;
|
|
|
+
|
|
|
+ let submit = {
|
|
|
+ "id": updatePwdDb.value.id,
|
|
|
+ // 账号
|
|
|
+ "userName": updatePwdDb.value.userName,
|
|
|
+ // 0 表示教师,1表示学生
|
|
|
+ "userType": updatePwdDb.value.userType,
|
|
|
+ // 昵称
|
|
|
+ "nickName": updatePwdDb.value.nickName,
|
|
|
+ // 用户分配到的班级数组,可以是多个【通过测试,班级不可以减少,但是新增多个,则会新增】
|
|
|
+ "classInfo": classInfoArray,
|
|
|
+ // 密码
|
|
|
+ "password": password,
|
|
|
+ // 确认密码
|
|
|
+ "password2": password2,
|
|
|
+ };
|
|
|
+
|
|
|
+ if (typeof password == 'string' && password.length < 5) {
|
|
|
+ ElMessage({ type: 'error', message: '密码长度必须大等于6', });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (typeof password2 == 'string' && password2.length < 5) {
|
|
|
+ ElMessage({ type: 'error', message: '确认密码长度必须大等于6', });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (password != password2) {
|
|
|
+ ElMessage({ type: 'error', message: '密码和确认密码必须一致', });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ userUpdate(submit)
|
|
|
+ .then(response => {
|
|
|
+
|
|
|
+ // let data = response?.data?.data;
|
|
|
+ // console.log(
|
|
|
+ // "userUpdateEvent response", response, data
|
|
|
+ // );
|
|
|
+
|
|
|
+ // 重新查找分页数据
|
|
|
+ pageUpdateEvent();
|
|
|
+ // 接口请求完成,隐藏模态框
|
|
|
+ state.value.showUpdatePwd = false;
|
|
|
+
|
|
|
+ }).catch(error => {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // console.log('error submit!', fields)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 批量删除,同时也可以处理单个删除逻辑
|
|
|
+ * delIdArray 批量删除的id值
|
|
|
+ * 例如
|
|
|
+ * [ { "id" : "1" }, { "id" : "2" } ]
|
|
|
+ * callback 全部删除完成,回调
|
|
|
+ *
|
|
|
+ */
|
|
|
+const idDelAll = (delIdArray, callback) => {
|
|
|
+
|
|
|
+ // 删除完成次数
|
|
|
+ let okNum = 0;
|
|
|
+
|
|
|
+ for (let i = 0; i < delIdArray.length; i++) {
|
|
|
+
|
|
|
+ let thisDelIdArray = delIdArray[i];
|
|
|
+ // console.log(
|
|
|
+ // "thisDelIdArray", thisDelIdArray
|
|
|
+ // );
|
|
|
+
|
|
|
+ let submit = {
|
|
|
+ "id": thisDelIdArray.id,
|
|
|
+ };
|
|
|
+
|
|
|
+ userDelete(submit)
|
|
|
+ .then(response => {
|
|
|
+
|
|
|
+ // let data = response?.data?.data;
|
|
|
+ // console.log(
|
|
|
+ // "userDeleteEvent response", response, data
|
|
|
+ // );
|
|
|
+
|
|
|
+ okNum += 1;
|
|
|
+
|
|
|
+ if (okNum >= delIdArray.length) {
|
|
|
+ callback("yes");
|
|
|
+ }
|
|
|
+
|
|
|
+ }).catch(error => {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 删除选中分页的某个数据
|
|
|
+ * @param res
|
|
|
+ */
|
|
|
+const btnDel = (res) => {
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "删除选中分页的某个数据", res
|
|
|
+ // );
|
|
|
+
|
|
|
+ let delIdArray = [
|
|
|
+ { "id" : res.id }
|
|
|
+ ];
|
|
|
+
|
|
|
+ idDelAll(
|
|
|
+ delIdArray,
|
|
|
+ function() {
|
|
|
+
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ message: '删除成功',
|
|
|
+ });
|
|
|
+
|
|
|
+ // 重新查找分页数据
|
|
|
+ pageUpdateEvent();
|
|
|
+
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 弹出批量删除模态框逻辑
|
|
|
+ */
|
|
|
+const btnShowDel = () => {
|
|
|
+ if (state.value.ids && state.value.ids.length > 0) {
|
|
|
+ state.value.showDel = true
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 开始批量删除处理
|
|
|
+ */
|
|
|
+const btnBatchDel = () => {
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "开始批量删除处理", state.value.ids
|
|
|
+ // );
|
|
|
+
|
|
|
+ let delIdArray = [];
|
|
|
+ for (let i = 0; i < state.value.ids.length; i++) {
|
|
|
+
|
|
|
+ let thisIds = state.value.ids[i];
|
|
|
+ let addJson = { "id" : thisIds.id };
|
|
|
+ delIdArray.push(addJson);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "btnBatchDel delIdArray ===>", delIdArray
|
|
|
+ // );
|
|
|
+
|
|
|
+ idDelAll(
|
|
|
+ delIdArray,
|
|
|
+ function() {
|
|
|
+
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ message: '删除成功',
|
|
|
+ });
|
|
|
+
|
|
|
+ // 重新查找分页数据
|
|
|
+ pageUpdateEvent();
|
|
|
+
|
|
|
+ // 批量选中的列表重置
|
|
|
+ state.value.ids = [];
|
|
|
+ // 隐藏模态框
|
|
|
+ state.value.showDel = false;
|
|
|
+
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 弹出指定分页详情
|
|
|
+ * @param res 当前点击分页的数据参数
|
|
|
+ * type 类型 ,不传的时候,弹出,编辑, pwd 弹出修改密码
|
|
|
+ */
|
|
|
+const btnDetail = (res, type) => {
|
|
|
+
|
|
|
+ console.log('弹出指定分页详情', res, type);
|
|
|
+
|
|
|
+ let submit = {
|
|
|
+ id: res.id,
|
|
|
+ };
|
|
|
+
|
|
|
+ userDetail(submit)
|
|
|
+ .then(response => {
|
|
|
+
|
|
|
+ let data = response?.data?.data;
|
|
|
+ // console.log(
|
|
|
+ // "userDetailEvent response", response, data
|
|
|
+ // );
|
|
|
+
|
|
|
+ let classInfoIdArray = [];
|
|
|
+ if (data.classInfo != null && data.classInfo != undefined) {
|
|
|
+ for (let i = 0; i < data.classInfo.length; i++) {
|
|
|
+ let thisClassInfo = data.classInfo[i];
|
|
|
+ // console.log("thisClassInfo", thisClassInfo);
|
|
|
+ classInfoIdArray.push(thisClassInfo.id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ detailsDb.value = {
|
|
|
+ "id": data.id,
|
|
|
+ // 账号
|
|
|
+ "userName": data.userName,
|
|
|
+ // 0 表示教师,1表示学生
|
|
|
+ "userType": data.userType,
|
|
|
+ // 昵称
|
|
|
+ "nickName": data.nickName,
|
|
|
+ // 用户分配到的班级数组,可以是多个
|
|
|
+ "classInfo": classInfoIdArray,
|
|
|
+ // // 密码
|
|
|
+ // "password": data.password,
|
|
|
+ // // 确认密码
|
|
|
+ // "password2": data.password2
|
|
|
+ }
|
|
|
+
|
|
|
+ updatePwdDb.value = {
|
|
|
+ "id": data.id,
|
|
|
+ // 账号
|
|
|
+ "userName": data.userName,
|
|
|
+ // 0 表示教师,1表示学生
|
|
|
+ "userType": data.userType,
|
|
|
+ // 昵称
|
|
|
+ "nickName": data.nickName,
|
|
|
+ // 用户分配到的班级数组,可以是多个
|
|
|
+ "classInfo": classInfoIdArray,
|
|
|
+ // 密码
|
|
|
+ "password": data.password,
|
|
|
+ // 确认密码
|
|
|
+ "password2": data.password2
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log("detailsDb.value", detailsDb.value);
|
|
|
+
|
|
|
+ if (type == null || type == undefined) {
|
|
|
+ state.value.showDetails = true;
|
|
|
+ }
|
|
|
+ else if (type == 'pwd') {
|
|
|
+ state.value.showUpdatePwd = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ }).catch(error => {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 记录,学校到班级对应的所有id和json数据
|
|
|
+ *
|
|
|
+ */
|
|
|
+let schoolIdJson = {};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 本次遍历的数组
|
|
|
+ * array
|
|
|
+ */
|
|
|
+const schoolIdJsonUpdateEvent = (array) => {
|
|
|
+
|
|
|
+ if (array == null || array == undefined) {
|
|
|
+ return array;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let i = 0; i < array.length; i++) {
|
|
|
+
|
|
|
+ let objArray = array[i];
|
|
|
+ let id = objArray.id;
|
|
|
+
|
|
|
+
|
|
|
+ schoolIdJson[id] = objArray;
|
|
|
+ if (objArray.children != null && objArray.children != undefined) {
|
|
|
+ let children = objArray.children;
|
|
|
+ schoolIdJsonUpdateEvent(children);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 根据id得到对应学校到班级的数据
|
|
|
+ * id
|
|
|
+ * 存在返回json数据,否则返回 null
|
|
|
+ */
|
|
|
+const getSchoolIdJson = (id) => {
|
|
|
+
|
|
|
+ if (schoolIdJson[id] == null || schoolIdJson[id] == undefined) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ let objJson = schoolIdJson[id];
|
|
|
+ return objJson;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 获取父子级的树形结构数据
|
|
|
+ */
|
|
|
+const optionsUpdate = () => {
|
|
|
+
|
|
|
+ // 先获取所有最顶级的数据
|
|
|
+ let submit = {
|
|
|
+ // 默认优先去顶级所有,传 0 。 否则你要看到 学院, 专业 ,班级 的列表,这里固定就传 学院这个的id值
|
|
|
+ "schoolId" : 0,
|
|
|
+ };
|
|
|
+
|
|
|
+ schoolTree(submit)
|
|
|
+ .then(response => {
|
|
|
+
|
|
|
+ options = [];
|
|
|
+
|
|
|
+ let data = response?.data?.data;
|
|
|
+
|
|
|
+ options = data;
|
|
|
+ // console.log(
|
|
|
+ // "schoolTreeEvent response", response, data
|
|
|
+ // );
|
|
|
+
|
|
|
+ for (let i = 0; i < options.length; i++) {
|
|
|
+
|
|
|
+ let thisOptions = options[i];
|
|
|
+ // console.log(
|
|
|
+ // "thisOptions", thisOptions
|
|
|
+ // );
|
|
|
+ optionsChildrenUpdate(i, thisOptions.id);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }).catch(error => {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 将对应子级的数据获取
|
|
|
+ * optionsIndex options 对应的数组下标
|
|
|
+ * id 当前父级 的id值
|
|
|
+ */
|
|
|
+const optionsChildrenUpdate = (optionsIndex, id) => {
|
|
|
+
|
|
|
+ let submit = {
|
|
|
+ // 默认优先去顶级所有,传 0 。 否则你要看到 学院, 专业 ,班级 的列表,这里固定就传 学院这个的id值
|
|
|
+ "schoolId" : id,
|
|
|
+ };
|
|
|
+
|
|
|
+ schoolTree(submit)
|
|
|
+ .then(response => {
|
|
|
+
|
|
|
+ let data = response?.data?.data;
|
|
|
+
|
|
|
+ // console.log(
|
|
|
+ // "optionsChildrenUpdate response", data
|
|
|
+ // );
|
|
|
+
|
|
|
+ options[optionsIndex] = data[0];
|
|
|
+ schoolIdJsonUpdateEvent(options);
|
|
|
+ // console.log("options ===>", options, schoolIdJson);
|
|
|
+
|
|
|
+ }).catch(error => {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(function() {
|
|
|
+ pageUpdateEvent();
|
|
|
+ optionsUpdate();
|
|
|
+});
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="ManageUser">
|
|
|
+
|
|
|
+ <div class="content commonsScrollbar">
|
|
|
+ <div class="contentTitle">
|
|
|
+ <div class="contentTitle-line"></div>
|
|
|
+ <div class="contentTitle-text">管理学生</div>
|
|
|
+ </div>
|
|
|
+ <div class="contentRow">
|
|
|
+ <div class="rowLeft">
|
|
|
+ <!-- <div class="rowSelect">
|
|
|
+ <el-select
|
|
|
+ v-model="state.listParams.userType"
|
|
|
+ clearable
|
|
|
+ placeholder="账号类型"
|
|
|
+ size="large"
|
|
|
+ style="width: 15rem"
|
|
|
+ @change="classChange"
|
|
|
+ >
|
|
|
+ <el-option v-for="item in state.optionUserType" :key="item.value" :label="item.name" :value="item.value" />
|
|
|
+ </el-select>
|
|
|
+ </div> -->
|
|
|
+ <div class="rowBtn rowBtn1" @click="btnAddStudent(ruleFormRef)">
|
|
|
+ <img src="./assets/img/manageUser/add.svg" alt="" />
|
|
|
+ <span class="rowBtn-text rowBtn-text1">添加账号</span>
|
|
|
+ </div>
|
|
|
+ <!-- <div class="rowBtn rowBtn2">
|
|
|
+ <img src="./assets/img/manageUser/download.svg" alt="" />
|
|
|
+ <span class="rowBtn-text rowBtn-text2">模板下载</span>
|
|
|
+ </div>
|
|
|
+ <div class="rowBtn rowBtn1">
|
|
|
+ <img src="./assets/img/manageUser/import.svg" alt="" />
|
|
|
+ <span class="rowBtn-text rowBtn-text1">批量导入</span>
|
|
|
+ </div>
|
|
|
+ <div class="rowBtn rowBtn1">
|
|
|
+ <img src="./assets/img/manageUser/export.svg" alt="" />
|
|
|
+ <span class="rowBtn-text rowBtn-text1">批量导出</span>
|
|
|
+ </div> -->
|
|
|
+ <div class="rowBtn rowBtn3" @click="btnShowDel">
|
|
|
+ <img src="./assets/img/manageUser/delete.svg" alt="" />
|
|
|
+ <span class="rowBtn-text rowBtn-text3">批量删除</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="rowRight">
|
|
|
+ <el-input
|
|
|
+ class="searchInput"
|
|
|
+ v-model="state.listParams.keyword"
|
|
|
+ :prefix-icon="Search"
|
|
|
+ clearable
|
|
|
+ placeholder="搜索账号"
|
|
|
+ @clear="btnSearchName"
|
|
|
+ />
|
|
|
+ <el-input
|
|
|
+ class="searchInput"
|
|
|
+ v-model="state.listParams.nickName"
|
|
|
+ :prefix-icon="Search"
|
|
|
+ clearable
|
|
|
+ placeholder="搜索姓名"
|
|
|
+ @clear="btnSearchName"
|
|
|
+ />
|
|
|
+ <div class="rowSearch" @click="btnSearchName">搜索</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="contentTable commonsScrollbar">
|
|
|
+ <el-table :data="state.list" style="width: 100%" @selection-change="selectionChange">
|
|
|
+ <el-table-column align="center" type="selection" width="110" />
|
|
|
+ <el-table-column prop="userName" label="账号" />
|
|
|
+ <el-table-column prop="nickName" label="姓名" />
|
|
|
+ <el-table-column prop="newType" label="类型" />
|
|
|
+ <el-table-column label="操作">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button link type="primary" @click="btnDetail(scope.row)">编辑</el-button>
|
|
|
+ <el-button link type="primary" @click="btnDetail(scope.row, 'pwd')">修改密码</el-button>
|
|
|
+ <el-popconfirm :title="`你确定删除${scope.row.userName}吗?`" @confirm="btnDel(scope.row)">
|
|
|
+ <template #reference>
|
|
|
+ <el-button link type="danger" style="margin-left: 3rem">移除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-popconfirm>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ <el-pagination
|
|
|
+ class="classPagination"
|
|
|
+ v-model:current-page="state.listParams.page"
|
|
|
+ v-model:page-size="state.listParams.limit"
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
+ background
|
|
|
+ :layout="' ->, total,prev, pager, next, jumper'"
|
|
|
+ :total="state.total"
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ >
|
|
|
+ </el-pagination>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 添加模态框 -->
|
|
|
+ <el-dialog v-model="state.showDialog" class="dialog">
|
|
|
+ <template #header>
|
|
|
+ <div class="dialog-title">添加账号</div>
|
|
|
+ </template>
|
|
|
+ <div class="dialogBody">
|
|
|
+ <el-form ref="ruleFormRef" :model="addParams" :rules="addRules">
|
|
|
+ <el-form-item label="账号" prop="userName">
|
|
|
+ <el-input v-model="addParams.userName" clearable placeholder="请填写账号"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="姓名" prop="nickName">
|
|
|
+ <el-input v-model="addParams.nickName" clearable placeholder="请填写姓名"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="账号类型" prop="userType">
|
|
|
+ <el-select
|
|
|
+ v-model="addParams.userType"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择账号类型"
|
|
|
+ size="large"
|
|
|
+ >
|
|
|
+ <el-option v-for="item in state.optionUserType" :key="item.value" :label="item.name" :value="item.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="班级" prop="classInfo">
|
|
|
+ <el-cascader v-model="addParams.classInfo"
|
|
|
+ :options="options"
|
|
|
+ :props="{
|
|
|
+ children: 'children',
|
|
|
+ label: 'name',
|
|
|
+ value: 'id',
|
|
|
+ checkStrictly: false,
|
|
|
+ expandTrigger: 'hover',
|
|
|
+ emitPath: false,
|
|
|
+ multiple: true,
|
|
|
+ }"
|
|
|
+ clearable placeholder="请选择班级" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="密码" prop="password">
|
|
|
+ <el-input v-model="addParams.password" clearable placeholder="请填写密码"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="确认密码" prop="password2">
|
|
|
+ <el-input v-model="addParams.password2" clearable placeholder="请填写确认密码"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div class="dialogFoot">
|
|
|
+ <el-button color="#EAEAEA" @click="state.showDialog = false" style="margin-right: 0.6rem">取消</el-button>
|
|
|
+ <el-button color="#2C68FF" @click="submitForm(ruleFormRef)">确认</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 详情模态框 -->
|
|
|
+ <el-dialog v-model="state.showDetails" class="dialog">
|
|
|
+ <template #header>
|
|
|
+ <div class="dialog-title">账号详情</div>
|
|
|
+ </template>
|
|
|
+ <div class="dialogBody">
|
|
|
+ <el-form ref="ruleFormRef" :model="detailsDb" :rules="addRules">
|
|
|
+ <el-form-item label="账号" prop="userName">
|
|
|
+ <el-input v-model="detailsDb.userName" clearable placeholder="请填写账号"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="姓名" prop="nickName">
|
|
|
+ <el-input v-model="detailsDb.nickName" clearable placeholder="请填写姓名"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="账号类型" prop="userType">
|
|
|
+ <el-select
|
|
|
+ v-model="detailsDb.userType"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择账号类型"
|
|
|
+ size="large"
|
|
|
+ >
|
|
|
+ <el-option v-for="item in state.optionUserType" :key="item.value" :label="item.name" :value="item.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="班级" prop="classInfo">
|
|
|
+ <el-cascader v-model="detailsDb.classInfo"
|
|
|
+ :options="options"
|
|
|
+ :props="{
|
|
|
+ children: 'children',
|
|
|
+ label: 'name',
|
|
|
+ value: 'id',
|
|
|
+ checkStrictly: false,
|
|
|
+ expandTrigger: 'hover',
|
|
|
+ emitPath: false,
|
|
|
+ multiple: true,
|
|
|
+ }"
|
|
|
+ clearable placeholder="请选择班级" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div class="dialogFoot">
|
|
|
+ <el-button color="#EAEAEA" @click="state.showDetails = false" style="margin-right: 0.6rem">取消</el-button>
|
|
|
+ <el-button color="#2C68FF" @click="updateForm(ruleFormRef)">更新</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 更新密码模态框 -->
|
|
|
+ <el-dialog v-model="state.showUpdatePwd" class="dialog">
|
|
|
+ <template #header>
|
|
|
+ <div class="dialog-title">账号更新密码</div>
|
|
|
+ </template>
|
|
|
+ <div class="dialogBody">
|
|
|
+ <el-form ref="ruleFormRefUpdatePwd" :model="updatePwdDb" :rules="addRules">
|
|
|
+ <el-form-item label="账号" prop="userName">
|
|
|
+ <el-input v-model="updatePwdDb.userName" clearable placeholder="请填写账号" disabled ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="密码" prop="password">
|
|
|
+ <el-input v-model="updatePwdDb.password" clearable placeholder="请填写密码"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="确认密码" prop="password2">
|
|
|
+ <el-input v-model="updatePwdDb.password2" clearable placeholder="请填写确认密码"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div class="dialogFoot">
|
|
|
+ <el-button color="#EAEAEA" @click="state.showUpdatePwd = false" style="margin-right: 0.6rem">取消</el-button>
|
|
|
+ <el-button color="#2C68FF" @click="updatePwdForm(ruleFormRefUpdatePwd)">更新密码</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 用于批量删除模态框 -->
|
|
|
+ <el-dialog v-model="state.showDel" width="600" class="del">
|
|
|
+ <template #header>
|
|
|
+ <div style="display: flex; align-items: center">
|
|
|
+ <img class="del-img" src="./assets/img/manageUser/error-line.svg" alt="" />
|
|
|
+ <div class="del-name">批量删除</div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <span class="delBody">是否确认批量删除?删除后不可恢复!</span>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="state.showDel = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="btnBatchDel">删除</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+@use './css/commonsScrollbar.scss';
|
|
|
+
|
|
|
+.ManageUser * {
|
|
|
+ -moz-user-select: none;
|
|
|
+ -webkit-user-select: none;
|
|
|
+ -ms-user-select: none;
|
|
|
+ -khtml-user-select: none;
|
|
|
+
|
|
|
+ user-select: none;
|
|
|
+ box-sizing:border-box;
|
|
|
+ -moz-box-sizing:border-box; /* Firefox */
|
|
|
+ -webkit-box-sizing:border-box; /* Safari */
|
|
|
+}
|
|
|
+
|
|
|
+.ManageUser {
|
|
|
+
|
|
|
+ position: relative;
|
|
|
+ z-index: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ top: 0px;
|
|
|
+ left: 0px;
|
|
|
+ background-color: #ffffff;
|
|
|
+
|
|
|
+ .content {
|
|
|
+
|
|
|
+ position: relative;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ border-radius: 1rem;
|
|
|
+ background: #ffffff;
|
|
|
+ padding: 2rem 4rem 2rem 3rem;
|
|
|
+ box-sizing: border-box;
|
|
|
+ .contentTitle {
|
|
|
+ padding: 0 0.5rem;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ .contentTitle-line {
|
|
|
+ width: 0.35rem;
|
|
|
+ height: 2rem;
|
|
|
+ background: #2c68ff;
|
|
|
+ border-radius: 0.85rem;
|
|
|
+ }
|
|
|
+ .contentTitle-text {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 1.8rem;
|
|
|
+ color: #373737;
|
|
|
+ margin-left: 1.4rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .contentRow {
|
|
|
+ margin-top: 2.8rem;
|
|
|
+ padding: 0 1.5rem 0 1rem;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ .rowLeft {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ .rowSelect {
|
|
|
+ :deep(.el-select__wrapper) {
|
|
|
+ height: 3rem;
|
|
|
+ font-size: 1.1rem;
|
|
|
+ min-height: 0;
|
|
|
+ border-radius: 0.57rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .rowBtn {
|
|
|
+ cursor: pointer;
|
|
|
+ width: 8.8rem;
|
|
|
+ height: 3rem;
|
|
|
+ border-radius: 0.57rem;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ margin-left: 2rem;
|
|
|
+
|
|
|
+ img {
|
|
|
+ width: 1.5rem;
|
|
|
+ height: 1.5rem;
|
|
|
+ }
|
|
|
+ .rowBtn-text {
|
|
|
+ font-size: 1.15rem;
|
|
|
+ margin-left: 0.7rem;
|
|
|
+ }
|
|
|
+ .rowBtn-text1 {
|
|
|
+ color: #3d7cff;
|
|
|
+ }
|
|
|
+ .rowBtn-text2 {
|
|
|
+ color: #d8a216;
|
|
|
+ }
|
|
|
+ .rowBtn-text3 {
|
|
|
+ color: #e84d4d;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .rowBtn1 {
|
|
|
+ background: #e5eeff;
|
|
|
+ &:hover {
|
|
|
+ background: #edf3ff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .rowBtn2 {
|
|
|
+ background: rgba(214, 154, 1, 0.1);
|
|
|
+ &:hover {
|
|
|
+ background: #f4e5bd;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .rowBtn3 {
|
|
|
+ background: rgba(232, 77, 77, 0.05);
|
|
|
+ &:hover {
|
|
|
+ background: #fad4d4;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .rowRight {
|
|
|
+ display: flex;
|
|
|
+ :deep(.el-input__wrapper) {
|
|
|
+ font-size: 1rem;
|
|
|
+ border-radius: 0.57rem;
|
|
|
+ }
|
|
|
+ .rowSearch {
|
|
|
+ cursor: pointer;
|
|
|
+ width: 3.9rem;
|
|
|
+ height: 3rem;
|
|
|
+ background: #3d7cff;
|
|
|
+ border-radius: 0.57rem;
|
|
|
+ font-size: 1.1rem;
|
|
|
+ color: #ffffff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ margin-left: 0.7rem;
|
|
|
+ &:hover {
|
|
|
+ background: #77a3ff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .searchInput {
|
|
|
+ width: 17rem;
|
|
|
+ height: 3rem;
|
|
|
+ margin: 0px 0.5rem 0px 0.5rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .contentTable {
|
|
|
+ margin-top: 2.3rem;
|
|
|
+ height: 36rem;
|
|
|
+
|
|
|
+ :deep(tr) {
|
|
|
+ border-radius: 0.57rem;
|
|
|
+ }
|
|
|
+ :deep(th) {
|
|
|
+ background: #f5f7fa;
|
|
|
+ height: 5rem;
|
|
|
+ font-size: 1.4rem;
|
|
|
+ color: #333746;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+ :deep(td) {
|
|
|
+ height: 5rem;
|
|
|
+ font-size: 1.2rem;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+ :deep(.cell) {
|
|
|
+ height: 2rem;
|
|
|
+ }
|
|
|
+ :deep(.el-checkbox) {
|
|
|
+ --el-checkbox-input-height: 2rem;
|
|
|
+ --el-checkbox-input-width: 2rem;
|
|
|
+ --el-checkbox-border-radius: 0.28rem;
|
|
|
+ // border: 1px solid #cad2d8;
|
|
|
+ }
|
|
|
+ :deep(.el-checkbox__inner:after) {
|
|
|
+ height: 1.07rem;
|
|
|
+ left: 0.64rem;
|
|
|
+ top: 0.21rem;
|
|
|
+ width: 0.5rem;
|
|
|
+ }
|
|
|
+ :deep(.el-checkbox__inner::before) {
|
|
|
+ top: 0.85rem;
|
|
|
+ }
|
|
|
+ :deep(.el-button) {
|
|
|
+ font-size: 1.2rem;
|
|
|
+ }
|
|
|
+ :deep(.el-table__inner-wrapper::before) {
|
|
|
+ height: 0px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ :deep(.classPagination) {
|
|
|
+ .el-pagination__rightwrapper {
|
|
|
+ justify-content: center;
|
|
|
+ .el-pagination__total {
|
|
|
+ color: #000000;
|
|
|
+ }
|
|
|
+ .btn-prev,
|
|
|
+ .btn-next {
|
|
|
+ background: #f7f7f7;
|
|
|
+ color: #000000;
|
|
|
+ border-radius: 1rem;
|
|
|
+ }
|
|
|
+ .number {
|
|
|
+ background: #f7f7f7;
|
|
|
+ color: #000000;
|
|
|
+ border-radius: 0.5rem;
|
|
|
+ }
|
|
|
+ .is-active {
|
|
|
+ background: #2c68ff;
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+ .el-pagination__jump {
|
|
|
+ color: #000000;
|
|
|
+ .el-pagination__editor.el-input {
|
|
|
+ width: 4.57rem;
|
|
|
+ .el-input__wrapper {
|
|
|
+ border-radius: 1rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.dialog) {
|
|
|
+ width: 55rem;
|
|
|
+ padding: 0;
|
|
|
+ border-radius: 1.1rem;
|
|
|
+
|
|
|
+ .el-dialog__header {
|
|
|
+ padding: 0px;
|
|
|
+ margin: 0px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialog-title {
|
|
|
+
|
|
|
+ // width: 55rem;
|
|
|
+ width: 100%;
|
|
|
+ height: 5.9rem;
|
|
|
+ background: #2c68ff;
|
|
|
+ font-size: 1.8rem;
|
|
|
+ color: #ffffff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ border-radius: 1.1rem 1.1rem 0 0;
|
|
|
+ padding-left: 4rem;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+ .el-dialog__headerbtn {
|
|
|
+ font-size: 1.7rem;
|
|
|
+ width: 3.57rem;
|
|
|
+ height: 3.57rem;
|
|
|
+ top: 1rem;
|
|
|
+ right: 1rem;
|
|
|
+ .el-dialog__close {
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 3.7rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .dialogBody {
|
|
|
+ padding: 0.8rem 8rem 3.5rem 6.7rem;
|
|
|
+ box-sizing: border-box;
|
|
|
+ .el-form-item {
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 2rem;
|
|
|
+ }
|
|
|
+ .el-form-item__label {
|
|
|
+ font-size: 1.2rem;
|
|
|
+ color: #000000;
|
|
|
+ padding-right: 2rem;
|
|
|
+ }
|
|
|
+ .el-input {
|
|
|
+ // height: 3.7rem;
|
|
|
+ // 这里不要限制高度,否则,多级联动多选的时候,样式会有问题,可以限制,最小高度
|
|
|
+ min-height: 3.7rem;
|
|
|
+ --el-input-bg-color: #efefef;
|
|
|
+ font-size: 1.2rem;
|
|
|
+ --el-input-border-radius: 0.57rem;
|
|
|
+ --el-input-border-color: #efefef;
|
|
|
+ --el-input-focus-border-color: #efefef;
|
|
|
+ --el-input-hover-border-color: #efefef;
|
|
|
+ .el-input__wrapper {
|
|
|
+ padding: 0 2rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-select {
|
|
|
+ .el-select__wrapper {
|
|
|
+ height: 3.7rem;
|
|
|
+ background-color: #efefef;
|
|
|
+ font-size: 1.2rem;
|
|
|
+ border-radius: 0.57rem;
|
|
|
+ // box-shadow: 0 0 0 1px #efefef inset;
|
|
|
+ padding: 0 2rem;
|
|
|
+ .el-select__caret {
|
|
|
+ color: #555555;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .dialogFoot {
|
|
|
+ display: flex;
|
|
|
+ justify-content: end;
|
|
|
+ margin-top: 4rem;
|
|
|
+ .el-button {
|
|
|
+ width: 8.5rem;
|
|
|
+ height: 3.2rem;
|
|
|
+ border-radius: 0.57rem;
|
|
|
+ font-size: 1.2rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-cascader {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ :deep(.del) {
|
|
|
+ .del-img {
|
|
|
+ width: 1.5rem;
|
|
|
+ height: 1.5rem;
|
|
|
+ margin-right: 0.3rem;
|
|
|
+ }
|
|
|
+ .del-name {
|
|
|
+ font-size: 1.2rem;
|
|
|
+ color: #e84d4d;
|
|
|
+ }
|
|
|
+ .el-dialog__body {
|
|
|
+ width: 100%;
|
|
|
+ height: 10rem;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ padding-top: 3rem;
|
|
|
+ color: #000000;
|
|
|
+ box-sizing: border-box;
|
|
|
+ font-size: 1.2rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+</style>
|