staffManager.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. <template>
  2. <div class='m-container'>
  3. <h2>
  4. <div class="squrt"></div>员工管理
  5. </h2>
  6. <div class="m-core">
  7. <div @click="roleOperation('create')"
  8. v-permission="'employee/add'"
  9. class='newBand'>添加</div>
  10. <save-form :inline="true"
  11. class="searchForm"
  12. ref="searchForm"
  13. @submit="search"
  14. @reset="reset"
  15. :model="searchForm">
  16. <el-form-item prop="search">
  17. <el-input type="text" clearable
  18. v-model.trim="searchForm.search"
  19. @keyup.enter.native='search'
  20. placeholder="姓名或手机号"></el-input>
  21. </el-form-item>
  22. <el-form-item prop="jobNature">
  23. <el-select v-model.trim="searchForm.jobNature"
  24. clearable
  25. filterable
  26. placeholder="请选择工作类型">
  27. <el-option label="全职"
  28. value="FULL_TIME"></el-option>
  29. <el-option label="兼职"
  30. value="PART_TIME"></el-option>
  31. <el-option label="临时"
  32. value="TEMPORARY"></el-option>
  33. </el-select>
  34. </el-form-item>
  35. <el-form-item prop="organId">
  36. <el-select v-model.trim="searchForm.organId"
  37. clearable
  38. filterable
  39. placeholder="请选择分部">
  40. <el-option v-for="item in selects.branchs"
  41. :key="item.id"
  42. :label="item.name"
  43. :value="item.id"></el-option>
  44. </el-select>
  45. </el-form-item>
  46. <el-form-item prop="roleId">
  47. <!-- multiple -->
  48. <el-select v-model.trim="searchForm.roleId"
  49. clearable
  50. filterable
  51. placeholder="请选择角色">
  52. <el-option v-for="item in roleList"
  53. :key="item.value"
  54. :label="item.label"
  55. :value="item.value"></el-option>
  56. </el-select>
  57. <!-- collapse-tags -->
  58. </el-form-item>
  59. <el-form-item>
  60. <el-button native-type="submit" type="danger">搜索</el-button>
  61. <el-button native-type="reset" type="primary">重置</el-button>
  62. </el-form-item>
  63. </save-form>
  64. <!-- 列表 -->
  65. <div class="tableWrap">
  66. <el-table :data='tableList'
  67. :header-cell-style="{background:'#EDEEF0',color:'#444'}">
  68. <el-table-column align='center'
  69. prop="id"
  70. label="员工编号">
  71. <template slot-scope="scope">
  72. <copy-text>{{ scope.row.id }}</copy-text>
  73. </template>
  74. </el-table-column>
  75. <el-table-column align='center'
  76. prop="realName"
  77. label="姓名">
  78. <template slot-scope="scope">
  79. <copy-text>{{ scope.row.realName }}</copy-text>
  80. </template>
  81. </el-table-column>
  82. <el-table-column align='center'
  83. prop="phone"
  84. label="手机号">
  85. <template slot-scope="scope">
  86. <copy-text>{{ scope.row.phone }}</copy-text>
  87. </template>
  88. </el-table-column>
  89. <el-table-column align='center'
  90. label="角色分类">
  91. <template slot-scope="scope">
  92. <tooltip :content="scope.row.roleNames | joinArray(',')"></tooltip>
  93. </template>
  94. </el-table-column>
  95. <el-table-column align='center'
  96. prop="jobNature"
  97. label="工作类型">
  98. <template slot-scope="scope">
  99. {{ scope.row.jobNature | jobNature }}
  100. </template>
  101. </el-table-column>
  102. <el-table-column align='center'
  103. label="所属部门">
  104. <template slot-scope="scope">
  105. <tooltip :content="scope.row.organNameList | joinArray(',')"></tooltip>
  106. </template>
  107. </el-table-column>
  108. <el-table-column align='center'
  109. label="状态"
  110. :formatter="formatLockFlag">
  111. </el-table-column>
  112. <el-table-column align='center'
  113. label="入职时间">
  114. <template slot-scope="scope">
  115. {{ scope.row.entryDate | formatTimer }}
  116. </template>
  117. </el-table-column>
  118. <el-table-column align='center'
  119. label="离职时间">
  120. <template slot-scope="scope">
  121. {{ scope.row.demissionDate | formatTimer }}
  122. </template>
  123. </el-table-column>
  124. <el-table-column align='center'
  125. width="250px"
  126. fixed="right"
  127. label="操作">
  128. <template slot-scope="scope">
  129. <el-button @click="roleOperation('update', scope.row)"
  130. v-permission="'employee/update'"
  131. type="text">修改</el-button>
  132. <el-button @click="onStaffOperation('RESET_PASSWORD', scope.row)"
  133. v-permission="'employee/employeeOperate'"
  134. type="text">重置密码</el-button>
  135. <el-button @click="onStaffOperation('LOCK_UNLOCK', scope.row)"
  136. v-permission="'employee/employeeOperate'"
  137. type="text">{{ scope.row.lockFlag == 1 ? '解冻' : '冻结' }}</el-button>
  138. <el-button @click="onStaffOperation('DEMISSION', scope.row)"
  139. v-permission="'employee/employeeOperate'"
  140. v-if="scope.row.demissionDate"
  141. type="text">复职</el-button>
  142. <el-button @click="handover(scope.row)"
  143. v-if="!scope.row.demissionDate && permission('employee/level') && permission('employee/levelDetail')"
  144. type="text">离职</el-button>
  145. </template>
  146. </el-table-column>
  147. </el-table>
  148. <pagination sync :total.sync="pageInfo.total"
  149. :page.sync="pageInfo.page"
  150. :limit.sync="pageInfo.limit"
  151. :page-sizes="pageInfo.page_size"
  152. @pagination="getList" />
  153. </div>
  154. </div>
  155. <el-dialog :title="formTitle[formActionTitle]"
  156. :visible.sync="roleStatus"
  157. @close="onFormClose('ruleForm')"
  158. width="500px">
  159. <el-form :model="form"
  160. :rules="rules"
  161. ref="ruleForm">
  162. <el-form-item label="姓名"
  163. prop="realName"
  164. :label-width="formLabelWidth">
  165. <el-input v-model.trim="form.realName" placeholder="请输入姓名"
  166. autocomplete="off"></el-input>
  167. </el-form-item>
  168. <el-form-item label="性别"
  169. prop="gender"
  170. :label-width="formLabelWidth">
  171. <el-select v-model.trim="form.gender"
  172. placeholder="请选择性别"
  173. clearable
  174. filterable>
  175. <el-option label="男"
  176. :value="1"></el-option>
  177. <el-option label="女"
  178. :value="0"></el-option>
  179. </el-select>
  180. </el-form-item>
  181. <el-form-item label="手机号"
  182. prop="phone"
  183. :label-width="formLabelWidth">
  184. <el-input v-model.trim.number="form.phone" placeholder="请输入手机号"
  185. autocomplete="off"></el-input>
  186. </el-form-item>
  187. <el-form-item label="角色分类"
  188. prop="roleIds"
  189. :label-width="formLabelWidth">
  190. <el-select v-model.trim="form.roleIds"
  191. placeholder="请选择角色分类"
  192. clearable
  193. filterable
  194. collapse-tags
  195. multiple>
  196. <el-option v-for="item in roleList"
  197. :key="item.value"
  198. :label="item.label"
  199. :value="item.value"></el-option>
  200. </el-select>
  201. </el-form-item>
  202. <el-form-item label="所属部门"
  203. prop="organIdLists"
  204. :label-width="formLabelWidth">
  205. <el-select style="width: calc(100% - 75px) !important;"
  206. filterable
  207. clearable
  208. placeholder="请选择部门"
  209. collapse-tags
  210. v-model.trim="form.organIdLists"
  211. multiple>
  212. <el-option v-for="item in selects.branchs"
  213. :key="item.id"
  214. :label="item.name"
  215. :value="item.id"></el-option>
  216. </el-select>
  217. <el-button @click="onBranchCheckAll">全选</el-button>
  218. </el-form-item>
  219. <el-form-item label="工作类型"
  220. prop="jobNature"
  221. :label-width="formLabelWidth">
  222. <el-select v-model.trim="form.jobNature"
  223. clearable
  224. placeholder="请选择工作类型"
  225. filterable>
  226. <el-option label="全职"
  227. value="FULL_TIME"></el-option>
  228. <el-option label="兼职"
  229. value="PART_TIME"></el-option>
  230. <el-option label="临时"
  231. value="TEMPORARY"></el-option>
  232. </el-select>
  233. </el-form-item>
  234. <el-form-item label="入职时间"
  235. prop="entryDate"
  236. :label-width="formLabelWidth">
  237. <el-date-picker v-model.trim="form.entryDate"
  238. type="date"
  239. :picker-options="{
  240. firstDayOfWeek:1
  241. }"
  242. value-format="yyyy-MM-dd HH:mm:ss"
  243. placeholder="选择入职日期">
  244. </el-date-picker>
  245. </el-form-item>
  246. <el-form-item label="通讯地址"
  247. prop="contactAddress"
  248. :label-width="formLabelWidth">
  249. <el-input v-model.trim="form.contactAddress" placeholder="请输入通讯地址"
  250. autocomplete="off"></el-input>
  251. </el-form-item>
  252. <el-form-item label="邮政编码"
  253. prop="postalCode"
  254. :label-width="formLabelWidth">
  255. <el-input v-model.trim="form.postalCode" placeholder="请输入邮政编码"
  256. autocomplete="off"></el-input>
  257. </el-form-item>
  258. </el-form>
  259. <span slot="footer"
  260. class="dialog-footer">
  261. <el-button @click="roleStatus = false">取 消</el-button>
  262. <el-button @click="onRoleSubmit('ruleForm')"
  263. type="primary">确 定</el-button>
  264. </span>
  265. </el-dialog>
  266. <el-dialog
  267. title="工作交接"
  268. :visible.sync="handoverVisible"
  269. width="500px"
  270. >
  271. <handover
  272. v-if="handoverVisible"
  273. :detail="detail"
  274. @close="handoverVisible = false"
  275. @submited="getList"
  276. />
  277. </el-dialog>
  278. <el-dialog title="教务交接"
  279. width="400px"
  280. destroy-on-close
  281. close-on-click-modal
  282. :visible.sync="educationViseble">
  283. <el-form :model="educationForm"
  284. :inline="true"
  285. ref="educationForm">
  286. <el-form-item label="乐团主管"
  287. :rules="[{
  288. required:
  289. true,
  290. message: '请选择乐团主管'
  291. ,
  292. trigger: 'blur'
  293. }]">
  294. <el-select v-model.trim="
  295. educationForm.targetUserId"
  296. clearable
  297. filterable>
  298. <el-option v-for="item in educationList"
  299. :key="item.userId"
  300. :label="item.userName"
  301. :value="item.userId"></el-option>
  302. </el-select>
  303. </el-form-item>
  304. </el-form>
  305. <span slot="footer"
  306. class="dialog-footer">
  307. <el-button @click="educationViseble = false">取 消</el-button>
  308. <el-button @click="submitEducation"
  309. type="primary">确 定</el-button>
  310. </span>
  311. </el-dialog>
  312. </div>
  313. </template>
  314. <script>
  315. import pagination from '@/components/Pagination/index'
  316. import { permission } from "@/utils/directivePage";
  317. import { queryEmployByOrganId, employeeOperate, getUserRole, employeeAdd, employeeUpdate, hasCourseGroupRelation, updateEducationTeacherId } from '@/api/systemManage'
  318. import { findEducationTeacher } from '@/api/specialSetting'
  319. import { findEducationUsers } from '@/api/buildTeam'
  320. import Tooltip from '@/components/Tooltip/index'
  321. import { isvalidPhone } from '@/utils/validate'
  322. import handover from './modals/handover'
  323. let validPhone = (rule, value, callback) => {
  324. if (!value) {
  325. callback(new Error('请输入电话号码'))
  326. } else if (!isvalidPhone(value)) {
  327. callback(new Error('请输入正确的11位手机号码'))
  328. } else {
  329. callback()
  330. }
  331. }
  332. export default {
  333. name: 'staffManager',
  334. components: { pagination, Tooltip, handover },
  335. data () {
  336. return {
  337. tableList: [],
  338. educationList: [],
  339. educationForm: {
  340. targetUserId: ''
  341. },
  342. educationViseble: false,
  343. activeRow: null,
  344. pageInfo: {
  345. // 分页规则
  346. limit: 10, // 限制显示条数
  347. page: 1, // 当前页
  348. total: 0, // 总条数
  349. page_size: [10, 20, 40, 50] // 选择限制显示条数
  350. },
  351. detail: null,
  352. handoverVisible: false,
  353. roleStatus: false,
  354. formActionTitle: 'create',
  355. roleList: [], // 角色列表
  356. formTitle: {
  357. create: '添加员工',
  358. update: '修改员工'
  359. },
  360. formLabelWidth: '100px',
  361. form: {
  362. realName: null,
  363. gender: null,
  364. phone: null,
  365. roleIds: [],
  366. organIdLists: [],
  367. jobNature: null,
  368. entryDate: null,
  369. contactAddress: null,
  370. postalCode: null
  371. },
  372. rules: {
  373. realName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  374. gender: [{ required: true, message: '请选择性别', trigger: 'change' }],
  375. phone: [{ type: 'number', required: true, validator: validPhone, trigger: 'blur' }, { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }],
  376. roleIds: [{ type: 'array', required: true, message: '请选择分类', trigger: 'change' }],
  377. organIdLists: [{ type: 'array', required: true, message: '请选择所属部门', trigger: 'change' }],
  378. jobNature: [{ required: true, message: '请选择工作类型', trigger: 'change' }],
  379. entryDate: [{ required: true, message: '请选择入职时间', trigger: 'blur' }],
  380. },
  381. searchForm: {
  382. search: null,
  383. jobNature: null,
  384. organId: null,
  385. roleId: null
  386. }
  387. }
  388. },
  389. mounted () {
  390. this.getList()
  391. this.getRoleList()
  392. },
  393. methods: {
  394. permission,
  395. handover(row) {
  396. this.detail = row
  397. this.handoverVisible = true
  398. },
  399. onBranchCheckAll () {
  400. this.form.organIdLists = []
  401. this.selects.branchs.forEach(item => {
  402. this.form.organIdLists.push(item.id)
  403. })
  404. },
  405. onRoleSubmit (formName) {
  406. this.$refs[formName].validate((valid) => {
  407. if (valid) {
  408. this.form.organIdList = this.form.organIdLists.join(',')
  409. if (this.formActionTitle == 'create') {
  410. if (this.form.id) { // 判断有没有Id,如果有则删除
  411. delete this.form.id
  412. }
  413. employeeAdd(this.form).then(res => {
  414. this.messageTips('添加', res)
  415. })
  416. } else if (this.formActionTitle == 'update') {
  417. employeeUpdate(this.form).then(res => {
  418. this.messageTips('修改', res)
  419. })
  420. }
  421. } else {
  422. return
  423. }
  424. })
  425. },
  426. messageTips (title, res) {
  427. if (res.code == 200) {
  428. this.$message.success(title + '成功')
  429. this.roleStatus = false
  430. this.getList()
  431. } else {
  432. this.$message.error(res.msg)
  433. }
  434. },
  435. search () {
  436. this.pageInfo.page = 1
  437. this.getList()
  438. },
  439. reset() {
  440. this.$refs.searchForm.resetFields()
  441. this.search()
  442. },
  443. getList () {
  444. let searchForm = this.searchForm
  445. let params = {
  446. search: searchForm.search ? searchForm.search : null,
  447. jobNature: searchForm.jobNature ? searchForm.jobNature : null,
  448. organId: searchForm.organId ? searchForm.organId : null,
  449. roleId: searchForm.roleId ? searchForm.roleId : null,
  450. rows: this.pageInfo.limit,
  451. page: this.pageInfo.page
  452. }
  453. queryEmployByOrganId(params).then(res => {
  454. if (res.code == 200 && res.data) {
  455. this.tableList = res.data.rows
  456. this.pageInfo.total = res.data.total
  457. }
  458. })
  459. },
  460. getRoleList () { // 获取角色
  461. getUserRole({ delFlag: 0, rows: 9999 }).then(res => {
  462. let result = res.data
  463. if (res.code == 200 && result && result.rows.length > 0) {
  464. this.roleList = []
  465. result.rows.forEach(item => {
  466. this.roleList.push({
  467. label: item.roleName,
  468. value: item.id
  469. })
  470. })
  471. }
  472. })
  473. this.$store.dispatch('setBranchs')
  474. },
  475. roleOperation (type, data) {
  476. this.formActionTitle = type
  477. this.roleStatus = true
  478. // 修改的时候
  479. if (type == 'update') {
  480. this.form = {
  481. id: data.id,
  482. realName: data.realName,
  483. gender: data.gender,
  484. phone: Number(data.phone),
  485. roleIds: data.roleIds,
  486. organIdLists: data.organIdList ? data.organIdList : [],
  487. jobNature: data.jobNature,
  488. entryDate: data.entryDate,
  489. contactAddress: data.contactAddress,
  490. postalCode: data.postalCode
  491. }
  492. }
  493. },
  494. onFormClose (formName) { // 关闭弹窗重置验证
  495. this.form = {
  496. realName: null,
  497. gender: null,
  498. phone: null,
  499. roleName: null,
  500. organIdLists: [],
  501. jobNature: null,
  502. entryDate: null
  503. }
  504. this.$refs[formName].resetFields()
  505. },
  506. formatLockFlag (row) {
  507. let reuslt = ['正常', '冻结']
  508. if (row.demissionDate) {
  509. return '离职'
  510. } else {
  511. return reuslt[row.lockFlag]
  512. }
  513. },
  514. async checkStatus (data) {
  515. let status;
  516. await hasCourseGroupRelation({ employeeId: data.id }).then(async res => {
  517. if (res.code === 200) {
  518. if (res.data.hasCourseSchedule) {
  519. this.$message.error('请先交接指导老师课程')
  520. status = false
  521. } else {
  522. if (res.data.hasCourseGroupRelation) {
  523. let userId = data.id
  524. await findEducationTeacher({ userId }).then(res => {
  525. if (res.code === 200) {
  526. this.educationList = res.data;
  527. this.educationViseble = true
  528. status = false
  529. }
  530. })
  531. } else {
  532. // 1 要弹出
  533. status = true
  534. }
  535. }
  536. }
  537. })
  538. return status
  539. },
  540. onStaffOperation (type, data) {
  541. const tempStatus = type == 'RESET_PASSWORD' ? true : false
  542. this.$confirm(`您确定${tempStatus ? '重置密码' : '修改员工状态'}?`, "提示", {
  543. confirmButtonText: "确定",
  544. cancelButtonText: "取消",
  545. type: "warning"
  546. }).then(async () => {
  547. if (type === 'DEMISSION' && !data.demissionDate) {
  548. this.activeRow = data;
  549. // 1.点击的是离职按钮
  550. // 2.判断该考级是否存在乐团主管
  551. const status = await this.checkStatus(data)
  552. if (!status) {
  553. return
  554. }
  555. }
  556. employeeOperate({
  557. employeeId: data.id,
  558. operate: type
  559. }).then(res => {
  560. if (res.code == 200) {
  561. this.$message.success(tempStatus ? '重置密码成功' : '更改成功')
  562. this.roleStatus = false
  563. this.getList()
  564. } else {
  565. this.$message.error(res.msg)
  566. }
  567. })
  568. }).catch(err => { })
  569. },
  570. submitEducation () {
  571. // 发请求 提交信息
  572. updateEducationTeacherId({ currentUserId: this.activeRow.id, targetUserId: this.educationForm.targetUserId }).then(res => {
  573. if (res.code === 200) {
  574. const type = 'DEMISSION'
  575. const data = this.activeRow;
  576. employeeOperate({
  577. employeeId: data.id,
  578. operate: type
  579. }).then(res => {
  580. if (res.code == 200) {
  581. this.$message.success('更改成功')
  582. this.roleStatus = false
  583. this.educationViseble = false
  584. this.getList()
  585. } else {
  586. this.$message.error(res.msg)
  587. }
  588. })
  589. }
  590. })
  591. },
  592. },
  593. watch: {
  594. educationViseble (val) {
  595. if (!val) {
  596. this.educationForm.targetUserId = ''
  597. this.$refs['educationForm'].resetFields()
  598. }
  599. }
  600. }
  601. }
  602. </script>
  603. <style lang="scss" scoped>
  604. /deep/.el-button--primary {
  605. background: #14928a;
  606. border-color: #14928a;
  607. color: #fff;
  608. &:hover,
  609. &:active,
  610. &:focus {
  611. background: #14928a;
  612. border-color: #14928a;
  613. color: #fff;
  614. }
  615. }
  616. /deep/.el-dialog__body {
  617. padding: 0 20px;
  618. }
  619. /deep/.el-select,
  620. /deep/.el-date-editor.el-input {
  621. width: 100% !important;
  622. }
  623. </style>