student.vue 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411
  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">添加学生</el-button>
  52. <el-upload 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">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">添加学生</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. let mail = '';
  384. if(/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/.test(this.sMail)){
  385. mail = this.sMail;
  386. }else{
  387. mail = this.sMail + "@" + this.userSuffix
  388. }
  389. if (this.time()) {
  390. // let params = { un: this.sPhone };
  391. // this.ajax
  392. // .get(this.$store.state.api + "findPhone", params)
  393. // .then((res) => {
  394. // if (res.data[0].length > 0) {
  395. // this.$message.error("此学生手机号码已被注册");
  396. // } else {
  397. let params = { un: mail };
  398. this.ajax
  399. .get(this.$store.state.api + "findMail", params)
  400. .then((res) => {
  401. if (res.data[0].length > 0) {
  402. this.$message.error("此学生账号已被注册");
  403. } else {
  404. // let params = { un: this.sId };
  405. // this.ajax
  406. // .get(this.$store.state.api + "findSid", params)
  407. // .then((res) => {
  408. // if (res.data[0].length > 0) {
  409. // this.$message.error("此学生学号已被注册");
  410. // } else {
  411. this.add_Student();
  412. // }
  413. // })
  414. // .catch((err) => {
  415. // console.error(err);
  416. // });
  417. }
  418. })
  419. .catch((err) => {
  420. console.error(err);
  421. });
  422. // }
  423. // })
  424. // .catch((err) => {
  425. // console.error(err);
  426. // });
  427. }
  428. },
  429. add_Student() {
  430. let mail = '';
  431. if(/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/.test(this.sMail)){
  432. mail = this.sMail;
  433. }else{
  434. mail = this.sMail + "@" + this.userSuffix
  435. }
  436. let params = [
  437. {
  438. username: mail,
  439. userpassword: 123456,
  440. alias: this.sName,
  441. oid: this.oid,
  442. ph: this.sPhone,
  443. sid: this.sId,
  444. cid: this.sByClass.join(","),
  445. org: this.org,
  446. },
  447. ];
  448. this.ajax
  449. .post(this.$store.state.api + "batchRegistrationOrg", params)
  450. .then((res) => {
  451. // console.log(res.data.uid, res.data.ph, res.data.oid, res.data.cid);
  452. // this.isLoading = false;
  453. // let params = [
  454. // {
  455. // userid: res.data.uid,
  456. // username: this.sName,
  457. // sid: this.sId,
  458. // type: 2,
  459. // oid: res.data.oid,
  460. // phone: res.data.ph,
  461. // cid: res.data.cid,
  462. // intro: "",
  463. // sex: "0",
  464. // org: this.org,
  465. // },
  466. // ];
  467. // this.ajax
  468. // // .post(this.$store.state.api + "updateUser", params)
  469. // .post(this.$store.state.api + "updateUserByEduOrg", params)
  470. // .then((res) => {
  471. // console.log(res);
  472. // })
  473. // .catch((err) => {
  474. // console.error(err);
  475. // });
  476. this.$message({
  477. message: "新增成功",
  478. type: "success",
  479. });
  480. this.dialogVisible = false;
  481. this.sPhone = "";
  482. this.sName = "";
  483. // this.sBySchool = [];
  484. this.sByClass = [];
  485. this.sMail = "";
  486. this.getStudent();
  487. })
  488. .catch((err) => {
  489. this.isLoading = false;
  490. this.$message({
  491. message: "新增失败",
  492. type: "error",
  493. });
  494. console.error(err);
  495. });
  496. },
  497. //获取班级列表
  498. getClass() {
  499. this.isLoading = true;
  500. let params = {
  501. oid: this.oid,
  502. };
  503. this.ajax
  504. .get(this.$store.state.api + "selectClassBySchool", params)
  505. .then((res) => {
  506. this.isLoading = false;
  507. this.classJuri = res.data[0];
  508. })
  509. .catch((err) => {
  510. this.isLoading = false;
  511. console.error(err);
  512. });
  513. },
  514. // getSchool() {
  515. // this.isLoading = true;
  516. // let params = {
  517. // page: this.page,
  518. // };
  519. // this.ajax
  520. // .get(this.$store.state.api + "selectOrg", params)
  521. // .then((res) => {
  522. // this.isLoading = false;
  523. // this.schoolJuri = res.data[0];
  524. // })
  525. // .catch((err) => {
  526. // this.isLoading = false;
  527. // console.error(err);
  528. // });
  529. // },
  530. getStudent() {
  531. this.isLoading = true;
  532. let params = {
  533. oid: this.oid,
  534. cid: this.cid,
  535. cu: "",
  536. cn: this.sPhoneUser,
  537. page: this.page,
  538. };
  539. this.ajax
  540. .get(this.$store.state.api + "selectStudent2", params)
  541. .then((res) => {
  542. this.isLoading = false;
  543. this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
  544. this.tableData = res.data[0];
  545. })
  546. .catch((err) => {
  547. this.isLoading = false;
  548. console.error(err);
  549. });
  550. },
  551. handleChange(file) {
  552. this.fileTemp = file.file;
  553. if (this.fileTemp) {
  554. if (
  555. this.fileTemp.type ==
  556. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ||
  557. this.fileTemp.type == "application/vnd.ms-excel"
  558. ) {
  559. this.importCount = 1;
  560. this.importfxx(this.fileTemp);
  561. } else {
  562. this.$message({
  563. type: "warning",
  564. message: "附件格式错误,请删除后重新上传!",
  565. });
  566. }
  567. } else {
  568. this.$message({
  569. type: "warning",
  570. message: "请上传附件!",
  571. });
  572. }
  573. },
  574. handleRemove(file, fileList) {
  575. this.fileTemp = null;
  576. },
  577. exportExcel() {
  578. try {
  579. let params = {
  580. oid: this.oid,
  581. };
  582. this.ajax
  583. .get(this.$store.state.api + "selectUserBySchool", params)
  584. .then((res) => {
  585. var res = res.data[0];
  586. //如果value的json字段的key值和想要的headers值不一致时,可做如下更改
  587. //将和下面的Object.fromEntries结合,将json字段的key值改变为要求的excel的header值
  588. var array = [];
  589. for (var i = 0; i < res.length; i++) {
  590. var _json = {};
  591. _json["用户名"] = res[i].username;
  592. _json["姓名"] = res[i].alias ? res[i].alias : "";
  593. _json["班级"] = res[i].classid ? res[i].classid : "";
  594. array.push(_json);
  595. }
  596. var XLSX = require("xlsx");
  597. const workbook = XLSX.utils.book_new(); //创建一个新的工作簿对象
  598. let ws = XLSX.utils.json_to_sheet(array); //将json对象数组转化成工作表
  599. ws["!cols"] = [
  600. //设置每一列的宽度
  601. { wch: 50 },
  602. { wch: 50 },
  603. { wch: 50 },
  604. ];
  605. XLSX.utils.book_append_sheet(workbook, ws, "sheet1"); //把sheet添加到workbook里,第三个参数是sheet名
  606. XLSX.writeFile(workbook, "学生信息.xlsx");
  607. // const wopts = { bookType: "xlsx", bookSST: false, type: "array" };//写入的样式bookType:输出的文件类型,type:输出的数据类型,bookSST: 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
  608. // const wbout = XLSX.write(workbook, wopts);// 浏览器端和node共有的API,实际上node可以直接使用xlsx.writeFile来写入文件,但是浏览器没有该API
  609. // FileSaver.saveAs(new Blob([wbout], { type: "application/octet-stream" }), `${title} demo.xlsx`);//保存文件
  610. this.$message({
  611. message: "导出成功",
  612. type: "success",
  613. });
  614. })
  615. .catch((err) => {
  616. console.error(err);
  617. });
  618. } catch (e) {
  619. console.log(e, e.stack);
  620. }
  621. },
  622. importfxx(obj) {
  623. const loading = this.$loading.service({
  624. background: "rgba(255, 255, 255, 0.7)",
  625. target: document.body,
  626. });
  627. var _$ = $;
  628. this.importCount++;
  629. let _this = this;
  630. // 通过DOM取文件数据
  631. this.file = obj;
  632. var rABS = false; //是否将文件读取为二进制字符串
  633. var f = this.file;
  634. var reader = new FileReader();
  635. //if (!FileReader.prototype.readAsBinaryString) {
  636. FileReader.prototype.readAsBinaryString = function (f) {
  637. var binary = "";
  638. var rABS = false; //是否将文件读取为二进制字符串
  639. var pt = this;
  640. var wb; //读取完成的数据
  641. var outdata;
  642. var reader = new FileReader();
  643. reader.onload = function (e) {
  644. var bytes = new Uint8Array(reader.result);
  645. var length = bytes.byteLength;
  646. for (var i = 0; i < length; i++) {
  647. binary += String.fromCharCode(bytes[i]);
  648. }
  649. var XLSX = require("xlsx");
  650. if (rABS) {
  651. wb = XLSX.read(btoa(fixdata(binary)), {
  652. //手动转化
  653. type: "base64",
  654. });
  655. } else {
  656. wb = XLSX.read(binary, {
  657. type: "binary",
  658. });
  659. }
  660. outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); //outdata就是你想要的东西
  661. this.da = [...outdata];
  662. let arr = [];
  663. this.da.map((v) => {
  664. let obj = {};
  665. let a = "";
  666. var num = "";
  667. for (var cj = 0; cj < 3; cj++) {
  668. num += Math.floor(Math.random() * 10);
  669. }
  670. a =
  671. pinyin.getFullChars(v["学生姓名"]).toLowerCase() +
  672. num +
  673. "@cocorobo.cc";
  674. obj.sId = v["学号"];
  675. obj.name = v["学生姓名"];
  676. obj.mail = v["学生账号"] ? v["学生账号"] : a;
  677. obj.phone = v["学生手机号"];
  678. obj.class = v["班级"];
  679. arr.push(obj);
  680. });
  681. console.log(arr);
  682. let _b = 1;
  683. for (var i = 0; i < arr.length; i++) {
  684. let item = arr[i];
  685. if (item.class === "") {
  686. _b = 1;
  687. _this.$message.error("学生班级不能为空,请重新上传");
  688. break;
  689. } else if (item.name === "") {
  690. _b = 1;
  691. _this.$message.error("学生姓名不能为空,请重新上传");
  692. break;
  693. } else if (item.sId === "") {
  694. _b = 1;
  695. _this.$message.error("学生学号不能为空,请重新上传");
  696. }
  697. // else if (item.phone === "") {
  698. // _b = 1;
  699. // _this.$message.error("学生手机号不能为空,请重新上传");
  700. // break;
  701. // } else if (!/^[1][3,4,5,7,8][0-9]{9}$/.test(item.phone)) {
  702. // _b = 1;
  703. // _this.$message.error("有学生手机号格式不正确,请重新上传");
  704. // break;
  705. // }
  706. else if (item.mail === "") {
  707. _b = 1;
  708. _this.$message.error("学生账号不能为空,请重新上传");
  709. break;
  710. } else if (
  711. !/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/.test(
  712. item.mail
  713. )
  714. ) {
  715. _b = 1;
  716. _this.$message.error("有学生账号格式不正确,请重新上传");
  717. break;
  718. }
  719. // else if (item.school === "") {
  720. // _b = 1;
  721. // _this.$message.error("学生学校不能为空,请重新上传");
  722. // break;
  723. // }
  724. // else if (item.sex === "") {
  725. // _b = 1;
  726. // _this.$message.error("学生性别不能为空,请重新上传");
  727. // break;
  728. // }
  729. // if (item.class != "") {
  730. // let _a;
  731. // let params = {
  732. // className: item.class,
  733. // };
  734. // _$.ajax({
  735. // url: _this.$store.state.api + "selectC", //url路径
  736. // type: "GET", //GET
  737. // async: false, //或false,是否异步
  738. // data: params,
  739. // timeout: 5000, //超时时间
  740. // dataType: "json", //返回的数据格式:
  741. // beforeSend: function (xhr) {},
  742. // success: function (res, textStatus, jqXHR) {
  743. // if (res[0].length == 0) {
  744. // _a = 1;
  745. // _this.$message.error(
  746. // "有学生班级不存在,请去添加后并重新上传"
  747. // );
  748. // } else {
  749. // item.classid = res[0][0].id;
  750. // }
  751. // },
  752. // error: function (xhr, textStatus) {
  753. // console.log(textStatus);
  754. // },
  755. // complete: function () {},
  756. // });
  757. // if (_a == 1) {
  758. // _b = 1;
  759. // break;
  760. // }
  761. // }
  762. // if (item.school != "") {
  763. // let _a;
  764. // let params = {
  765. // schoolName: item.school,
  766. // };
  767. // _$.ajax({
  768. // url: _this.$store.state.api + "selectS", //url路径
  769. // type: "GET", //GET
  770. // async: false, //或false,是否异步
  771. // data: params,
  772. // timeout: 5000, //超时时间
  773. // dataType: "json", //返回的数据格式:
  774. // beforeSend: function (xhr) {},
  775. // success: function (res, textStatus, jqXHR) {
  776. // if (res[0].length == 0) {
  777. // _a = 1;
  778. // _this.$message.error(
  779. // "有学生学校不存在,请去添加后并重新上传"
  780. // );
  781. // } else {
  782. // item.schoolid = res[0][0].id;
  783. // }
  784. // },
  785. // error: function (xhr, textStatus) {
  786. // console.log(textStatus);
  787. // },
  788. // complete: function () {},
  789. // });
  790. // if (_a == 1) {
  791. // _b = 1;
  792. // break;
  793. // }
  794. // }
  795. // for (var k = 0; k < arr.length; k++) {
  796. // if (item.phone != "") {
  797. // let params = { un: item.phone };
  798. // let _a;
  799. // _$.ajax({
  800. // url: _this.$store.state.api + "findPhone", //url路径
  801. // type: "GET", //GET
  802. // async: false, //或false,是否异步
  803. // data: params,
  804. // timeout: 5000, //超时时间
  805. // dataType: "json", //返回的数据格式:
  806. // beforeSend: function (xhr) {},
  807. // success: function (res, textStatus, jqXHR) {
  808. // if (res[0].length > 0) {
  809. // _this.$message.error("有学生手机号码已被注册");
  810. // _a = 1;
  811. // }
  812. // },
  813. // error: function (xhr, textStatus) {
  814. // console.log(textStatus);
  815. // },
  816. // complete: function () {},
  817. // });
  818. // if (_a == 1) {
  819. // _b = 1;
  820. // break;
  821. // }
  822. // }
  823. // if (item.mail != "") {
  824. // let params = { un: item.mail };
  825. // let _a;
  826. // _$.ajax({
  827. // url: _this.$store.state.api + "findMail", //url路径
  828. // type: "GET", //GET
  829. // async: false, //或false,是否异步
  830. // data: params,
  831. // timeout: 5000, //超时时间
  832. // dataType: "json", //返回的数据格式:
  833. // beforeSend: function (xhr) {},
  834. // success: function (res, textStatus, jqXHR) {
  835. // if (res[0].length > 0) {
  836. // _this.$message.error("有学生账号已被注册");
  837. // _a = 1;
  838. // }
  839. // },
  840. // error: function (xhr, textStatus) {
  841. // console.log(textStatus);
  842. // },
  843. // complete: function () {},
  844. // });
  845. // if (_a == 1) {
  846. // _b = 1;
  847. // break;
  848. // }
  849. // }
  850. // if (item.sId != "") {
  851. // let params = { un: item.sId };
  852. // let _a;
  853. // _$.ajax({
  854. // url: _this.$store.state.api + "findSid", //url路径
  855. // type: "GET", //GET
  856. // async: false, //或false,是否异步
  857. // data: params,
  858. // timeout: 5000, //超时时间
  859. // dataType: "json", //返回的数据格式:
  860. // beforeSend: function (xhr) {},
  861. // success: function (res, textStatus, jqXHR) {
  862. // if (res[0].length > 0) {
  863. // _this.$message.error("有学生学号重复");
  864. // _a = 1;
  865. // }
  866. // },
  867. // error: function (xhr, textStatus) {
  868. // console.log(textStatus);
  869. // },
  870. // complete: function () {},
  871. // });
  872. // if (_a == 1) {
  873. // _b = 1;
  874. // break;
  875. // }
  876. // }
  877. // _b = 2;
  878. // }
  879. // }
  880. // if (_b == 2) {
  881. // for (var i = 0; i < arr.length; i++) {
  882. // let _i = i;
  883. // let item = arr[i];
  884. // let params = [
  885. // {
  886. // alias: item.name,
  887. // username: item.mail,
  888. // userpassword: 123456,
  889. // oid: _this.oid,
  890. // ph: item.phone,
  891. // cid: item.class,
  892. // },
  893. // ];
  894. // _this.ajax
  895. // .post(_this.$store.state.api + "batchRegistration", params)
  896. // .then((res) => {
  897. // let params = [
  898. // {
  899. // userid: res.data.uid,
  900. // username: item.name,
  901. // sId: item.sId,
  902. // type: 2,
  903. // oid: res.data.oid,
  904. // phone: res.data.ph ? res.data.ph : "",
  905. // cid: res.data.cid ? res.data.cid : "",
  906. // intro: "",
  907. // sex: "0",
  908. // },
  909. // ];
  910. // _this.ajax
  911. // .post(_this.$store.state.api + "updateUserByEdu", params)
  912. // .then((res) => {
  913. // console.log(res);
  914. // })
  915. // .catch((err) => {
  916. // console.error(err);
  917. // });
  918. // loading.close();
  919. // // _this.$message({
  920. // // message: "新增成功",
  921. // // type: "success",
  922. // // });
  923. // _this.getStudent();
  924. // // if (_i == arr.length - 1) {
  925. // // loading.close();
  926. // // _this.$message({
  927. // // message: "上传成功",
  928. // // type: "success",
  929. // // });
  930. // // _this.getStudent();
  931. // // }
  932. // })
  933. // .catch((err) => {
  934. // _this.$message.error("上传失败");
  935. // console.error(err);
  936. // });
  937. // }
  938. // } else {
  939. // loading.close();
  940. }
  941. let z = 2;
  942. let newArr = JSON.stringify(arr);
  943. let params = [
  944. {
  945. arr: newArr,
  946. userpassword: 123456,
  947. oid: _this.oid,
  948. },
  949. ];
  950. _this.ajax
  951. .post(_this.$store.state.api + "batchRegistrationMore", params)
  952. .then((res) => {
  953. if (res.data.type == 1) {
  954. _this.$message.error("有学生手机号码已被注册");
  955. z = 1;
  956. }
  957. if (res.data.type == 2) {
  958. _this.$message.error("有学生账号已被注册");
  959. z = 1;
  960. }
  961. if (res.data.type == 3) {
  962. _this.$message.error("有学生学号重复");
  963. z = 1;
  964. }
  965. if (z == 2) {
  966. _this.$message({
  967. message: "新增成功",
  968. type: "success",
  969. });
  970. _this.getStudent();
  971. }
  972. loading.close();
  973. })
  974. .catch((err) => {
  975. console.error(err);
  976. });
  977. _this.fileListUpload = [];
  978. };
  979. reader.readAsArrayBuffer(f);
  980. };
  981. if (rABS) {
  982. reader.readAsArrayBuffer(f);
  983. } else {
  984. reader.readAsBinaryString(f);
  985. }
  986. },
  987. getSchoolName() {
  988. let params = {
  989. oid: this.oid,
  990. };
  991. this.ajax
  992. .get(this.$store.state.api + "selectSchoolName2", params)
  993. .then((res) => {
  994. this.schoolName = res.data[0][0].name;
  995. })
  996. .catch((err) => {
  997. console.error(err);
  998. });
  999. },
  1000. deleteStudent(id, state) {
  1001. state = 0;
  1002. let params = [{ uid: id, state: state }];
  1003. this.$confirm("确定" + "删除" + "此学生吗?", "提示", {
  1004. confirmButtonText: "确定",
  1005. cancelButtonText: "取消",
  1006. type: "warning",
  1007. })
  1008. .then(() => {
  1009. this.ajax
  1010. .post(this.$store.state.api + "deleteStudent", params)
  1011. .then((res) => {
  1012. this.$message({
  1013. message: "操作成功",
  1014. type: "success",
  1015. });
  1016. this.getStudent();
  1017. })
  1018. .catch((err) => {
  1019. this.$message.error("操作失败");
  1020. console.error(err);
  1021. });
  1022. })
  1023. .catch(() => { });
  1024. },
  1025. iniPassword(id) {
  1026. this.$confirm("确定" + "初始化" + "此学生的密码吗?", "提示", {
  1027. confirmButtonText: "确定",
  1028. cancelButtonText: "取消",
  1029. type: "warning",
  1030. })
  1031. .then(() => {
  1032. let params = [
  1033. {
  1034. uid: id,
  1035. pa: 123456,
  1036. },
  1037. ];
  1038. this.ajax
  1039. .post(this.$store.state.api + "iniPassword", params)
  1040. .then((res) => {
  1041. this.$message({
  1042. message: "初始化密码成功!",
  1043. type: "success",
  1044. });
  1045. })
  1046. .catch((err) => {
  1047. console.error(err);
  1048. });
  1049. })
  1050. .catch(() => { });
  1051. },
  1052. updateStudentA(res) {
  1053. this.userinfo = JSON.parse(JSON.stringify(res));
  1054. this.userinfoA = JSON.parse(JSON.stringify(res));
  1055. this.userinfo.classid = this.userinfo.classid.split(",");
  1056. this.dialogVisibleUpdate = true;
  1057. },
  1058. updateStudent() {
  1059. if (this.userinfo.name === "") {
  1060. this.$message.error("学生姓名不能为空");
  1061. return;
  1062. } else if (!this.userinfo.classid) {
  1063. this.$message.error("请为学生选择班级");
  1064. return;
  1065. } else if (
  1066. this.userinfo.phonenumber &&
  1067. !/^[1][3,4,5,7,8][0-9]{9}$/.test(this.userinfo.phonenumber)
  1068. ) {
  1069. this.$message.error("手机号格式不正确");
  1070. return;
  1071. } else if (
  1072. !/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/.test(
  1073. this.userinfo.un
  1074. )
  1075. ) {
  1076. this.$message.error("邮箱格式不正确");
  1077. return;
  1078. }
  1079. if (this.time()) {
  1080. if (this.userinfoA.un != this.userinfo.un) {
  1081. let params = { un: this.userinfo.un };
  1082. this.ajax
  1083. .get(this.$store.state.api + "findMail", params)
  1084. .then((res) => {
  1085. if (res.data[0].length > 0) {
  1086. this.$message.error("此学生账号已被注册");
  1087. } else {
  1088. this.update_Student();
  1089. }
  1090. })
  1091. .catch((err) => {
  1092. console.error(err);
  1093. });
  1094. } else {
  1095. this.update_Student();
  1096. }
  1097. }
  1098. },
  1099. update_Student() {
  1100. let params = [
  1101. {
  1102. userid: this.userinfo.userid,
  1103. username: this.userinfo.un,
  1104. alias: this.userinfo.name,
  1105. ph: this.userinfo.phonenumber,
  1106. sid: this.userinfo.studentid,
  1107. cid: this.userinfo.classid.join(","),
  1108. },
  1109. ];
  1110. this.ajax
  1111. .post(this.$store.state.api + "updateStudentInfo", params)
  1112. .then((res) => {
  1113. this.$message({
  1114. message: "修改成功",
  1115. type: "success",
  1116. });
  1117. this.dialogVisibleUpdate = false;
  1118. this.getStudent();
  1119. })
  1120. .catch((err) => {
  1121. this.isLoading = false;
  1122. this.$message({
  1123. message: "修改失败",
  1124. type: "error",
  1125. });
  1126. console.error(err);
  1127. });
  1128. },
  1129. },
  1130. created() {
  1131. this.page = 1;
  1132. this.getStudent();
  1133. this.getSchoolName();
  1134. this.getClass();
  1135. },
  1136. };
  1137. </script>
  1138. <style scoped>
  1139. .pb_head>span:nth-child(2) {
  1140. font-size: 20px;
  1141. margin-left: 5px;
  1142. color: #828282;
  1143. }
  1144. .pb_head {
  1145. margin: 0 !important;
  1146. width: 100% !important;
  1147. }
  1148. .student_page {
  1149. margin-top: 10px;
  1150. }
  1151. .student_head {
  1152. margin-top: 10px;
  1153. padding-bottom: 10px;
  1154. display: flex;
  1155. justify-content: space-between;
  1156. }
  1157. .head_left {
  1158. display: flex;
  1159. align-items: center;
  1160. line-height: 40px;
  1161. }
  1162. .head_right {
  1163. display: flex;
  1164. flex-direction: row;
  1165. flex-wrap: nowrap;
  1166. align-items: center;
  1167. }
  1168. .student_input>>>.el-input__inner {
  1169. height: 30px;
  1170. width: 190px;
  1171. font-size: 13px;
  1172. padding: 0 10px;
  1173. }
  1174. .student_button {
  1175. color: #fff;
  1176. background: #2268bc;
  1177. width: 60px;
  1178. height: 30px;
  1179. padding: 0 !important;
  1180. font-size: 12px;
  1181. line-height: 30px;
  1182. }
  1183. .head_right>button:nth-child(1) {
  1184. color: #fff;
  1185. background: #2268bc;
  1186. width: 70px;
  1187. height: 30px;
  1188. padding: 0 !important;
  1189. font-size: 12px;
  1190. line-height: 30px;
  1191. }
  1192. .head_right>button:nth-child(2) {
  1193. color: #fff;
  1194. background: #2268bc;
  1195. width: 70px;
  1196. height: 30px;
  1197. padding: 0 !important;
  1198. font-size: 12px;
  1199. line-height: 30px;
  1200. }
  1201. .head_right>div {
  1202. font-size: 12px;
  1203. line-height: 40px;
  1204. margin-left: 10px;
  1205. color: #2a6dbe;
  1206. text-decoration: underline;
  1207. cursor: pointer;
  1208. }
  1209. .student_table>>>.el-table--border td {
  1210. border-right: 0px !important;
  1211. }
  1212. .student_table>>>.el-table,
  1213. .student_table>>>.el-table__body-wrapper {
  1214. height: auto !important;
  1215. }
  1216. .el-table>>>.even_row {
  1217. background-color: #f1f1f1 !important;
  1218. }
  1219. .de_button {
  1220. color: #fff;
  1221. background: #5190fd;
  1222. width: 50px;
  1223. height: 25px;
  1224. padding: 0 !important;
  1225. font-size: 12px;
  1226. line-height: 25px;
  1227. }
  1228. .add_student>>>.el-dialog__header {
  1229. padding: 20px 20px 10px;
  1230. text-align: center;
  1231. background: #32455b;
  1232. }
  1233. .add_student>>>.el-dialog__title {
  1234. font-size: 14px !important;
  1235. color: #fff !important;
  1236. }
  1237. .add_student>>>.el-dialog__headerbtn {
  1238. font-size: 20px !important;
  1239. }
  1240. .add_student>>>.el-form-item__label {
  1241. margin-left: 65px;
  1242. }
  1243. .add_student>>>.el-form-item {
  1244. display: flex;
  1245. }
  1246. .add_student>>>.el-form-item__content {
  1247. margin: 0 !important;
  1248. }
  1249. .add_input {
  1250. width: 365px;
  1251. }
  1252. .add_student>>>.el-dialog__footer {
  1253. text-align: center !important;
  1254. }
  1255. .right {
  1256. width: 250px;
  1257. color: #fff;
  1258. background: #0e72e6;
  1259. margin-bottom: 20px;
  1260. }
  1261. .header-title {
  1262. display: flex;
  1263. }
  1264. .logoImg {
  1265. width: 30px;
  1266. }
  1267. .logoImg>img {
  1268. width: 100%;
  1269. height: 100%;
  1270. }
  1271. .title_add_student {
  1272. margin: 0 auto;
  1273. color: #fff;
  1274. }
  1275. .upload-demo {
  1276. line-height: 0px !important;
  1277. }
  1278. .upload-demo>>>.el-button {
  1279. color: #fff;
  1280. background: #2268bc;
  1281. width: 70px;
  1282. height: 30px;
  1283. padding: 0 !important;
  1284. font-size: 12px;
  1285. line-height: 0 !important;
  1286. }
  1287. .userImg {
  1288. display: flex;
  1289. flex-direction: row;
  1290. justify-content: center;
  1291. align-items: center;
  1292. }
  1293. .tx {
  1294. width: 40px;
  1295. margin-right: 10px;
  1296. }
  1297. .delete {
  1298. width: 25px;
  1299. height: 25px;
  1300. cursor: pointer;
  1301. margin-left: 10px;
  1302. }
  1303. .tx>img,
  1304. .delete>img {
  1305. width: 100%;
  1306. height: 100%;
  1307. }
  1308. .newCss {
  1309. display: flex;
  1310. flex-direction: row;
  1311. flex-wrap: nowrap;
  1312. align-items: baseline;
  1313. }
  1314. .student_input.el-input {
  1315. width: auto;
  1316. }
  1317. .student_input {
  1318. margin-right: 10px;
  1319. }
  1320. .student_input>>>.el-input__icon {
  1321. line-height: unset;
  1322. }
  1323. .btnBox {
  1324. display: flex;
  1325. align-items: center;
  1326. }
  1327. .sub_head {
  1328. position: relative;
  1329. }
  1330. .sub_head::after {
  1331. content: "";
  1332. width: 100%;
  1333. background: #5a9cea;
  1334. height: 2px;
  1335. position: absolute;
  1336. left: 0;
  1337. bottom: -10px;
  1338. }
  1339. .subClick {
  1340. /* font-size: 16px; */
  1341. font-size: 26px;
  1342. cursor: pointer;
  1343. /* margin-left: 17.5px; */
  1344. /* color: #ab582f; */
  1345. /* color: #409eff; */
  1346. color: #999;
  1347. }
  1348. .subClick:hover {
  1349. color: #000;
  1350. }
  1351. .sub_head + .subClick,
  1352. .subClick + .subClick,
  1353. .subClick + .sub_head{
  1354. margin-left: 17.5px;
  1355. }
  1356. </style>