staffManager.vue 20 KB

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