staffManager.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  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 selects.branchs"
  39. :key="item.id"
  40. :label="item.name"
  41. :value="item.id"></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. collapse-tags
  198. v-model.trim="form.organIdLists"
  199. multiple>
  200. <el-option v-for="item in selects.branchs"
  201. :key="item.id"
  202. :label="item.name"
  203. :value="item.id"></el-option>
  204. </el-select>
  205. <el-button @click="onBranchCheckAll">全选</el-button>
  206. </el-form-item>
  207. <el-form-item label="工作类型"
  208. prop="jobNature"
  209. :label-width="formLabelWidth">
  210. <el-select v-model.trim="form.jobNature"
  211. clearable
  212. filterable>
  213. <el-option label="全职"
  214. value="FULL_TIME"></el-option>
  215. <el-option label="兼职"
  216. value="PART_TIME"></el-option>
  217. <el-option label="临时"
  218. value="TEMPORARY"></el-option>
  219. </el-select>
  220. </el-form-item>
  221. <el-form-item label="入职时间"
  222. prop="entryDate"
  223. :label-width="formLabelWidth">
  224. <el-date-picker v-model.trim="form.entryDate"
  225. type="date"
  226. :picker-options="{
  227. firstDayOfWeek:1
  228. }"
  229. value-format="yyyy-MM-dd HH:mm:ss"
  230. placeholder="选择日期">
  231. </el-date-picker>
  232. </el-form-item>
  233. <el-form-item label="通讯地址"
  234. prop="contactAddress"
  235. :label-width="formLabelWidth">
  236. <el-input v-model.trim="form.contactAddress"
  237. autocomplete="off"></el-input>
  238. </el-form-item>
  239. <el-form-item label="邮政编码"
  240. prop="postalCode"
  241. :label-width="formLabelWidth">
  242. <el-input v-model.trim="form.postalCode"
  243. autocomplete="off"></el-input>
  244. </el-form-item>
  245. </el-form>
  246. <span slot="footer"
  247. class="dialog-footer">
  248. <el-button @click="roleStatus = false">取 消</el-button>
  249. <el-button @click="onRoleSubmit('ruleForm')"
  250. type="primary">确 定</el-button>
  251. </span>
  252. </el-dialog>
  253. <el-dialog title="教务交接"
  254. width="400px"
  255. destroy-on-close
  256. close-on-click-modal
  257. :visible.sync="educationViseble">
  258. <el-form :model="educationForm"
  259. :inline="true"
  260. ref="educationForm">
  261. <el-form-item label="乐团主管"
  262. :rules="[{
  263. required:
  264. true,
  265. message: '请选择乐团主管'
  266. ,
  267. trigger: 'blur'
  268. }]">
  269. <el-select v-model.trim="
  270. educationForm.targetUserId"
  271. clearable
  272. filterable>
  273. <el-option v-for="item in educationList"
  274. :key="item.userId"
  275. :label="item.userName"
  276. :value="item.userId"></el-option>
  277. </el-select>
  278. </el-form-item>
  279. </el-form>
  280. <span slot="footer"
  281. class="dialog-footer">
  282. <el-button @click="educationViseble = false">取 消</el-button>
  283. <el-button @click="submitEducation"
  284. type="primary">确 定</el-button>
  285. </span>
  286. </el-dialog>
  287. </div>
  288. </template>
  289. <script>
  290. import pagination from '@/components/Pagination/index'
  291. import { queryEmployByOrganId, employeeOperate, getUserRole, employeeAdd, employeeUpdate, hasCourseGroupRelation, updateEducationTeacherId } from '@/api/systemManage'
  292. import { branchQueryPage, findEducationTeacher } from '@/api/specialSetting'
  293. import { findEducationUsers } from '@/api/buildTeam'
  294. import store from '@/store'
  295. import { isvalidPhone } from '@/utils/validate'
  296. let validPhone = (rule, value, callback) => {
  297. if (!value) {
  298. callback(new Error('请输入电话号码'))
  299. } else if (!isvalidPhone(value)) {
  300. callback(new Error('请输入正确的11位手机号码'))
  301. } else {
  302. callback()
  303. }
  304. }
  305. export default {
  306. name: 'staffManager',
  307. components: { pagination },
  308. data () {
  309. return {
  310. tableList: [],
  311. educationList: [],
  312. educationForm: {
  313. targetUserId: ''
  314. },
  315. educationViseble: false,
  316. activeRow: null,
  317. pageInfo: {
  318. // 分页规则
  319. limit: 10, // 限制显示条数
  320. page: 1, // 当前页
  321. total: 0, // 总条数
  322. page_size: [10, 20, 40, 50] // 选择限制显示条数
  323. },
  324. roleStatus: false,
  325. formActionTitle: 'create',
  326. roleList: [], // 角色列表
  327. formTitle: {
  328. create: '添加员工',
  329. update: '修改员工'
  330. },
  331. formLabelWidth: '100px',
  332. form: {
  333. realName: null,
  334. gender: null,
  335. phone: null,
  336. roleIds: [],
  337. organIdLists: [],
  338. jobNature: null,
  339. entryDate: null,
  340. contactAddress: null,
  341. postalCode: null
  342. },
  343. rules: {
  344. realName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  345. gender: [{ required: true, message: '请选择性别', trigger: 'change' }],
  346. phone: [{ type: 'number', required: true, validator: validPhone, trigger: 'blur' }, { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }],
  347. roleIds: [{ type: 'array', required: true, message: '请选择分类', trigger: 'change' }],
  348. organIdLists: [{ type: 'array', required: true, message: '请选择所属部门', trigger: 'change' }],
  349. jobNature: [{ required: true, message: '请选择工作类型', trigger: 'change' }],
  350. entryDate: [{ required: true, message: '请选择入职时间', trigger: 'blur' }],
  351. },
  352. searchForm: {
  353. search: null,
  354. jobNature: null,
  355. organId: null,
  356. roleId: null
  357. }
  358. }
  359. },
  360. mounted () {
  361. this.getList()
  362. this.getRoleList()
  363. },
  364. activated () {
  365. this.getList()
  366. this.getRoleList()
  367. },
  368. methods: {
  369. onBranchCheckAll () {
  370. this.form.organIdLists = []
  371. this.selects.branchs.forEach(item => {
  372. this.form.organIdLists.push(item.value)
  373. })
  374. },
  375. onRoleSubmit (formName) {
  376. this.$refs[formName].validate((valid) => {
  377. if (valid) {
  378. this.form.organIdList = this.form.organIdLists.join(',')
  379. if (this.formActionTitle == 'create') {
  380. if (this.form.id) { // 判断有没有Id,如果有则删除
  381. delete this.form.id
  382. }
  383. employeeAdd(this.form).then(res => {
  384. this.messageTips('添加', res)
  385. })
  386. } else if (this.formActionTitle == 'update') {
  387. employeeUpdate(this.form).then(res => {
  388. this.messageTips('修改', res)
  389. })
  390. }
  391. } else {
  392. return
  393. }
  394. })
  395. },
  396. messageTips (title, res) {
  397. if (res.code == 200) {
  398. this.$message.success(title + '成功')
  399. this.roleStatus = false
  400. this.getList()
  401. } else {
  402. this.$message.error(res.msg)
  403. }
  404. },
  405. search () {
  406. this.pageInfo.page = 1
  407. this.getList()
  408. },
  409. getList () {
  410. let searchForm = this.searchForm
  411. let params = {
  412. search: searchForm.search ? searchForm.search : null,
  413. jobNature: searchForm.jobNature ? searchForm.jobNature : null,
  414. organId: searchForm.organId ? searchForm.organId : null,
  415. roleId: searchForm.roleId ? searchForm.roleId : null,
  416. rows: this.pageInfo.limit,
  417. page: this.pageInfo.page
  418. }
  419. queryEmployByOrganId(params).then(res => {
  420. if (res.code == 200 && res.data) {
  421. this.tableList = res.data.rows
  422. this.pageInfo.total = res.data.total
  423. }
  424. })
  425. },
  426. getRoleList () { // 获取角色
  427. getUserRole({ delFlag: 0, rows: 9999 }).then(res => {
  428. let result = res.data
  429. if (res.code == 200 && result && result.rows.length > 0) {
  430. this.roleList = []
  431. result.rows.forEach(item => {
  432. this.roleList.push({
  433. label: item.roleName,
  434. value: item.id
  435. })
  436. })
  437. }
  438. })
  439. this.$store.dispatch('setBranchs')
  440. },
  441. roleOperation (type, data) {
  442. this.formActionTitle = type
  443. this.roleStatus = true
  444. // 修改的时候
  445. if (type == 'update') {
  446. this.form = {
  447. id: data.id,
  448. realName: data.realName,
  449. gender: data.gender,
  450. phone: Number(data.phone),
  451. roleIds: data.roleIds,
  452. organIdLists: data.organIdList ? data.organIdList : [],
  453. jobNature: data.jobNature,
  454. entryDate: data.entryDate,
  455. contactAddress: data.contactAddress,
  456. postalCode: data.postalCode
  457. }
  458. }
  459. },
  460. onFormClose (formName) { // 关闭弹窗重置验证
  461. this.form = {
  462. realName: null,
  463. gender: null,
  464. phone: null,
  465. roleName: null,
  466. organIdLists: [],
  467. jobNature: null,
  468. entryDate: null
  469. }
  470. this.$refs[formName].resetFields()
  471. },
  472. formatLockFlag (row) {
  473. let reuslt = ['正常', '冻结']
  474. if (row.demissionDate) {
  475. return '离职'
  476. } else {
  477. return reuslt[row.lockFlag]
  478. }
  479. },
  480. async checkStatus (data) {
  481. let status;
  482. await hasCourseGroupRelation({ employeeId: data.id }).then(async res => {
  483. if (res.code === 200) {
  484. if (res.data.hasCourseSchedule) {
  485. this.$message.error('请先交接指导老师课程')
  486. status = false
  487. } else {
  488. if (res.data.hasCourseGroupRelation) {
  489. let userId = data.id
  490. await findEducationTeacher({ userId }).then(res => {
  491. if (res.code === 200) {
  492. this.educationList = res.data;
  493. this.educationViseble = true
  494. status = false
  495. }
  496. })
  497. } else {
  498. // 1 要弹出
  499. status = true
  500. }
  501. }
  502. }
  503. })
  504. return status
  505. },
  506. onStaffOperation (type, data) {
  507. const tempStatus = type == 'RESET_PASSWORD' ? true : false
  508. this.$confirm(`您确定${tempStatus ? '重置密码' : '修改员工状态'}?`, "提示", {
  509. confirmButtonText: "确定",
  510. cancelButtonText: "取消",
  511. type: "warning"
  512. }).then(async () => {
  513. if (type === 'DEMISSION' && !data.demissionDate) {
  514. this.activeRow = data;
  515. // 1.点击的是离职按钮
  516. // 2.判断该考级是否存在乐团主管
  517. const status = await this.checkStatus(data)
  518. if (!status) {
  519. return
  520. }
  521. }
  522. employeeOperate({
  523. employeeId: data.id,
  524. operate: type
  525. }).then(res => {
  526. if (res.code == 200) {
  527. this.$message.success(tempStatus ? '重置密码成功' : '更改成功')
  528. this.roleStatus = false
  529. this.getList()
  530. } else {
  531. this.$message.error(res.msg)
  532. }
  533. })
  534. }).catch(err => { })
  535. },
  536. submitEducation () {
  537. // 发请求 提交信息
  538. updateEducationTeacherId({ currentUserId: this.activeRow.id, targetUserId: this.educationForm.targetUserId }).then(res => {
  539. if (res.code === 200) {
  540. const type = 'DEMISSION'
  541. const data = this.activeRow;
  542. employeeOperate({
  543. employeeId: data.id,
  544. operate: type
  545. }).then(res => {
  546. if (res.code == 200) {
  547. this.$message.success('更改成功')
  548. this.roleStatus = false
  549. this.educationViseble = false
  550. this.getList()
  551. } else {
  552. this.$message.error(res.msg)
  553. }
  554. })
  555. }
  556. })
  557. },
  558. },
  559. watch: {
  560. educationViseble (val) {
  561. if (!val) {
  562. this.educationForm.targetUserId = ''
  563. this.$refs['educationForm'].resetFields()
  564. }
  565. }
  566. }
  567. }
  568. </script>
  569. <style lang="scss" scoped>
  570. /deep/.el-button--primary {
  571. background: #14928a;
  572. border-color: #14928a;
  573. color: #fff;
  574. &:hover,
  575. &:active,
  576. &:focus {
  577. background: #14928a;
  578. border-color: #14928a;
  579. color: #fff;
  580. }
  581. }
  582. /deep/.el-dialog__body {
  583. padding: 0 20px;
  584. }
  585. /deep/.el-select,
  586. /deep/.el-date-editor.el-input {
  587. width: 100% !important;
  588. }
  589. </style>