User.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <script setup lang="tsx">
  2. import { ContentWrap } from '@/components/ContentWrap'
  3. import { useI18n } from '@/hooks/web/useI18n'
  4. import { Table, TableColumn } from '@/components/Table'
  5. import { ref, unref, nextTick, watch } from 'vue'
  6. import { ElButton, ElTree, ElInput, ElDivider } from 'element-plus'
  7. import { getDepartmentApi, getUserByIdApi } from '@/api/department'
  8. import type { DepartmentItem, DepartmentUserItem } from '@/api/department/types'
  9. import { useTable } from '@/hooks/web/useTable'
  10. import { Search } from '@/components/Search'
  11. import { FormSchema } from '@/components/Form'
  12. const { t } = useI18n()
  13. const { tableRegister, tableState, tableMethods } = useTable({
  14. fetchDataApi: async () => {
  15. const { pageSize, currentPage } = tableState
  16. const res = await getUserByIdApi({
  17. id: unref(currentNodeKey),
  18. pageIndex: unref(currentPage),
  19. pageSize: unref(pageSize),
  20. ...unref(searchParams)
  21. })
  22. return {
  23. list: res.data.list || [],
  24. total: res.data.total || 0
  25. }
  26. }
  27. })
  28. const { total, loading, dataList, pageSize, currentPage } = tableState
  29. const { getList } = tableMethods
  30. const columns: TableColumn[] = [
  31. {
  32. field: 'index',
  33. label: t('userDemo.index'),
  34. type: 'index'
  35. },
  36. {
  37. field: 'username',
  38. label: t('userDemo.username')
  39. },
  40. {
  41. field: 'account',
  42. label: t('userDemo.account')
  43. },
  44. {
  45. field: 'role',
  46. label: t('userDemo.role')
  47. },
  48. {
  49. field: 'email',
  50. label: t('userDemo.email')
  51. },
  52. {
  53. field: 'createTime',
  54. label: t('userDemo.createTime')
  55. },
  56. {
  57. field: 'action',
  58. label: t('userDemo.action'),
  59. slots: {
  60. default: (data) => {
  61. return (
  62. <ElButton type="primary" onClick={() => actionFn(data[0].row)}>
  63. {t('tableDemo.action')}
  64. </ElButton>
  65. )
  66. }
  67. }
  68. }
  69. ]
  70. const searchSchema: FormSchema[] = [
  71. {
  72. field: 'username',
  73. label: t('userDemo.username'),
  74. component: 'Input'
  75. },
  76. {
  77. field: 'account',
  78. label: t('userDemo.account'),
  79. component: 'Input'
  80. }
  81. ]
  82. const searchParams = ref({})
  83. const setSearchParams = (params: any) => {
  84. currentPage.value = 1
  85. searchParams.value = params
  86. getList()
  87. }
  88. const actionFn = (data: DepartmentUserItem) => {
  89. console.log(data)
  90. }
  91. const treeEl = ref<typeof ElTree>()
  92. const currentNodeKey = ref('')
  93. const departmentList = ref<DepartmentItem[]>([])
  94. const fetchDepartment = async () => {
  95. const res = await getDepartmentApi()
  96. departmentList.value = res.data.list
  97. currentNodeKey.value =
  98. (res.data.list[0] && res.data.list[0]?.children && res.data.list[0].children[0].id) || ''
  99. await nextTick()
  100. unref(treeEl)?.setCurrentKey(currentNodeKey.value)
  101. }
  102. fetchDepartment()
  103. const currentDepartment = ref('')
  104. watch(
  105. () => currentDepartment.value,
  106. (val) => {
  107. unref(treeEl)!.filter(val)
  108. }
  109. )
  110. const currentChange = (data: DepartmentItem) => {
  111. if (data.children) return
  112. currentNodeKey.value = data.id
  113. currentPage.value = 1
  114. getList()
  115. }
  116. const filterNode = (value: string, data: DepartmentItem) => {
  117. if (!value) return true
  118. return data.departmentName.includes(value)
  119. }
  120. </script>
  121. <template>
  122. <div class="flex w-100% h-100%">
  123. <ContentWrap class="flex-1">
  124. <div class="flex justify-center items-center">
  125. <div class="flex-1">{{ t('userDemo.departmentList') }}</div>
  126. <ElInput
  127. v-model="currentDepartment"
  128. class="flex-[2]"
  129. :placeholder="t('userDemo.searchDepartment')"
  130. clearable
  131. />
  132. </div>
  133. <ElDivider />
  134. <ElTree
  135. ref="treeEl"
  136. :data="departmentList"
  137. default-expand-all
  138. node-key="id"
  139. :current-node-key="currentNodeKey"
  140. :props="{
  141. label: 'departmentName'
  142. }"
  143. :filter-node-method="filterNode"
  144. @current-change="currentChange"
  145. />
  146. </ContentWrap>
  147. <ContentWrap class="flex-[2] ml-20px">
  148. <Search
  149. :schema="searchSchema"
  150. @reset="setSearchParams"
  151. @search="setSearchParams"
  152. :search-loading="loading"
  153. />
  154. <div>
  155. <Table
  156. v-model:current-page="currentPage"
  157. v-model:page-size="pageSize"
  158. :columns="columns"
  159. :data="dataList"
  160. :loading="loading"
  161. @register="tableRegister"
  162. :pagination="{
  163. total
  164. }"
  165. />
  166. </div>
  167. </ContentWrap>
  168. </div>
  169. </template>