teacherList.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <div class="squrt"></div>
  5. 老师管理
  6. </h2>
  7. <div class="m-core">
  8. <!-- 搜索标题 -->
  9. <save-form
  10. :inline="true"
  11. @submit="search"
  12. @reset="onReSet"
  13. class="searchForm"
  14. :model="searchForm"
  15. ref="searchForm"
  16. >
  17. <el-form-item>
  18. <el-input
  19. v-model.trim="searchForm.search"
  20. clearable
  21. @keyup.enter.native="
  22. e => {
  23. e.target.blur();
  24. $refs.searchForm.save();
  25. search();
  26. }
  27. "
  28. placeholder="老师姓名或电话"
  29. ></el-input>
  30. </el-form-item>
  31. <el-form-item>
  32. <el-select
  33. v-model.trim="searchForm.lockFlag"
  34. clearable
  35. filterable
  36. placeholder="老师状态"
  37. >
  38. <el-option
  39. v-for="item in teacherStatus"
  40. :key="item.value"
  41. :label="item.label"
  42. :value="item.value"
  43. ></el-option>
  44. </el-select>
  45. </el-form-item>
  46. <el-form-item>
  47. <el-select
  48. style="width: 100% !important"
  49. filterable
  50. clearable
  51. v-model.trim="searchForm.subjectId"
  52. placeholder="专业技能"
  53. >
  54. <el-option
  55. v-for="(item, i) in selects.subjects"
  56. :key="i"
  57. :label="item.name"
  58. :value="item.id"
  59. ></el-option>
  60. </el-select>
  61. <!-- <el-select
  62. v-model.trim="searchForm.subjectId"
  63. filterable
  64. clearable
  65. placeholder="专业技能"
  66. >
  67. <el-option-group
  68. v-for="group in subjectList"
  69. :key="group.label"
  70. :label="group.label"
  71. >
  72. <el-option
  73. v-for="item in group.options"
  74. :key="item.value"
  75. :label="item.label"
  76. :value="item.value"
  77. ></el-option>
  78. </el-option-group>
  79. </el-select> -->
  80. </el-form-item>
  81. <el-form-item>
  82. <el-select
  83. v-model.trim="searchForm.organId"
  84. filterable
  85. clearable
  86. multiple
  87. collapse-tags
  88. placeholder="请选择分部"
  89. >
  90. <el-option
  91. v-for="item in selects.branchs"
  92. :key="item.id"
  93. :label="item.name"
  94. :value="item.id"
  95. >
  96. </el-option>
  97. </el-select>
  98. </el-form-item>
  99. <el-form-item v-if="tenantConfig.tenantId != 28">
  100. <el-select
  101. v-model.trim="searchForm.jobNature"
  102. filterable
  103. clearable
  104. placeholder="工作类型"
  105. >
  106. <el-option
  107. v-for="item in jobNature"
  108. :key="item.value"
  109. :label="item.label"
  110. :value="item.value"
  111. ></el-option>
  112. </el-select>
  113. </el-form-item>
  114. <el-form-item>
  115. <el-select
  116. v-model.trim="searchForm.isProbationPeriod"
  117. clearable
  118. filterable
  119. placeholder="员工状态"
  120. >
  121. <el-option
  122. v-for="item in ProbationPeriodList"
  123. :key="item.value"
  124. :label="item.label"
  125. :value="item.value"
  126. ></el-option>
  127. <!-- <el-option label="正式" value="0"></el-option>
  128. <el-option label="试用" value="1"></el-option>
  129. <el-option label="实习" value="3"></el-option> -->
  130. </el-select>
  131. </el-form-item>
  132. <!-- isSupportExtraPracticeLesson -->
  133. <el-form-item>
  134. <el-select
  135. v-model.trim="searchForm.isSupportExtraPracticeLesson"
  136. clearable
  137. filterable
  138. placeholder="开放陪练"
  139. >
  140. <el-option label="是" value="true"></el-option>
  141. <el-option label="否" value="false"></el-option>
  142. </el-select>
  143. </el-form-item>
  144. <el-form-item>
  145. <el-button native-type="submit" type="danger">搜索</el-button>
  146. <el-button native-type="reset" type="primary">重置</el-button>
  147. <el-button
  148. type="primary"
  149. v-permission="'export/teacherList'"
  150. @click="downLoadTeacher"
  151. >导出</el-button
  152. >
  153. </el-form-item>
  154. </save-form>
  155. <el-button
  156. v-permission="'/teacherOperationAdd'"
  157. @click="onTeacher('create')"
  158. type="primary"
  159. style="margin-bottom:20px"
  160. >
  161. 老师新增
  162. </el-button>
  163. <!-- 列表 -->
  164. <div class="tableWrap">
  165. <el-table
  166. :data="tableList"
  167. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  168. >
  169. <el-table-column
  170. align="center"
  171. prop="id"
  172. label="老师编号"
  173. ></el-table-column>
  174. <el-table-column align="center" prop="realName" label="老师名称">
  175. <template slot-scope="scope">
  176. <div>
  177. <p>{{ scope.row.realName }}</p>
  178. <p v-if="scope.row.memo">{{ "(" + scope.row.memo + ")" }}</p>
  179. </div>
  180. </template>
  181. </el-table-column>
  182. <el-table-column
  183. align="center"
  184. prop="organName"
  185. label="所属分部"
  186. ></el-table-column>
  187. <el-table-column align="center" width="150px" label="老师状态">
  188. <template slot-scope="scope">{{
  189. scope.row.lockFlag | teacherStatus
  190. }}</template>
  191. </el-table-column>
  192. <el-table-column
  193. align="center"
  194. :show-overflow-tooltip="true"
  195. width="200px"
  196. label="专业技能"
  197. >
  198. <template slot-scope="scope">
  199. <span
  200. style="max-height: 68px; display: block"
  201. :title="scope.row.splitSubjectName"
  202. >{{ scope.row.splitSubjectName }}</span
  203. >
  204. </template>
  205. </el-table-column>
  206. <el-table-column
  207. align="center"
  208. prop="phone"
  209. width="150px"
  210. label="联系电话"
  211. ></el-table-column>
  212. <el-table-column align="center" label="工作类型">
  213. <template slot-scope="scope">
  214. <p v-if="scope.row.tenantId === 28">
  215. 自由工作者
  216. </p>
  217. <p v-else>{{ scope.row.jobNature | jobNature }}</p>
  218. </template>
  219. </el-table-column>
  220. <el-table-column align="center" label="员工状态">
  221. <template slot-scope="scope">
  222. {{ scope.row.isProbationPeriod | ProbationPeriod }}
  223. </template>
  224. </el-table-column>
  225. <el-table-column
  226. align="center"
  227. prop="vipNum"
  228. label="已开小课"
  229. ></el-table-column>
  230. <el-table-column align="center" width="130px" label="试听课安排">
  231. <template slot-scope="scope">{{
  232. scope.row.demoNum > 0 ? "是" : "否"
  233. }}</template>
  234. </el-table-column>
  235. <el-table-column align="center" width="120px" label="开放网管课">
  236. <template slot-scope="scope">{{
  237. scope.row.isSupportExtraPracticeLesson ? "是" : "否"
  238. }}</template>
  239. </el-table-column>
  240. <!-- <el-table-column align="center" label="运营指标">
  241. <template slot-scope="scope">
  242. <el-button type="text" @click="gotoOperating(scope.row)">{{
  243. scope.row.operatingIndex + "%"
  244. }}</el-button>
  245. </template>
  246. </el-table-column>
  247. <el-table-column align="center" label="服务指标">
  248. <template slot-scope="scope">
  249. <el-button type="text" @click="gotoAfterSchool(scope.row)">{{
  250. scope.row.serviceIndex + "%"
  251. }}</el-button>
  252. </template>
  253. </el-table-column> -->
  254. <el-table-column align="center" label="转正日期">
  255. <template slot-scope="scope">
  256. <div>
  257. {{ scope.row.formalStaffDate | dayjsFormat }}
  258. </div>
  259. </template>
  260. </el-table-column>
  261. <el-table-column align="center" label="离职日期">
  262. <template slot-scope="scope">
  263. <div>
  264. {{ scope.row.demissionDate | dayjsFormat }}
  265. </div>
  266. </template>
  267. </el-table-column>
  268. <el-table-column
  269. align="center"
  270. fixed="right"
  271. width="200"
  272. label="操作"
  273. >
  274. <template slot-scope="scope">
  275. <!-- let search = JSON.stringify(this.searchForm)
  276. let rules = JSON.stringify(this.pageInfo)-->
  277. <auth auths="/teacherDetail">
  278. <router-link
  279. class="el-button--text"
  280. :to="{
  281. path: `/business/teacherDetail?teacherId=${
  282. scope.row.id
  283. }&teacherName=${scope.row.realName}`
  284. }"
  285. >查看</router-link
  286. >
  287. </auth>
  288. <auth auths="/teacherOperationUpdate">
  289. <el-button @click="onTeacher('update', scope.row)" type="text"
  290. >修改</el-button
  291. >
  292. </auth>
  293. <auth
  294. :auths="
  295. scope.row.lockFlag == 1
  296. ? 'employee/employeeOperate/UNLOCK'
  297. : 'employee/employeeOperate/LOCK'
  298. "
  299. >
  300. <el-button
  301. @click="onStaffOperation('LOCK_UNLOCK', scope.row)"
  302. type="text"
  303. >{{ scope.row.lockFlag == 1 ? "解冻" : "冻结" }}</el-button
  304. >
  305. </auth>
  306. <auth auths="user/updatePassword2">
  307. <el-button @click="resetPassWrod(scope.row)" type="text"
  308. >修改密码</el-button
  309. >
  310. </auth>
  311. <el-button
  312. v-if="scope.row.contractUrl"
  313. @click="onDownloadProtocol(scope.row)"
  314. type="text"
  315. >下载协议</el-button
  316. >
  317. <!-- -->
  318. </template>
  319. </el-table-column>
  320. </el-table>
  321. <pagination
  322. sync
  323. :total.sync="pageInfo.total"
  324. :page.sync="pageInfo.page"
  325. :limit.sync="pageInfo.limit"
  326. :page-sizes="pageInfo.page_size"
  327. @pagination="getList"
  328. />
  329. </div>
  330. </div>
  331. <el-dialog
  332. title="修改密码"
  333. :visible.sync="passwrodVisiable"
  334. :before-close="closePassWord"
  335. width="400px"
  336. >
  337. <el-form :model="passwrodForm" ref="passwrodForm" :inline="true">
  338. <el-form-item
  339. label="手机号"
  340. prop="phone"
  341. label-width="80px"
  342. :rules="[
  343. { required: true, message: '手机号不能为空', trigger: 'blur' },
  344. {
  345. pattern: /^1\d{10}$/,
  346. message: '请输入正确的手机号',
  347. trigger: 'blur'
  348. }
  349. ]"
  350. >
  351. <copy-text>{{ passwrodForm.phone }}</copy-text>
  352. </el-form-item>
  353. <el-form-item
  354. label="输入密码"
  355. prop="password"
  356. label-width="80px"
  357. :rules="[
  358. { required: true, message: '密码不能为空', trigger: 'blur' },
  359. {
  360. pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/,
  361. message: '密码为6-20位数字和字母组合',
  362. trigger: 'blur'
  363. }
  364. ]"
  365. >
  366. <el-input v-model.trim="passwrodForm.password"></el-input>
  367. </el-form-item>
  368. <el-form-item
  369. label="再次输入"
  370. prop="password2"
  371. label-width="80px"
  372. :rules="[
  373. { required: true, message: '密码不能为空', trigger: 'blur' },
  374. {
  375. pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/,
  376. message: '密码为6-20位数字和字母组合',
  377. trigger: 'blur'
  378. }
  379. ]"
  380. >
  381. <el-input v-model.trim="passwrodForm.password2"></el-input>
  382. </el-form-item>
  383. </el-form>
  384. <span slot="footer" class="dialog-footer">
  385. <el-button @click="passwrodVisiable = false">取 消</el-button>
  386. <el-button type="primary" @click="submitResetPassWord">确 定</el-button>
  387. </span>
  388. </el-dialog>
  389. </div>
  390. </template>
  391. <script>
  392. import pagination from "@/components/Pagination/index";
  393. import { teacherQueryPage } from "@/api/teacherManager";
  394. import { employeeOperate } from "@/api/systemManage";
  395. // import { subjectListTree } from "@/api/specialSetting";
  396. import { resetPassword2 } from "@/api/buildTeam";
  397. import { Export } from "@/utils/downLoadFile";
  398. import cleanDeep from "clean-deep";
  399. import {
  400. jobNature,
  401. teacherStatus,
  402. ProbationPeriodList
  403. } from "@/utils/searchArray";
  404. import store from "@/store";
  405. export default {
  406. name: "teacherList",
  407. components: {
  408. pagination
  409. },
  410. data() {
  411. return {
  412. searchForm: {
  413. lockFlag: null,
  414. isProbationPeriod: null,
  415. jobNature: null,
  416. subjectId: null,
  417. organId: [],
  418. search: null, // 老师姓名或电话
  419. isSupportExtraPracticeLesson: null
  420. },
  421. jobNature: jobNature, // 工作类型
  422. teacherStatus: teacherStatus, // 老师状态
  423. ProbationPeriodList: ProbationPeriodList,
  424. subjectList: [], // 声部列表
  425. branchList: [], // 分部列表
  426. tableList: [],
  427. // organId: store.getters.organ,
  428. pageInfo: {
  429. // 分页规则
  430. limit: 10, // 限制显示条数
  431. page: 1, // 当前页
  432. total: 1, // 总条数
  433. page_size: [10, 20, 40, 50] // 选择限制显示条数
  434. },
  435. passwrodVisiable: false,
  436. passwrodForm: {
  437. phone: "",
  438. password: "",
  439. password2: ""
  440. },
  441. activatedRow: null,
  442. lookServer: false,
  443. infoList: [],
  444. tenantConfig: {}
  445. };
  446. },
  447. // activated() {
  448. // this.__init();
  449. // this.getList();
  450. // },
  451. mounted() {
  452. let tenantConfig = sessionStorage.getItem("tenantConfig");
  453. tenantConfig = tenantConfig ? JSON.parse(tenantConfig) : {};
  454. this.tenantConfig = tenantConfig;
  455. if (this.$route.params.search) {
  456. this.searchForm.search = this.$route.params.search;
  457. }
  458. this.__init();
  459. this.getList();
  460. },
  461. methods: {
  462. search() {
  463. this.pageInfo.page = 1;
  464. this.getList();
  465. },
  466. async __init() {
  467. // 获取分部
  468. await this.$store.dispatch("setBranchs");
  469. await this.$store.dispatch("setSubjects");
  470. },
  471. onTeacher(type, row) {
  472. let params = {
  473. type: type
  474. };
  475. if (row) {
  476. params.teacherId = row.id;
  477. params.teacherName = row.realName;
  478. }
  479. let path = "/business/teacherOperation";
  480. // (params)
  481. // teacherId=${scope.row.id}&teacherName=${scope.row.realName}
  482. this.$router.push(
  483. {
  484. path: path,
  485. query: params
  486. },
  487. router => {
  488. if (type == "update") {
  489. router.meta.title = "老师修改";
  490. } else {
  491. router.meta.title = "老师新增";
  492. }
  493. }
  494. );
  495. },
  496. downLoadTeacher() {
  497. let params = { ...this.searchForm };
  498. params.lockFlag ? params.lockFlag : (params.lockFlag = null);
  499. params.isProbationPeriod
  500. ? params.isProbationPeriod
  501. : (params.isProbationPeriod = null);
  502. params.jobNature ? params.jobNature : (params.jobNature = null);
  503. // params.subjectId?params.subjectId:params.subjectId = null
  504. params.subjectId ? params.subjectId : (params.subjectId = null);
  505. params.search ? params.search : (params.search = null);
  506. params.organId = this.searchForm.organId.join(",");
  507. params.isSupportExtraPracticeLesson
  508. ? params.isSupportExtraPracticeLesson
  509. : (params.isSupportExtraPracticeLesson = null);
  510. Export(
  511. this,
  512. {
  513. url: "/api-web/export/teacherList",
  514. fileName: `老师列表导出.xls`,
  515. params: cleanDeep({
  516. ...params
  517. })
  518. },
  519. "是否确认导出老师列表?"
  520. );
  521. },
  522. onDownloadProtocol(item) {
  523. window.location.href = item.contractUrl;
  524. },
  525. getList() {
  526. let params = { ...this.searchForm };
  527. // params.organId = this.organId
  528. // searchForm: {
  529. // lockFlag: null,
  530. // isProbationPeriod: null,
  531. // jobNature: null,
  532. // subjectId: null,
  533. // organId: null,
  534. // search: null, // 老师姓名或电话
  535. // isSupportExtraPracticeLesson:null
  536. // },
  537. params.lockFlag ? params.lockFlag : (params.lockFlag = null);
  538. params.isProbationPeriod
  539. ? params.isProbationPeriod
  540. : (params.isProbationPeriod = null);
  541. params.jobNature ? params.jobNature : (params.jobNature = null);
  542. // params.subjectId?params.subjectId:params.subjectId = null
  543. params.subjectId ? params.subjectId : (params.subjectId = null);
  544. params.search ? params.search : (params.search = null);
  545. params.isSupportExtraPracticeLesson
  546. ? params.isSupportExtraPracticeLesson
  547. : (params.isSupportExtraPracticeLesson = null);
  548. params.rows = this.pageInfo.limit;
  549. params.page = this.pageInfo.page;
  550. params.organId = this.searchForm.organId.join(",");
  551. teacherQueryPage(params).then(res => {
  552. if (res.code == 200) {
  553. // (res)
  554. this.tableList = res.data.rows;
  555. this.pageInfo.total = res.data.total;
  556. }
  557. });
  558. },
  559. onStaffOperation(type, data) {
  560. let str = "";
  561. if (data.lockFlag != 1) {
  562. str = `是否冻结${data.realName}老师?`;
  563. } else {
  564. str = `是否解冻${data.realName}老师?`;
  565. }
  566. this.$confirm(str, "提示", {
  567. confirmButtonText: "确定",
  568. cancelButtonText: "取消",
  569. type: "warning"
  570. })
  571. .then(() => {
  572. employeeOperate({
  573. employeeId: data.id,
  574. operate: type
  575. }).then(res => {
  576. if (res.code == 200) {
  577. this.$message.success("更改成功");
  578. this.roleStatus = false;
  579. this.getList();
  580. } else {
  581. this.$message.error(res.msg);
  582. }
  583. });
  584. })
  585. .catch(() => {});
  586. },
  587. onReSet() {
  588. this.searchForm = {
  589. lockFlag: null,
  590. isProbationPeriod: null,
  591. jobNature: null,
  592. organId: [],
  593. subjectId: null,
  594. search: null
  595. };
  596. this.search();
  597. },
  598. resetPassWrod(row) {
  599. this.activatedRow = row;
  600. this.passwrodForm.phone = row.phone;
  601. this.passwrodVisiable = true;
  602. },
  603. closePassWord() {
  604. this.activatedRow = null;
  605. this.passwrodForm = {
  606. phone: "",
  607. password: "",
  608. password2: ""
  609. };
  610. this.$refs["passwrodForm"].resetFields();
  611. this.passwrodVisiable = false;
  612. },
  613. submitResetPassWord() {
  614. if (this.passwrodForm.password !== this.passwrodForm.password2) {
  615. this.$message.error("两次密码必须相同");
  616. return;
  617. }
  618. this.$refs["passwrodForm"].validate(res => {
  619. if (res) {
  620. // 发请求
  621. resetPassword2({
  622. mobile: this.passwrodForm.phone,
  623. newPassword: this.passwrodForm.password,
  624. userId: this.activatedRow.id
  625. }).then(res => {
  626. if (res.code == 200) {
  627. // 修改成功
  628. this.$message.success("修改成功");
  629. this.closePassWord();
  630. }
  631. });
  632. }
  633. });
  634. }
  635. }
  636. };
  637. </script>
  638. <style lang="scss" scoped>
  639. .el-button + .el-button {
  640. margin-left: 0;
  641. }
  642. .hanlderWrap {
  643. display: flex;
  644. flex-direction: row;
  645. justify-content: space-between;
  646. align-items: center;
  647. }
  648. </style>