index.vue 4.9 KB

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