星火管控前端
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

userManage.vue 31KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. <template>
  2. <div class="main_root">
  3. <div class="schoolInfo">
  4. <div
  5. class="schoolname"
  6. :class="[
  7. curClass.id === schoolInfo.id && curClass.type === schoolInfo.type
  8. ? 'active'
  9. : ''
  10. ]"
  11. @click="selectClass(schoolInfo)"
  12. >
  13. {{ schoolInfo.name }}
  14. </div>
  15. <div class="class_list">
  16. <div v-for="item in schoolInfo.children" :key="item.id">
  17. <div
  18. :class="[
  19. 'class_item',
  20. curClass.id === item.id && curClass.type === item.type
  21. ? 'active'
  22. : ''
  23. ]"
  24. :title="item.name"
  25. @click="selectClass(item)"
  26. >
  27. {{ item.name }}
  28. </div>
  29. <span
  30. @click="toOpenMenu(item, $event)"
  31. class="ivu-icon iconfont icon-sandian"
  32. ></span>
  33. </div>
  34. </div>
  35. </div>
  36. <div class="user_list">
  37. <div class="search_header">
  38. <div class="search_left">
  39. <Select
  40. :transfer="true"
  41. v-model="searchForm.care"
  42. style="width: 140px"
  43. @on-change="searchList()"
  44. >
  45. <Option v-for="item in care_list" :value="item.id" :key="item.id">{{
  46. item.title
  47. }}</Option>
  48. </Select>
  49. <Select
  50. :transfer="true"
  51. v-model="searchForm.enabled"
  52. style="width: 140px; margin: 0 10px"
  53. @on-change="searchList()"
  54. >
  55. <Option
  56. v-for="item in enabled_list"
  57. :value="item.id"
  58. :key="item.id"
  59. >{{ item.title }}</Option
  60. >
  61. </Select>
  62. <Select
  63. :transfer="true"
  64. v-model="searchForm.control"
  65. style="width: 140px; margin-right: 10px"
  66. @on-change="searchList()"
  67. >
  68. <Option
  69. v-for="item in control_list"
  70. :value="item.id"
  71. :key="item.id"
  72. >{{ item.title }}</Option
  73. >
  74. </Select>
  75. <Input
  76. v-model="searchForm.username"
  77. placeholder="请输入姓名"
  78. search
  79. @on-search="searchList()"
  80. style="width: 150px"
  81. />
  82. </div>
  83. <div>
  84. <Button type="primary" class="primary_btn" @click="userImport()"
  85. >用户导入</Button
  86. >
  87. <Button
  88. style="margin: 0 10px"
  89. type="primary"
  90. class="primary_btn"
  91. @click="userExport()"
  92. >用户导出</Button
  93. >
  94. <Button type="primary" class="primary_btn" @click="toAdd()"
  95. >新建</Button
  96. >
  97. </div>
  98. </div>
  99. <div class="table_wrap">
  100. <Table :columns="columns" :data="searchForm.list">
  101. <template slot-scope="{ row }" slot="loginname">
  102. <span
  103. v-if="row.care === 1"
  104. style="color: #fcc138"
  105. class="ivu-icon iconfont icon-guanzhu-yiguanzhu"
  106. ></span>
  107. {{ row.loginname }}
  108. </template>
  109. <template slot-scope="{ row }" slot="enabled">
  110. <i-switch
  111. size="large"
  112. v-model="row.enabled"
  113. :true-value="1"
  114. :false-value="2"
  115. @on-change="enabledChange(row)"
  116. >
  117. <span slot="open">启用</span>
  118. <span slot="close">禁用</span>
  119. </i-switch>
  120. </template>
  121. <template slot-scope="{ row }" slot="actionSlot">
  122. <div class="action_list">
  123. <div class="action_del" @click="toDel(row)">删除</div>
  124. <div class="action_success" @click="toCare(row)">
  125. <span v-if="row.care === 2">重点关注</span>
  126. <span v-else>取消关注</span>
  127. </div>
  128. </div>
  129. </template>
  130. </Table>
  131. </div>
  132. <div class="page_wrap">
  133. <Page
  134. :transfer="true"
  135. :total="searchForm.total"
  136. :current="searchForm.page"
  137. :page-size="searchForm.size"
  138. :page-size-opts="[10, 20, 40, 60]"
  139. @on-change="pageChange"
  140. @on-page-size-change="pageSizeChange"
  141. show-total
  142. show-sizer
  143. ></Page>
  144. </div>
  145. </div>
  146. <!-- 更多菜单弹窗 -->
  147. <div
  148. class="more_menu"
  149. ref="moreMenuRef"
  150. @mousedown.stop
  151. @contextmenu.stop.prevent
  152. @mousewheel.stop
  153. >
  154. <div @click="toSelectMenuItem(1)" class="menu_group">编辑</div>
  155. <div @click="toSelectMenuItem(2)" class="menu_group">删除</div>
  156. </div>
  157. <!-- 编辑班级 -->
  158. <Modal
  159. v-model="classInfo.show"
  160. :mask-closable="false"
  161. class="modal_tip"
  162. title="编辑"
  163. >
  164. <Form
  165. v-if="classInfo.show"
  166. ref="classInfo"
  167. :model="classInfo"
  168. :rules="rules"
  169. :label-width="110"
  170. >
  171. <FormItem label="班级名称" prop="classname">
  172. <Input
  173. v-model.trim="classInfo.classname"
  174. placeholder="请输入班级名称"
  175. ></Input>
  176. </FormItem>
  177. </Form>
  178. <div slot="footer" style="text-align: right">
  179. <Button @click="exitInfo.show = false">取消</Button>
  180. <Button @click="saveclassInfo()" type="primary" class="primary_btn"
  181. >保存</Button
  182. >
  183. </div>
  184. </Modal>
  185. <!-- 已存在列表 -->
  186. <Modal
  187. v-model="exitInfo.show"
  188. :mask-closable="false"
  189. class="exit_modal modal1"
  190. title="提示"
  191. >
  192. <div class="exit">
  193. <div>
  194. <div v-if="exitInfo.studentsExisted.length > 0">
  195. 以下学生信息已存在
  196. <Table border :columns="columns2" :data="exitInfo.studentsExisted">
  197. <template slot-scope="{ row }" slot="usersex">
  198. <span>
  199. {{
  200. row.usersex == 1 ? "男" : row.usersex == 2 ? "女" : "未知"
  201. }}
  202. </span>
  203. </template>
  204. </Table>
  205. </div>
  206. <div v-if="exitInfo.usersExisted.length > 0">
  207. 已存在非本校账号列表
  208. <Table border :columns="columns2" :data="exitInfo.usersExisted">
  209. <template slot-scope="{ row }" slot="usersex">
  210. <span>
  211. {{
  212. row.usersex == 1 ? "男" : row.usersex == 2 ? "女" : "未知"
  213. }}
  214. </span>
  215. </template>
  216. </Table>
  217. </div>
  218. </div>
  219. </div>
  220. </Modal>
  221. <!-- 导入 -->
  222. <Modal
  223. :mask-closable="false"
  224. v-model="importInfo.show"
  225. class="modal_tip"
  226. title="导入"
  227. >
  228. <Upload
  229. v-if="importInfo.show"
  230. type="drag"
  231. action
  232. accept=".xls,.xlsx"
  233. :before-upload="handleUpload"
  234. >
  235. <div style="padding: 30px 0; background: #f8f8f9">
  236. <Button type="primary" class="primary_btn" style="font-size: 16px">
  237. <Icon type="ios-cloud-upload-outline" size="18"></Icon>上传excel
  238. </Button>
  239. <div style="margin-top: 10px; color: #999">支持上传xlsx/xls文件</div>
  240. </div>
  241. </Upload>
  242. <div v-if="importInfo.file" class="files_list">
  243. {{ importInfo.file.name }}
  244. </div>
  245. <div class="import_tip">
  246. 导入数据需按照模板填写信息,
  247. <span class="theme_color" @click="download()">下载表格模板</span>
  248. </div>
  249. <div slot="footer">
  250. <Button @click="importInfo.show = false">取消</Button>
  251. <Button
  252. @click="ok_import"
  253. class="primary_btn"
  254. :loading="wait_flag"
  255. type="primary"
  256. >保存</Button
  257. >
  258. </div>
  259. </Modal>
  260. <!-- 新建 -->
  261. <Modal
  262. class="modal1"
  263. :mask-closable="false"
  264. v-model="addInfo.show"
  265. title="新建"
  266. >
  267. <Form
  268. v-if="addInfo.show"
  269. ref="addForm"
  270. :model="addInfo"
  271. :rules="rules"
  272. :label-width="110"
  273. inline
  274. >
  275. <FormItem label="姓名" prop="username" style="width: calc(50% - 10px)">
  276. <Input v-model="addInfo.username" placeholder="请输入姓名"></Input>
  277. </FormItem>
  278. <FormItem label="性别" style="width: calc(50% - 10px)">
  279. <RadioGroup v-model="addInfo.usersex">
  280. <Radio :label="1">男</Radio>
  281. <Radio :label="2">女</Radio>
  282. <Radio :label="0">未知</Radio>
  283. </RadioGroup>
  284. </FormItem>
  285. <FormItem label="密码" prop="loginpwd" style="width: calc(50% - 10px)">
  286. <Input v-model="addInfo.loginpwd" placeholder="请输入密码"></Input>
  287. </FormItem>
  288. <FormItem
  289. label="确认密码"
  290. prop="loginpwd1"
  291. style="width: calc(50% - 10px)"
  292. >
  293. <Input
  294. v-model="addInfo.loginpwd1"
  295. placeholder="请输入确认密码"
  296. ></Input>
  297. </FormItem>
  298. <FormItem label="登录名" prop="loginname" style="width: 100%">
  299. <Input v-model="addInfo.loginname" placeholder="请输入登录名"></Input>
  300. </FormItem>
  301. <FormItem label="班级" class="require" style="width: 100%">
  302. <Select
  303. v-model="addInfo.classid"
  304. placeholder="请选择班级"
  305. style="width: 300px"
  306. @on-change="classChange()"
  307. >
  308. <template v-if="schoolInfo.children.length > 0">
  309. <Option
  310. v-for="item in schoolInfo.children"
  311. :value="item.id"
  312. :key="item.id"
  313. >{{ item.name }}</Option
  314. >
  315. </template>
  316. </Select>
  317. </FormItem>
  318. <FormItem label="状态" style="width: 100%">
  319. <RadioGroup v-model="addInfo.enabled">
  320. <Radio :label="1">启用</Radio>
  321. <Radio :label="2">禁用</Radio>
  322. </RadioGroup>
  323. </FormItem>
  324. <FormItem label="学号" style="width: 100%">
  325. <Input v-model="addInfo.studentno" placeholder="请输入学号"></Input>
  326. </FormItem>
  327. <FormItem label="手机号码" style="width: 100%">
  328. <Input
  329. v-model="addInfo.userphone"
  330. placeholder="请输入手机号码"
  331. ></Input>
  332. </FormItem>
  333. <FormItem label="身份证号码" style="width: 100%">
  334. <Input
  335. v-model="addInfo.cardid"
  336. placeholder="请输入身份证号码"
  337. ></Input>
  338. </FormItem>
  339. </Form>
  340. <div
  341. slot="footer"
  342. style="
  343. display: flex;
  344. justify-content: space-between;
  345. align-items: center;
  346. "
  347. >
  348. <div style="color: #b50000">
  349. 注:密码必须是6-16位的大小写英文字母、数字组合。
  350. </div>
  351. <div>
  352. <Button @click="addInfo.show = false">取消</Button>
  353. <Button @click="saveAddInfo()" type="primary" class="primary_btn"
  354. >保存</Button
  355. >
  356. </div>
  357. </div>
  358. </Modal>
  359. <Spin fix v-if="showLoading" style="background-color: transparent">
  360. <Icon type="ios-loading" size="18" class="demo-spin-icon-load"></Icon>
  361. <div>加载中</div>
  362. </Spin>
  363. </div>
  364. </template>
  365. <script>
  366. import {
  367. class_delete,
  368. class_edit,
  369. class_list,
  370. user_care,
  371. user_delete,
  372. user_disabled,
  373. user_enable,
  374. user_export,
  375. user_import,
  376. user_list,
  377. user_un_care
  378. } from "@/api/school";
  379. import { user_add, user_edit } from "@/api/school";
  380. import { exportToExcel } from "@/utils/exportToExcel";
  381. import { generateRandomString, pwdCheck, reg } from "@/utils";
  382. export default {
  383. data() {
  384. const classnameCheck = async (rule, value, callback) => {
  385. if (value) {
  386. let flag = this.schoolInfo.children.some((v) => {
  387. return (
  388. v.name === this.classInfo.classname &&
  389. v.id != this.classInfo.classid
  390. );
  391. });
  392. if (flag) {
  393. return callback(new Error("班级名称已存在!"));
  394. } else {
  395. callback();
  396. }
  397. } else {
  398. return callback(new Error("班级名称不能为空!"));
  399. }
  400. };
  401. // 重复密码验证
  402. const pwdAgainCheck = async (rule, value, callback) => {
  403. if (!reg.test(value)) {
  404. return callback(new Error("密码格式不正确!"));
  405. }
  406. if (this.addInfo.loginpwd != value) {
  407. return callback(new Error("两次输入密码不一致!"));
  408. }
  409. callback();
  410. };
  411. return {
  412. userInfo: {},
  413. importInfo: {
  414. show: false,
  415. file: null
  416. },
  417. exitInfo: {
  418. show: false,
  419. studentsExisted: [],
  420. usersExisted: []
  421. },
  422. columns2: [
  423. {
  424. title: "姓名",
  425. key: "username",
  426. minWidth: 140,
  427. align: "center"
  428. },
  429. {
  430. title: "登录名",
  431. key: "loginname",
  432. minWidth: 140,
  433. align: "center"
  434. },
  435. {
  436. title: "性别",
  437. key: "usersex",
  438. align: "center",
  439. slot: "usersex"
  440. }
  441. ],
  442. form_data: null,
  443. wait_flag: false,
  444. showLoading: false,
  445. care_list: [
  446. { id: 0, title: "请选择关注状态" },
  447. { id: 1, title: "重点关注" },
  448. { id: 2, title: "不关注" }
  449. ],
  450. enabled_list: [
  451. { id: 0, title: "请选择启动状态" },
  452. { id: 1, title: "启用" },
  453. { id: 2, title: "禁用" }
  454. ],
  455. control_list: [
  456. { id: 0, title: "请选择管控状态" },
  457. { id: 1, title: "管控中" },
  458. { id: 2, title: "解除管控" }
  459. ],
  460. curClass: {
  461. id: 0,
  462. type: 1,
  463. name: ""
  464. },
  465. addInfo: {
  466. show: false,
  467. userid: null,
  468. username: "",
  469. loginname: "",
  470. loginpwd: "",
  471. loginpwd1: "",
  472. classid: "",
  473. classname: "",
  474. schoolid: null,
  475. regionid: null,
  476. enabled: 1,
  477. studentno: "",
  478. userphone: "",
  479. cardid: ""
  480. },
  481. rules: {
  482. classname: [
  483. {
  484. required: true,
  485. validator: classnameCheck,
  486. trigger: "blur"
  487. }
  488. ],
  489. username: [
  490. {
  491. required: true,
  492. message: "请输入姓名",
  493. trigger: "blur"
  494. }
  495. ],
  496. loginname: [
  497. {
  498. required: true,
  499. message: "请输入请输入登录名",
  500. trigger: "blur"
  501. }
  502. ],
  503. loginpwd: [
  504. {
  505. required: true,
  506. validator: pwdCheck,
  507. trigger: "blur"
  508. }
  509. ],
  510. loginpwd1: [
  511. {
  512. required: true,
  513. validator: pwdAgainCheck,
  514. trigger: "blur"
  515. }
  516. ]
  517. },
  518. searchForm: {
  519. page: 1,
  520. size: 10,
  521. schoolid: 1,
  522. classid: 0,
  523. care: 0,
  524. enabled: 0,
  525. control: 0,
  526. username: "",
  527. list: [],
  528. tital: 0
  529. },
  530. columns: [
  531. {
  532. title: "序号",
  533. align: "center",
  534. width: 70,
  535. render: (h, params) => {
  536. return h(
  537. "span",
  538. params.index +
  539. (this.searchForm.page - 1) * this.searchForm.size +
  540. 1
  541. );
  542. }
  543. },
  544. {
  545. title: "登录名",
  546. slot: "loginname",
  547. align: "center"
  548. },
  549. {
  550. title: "姓名",
  551. key: "username",
  552. align: "center",
  553. width: 140
  554. },
  555. {
  556. title: "班级",
  557. key: "classname",
  558. align: "center",
  559. width: 140
  560. },
  561. {
  562. title: "状态",
  563. slot: "enabled",
  564. width: 100,
  565. align: "center"
  566. },
  567. {
  568. title: "最后登录时间",
  569. key: "lasttime",
  570. align: "center",
  571. width: 180
  572. },
  573. {
  574. title: "操作",
  575. slot: "actionSlot",
  576. width: 240,
  577. align: "center"
  578. }
  579. ],
  580. classInfo: {},
  581. selectedModel: {},
  582. schoolInfo: {
  583. children: [],
  584. name: ""
  585. }
  586. };
  587. },
  588. computed: {
  589. powerParams() {
  590. return this.$store.getters.powerParams;
  591. }
  592. },
  593. created() {
  594. this.userInfo = JSON.parse(
  595. localStorage.getItem("xh_control_userInfo")
  596. ).content;
  597. this.init();
  598. this.searchList();
  599. },
  600. methods: {
  601. saveclassInfo() {
  602. this.$refs.classInfo.validate((valid) => {
  603. if (valid) {
  604. this.showLoading = true;
  605. class_edit({
  606. classid: this.classInfo.classid,
  607. classname: this.classInfo.classname,
  608. rversion: this.classInfo.rversion
  609. }).then((res) => {
  610. this.showLoading = false;
  611. if (res.code === 0) {
  612. if (this.classInfo.classid === this.curClass.id) {
  613. this.curClass.name = this.classInfo.classname;
  614. }
  615. this.classInfo.show = false;
  616. this.init();
  617. this.$Message.success(res.msg);
  618. } else {
  619. this.$Message.error(res.msg);
  620. }
  621. });
  622. }
  623. });
  624. },
  625. toSelectMenuItem(type) {
  626. this.removeMoreMenu();
  627. //type 1编辑 2删除
  628. if (type === 1) {
  629. this.classInfo = {
  630. show: true,
  631. classid: this.selectedModel.id,
  632. rversion: this.selectedModel.rversion,
  633. classname: this.selectedModel.name
  634. };
  635. } else {
  636. this.$Modal.confirm({
  637. title: "提示",
  638. content: "您确定删除【" + this.selectedModel.name + "】吗?",
  639. onOk: () => {
  640. class_delete({
  641. classid: this.selectedModel.id,
  642. rversion: this.selectedModel.rversion
  643. }).then((res) => {
  644. if (res.code === 0) {
  645. this.init();
  646. this.$Message.success(res.msg);
  647. } else {
  648. this.$Message.error(res.msg);
  649. }
  650. });
  651. },
  652. onCancel: () => {}
  653. });
  654. }
  655. },
  656. // 打开弹窗菜单
  657. toOpenMenu(Item, event) {
  658. this.selectClass(Item);
  659. if (!this.$refs.moreMenuRef) {
  660. return;
  661. }
  662. this.selectedModel = Item;
  663. let _clientX = event.clientX;
  664. let _clientY = event.clientY;
  665. this.$refs.moreMenuRef.style.display = `block`;
  666. this.$nextTick(() => {
  667. let _bodyHeight = document.body.clientHeight;
  668. let _domHeight = this.$refs.moreMenuRef.getBoundingClientRect().height;
  669. this.$refs.moreMenuRef.style.left = `${_clientX - 105}px`;
  670. if (_clientY + _domHeight > _bodyHeight) {
  671. this.$refs.moreMenuRef.style.top = `${_bodyHeight - _domHeight}px`;
  672. } else {
  673. this.$refs.moreMenuRef.style.top = `${_clientY}px`;
  674. }
  675. });
  676. },
  677. // 隐藏弹窗菜单
  678. removeMoreMenu() {
  679. if (!this.$refs.moreMenuRef) {
  680. return;
  681. }
  682. this.$refs.moreMenuRef.style.display = `none`;
  683. this.$refs.moreMenuRef.style.left = `-9999px`;
  684. this.$refs.moreMenuRef.style.top = `-9999px`;
  685. },
  686. classChange() {
  687. if (this.schoolInfo.children.length === 0) {
  688. return;
  689. }
  690. let classInfo = this.schoolInfo.children.filter(
  691. (v) => v.id === this.addInfo.classid
  692. )[0];
  693. this.addInfo.classname = classInfo.name;
  694. },
  695. download() {
  696. //下载模版
  697. let url = "../../../../doc/student.xls";
  698. const a = document.createElement("a"); // 创建a标签
  699. a.setAttribute("download", "学生信息模版"); // download属性
  700. a.setAttribute("href", url); // href链接
  701. a.click(); // 自执行点击事件
  702. },
  703. //确定导入
  704. ok_import() {
  705. if (!this.importInfo.file) {
  706. this.$Message.error("请选择上传文件");
  707. return;
  708. }
  709. this.wait_flag = true; //showLoading
  710. let that = this;
  711. user_import(this.form_data)
  712. .then((res) => {
  713. this.wait_flag = false;
  714. if (res.code == 0) {
  715. this.importInfo = {
  716. show: false,
  717. file: null
  718. };
  719. if (res.obj.code == 0) {
  720. this.$Message.success("导入成功");
  721. this.init();
  722. this.searchList();
  723. } else {
  724. this.exitInfo = {
  725. show: true,
  726. studentsExisted: res.obj.studentsExisted,
  727. usersExisted: res.obj.usersExisted
  728. };
  729. }
  730. } else {
  731. this.$Message.error(res.msg);
  732. }
  733. this.form_data = null;
  734. })
  735. .catch(() => {
  736. that.wait_flag = false;
  737. });
  738. },
  739. //导入
  740. userImport() {
  741. this.importInfo = {
  742. show: true,
  743. file: null
  744. };
  745. },
  746. // 上传文件
  747. handleUpload(file) {
  748. let str = file.name.split(".");
  749. let suffix = str[str.length - 1];
  750. suffix = suffix.toLowerCase();
  751. if (suffix === "xls" || suffix === "xlsx") {
  752. this.importInfo.file = file;
  753. this.import_img = true;
  754. this.form_data = new FormData();
  755. this.form_data.append("file", file);
  756. this.form_data.append("schoolid", this.powerParams.objectid);
  757. this.form_data.append("regionid", this.powerParams.objectid);
  758. } else {
  759. this.importInfo.file = null;
  760. this.$Message.error("请上传excel文件");
  761. }
  762. return false;
  763. },
  764. //导出
  765. userExport() {
  766. this.showLoading = true;
  767. user_export({
  768. rtype: this.powerParams.rtype,
  769. objectid: this.powerParams.objectid,
  770. schoolid: this.powerParams.objectid
  771. }).then((res) => {
  772. this.showLoading = false;
  773. if (res.code === 0) {
  774. exportToExcel(
  775. [
  776. {
  777. list: res.obj.map((item) => {
  778. return {
  779. 登录名: item.loginname,
  780. 姓名: item.username,
  781. 班级: item.classname,
  782. 状态: item.enabled === 1 ? "启用" : "禁用",
  783. 最后登录时间: item.lasttime || ""
  784. };
  785. }),
  786. name: this.curClass.name
  787. }
  788. ],
  789. this.curClass.name
  790. );
  791. } else {
  792. this.$Message.error(res.msg);
  793. }
  794. });
  795. },
  796. toAdd() {
  797. this.addInfo = {
  798. show: true,
  799. userid: null,
  800. usersex: 1,
  801. username: "",
  802. loginname: "",
  803. loginpwd: generateRandomString(),
  804. loginpwd1: "",
  805. classid: "",
  806. classname: "",
  807. schoolid: null,
  808. regionid: null,
  809. enabled: 1,
  810. studentno: "",
  811. userphone: "",
  812. cardid: ""
  813. };
  814. },
  815. saveAddInfo() {
  816. this.$refs.addForm.validate((valid) => {
  817. if (valid) {
  818. if (this.addInfo.userphone) {
  819. var filter = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
  820. if (!filter.test(this.addInfo.userphone)) {
  821. this.$Message.error("手机号码格式不正确!");
  822. return;
  823. }
  824. }
  825. if (!this.addInfo.classid) {
  826. this.$Message.error("请选择班级!");
  827. return;
  828. }
  829. let form = {
  830. username: this.addInfo.username,
  831. loginname: this.addInfo.loginname,
  832. usersex: this.addInfo.usersex,
  833. loginpwd: this.addInfo.loginpwd,
  834. classid: this.addInfo.classid,
  835. classname: this.addInfo.classname,
  836. rtype: this.powerParams.rtype,
  837. objectid: this.powerParams.objectid,
  838. regionid: this.powerParams.objectid,
  839. schoolid: this.addInfo.schoolid || 1,
  840. enabled: this.addInfo.enabled,
  841. studentno: this.addInfo.studentno,
  842. userphone: this.addInfo.userphone,
  843. cardid: this.addInfo.cardid
  844. };
  845. let api = this.addInfo.userid ? user_edit : user_add;
  846. this.showLoading = true;
  847. api(form).then((res) => {
  848. this.showLoading = false;
  849. if (res.code === 0) {
  850. this.addInfo.show = false;
  851. this.$Message.success(res.msg);
  852. this.searchList();
  853. } else {
  854. this.$Message.error(res.msg);
  855. }
  856. });
  857. }
  858. });
  859. },
  860. toCare(row) {
  861. let api = row.care === 1 ? user_un_care : user_care;
  862. api({
  863. rtype: this.powerParams.rtype,
  864. objectid: this.powerParams.objectid,
  865. userid: row.userid,
  866. rversion: row.rversion
  867. }).then((res) => {
  868. if (res.code === 0) {
  869. this.searchList();
  870. this.$Message.success(res.msg);
  871. } else {
  872. this.$Message.error(res.msg);
  873. }
  874. });
  875. },
  876. toDel(row) {
  877. this.$Modal.confirm({
  878. title: "提示",
  879. content: "您确定删除【" + row.username + "】吗?",
  880. onOk: () => {
  881. user_delete({
  882. rtype: this.powerParams.rtype,
  883. objectid: this.powerParams.objectid,
  884. userid: row.userid,
  885. rversion: row.rversion
  886. }).then((res) => {
  887. if (res.code === 0) {
  888. this.searchList();
  889. this.$Message.success(res.msg);
  890. } else {
  891. this.$Message.error(res.msg);
  892. }
  893. });
  894. },
  895. onCancel: () => {}
  896. });
  897. },
  898. enabledChange(row) {
  899. let api = row.enabled === 1 ? user_enable : user_disabled;
  900. api({
  901. rtype: this.powerParams.rtype,
  902. objectid: this.powerParams.objectid,
  903. userid: row.userid,
  904. rversion: row.rversion
  905. }).then((data) => {
  906. this.searchList();
  907. if (data.code === 0) {
  908. this.$Message.success(data.msg);
  909. } else {
  910. this.$Message.error(data.msg);
  911. }
  912. });
  913. },
  914. selectClass(item) {
  915. this.curClass = item;
  916. this.searchList();
  917. },
  918. init() {
  919. this.showLoading = true;
  920. class_list({
  921. schoolid: this.powerParams.objectid
  922. }).then((res) => {
  923. this.showLoading = false;
  924. if (res.code === 0) {
  925. this.schoolInfo = res.obj;
  926. if (!this.curClass.id) {
  927. this.curClass = res.obj;
  928. }
  929. } else {
  930. this.$Message.error(res.msg);
  931. }
  932. });
  933. },
  934. // 搜索
  935. searchList() {
  936. this.searchForm.page = 1;
  937. this.getList();
  938. },
  939. // 页码改变
  940. pageChange(page) {
  941. this.searchForm.page = page;
  942. this.getList();
  943. },
  944. // 每页显示数量改变
  945. pageSizeChange(size) {
  946. this.searchForm.size = size;
  947. this.searchForm.page = 1;
  948. this.getList();
  949. },
  950. // 获取列表
  951. getList() {
  952. this.showLoading = true;
  953. user_list({
  954. rtype: this.powerParams.rtype,
  955. objectid: this.powerParams.objectid,
  956. schoolid: this.powerParams.objectid,
  957. page: this.searchForm.page,
  958. size: this.searchForm.size,
  959. classid: this.curClass.type === 2 ? this.curClass.id : null,
  960. care: this.searchForm.care,
  961. enabled: this.searchForm.enabled,
  962. control: this.searchForm.control,
  963. username: this.searchForm.username
  964. }).then((res) => {
  965. this.showLoading = false;
  966. if (res.code === 0) {
  967. this.searchForm.list = res.obj.data;
  968. this.searchForm.total = res.obj.total;
  969. } else {
  970. this.$Message.error(res.msg);
  971. }
  972. });
  973. }
  974. }
  975. };
  976. </script>
  977. <style lang="less" scoped>
  978. .main_root {
  979. width: calc(100% - 32px);
  980. height: calc(100% - 60px);
  981. background-color: transparent;
  982. border: none;
  983. display: flex;
  984. .schoolInfo {
  985. width: 200px;
  986. flex: none;
  987. border-radius: 15px;
  988. margin-right: 16px;
  989. height: 100%;
  990. overflow-y: auto;
  991. padding: 10px;
  992. background-color: white;
  993. .schoolname {
  994. font-size: 16px;
  995. line-height: 40px;
  996. font-weight: bold;
  997. text-align: center;
  998. cursor: pointer;
  999. }
  1000. .class_list {
  1001. div {
  1002. line-height: 30px;
  1003. height: 30px;
  1004. text-align: center;
  1005. cursor: pointer;
  1006. position: relative;
  1007. .icon-sandian {
  1008. display: none;
  1009. }
  1010. &:hover {
  1011. .icon-sandian {
  1012. display: block;
  1013. position: absolute;
  1014. top: 4px;
  1015. right: 6px;
  1016. font-size: 24px;
  1017. }
  1018. }
  1019. }
  1020. }
  1021. .active {
  1022. border-radius: 6px;
  1023. background: #dbeeff;
  1024. }
  1025. }
  1026. .user_list {
  1027. width: calc(100% - 216px);
  1028. height: 100%;
  1029. overflow-y: auto;
  1030. border-radius: 15px;
  1031. background-color: white;
  1032. }
  1033. }
  1034. .search_header {
  1035. display: flex;
  1036. justify-content: space-between;
  1037. align-items: center;
  1038. margin: 16px 16px;
  1039. .search_left {
  1040. display: flex;
  1041. justify-content: flex-start;
  1042. align-items: center;
  1043. .search_drop {
  1044. margin-right: 10px;
  1045. width: 150px;
  1046. }
  1047. }
  1048. }
  1049. .table_wrap {
  1050. .appName {
  1051. display: flex;
  1052. margin: 16px 0;
  1053. .app_logo {
  1054. flex: none;
  1055. width: 56px;
  1056. height: 56px;
  1057. border-radius: 20px;
  1058. border: 1px solid #e5e5e5;
  1059. background: #ffffff;
  1060. padding: 10px;
  1061. img {
  1062. width: 38px;
  1063. height: 38px;
  1064. object-fit: cover;
  1065. }
  1066. }
  1067. .app_comm {
  1068. flex: none;
  1069. width: 120px;
  1070. margin-left: 10px;
  1071. text-align: left;
  1072. div {
  1073. color: #339dff;
  1074. }
  1075. }
  1076. }
  1077. }
  1078. .modal_tip {
  1079. .files_list {
  1080. height: 30px;
  1081. line-height: 30px;
  1082. }
  1083. .import_tip {
  1084. height: 30px;
  1085. line-height: 30px;
  1086. text-align: center;
  1087. .theme_color {
  1088. color: #339dff;
  1089. cursor: pointer;
  1090. }
  1091. }
  1092. }
  1093. // 存在信息
  1094. .exit_modal {
  1095. /deep/ .ivu-modal {
  1096. .ivu-modal-content {
  1097. .exit {
  1098. div {
  1099. // margin-bottom: 10px;
  1100. font-size: 18px;
  1101. line-height: 40px;
  1102. }
  1103. }
  1104. .ivu-table {
  1105. -moz-user-select: none;
  1106. -khtml-user-select: none;
  1107. user-select: none;
  1108. }
  1109. div .ivu-table-header thead tr > th {
  1110. height: 40px;
  1111. }
  1112. .ivu-modal-footer {
  1113. display: none;
  1114. }
  1115. }
  1116. }
  1117. }
  1118. .more_menu {
  1119. width: 100px;
  1120. text-align: center;
  1121. background: #ffffff;
  1122. box-shadow: 0 8px 30px 0 #bcc9e380;
  1123. border-radius: 10px;
  1124. border: none;
  1125. .menu_group {
  1126. height: 35px;
  1127. line-height: 35px;
  1128. cursor: pointer;
  1129. &:hover {
  1130. background-color: #dbeeffcc;
  1131. }
  1132. }
  1133. }
  1134. </style>