student.vue 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399
  1. <template>
  2. <div class="pb_content" style="background: unset">
  3. <div class="pb_content_body" style="
  4. background: #fff;
  5. padding: 0px 25px;
  6. box-sizing: border-box;
  7. border-radius: 5px;
  8. ">
  9. <div class="pb_head">
  10. <div style="
  11. display: flex;
  12. align-items: center;
  13. ">
  14. <span class="sub_head">学生管理</span>
  15. <span class="subClick" @click="
  16. goTo(
  17. '/class?userid=' +
  18. userid +
  19. '&oid=' +
  20. oid +
  21. '&org=' +
  22. org +
  23. '&role=' +
  24. role
  25. )
  26. ">班级管理</span>
  27. <span class="subClick" @click="
  28. goTo(
  29. '/grade?userid=' +
  30. userid +
  31. '&oid=' +
  32. oid +
  33. '&org=' +
  34. org +
  35. '&role=' +
  36. role
  37. )
  38. ">年级管理</span>
  39. </div>
  40. </div>
  41. <div class="student_head">
  42. <div class="head_left">
  43. <el-input v-model="sPhoneUser" class="student_input" placeholder="请输入用户名"></el-input>
  44. <el-select v-model="cid" placeholder="请选择班级" class="student_input" @change="searchStudent">
  45. <el-option label="所有人" value=""></el-option>
  46. <el-option v-for="(item, index) in classJuri" :key="index" :label="item.name" :value="item.id"></el-option>
  47. </el-select>
  48. <el-button class="student_button" @click="searchStudent" type="primary">查询</el-button>
  49. </div>
  50. <div class="head_right">
  51. <el-button @click="addStudent" type="primary" class="student_button">Add student</el-button>
  52. <el-upload v-show="role == 1" class="upload-demo newCss" :http-request="handleChange" :on-remove="handleRemove"
  53. action="#" :file-list="fileListUpload" accept=".xlsx">
  54. <el-button size="primary" type="primary">批量添加</el-button>
  55. <div slot="tip" class="el-upload__tip" style="margin-left: 10px">
  56. 只能上传xlsx文件,且不超过500kb
  57. </div>
  58. </el-upload>
  59. <!-- <el-button @click="exportExcel">导出学生</el-button> -->
  60. <div @click="getExcel" v-show="role == 1">xls 上传样例</div>
  61. </div>
  62. </div>
  63. </div>
  64. <div class="pb_content_body">
  65. <div class="student_table">
  66. <el-table ref="table" :data="tableData" border :height="tableHeight" :fit="true" v-loading="isLoading"
  67. style="width: 100%" :header-cell-style="{ background: '#f1f1f1', fontSize: '17px' }"
  68. :row-class-name="tableRowClassName">
  69. <el-table-column label="姓名" min-width="10" align="center">
  70. <template slot-scope="scope">
  71. <div class="userImg">
  72. <div class="tx">
  73. <img :src="scope.row.headportrait != null
  74. ? scope.row.headportrait
  75. : tx
  76. " alt />
  77. </div>
  78. <div style="
  79. width: 150px;
  80. text-align: left;
  81. white-space: nowrap;
  82. overflow: hidden;
  83. text-overflow: ellipsis;
  84. ">
  85. {{ scope.row.name }}
  86. </div>
  87. </div>
  88. </template>
  89. </el-table-column>
  90. <el-table-column label="学生账号" min-width="15" align="center">
  91. <template slot-scope="scope">
  92. <div>{{ scope.row.un ? scope.row.un : "" }}</div>
  93. </template>
  94. </el-table-column>
  95. <!-- <el-table-column label="电话" min-width="15" align="center">
  96. <template slot-scope="scope">
  97. <div>{{scope.row.phonenumber ? scope.row.phonenumber : "" }}</div>
  98. </template>
  99. </el-table-column> -->
  100. <!-- <el-table-column prop="studentid" label="学号" min-width="10" align="center"></el-table-column> -->
  101. <!-- <el-table-column
  102. prop="school"
  103. label="学校"
  104. min-width="30"
  105. align="center"
  106. >
  107. </el-table-column>-->
  108. <el-table-column prop="classname2" label="班级" min-width="15" align="center">
  109. </el-table-column>
  110. <el-table-column label="操作" width="250px">
  111. <template slot-scope="scope">
  112. <div class="btnBox">
  113. <el-button class="de_button" type="primary" size="small" style="
  114. width: auto;
  115. padding: 5px !important;
  116. line-height: 15px;
  117. " @click="iniPassword(scope.row.userid)">初始化密码</el-button>
  118. <el-button class="de_button" type="primary" size="small" @click="updateStudentA(scope.row)">修改</el-button>
  119. <div class="delete">
  120. <img src="../../assets/remove.png" alt @click="deleteStudent(scope.row.userid, scope.row.state)" />
  121. </div>
  122. </div>
  123. </template>
  124. </el-table-column>
  125. </el-table>
  126. </div>
  127. <div class="student_page">
  128. <el-pagination background layout="prev, pager, next" :page-size="10" :total="total" v-if="page"
  129. @current-change="handleCurrentChange"></el-pagination>
  130. </div>
  131. </div>
  132. <el-dialog :visible.sync="dialogVisible" :append-to-body="true" width="700px" :before-close="handleClose"
  133. class="add_student">
  134. <div slot="title" class="header-title">
  135. <div class="logoImg">
  136. <img src="../../assets/logo.png" alt />
  137. </div>
  138. <div class="title_add_student">Add student</div>
  139. </div>
  140. <el-form>
  141. <el-form-item label="学生姓名" :label-width="formLabelWidth">
  142. <span>
  143. <el-input placeholder="请输入学生姓名" clearable v-model="sName" class="add_input"></el-input>
  144. </span>
  145. </el-form-item>
  146. <!-- <el-form-item label="学生学号" :label-width="formLabelWidth">
  147. <span>
  148. <el-input
  149. placeholder="请输入学生学号"
  150. clearable
  151. v-model="sId"
  152. class="add_input"
  153. ></el-input>
  154. </span>
  155. </el-form-item>
  156. <el-form-item label="学生手机号" :label-width="formLabelWidth">
  157. <span>
  158. <el-input
  159. placeholder="请输入学生手机号"
  160. clearable
  161. v-model="sPhone"
  162. class="add_input"
  163. ></el-input>
  164. </span>
  165. </el-form-item> -->
  166. <el-form-item label="学生账号" :label-width="formLabelWidth">
  167. <span>
  168. <el-input placeholder="请输入学生账号" clearable v-model="sMail" class="add_input"></el-input>
  169. </span>
  170. </el-form-item>
  171. <el-form-item label="所属学校" :label-width="formLabelWidth">
  172. <el-input disabled style="width: 300px" v-model="schoolName"></el-input>
  173. </el-form-item>
  174. <el-form-item label="班级" :label-width="formLabelWidth">
  175. <el-select multiple collapse-tags v-model="sByClass" placeholder="请选择班级">
  176. <el-option v-for="(item, index) in classJuri" :key="index" :label="item.name" :value="item.id"></el-option>
  177. </el-select>
  178. </el-form-item>
  179. <div style="text-align: center; color: #adb3b7">
  180. 注:添加学生的账号密码为123456
  181. </div>
  182. </el-form>
  183. <span slot="footer" class="dialog-footer flex">
  184. <el-button class="right" @click="insertStudent">确认</el-button>
  185. </span>
  186. </el-dialog>
  187. <el-dialog :visible.sync="dialogVisibleUpdate" :append-to-body="true" width="700px" :before-close="handleClose"
  188. class="add_student">
  189. <div slot="title" class="header-title">
  190. <div class="logoImg">
  191. <img src="../../assets/logo.png" alt />
  192. </div>
  193. <div class="title_add_student">修改学生</div>
  194. </div>
  195. <el-form>
  196. <el-form-item label="学生名称" :label-width="formLabelWidth">
  197. <span>
  198. <el-input placeholder="请输入学生姓名" clearable v-model="userinfo.name" class="add_input"></el-input>
  199. </span>
  200. </el-form-item>
  201. <!-- <el-form-item label="学生学号" :label-width="formLabelWidth">
  202. <span>
  203. <el-input placeholder="请输入学生学号" clearable v-model="userinfo.studentid" class="add_input"></el-input>
  204. </span>
  205. </el-form-item>
  206. <el-form-item label="学生手机号" :label-width="formLabelWidth">
  207. <span>
  208. <el-input placeholder="请输入学生手机号" clearable v-model="userinfo.phonenumber" class="add_input"></el-input>
  209. </span>
  210. </el-form-item> -->
  211. <el-form-item label="学生账号" :label-width="formLabelWidth">
  212. <span>
  213. <el-input placeholder="请输入学生账号" clearable v-model="userinfo.un" class="add_input"></el-input>
  214. </span>
  215. </el-form-item>
  216. <el-form-item label="所属学校" :label-width="formLabelWidth">
  217. <el-input disabled style="width: 300px" v-model="schoolName"></el-input>
  218. </el-form-item>
  219. <el-form-item label="班级" :label-width="formLabelWidth">
  220. <el-select multiple collapse-tags v-model="userinfo.classid" placeholder="请选择班级">
  221. <el-option v-for="(item, index) in classJuri" :key="index" :label="item.name" :value="item.id"></el-option>
  222. </el-select>
  223. </el-form-item>
  224. <div style="text-align: center; color: #adb3b7">
  225. 注:添加学生的账号密码为123456
  226. </div>
  227. </el-form>
  228. <span slot="footer" class="dialog-footer flex">
  229. <el-button class="right" @click="updateStudent">修改</el-button>
  230. </span>
  231. </el-dialog>
  232. </div>
  233. </template>
  234. <script>
  235. import $ from "jquery";
  236. import pinyin from "../../../node_modules/js-pinyin/index";
  237. export default {
  238. data() {
  239. return {
  240. tableHeight: "500px",
  241. isLoading: false,
  242. formLabelWidth: "100px",
  243. tableData: [],
  244. dialogVisible: false,
  245. dialogVisibleUpdate: false,
  246. userinfo: {},
  247. userinfoA: {},
  248. sName: "",
  249. sPhone: "",
  250. sId: "",
  251. schoolName: "",
  252. // sBySchool: [],
  253. // sBySchoolName:"",
  254. sByClass: "",
  255. sMail: "",
  256. schoolJuri: [],
  257. classJuri: [],
  258. fileListUpload: [],
  259. page: 1,
  260. total: 0,
  261. sPhoneUser: "",
  262. userid: this.$route.query.userid,
  263. oid: this.$route.query.oid,
  264. org: this.$route.query.org,
  265. role: this.$route.query.role,
  266. cid: "",
  267. tx: require("../../assets/avatar.png"),
  268. userSuffix:""
  269. };
  270. },
  271. mounted() {
  272. this.$nextTick(function () {
  273. this.getUser()
  274. this.tableHeight =
  275. window.innerHeight - this.$refs.table.$el.offsetTop - 200;
  276. if (this.tableHeight <= 530) {
  277. this.tableHeight = 530;
  278. }
  279. // 监听窗口大小变化
  280. let self = this;
  281. window.onresize = function () {
  282. self.tableHeight =
  283. window.innerHeight - self.$refs.table.$el.offsetTop - 200;
  284. if (self.tableHeight <= 530) {
  285. self.tableHeight = 530;
  286. }
  287. };
  288. });
  289. },
  290. methods: {
  291. goTo(path) {
  292. this.$router.push(path);
  293. },
  294. getUser() {
  295. let params = {
  296. userid: this.userid
  297. }
  298. this.ajax
  299. .get(this.$store.state.api + "selectUser", params)
  300. .then((res) => {
  301. this.userSuffix = res.data[0][0].accountNumber.split("@")[1]
  302. })
  303. .catch((err) => {
  304. console.error(err);
  305. });
  306. },
  307. tableRowClassName({ row, rowIndex }) {
  308. if ((rowIndex + 1) % 2 === 0) {
  309. return "even_row";
  310. } else {
  311. return "";
  312. }
  313. },
  314. searchStudent() {
  315. this.page = 1;
  316. this.getStudent();
  317. },
  318. addStudent() {
  319. this.dialogVisible = true;
  320. (this.sName = ""), (this.sPhone = ""), (this.sByClass = ""), this.sMail;
  321. this.getClass();
  322. // this.getSchool();
  323. },
  324. handleClose(done) {
  325. done();
  326. },
  327. getExcel(res) {
  328. require.ensure([], () => {
  329. const { export_json_to_excel } = require("../../common/Export2Excel");
  330. const tHeader = ["学生姓名", "学生账号", "班级"];//"学号", "学生手机号",
  331. const data = [];
  332. export_json_to_excel(tHeader, data, "上传学生样例");
  333. });
  334. },
  335. handleCurrentChange(val) {
  336. this.page = val;
  337. this.getStudent();
  338. },
  339. time() {
  340. if (!this.now) {
  341. this.now = new Date().getTime();
  342. return true;
  343. } else {
  344. let time = new Date().getTime();
  345. if (time - this.now > 3000) {
  346. this.now = time;
  347. return true;
  348. } else {
  349. return false;
  350. }
  351. }
  352. },
  353. //新增学生
  354. insertStudent() {
  355. this.dialogVisible = true;
  356. if (this.sName === "") {
  357. this.$message.error("学生姓名不能为空");
  358. return;
  359. } else if (this.sByClass === "") {
  360. this.$message.error("请为学生选择班级");
  361. return;
  362. } else if (
  363. this.sPhone != "" &&
  364. !/^[1][3,4,5,7,8][0-9]{9}$/.test(this.sPhone)
  365. ) {
  366. this.$message.error("手机号格式不正确");
  367. return;
  368. } else if (
  369. // !/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/.test(this.sMail)
  370. this.sMail === ""
  371. ) {
  372. // this.$message.error("邮箱格式不正确");
  373. this.$message.error("学生账号不能为空");
  374. return;
  375. }
  376. // else if (this.sId === "") {
  377. // this.$message.error("学生学号不能为空");
  378. // return;
  379. // } else if (this.sPhone === "") {
  380. // this.$message.error("学生手机号不能为空");
  381. // return;
  382. // }
  383. if (this.time()) {
  384. // let params = { un: this.sPhone };
  385. // this.ajax
  386. // .get(this.$store.state.api + "findPhone", params)
  387. // .then((res) => {
  388. // if (res.data[0].length > 0) {
  389. // this.$message.error("此学生手机号码已被注册");
  390. // } else {
  391. let params = { un: this.sMail + '@' + this.userSuffix };
  392. this.ajax
  393. .get(this.$store.state.api + "findMail", params)
  394. .then((res) => {
  395. if (res.data[0].length > 0) {
  396. this.$message.error("此学生账号已被注册");
  397. } else {
  398. // let params = { un: this.sId };
  399. // this.ajax
  400. // .get(this.$store.state.api + "findSid", params)
  401. // .then((res) => {
  402. // if (res.data[0].length > 0) {
  403. // this.$message.error("此学生学号已被注册");
  404. // } else {
  405. this.add_Student();
  406. // }
  407. // })
  408. // .catch((err) => {
  409. // console.error(err);
  410. // });
  411. }
  412. })
  413. .catch((err) => {
  414. console.error(err);
  415. });
  416. // }
  417. // })
  418. // .catch((err) => {
  419. // console.error(err);
  420. // });
  421. }
  422. },
  423. add_Student() {
  424. let params = [
  425. {
  426. username: this.sMail + '@' + this.userSuffix,
  427. userpassword: 123456,
  428. alias: this.sName,
  429. oid: this.oid,
  430. ph: this.sPhone,
  431. sid: this.sId,
  432. cid: this.sByClass.join(","),
  433. org: this.org,
  434. },
  435. ];
  436. this.ajax
  437. .post(this.$store.state.api + "batchRegistrationOrg", params)
  438. .then((res) => {
  439. // console.log(res.data.uid, res.data.ph, res.data.oid, res.data.cid);
  440. // this.isLoading = false;
  441. let params = [
  442. {
  443. userid: res.data.uid,
  444. username: this.sName,
  445. sid: this.sId,
  446. type: 2,
  447. oid: res.data.oid,
  448. phone: res.data.ph,
  449. cid: res.data.cid,
  450. intro: "",
  451. sex: "0",
  452. org: this.org,
  453. },
  454. ];
  455. this.ajax
  456. // .post(this.$store.state.api + "updateUser", params)
  457. .post(this.$store.state.api + "updateUserByEduOrg", params)
  458. .then((res) => {
  459. console.log(res);
  460. })
  461. .catch((err) => {
  462. console.error(err);
  463. });
  464. this.$message({
  465. message: "新增成功",
  466. type: "success",
  467. });
  468. this.dialogVisible = false;
  469. this.sPhone = "";
  470. this.sName = "";
  471. // this.sBySchool = [];
  472. this.sByClass = [];
  473. this.sMail = "";
  474. this.getStudent();
  475. })
  476. .catch((err) => {
  477. this.isLoading = false;
  478. this.$message({
  479. message: "新增失败",
  480. type: "error",
  481. });
  482. console.error(err);
  483. });
  484. },
  485. //获取班级列表
  486. getClass() {
  487. this.isLoading = true;
  488. let params = {
  489. oid: this.oid,
  490. };
  491. this.ajax
  492. .get(this.$store.state.api + "selectClassBySchool", params)
  493. .then((res) => {
  494. this.isLoading = false;
  495. this.classJuri = res.data[0];
  496. })
  497. .catch((err) => {
  498. this.isLoading = false;
  499. console.error(err);
  500. });
  501. },
  502. // getSchool() {
  503. // this.isLoading = true;
  504. // let params = {
  505. // page: this.page,
  506. // };
  507. // this.ajax
  508. // .get(this.$store.state.api + "selectOrg", params)
  509. // .then((res) => {
  510. // this.isLoading = false;
  511. // this.schoolJuri = res.data[0];
  512. // })
  513. // .catch((err) => {
  514. // this.isLoading = false;
  515. // console.error(err);
  516. // });
  517. // },
  518. getStudent() {
  519. this.isLoading = true;
  520. let params = {
  521. oid: this.oid,
  522. cid: this.cid,
  523. cu: "",
  524. cn: this.sPhoneUser,
  525. page: this.page,
  526. };
  527. this.ajax
  528. .get(this.$store.state.api + "selectStudent2", params)
  529. .then((res) => {
  530. this.isLoading = false;
  531. this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
  532. this.tableData = res.data[0];
  533. })
  534. .catch((err) => {
  535. this.isLoading = false;
  536. console.error(err);
  537. });
  538. },
  539. handleChange(file) {
  540. this.fileTemp = file.file;
  541. if (this.fileTemp) {
  542. if (
  543. this.fileTemp.type ==
  544. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ||
  545. this.fileTemp.type == "application/vnd.ms-excel"
  546. ) {
  547. this.importCount = 1;
  548. this.importfxx(this.fileTemp);
  549. } else {
  550. this.$message({
  551. type: "warning",
  552. message: "附件格式错误,请删除后重新上传!",
  553. });
  554. }
  555. } else {
  556. this.$message({
  557. type: "warning",
  558. message: "请上传附件!",
  559. });
  560. }
  561. },
  562. handleRemove(file, fileList) {
  563. this.fileTemp = null;
  564. },
  565. exportExcel() {
  566. try {
  567. let params = {
  568. oid: this.oid,
  569. };
  570. this.ajax
  571. .get(this.$store.state.api + "selectUserBySchool", params)
  572. .then((res) => {
  573. var res = res.data[0];
  574. //如果value的json字段的key值和想要的headers值不一致时,可做如下更改
  575. //将和下面的Object.fromEntries结合,将json字段的key值改变为要求的excel的header值
  576. var array = [];
  577. for (var i = 0; i < res.length; i++) {
  578. var _json = {};
  579. _json["用户名"] = res[i].username;
  580. _json["姓名"] = res[i].alias ? res[i].alias : "";
  581. _json["班级"] = res[i].classid ? res[i].classid : "";
  582. array.push(_json);
  583. }
  584. var XLSX = require("xlsx");
  585. const workbook = XLSX.utils.book_new(); //创建一个新的工作簿对象
  586. let ws = XLSX.utils.json_to_sheet(array); //将json对象数组转化成工作表
  587. ws["!cols"] = [
  588. //设置每一列的宽度
  589. { wch: 50 },
  590. { wch: 50 },
  591. { wch: 50 },
  592. ];
  593. XLSX.utils.book_append_sheet(workbook, ws, "sheet1"); //把sheet添加到workbook里,第三个参数是sheet名
  594. XLSX.writeFile(workbook, "学生信息.xlsx");
  595. // const wopts = { bookType: "xlsx", bookSST: false, type: "array" };//写入的样式bookType:输出的文件类型,type:输出的数据类型,bookSST: 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
  596. // const wbout = XLSX.write(workbook, wopts);// 浏览器端和node共有的API,实际上node可以直接使用xlsx.writeFile来写入文件,但是浏览器没有该API
  597. // FileSaver.saveAs(new Blob([wbout], { type: "application/octet-stream" }), `${title} demo.xlsx`);//保存文件
  598. this.$message({
  599. message: "导出成功",
  600. type: "success",
  601. });
  602. })
  603. .catch((err) => {
  604. console.error(err);
  605. });
  606. } catch (e) {
  607. console.log(e, e.stack);
  608. }
  609. },
  610. importfxx(obj) {
  611. const loading = this.$loading.service({
  612. background: "rgba(255, 255, 255, 0.7)",
  613. target: document.body,
  614. });
  615. var _$ = $;
  616. this.importCount++;
  617. let _this = this;
  618. // 通过DOM取文件数据
  619. this.file = obj;
  620. var rABS = false; //是否将文件读取为二进制字符串
  621. var f = this.file;
  622. var reader = new FileReader();
  623. //if (!FileReader.prototype.readAsBinaryString) {
  624. FileReader.prototype.readAsBinaryString = function (f) {
  625. var binary = "";
  626. var rABS = false; //是否将文件读取为二进制字符串
  627. var pt = this;
  628. var wb; //读取完成的数据
  629. var outdata;
  630. var reader = new FileReader();
  631. reader.onload = function (e) {
  632. var bytes = new Uint8Array(reader.result);
  633. var length = bytes.byteLength;
  634. for (var i = 0; i < length; i++) {
  635. binary += String.fromCharCode(bytes[i]);
  636. }
  637. var XLSX = require("xlsx");
  638. if (rABS) {
  639. wb = XLSX.read(btoa(fixdata(binary)), {
  640. //手动转化
  641. type: "base64",
  642. });
  643. } else {
  644. wb = XLSX.read(binary, {
  645. type: "binary",
  646. });
  647. }
  648. outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); //outdata就是你想要的东西
  649. this.da = [...outdata];
  650. let arr = [];
  651. this.da.map((v) => {
  652. let obj = {};
  653. let a = "";
  654. var num = "";
  655. for (var cj = 0; cj < 3; cj++) {
  656. num += Math.floor(Math.random() * 10);
  657. }
  658. a =
  659. pinyin.getFullChars(v["学生姓名"]).toLowerCase() +
  660. num +
  661. "@cocorobo.cc";
  662. obj.sId = v["学号"];
  663. obj.name = v["学生姓名"];
  664. obj.mail = v["学生账号"] ? v["学生账号"] : a;
  665. obj.phone = v["学生手机号"];
  666. obj.class = v["班级"];
  667. arr.push(obj);
  668. });
  669. console.log(arr);
  670. let _b = 1;
  671. for (var i = 0; i < arr.length; i++) {
  672. let item = arr[i];
  673. if (item.class === "") {
  674. _b = 1;
  675. _this.$message.error("学生班级不能为空,请重新上传");
  676. break;
  677. } else if (item.name === "") {
  678. _b = 1;
  679. _this.$message.error("学生姓名不能为空,请重新上传");
  680. break;
  681. } else if (item.sId === "") {
  682. _b = 1;
  683. _this.$message.error("学生学号不能为空,请重新上传");
  684. }
  685. // else if (item.phone === "") {
  686. // _b = 1;
  687. // _this.$message.error("学生手机号不能为空,请重新上传");
  688. // break;
  689. // } else if (!/^[1][3,4,5,7,8][0-9]{9}$/.test(item.phone)) {
  690. // _b = 1;
  691. // _this.$message.error("有学生手机号格式不正确,请重新上传");
  692. // break;
  693. // }
  694. else if (item.mail === "") {
  695. _b = 1;
  696. _this.$message.error("学生账号不能为空,请重新上传");
  697. break;
  698. } else if (
  699. !/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/.test(
  700. item.mail
  701. )
  702. ) {
  703. _b = 1;
  704. _this.$message.error("有学生账号格式不正确,请重新上传");
  705. break;
  706. }
  707. // else if (item.school === "") {
  708. // _b = 1;
  709. // _this.$message.error("学生学校不能为空,请重新上传");
  710. // break;
  711. // }
  712. // else if (item.sex === "") {
  713. // _b = 1;
  714. // _this.$message.error("学生性别不能为空,请重新上传");
  715. // break;
  716. // }
  717. // if (item.class != "") {
  718. // let _a;
  719. // let params = {
  720. // className: item.class,
  721. // };
  722. // _$.ajax({
  723. // url: _this.$store.state.api + "selectC", //url路径
  724. // type: "GET", //GET
  725. // async: false, //或false,是否异步
  726. // data: params,
  727. // timeout: 5000, //超时时间
  728. // dataType: "json", //返回的数据格式:
  729. // beforeSend: function (xhr) {},
  730. // success: function (res, textStatus, jqXHR) {
  731. // if (res[0].length == 0) {
  732. // _a = 1;
  733. // _this.$message.error(
  734. // "有学生班级不存在,请去添加后并重新上传"
  735. // );
  736. // } else {
  737. // item.classid = res[0][0].id;
  738. // }
  739. // },
  740. // error: function (xhr, textStatus) {
  741. // console.log(textStatus);
  742. // },
  743. // complete: function () {},
  744. // });
  745. // if (_a == 1) {
  746. // _b = 1;
  747. // break;
  748. // }
  749. // }
  750. // if (item.school != "") {
  751. // let _a;
  752. // let params = {
  753. // schoolName: item.school,
  754. // };
  755. // _$.ajax({
  756. // url: _this.$store.state.api + "selectS", //url路径
  757. // type: "GET", //GET
  758. // async: false, //或false,是否异步
  759. // data: params,
  760. // timeout: 5000, //超时时间
  761. // dataType: "json", //返回的数据格式:
  762. // beforeSend: function (xhr) {},
  763. // success: function (res, textStatus, jqXHR) {
  764. // if (res[0].length == 0) {
  765. // _a = 1;
  766. // _this.$message.error(
  767. // "有学生学校不存在,请去添加后并重新上传"
  768. // );
  769. // } else {
  770. // item.schoolid = res[0][0].id;
  771. // }
  772. // },
  773. // error: function (xhr, textStatus) {
  774. // console.log(textStatus);
  775. // },
  776. // complete: function () {},
  777. // });
  778. // if (_a == 1) {
  779. // _b = 1;
  780. // break;
  781. // }
  782. // }
  783. // for (var k = 0; k < arr.length; k++) {
  784. // if (item.phone != "") {
  785. // let params = { un: item.phone };
  786. // let _a;
  787. // _$.ajax({
  788. // url: _this.$store.state.api + "findPhone", //url路径
  789. // type: "GET", //GET
  790. // async: false, //或false,是否异步
  791. // data: params,
  792. // timeout: 5000, //超时时间
  793. // dataType: "json", //返回的数据格式:
  794. // beforeSend: function (xhr) {},
  795. // success: function (res, textStatus, jqXHR) {
  796. // if (res[0].length > 0) {
  797. // _this.$message.error("有学生手机号码已被注册");
  798. // _a = 1;
  799. // }
  800. // },
  801. // error: function (xhr, textStatus) {
  802. // console.log(textStatus);
  803. // },
  804. // complete: function () {},
  805. // });
  806. // if (_a == 1) {
  807. // _b = 1;
  808. // break;
  809. // }
  810. // }
  811. // if (item.mail != "") {
  812. // let params = { un: item.mail };
  813. // let _a;
  814. // _$.ajax({
  815. // url: _this.$store.state.api + "findMail", //url路径
  816. // type: "GET", //GET
  817. // async: false, //或false,是否异步
  818. // data: params,
  819. // timeout: 5000, //超时时间
  820. // dataType: "json", //返回的数据格式:
  821. // beforeSend: function (xhr) {},
  822. // success: function (res, textStatus, jqXHR) {
  823. // if (res[0].length > 0) {
  824. // _this.$message.error("有学生账号已被注册");
  825. // _a = 1;
  826. // }
  827. // },
  828. // error: function (xhr, textStatus) {
  829. // console.log(textStatus);
  830. // },
  831. // complete: function () {},
  832. // });
  833. // if (_a == 1) {
  834. // _b = 1;
  835. // break;
  836. // }
  837. // }
  838. // if (item.sId != "") {
  839. // let params = { un: item.sId };
  840. // let _a;
  841. // _$.ajax({
  842. // url: _this.$store.state.api + "findSid", //url路径
  843. // type: "GET", //GET
  844. // async: false, //或false,是否异步
  845. // data: params,
  846. // timeout: 5000, //超时时间
  847. // dataType: "json", //返回的数据格式:
  848. // beforeSend: function (xhr) {},
  849. // success: function (res, textStatus, jqXHR) {
  850. // if (res[0].length > 0) {
  851. // _this.$message.error("有学生学号重复");
  852. // _a = 1;
  853. // }
  854. // },
  855. // error: function (xhr, textStatus) {
  856. // console.log(textStatus);
  857. // },
  858. // complete: function () {},
  859. // });
  860. // if (_a == 1) {
  861. // _b = 1;
  862. // break;
  863. // }
  864. // }
  865. // _b = 2;
  866. // }
  867. // }
  868. // if (_b == 2) {
  869. // for (var i = 0; i < arr.length; i++) {
  870. // let _i = i;
  871. // let item = arr[i];
  872. // let params = [
  873. // {
  874. // alias: item.name,
  875. // username: item.mail,
  876. // userpassword: 123456,
  877. // oid: _this.oid,
  878. // ph: item.phone,
  879. // cid: item.class,
  880. // },
  881. // ];
  882. // _this.ajax
  883. // .post(_this.$store.state.api + "batchRegistration", params)
  884. // .then((res) => {
  885. // let params = [
  886. // {
  887. // userid: res.data.uid,
  888. // username: item.name,
  889. // sId: item.sId,
  890. // type: 2,
  891. // oid: res.data.oid,
  892. // phone: res.data.ph ? res.data.ph : "",
  893. // cid: res.data.cid ? res.data.cid : "",
  894. // intro: "",
  895. // sex: "0",
  896. // },
  897. // ];
  898. // _this.ajax
  899. // .post(_this.$store.state.api + "updateUserByEdu", params)
  900. // .then((res) => {
  901. // console.log(res);
  902. // })
  903. // .catch((err) => {
  904. // console.error(err);
  905. // });
  906. // loading.close();
  907. // // _this.$message({
  908. // // message: "新增成功",
  909. // // type: "success",
  910. // // });
  911. // _this.getStudent();
  912. // // if (_i == arr.length - 1) {
  913. // // loading.close();
  914. // // _this.$message({
  915. // // message: "上传成功",
  916. // // type: "success",
  917. // // });
  918. // // _this.getStudent();
  919. // // }
  920. // })
  921. // .catch((err) => {
  922. // _this.$message.error("上传失败");
  923. // console.error(err);
  924. // });
  925. // }
  926. // } else {
  927. // loading.close();
  928. }
  929. let z = 2;
  930. let newArr = JSON.stringify(arr);
  931. let params = [
  932. {
  933. arr: newArr,
  934. userpassword: 123456,
  935. oid: _this.oid,
  936. },
  937. ];
  938. _this.ajax
  939. .post(_this.$store.state.api + "batchRegistrationMore", params)
  940. .then((res) => {
  941. if (res.data.type == 1) {
  942. _this.$message.error("有学生手机号码已被注册");
  943. z = 1;
  944. }
  945. if (res.data.type == 2) {
  946. _this.$message.error("有学生账号已被注册");
  947. z = 1;
  948. }
  949. if (res.data.type == 3) {
  950. _this.$message.error("有学生学号重复");
  951. z = 1;
  952. }
  953. if (z == 2) {
  954. _this.$message({
  955. message: "新增成功",
  956. type: "success",
  957. });
  958. _this.getStudent();
  959. }
  960. loading.close();
  961. })
  962. .catch((err) => {
  963. console.error(err);
  964. });
  965. _this.fileListUpload = [];
  966. };
  967. reader.readAsArrayBuffer(f);
  968. };
  969. if (rABS) {
  970. reader.readAsArrayBuffer(f);
  971. } else {
  972. reader.readAsBinaryString(f);
  973. }
  974. },
  975. getSchoolName() {
  976. let params = {
  977. oid: this.oid,
  978. };
  979. this.ajax
  980. .get(this.$store.state.api + "selectSchoolName2", params)
  981. .then((res) => {
  982. this.schoolName = res.data[0][0].name;
  983. })
  984. .catch((err) => {
  985. console.error(err);
  986. });
  987. },
  988. deleteStudent(id, state) {
  989. state = 0;
  990. let params = [{ uid: id, state: state }];
  991. this.$confirm("确定" + "删除" + "此学生吗?", "Notification", {
  992. confirmButtonText: "Save",
  993. cancelButtonText: "Cancel",
  994. type: "warning",
  995. })
  996. .then(() => {
  997. this.ajax
  998. .post(this.$store.state.api + "deleteStudent", params)
  999. .then((res) => {
  1000. this.$message({
  1001. message: "操作成功",
  1002. type: "success",
  1003. });
  1004. this.getStudent();
  1005. })
  1006. .catch((err) => {
  1007. this.$message.error("操作失败");
  1008. console.error(err);
  1009. });
  1010. })
  1011. .catch(() => { });
  1012. },
  1013. iniPassword(id) {
  1014. this.$confirm("确定" + "初始化" + "此学生的密码吗?", "Notification", {
  1015. confirmButtonText: "Save",
  1016. cancelButtonText: "Cancel",
  1017. type: "warning",
  1018. })
  1019. .then(() => {
  1020. let params = [
  1021. {
  1022. uid: id,
  1023. pa: 123456,
  1024. },
  1025. ];
  1026. this.ajax
  1027. .post(this.$store.state.api + "iniPassword", params)
  1028. .then((res) => {
  1029. this.$message({
  1030. message: "初始化密码成功!",
  1031. type: "success",
  1032. });
  1033. })
  1034. .catch((err) => {
  1035. console.error(err);
  1036. });
  1037. })
  1038. .catch(() => { });
  1039. },
  1040. updateStudentA(res) {
  1041. this.userinfo = JSON.parse(JSON.stringify(res));
  1042. this.userinfoA = JSON.parse(JSON.stringify(res));
  1043. this.userinfo.classid = this.userinfo.classid.split(",");
  1044. this.dialogVisibleUpdate = true;
  1045. },
  1046. updateStudent() {
  1047. if (this.userinfo.name === "") {
  1048. this.$message.error("学生姓名不能为空");
  1049. return;
  1050. } else if (!this.userinfo.classid) {
  1051. this.$message.error("请为学生选择班级");
  1052. return;
  1053. } else if (
  1054. this.userinfo.phonenumber &&
  1055. !/^[1][3,4,5,7,8][0-9]{9}$/.test(this.userinfo.phonenumber)
  1056. ) {
  1057. this.$message.error("手机号格式不正确");
  1058. return;
  1059. } else if (
  1060. !/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/.test(
  1061. this.userinfo.un
  1062. )
  1063. ) {
  1064. this.$message.error("邮箱格式不正确");
  1065. return;
  1066. }
  1067. if (this.time()) {
  1068. if (this.userinfoA.un != this.userinfo.un) {
  1069. let params = { un: this.userinfo.un };
  1070. this.ajax
  1071. .get(this.$store.state.api + "findMail", params)
  1072. .then((res) => {
  1073. if (res.data[0].length > 0) {
  1074. this.$message.error("此学生账号已被注册");
  1075. } else {
  1076. this.update_Student();
  1077. }
  1078. })
  1079. .catch((err) => {
  1080. console.error(err);
  1081. });
  1082. } else {
  1083. this.update_Student();
  1084. }
  1085. }
  1086. },
  1087. update_Student() {
  1088. let params = [
  1089. {
  1090. userid: this.userinfo.userid,
  1091. username: this.userinfo.un,
  1092. alias: this.userinfo.name,
  1093. ph: this.userinfo.phonenumber,
  1094. sid: this.userinfo.studentid,
  1095. cid: this.userinfo.classid.join(","),
  1096. },
  1097. ];
  1098. this.ajax
  1099. .post(this.$store.state.api + "updateStudentInfo", params)
  1100. .then((res) => {
  1101. this.$message({
  1102. message: "修改成功",
  1103. type: "success",
  1104. });
  1105. this.dialogVisibleUpdate = false;
  1106. this.getStudent();
  1107. })
  1108. .catch((err) => {
  1109. this.isLoading = false;
  1110. this.$message({
  1111. message: "修改失败",
  1112. type: "error",
  1113. });
  1114. console.error(err);
  1115. });
  1116. },
  1117. },
  1118. created() {
  1119. this.page = 1;
  1120. this.getStudent();
  1121. this.getSchoolName();
  1122. this.getClass();
  1123. },
  1124. };
  1125. </script>
  1126. <style scoped>
  1127. .pb_head>span:nth-child(2) {
  1128. font-size: 20px;
  1129. margin-left: 5px;
  1130. color: #828282;
  1131. }
  1132. .pb_head {
  1133. margin: 0 !important;
  1134. width: 100% !important;
  1135. }
  1136. .student_page {
  1137. margin-top: 10px;
  1138. }
  1139. .student_head {
  1140. margin-top: 10px;
  1141. padding-bottom: 10px;
  1142. display: flex;
  1143. justify-content: space-between;
  1144. }
  1145. .head_left {
  1146. display: flex;
  1147. align-items: center;
  1148. line-height: 40px;
  1149. }
  1150. .head_right {
  1151. display: flex;
  1152. flex-direction: row;
  1153. flex-wrap: nowrap;
  1154. align-items: center;
  1155. }
  1156. .student_input>>>.el-input__inner {
  1157. height: 30px;
  1158. width: 190px;
  1159. font-size: 13px;
  1160. padding: 0 10px;
  1161. }
  1162. .student_button {
  1163. color: #fff;
  1164. background: #2268bc;
  1165. width: 60px;
  1166. height: 30px;
  1167. padding: 0 !important;
  1168. font-size: 12px;
  1169. line-height: 30px;
  1170. }
  1171. .head_right>button:nth-child(1) {
  1172. color: #fff;
  1173. background: #2268bc;
  1174. width: 70px;
  1175. height: 30px;
  1176. padding: 0 !important;
  1177. font-size: 12px;
  1178. line-height: 30px;
  1179. }
  1180. .head_right>button:nth-child(2) {
  1181. color: #fff;
  1182. background: #2268bc;
  1183. width: 70px;
  1184. height: 30px;
  1185. padding: 0 !important;
  1186. font-size: 12px;
  1187. line-height: 30px;
  1188. }
  1189. .head_right>div {
  1190. font-size: 12px;
  1191. line-height: 40px;
  1192. margin-left: 10px;
  1193. color: #2a6dbe;
  1194. text-decoration: underline;
  1195. cursor: pointer;
  1196. }
  1197. .student_table>>>.el-table--border td {
  1198. border-right: 0px !important;
  1199. }
  1200. .student_table>>>.el-table,
  1201. .student_table>>>.el-table__body-wrapper {
  1202. height: auto !important;
  1203. }
  1204. .el-table>>>.even_row {
  1205. background-color: #f1f1f1 !important;
  1206. }
  1207. .de_button {
  1208. color: #fff;
  1209. background: #5190fd;
  1210. width: 50px;
  1211. height: 25px;
  1212. padding: 0 !important;
  1213. font-size: 12px;
  1214. line-height: 25px;
  1215. }
  1216. .add_student>>>.el-dialog__header {
  1217. padding: 20px 20px 10px;
  1218. text-align: center;
  1219. background: #32455b;
  1220. }
  1221. .add_student>>>.el-dialog__title {
  1222. font-size: 14px !important;
  1223. color: #fff !important;
  1224. }
  1225. .add_student>>>.el-dialog__headerbtn {
  1226. font-size: 20px !important;
  1227. }
  1228. .add_student>>>.el-form-item__label {
  1229. margin-left: 65px;
  1230. }
  1231. .add_student>>>.el-form-item {
  1232. display: flex;
  1233. }
  1234. .add_student>>>.el-form-item__content {
  1235. margin: 0 !important;
  1236. }
  1237. .add_input {
  1238. width: 365px;
  1239. }
  1240. .add_student>>>.el-dialog__footer {
  1241. text-align: center !important;
  1242. }
  1243. .right {
  1244. width: 250px;
  1245. color: #fff;
  1246. background: #0e72e6;
  1247. margin-bottom: 20px;
  1248. }
  1249. .header-title {
  1250. display: flex;
  1251. }
  1252. .logoImg {
  1253. width: 30px;
  1254. }
  1255. .logoImg>img {
  1256. width: 100%;
  1257. height: 100%;
  1258. }
  1259. .title_add_student {
  1260. margin: 0 auto;
  1261. color: #fff;
  1262. }
  1263. .upload-demo {
  1264. line-height: 0px !important;
  1265. }
  1266. .upload-demo>>>.el-button {
  1267. color: #fff;
  1268. background: #2268bc;
  1269. width: 70px;
  1270. height: 30px;
  1271. padding: 0 !important;
  1272. font-size: 12px;
  1273. line-height: 0 !important;
  1274. }
  1275. .userImg {
  1276. display: flex;
  1277. flex-direction: row;
  1278. justify-content: center;
  1279. align-items: center;
  1280. }
  1281. .tx {
  1282. width: 40px;
  1283. margin-right: 10px;
  1284. }
  1285. .delete {
  1286. width: 25px;
  1287. height: 25px;
  1288. cursor: pointer;
  1289. margin-left: 10px;
  1290. }
  1291. .tx>img,
  1292. .delete>img {
  1293. width: 100%;
  1294. height: 100%;
  1295. }
  1296. .newCss {
  1297. display: flex;
  1298. flex-direction: row;
  1299. flex-wrap: nowrap;
  1300. align-items: baseline;
  1301. }
  1302. .student_input.el-input {
  1303. width: auto;
  1304. }
  1305. .student_input {
  1306. margin-right: 10px;
  1307. }
  1308. .student_input>>>.el-input__icon {
  1309. line-height: unset;
  1310. }
  1311. .btnBox {
  1312. display: flex;
  1313. align-items: center;
  1314. }
  1315. .sub_head {
  1316. position: relative;
  1317. }
  1318. .sub_head::after {
  1319. content: "";
  1320. width: 100%;
  1321. background: #5a9cea;
  1322. height: 2px;
  1323. position: absolute;
  1324. left: 0;
  1325. bottom: -10px;
  1326. }
  1327. .subClick {
  1328. /* font-size: 16px; */
  1329. font-size: 26px;
  1330. cursor: pointer;
  1331. /* margin-left: 17.5px; */
  1332. /* color: #ab582f; */
  1333. /* color: #409eff; */
  1334. color: #999;
  1335. }
  1336. .subClick:hover {
  1337. color: #000;
  1338. }
  1339. .sub_head + .subClick,
  1340. .subClick + .subClick,
  1341. .subClick + .sub_head{
  1342. margin-left: 17.5px;
  1343. }
  1344. </style>