index.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <template>
  2. <div class="white pa-3 content" v-loading="loading">
  3. <m-card class="content-left mr-3">
  4. <el-tree
  5. ref="tree"
  6. :data="organizationTree"
  7. :props="defaultProps"
  8. node-key="organizationNo"
  9. :expand-on-click-node="false"
  10. highlight-current
  11. :default-expanded-keys="[expandExpandedKeys]"
  12. @node-click="handleNodeClick"
  13. >
  14. <template v-slot="{ data }">
  15. <div class="text">
  16. <div>{{ data.organizationName }}</div>
  17. <div class="eye text-link" @click.stop="onJump(data.organizationNo)">
  18. <span class="mdi mdi-eye"></span>
  19. <span class="min ml-1">
  20. 详情
  21. </span>
  22. </div>
  23. </div>
  24. </template>
  25. </el-tree>
  26. </m-card>
  27. <m-table
  28. class="content-right"
  29. :headers="headers"
  30. :items="items"
  31. :page-size="pageInfo.size"
  32. :page-current="pageInfo.current"
  33. :total="total"
  34. @page-change="onPageChange"
  35. @sort-change="onSortChange"
  36. >
  37. <template #parentOrganizationName="{ row }">
  38. <span class="text-link" @click="onJump(row.parentOrganizationNo)">
  39. {{ row.parentOrganizationName || '--' }}
  40. </span>
  41. </template>
  42. <template #deptName="{ row }">
  43. <span class="text-link" @click="onJump(row.organizationNo)">
  44. {{ row.deptName || '--' }}
  45. </span>
  46. </template>
  47. <template #employeeName="{ row }">
  48. <span class="text-link" @click="onJump(row.organizationNo, row)">
  49. {{ row.employeeName || '--' }}
  50. </span>
  51. </template>
  52. <template #actions-header>
  53. <el-input
  54. v-model="searchQuery.employeeName"
  55. size="mini"
  56. placeholder="输入员工名字,按回车搜索"
  57. @keydown.enter.native="onSearch"
  58. ></el-input>
  59. </template>
  60. </m-table>
  61. </div>
  62. </template>
  63. <script>
  64. import {
  65. getOrganizationDetails
  66. } from '@/api/system'
  67. import qs from 'qs'
  68. import { mapGetters } from 'vuex'
  69. export default {
  70. name: 'human-resources-panorama',
  71. data () {
  72. return {
  73. searchQuery: {
  74. organizationNo: null,
  75. employeeName: null
  76. },
  77. loading: false,
  78. defaultProps: {
  79. children: 'child',
  80. label: 'organizationName'
  81. },
  82. expandExpandedKeys: null,
  83. pageInfo: {
  84. current: 1,
  85. size: 10
  86. },
  87. total: 0,
  88. orders: [],
  89. headers: [
  90. { label: '上级机构', prop: 'parentOrganizationName' },
  91. { label: '部门', prop: 'deptName' },
  92. { label: '员工姓名', prop: 'employeeName', align: 'center' },
  93. { label: '岗位', prop: 'postName' },
  94. { label: '', prop: 'actions' }
  95. ],
  96. items: []
  97. }
  98. },
  99. computed: {
  100. ...mapGetters(['organizationTree'])
  101. },
  102. created () {
  103. this.getDept()
  104. },
  105. methods: {
  106. async getDept () {
  107. if (!this.organizationTree.length) {
  108. return
  109. }
  110. this.expandExpandedKeys = this.organizationTree[0].organizationNo
  111. this.handleNodeClick({ organizationNo: this.organizationTree[0].organizationNo })
  112. this.$nextTick(() => {
  113. this.$refs.tree.setCurrentKey(this.organizationTree[0].organizationNo)
  114. })
  115. },
  116. async onInit () {
  117. this.loading = true
  118. try {
  119. const { data } = await getOrganizationDetails({
  120. ...this.searchQuery,
  121. employeePage: {
  122. ...this.pageInfo,
  123. orders: this.orders
  124. }
  125. })
  126. this.items = data.employees.records
  127. this.total = data.employees.total
  128. } catch (error) {
  129. this.$message.error(error)
  130. } finally {
  131. this.loading = false
  132. }
  133. },
  134. async handleNodeClick ({ organizationNo }) {
  135. this.searchQuery.organizationNo = organizationNo
  136. this.onInit()
  137. },
  138. onJump (organizationNo, employee) {
  139. const _ROOT = '/human-resources/panorama/details'
  140. const query = {
  141. organizationNo: organizationNo
  142. }
  143. if (employee) {
  144. query.employeeNo = employee.personnelCode
  145. query.employeeName = employee.employeeName
  146. }
  147. window.open(`${_ROOT}?${qs.stringify(query)}`)
  148. },
  149. onPageChange (index) {
  150. this.pageInfo.current = index
  151. this.onInit()
  152. },
  153. onSearch () {
  154. this.pageInfo.current = 1
  155. this.onInit()
  156. },
  157. onSortChange (e) {
  158. this.orders = e
  159. this.onInit()
  160. }
  161. }
  162. }
  163. </script>
  164. <style lang="scss" scoped>
  165. .content {
  166. height: 100%;
  167. box-sizing: border-box;
  168. display: flex;
  169. &-left {
  170. width: 400px;
  171. overflow: auto;
  172. font-size: 14px;
  173. .text {
  174. display: flex;
  175. justify-content: space-between;
  176. flex: 1;
  177. .eye {
  178. position: absolute;
  179. right: 0;
  180. padding: 0 10px;
  181. font-size: 18px;
  182. display: flex;
  183. align-items: center;
  184. }
  185. }
  186. }
  187. &-right {
  188. flex: 1;
  189. width: 0;
  190. overflow: auto;
  191. }
  192. }
  193. .min {
  194. font-size: 12px;
  195. }
  196. </style>