index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <template>
  2. <div style="padding: 0px 0px 8px 8px">
  3. <el-row :gutter="8" style="width: 100%">
  4. <el-col :xs="24" :sm="8" :md="8" :lg="6" :xl="4">
  5. <div class="my-flex-column h100">
  6. <org-menu @node-click="onOrgNodeClick" class="my-flex-fill" select-first-node></org-menu>
  7. </div>
  8. </el-col>
  9. <el-col :xs="24" :sm="16" :md="16" :lg="18" :xl="20">
  10. <el-card shadow="never" :body-style="{ paddingBottom: '0' }" style="margin-top: 8px">
  11. <el-form :model="state.filterModel" :inline="true">
  12. <el-form-item label="姓名" prop="name">
  13. <el-input v-model="state.filterModel.name" placeholder="姓名" />
  14. </el-form-item>
  15. <el-form-item>
  16. <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
  17. <el-button v-auth="'api:admin:user:add'" type="primary" icon="ele-Plus" @click="onAdd"> 新增 </el-button>
  18. </el-form-item>
  19. </el-form>
  20. </el-card>
  21. <el-card shadow="never" style="margin-top: 8px">
  22. <el-table v-loading="state.loading" :data="state.userListData" row-key="id" style="width: 100%">
  23. <el-table-column prop="name" label="姓名" width="120" show-overflow-tooltip>
  24. <template #default="{ row }"> {{ row.name }} <el-tag v-if="row.isManager" type="success">主管</el-tag> </template>
  25. </el-table-column>
  26. <el-table-column prop="mobile" label="手机号" width="120" show-overflow-tooltip />
  27. <el-table-column prop="email" label="邮箱" min-width="120" show-overflow-tooltip />
  28. <el-table-column prop="roleNames" label="角色" min-width="120" show-overflow-tooltip>
  29. <template #default="{ row }">
  30. {{ row.roleNames ? row.roleNames.join(',') : '' }}
  31. </template>
  32. </el-table-column>
  33. <el-table-column label="操作" width="160" fixed="right" header-align="center" align="center">
  34. <template #default="{ row }">
  35. <el-button v-auth="'api:admin:user:update'" icon="ele-EditPen" size="small" text type="primary" @click="onEdit(row)">编辑</el-button>
  36. <my-dropdown-more v-auths="['api:admin:user:set-manager', 'api:admin:user:reset-password', 'api:admin:user:delete']">
  37. <template #dropdown>
  38. <el-dropdown-menu>
  39. <el-dropdown-item v-if="auth('api:admin:user:set-manager')" @click="onSetManager(row)"
  40. >{{ row.isManager ? '取消' : '设置' }}主管</el-dropdown-item
  41. >
  42. <el-dropdown-item v-if="auth('api:admin:user:reset-password')" @click="onResetPwd(row)">重置密码</el-dropdown-item>
  43. <el-dropdown-item v-if="auth('api:admin:user:delete')" @click="onDelete(row)">删除用户</el-dropdown-item>
  44. </el-dropdown-menu>
  45. </template>
  46. </my-dropdown-more>
  47. </template>
  48. </el-table-column>
  49. </el-table>
  50. <div class="my-flex my-flex-end" style="margin-top: 20px">
  51. <el-pagination
  52. v-model:currentPage="state.pageInput.currentPage"
  53. v-model:page-size="state.pageInput.pageSize"
  54. :total="state.total"
  55. :page-sizes="[10, 20, 50, 100]"
  56. small
  57. background
  58. @size-change="onSizeChange"
  59. @current-change="onCurrentChange"
  60. layout="total, sizes, prev, pager, next, jumper"
  61. />
  62. </div>
  63. </el-card>
  64. </el-col>
  65. </el-row>
  66. <user-form ref="userFormRef" :title="state.userFormTitle"></user-form>
  67. </div>
  68. </template>
  69. <script lang="ts" setup>
  70. import { ref, reactive, onMounted, getCurrentInstance, onUnmounted, defineAsyncComponent } from 'vue'
  71. import { UserGetPageOutput, PageInputUserGetPageDto, OrgListOutput, UserSetManagerInput, UserResetPasswordInput } from '/@/api/admin/data-contracts'
  72. import { User as UserApi } from '/@/api/admin/User'
  73. import eventBus from '/@/utils/mitt'
  74. import { auth } from '/@/utils/authFunction'
  75. // 引入组件
  76. const UserForm = defineAsyncComponent(() => import('./components/user-form.vue'))
  77. const OrgMenu = defineAsyncComponent(() => import('/@/views/admin/org/components/org-menu.vue'))
  78. const MyDropdownMore = defineAsyncComponent(() => import('/@/components/my-dropdown-more/index.vue'))
  79. const { proxy } = getCurrentInstance() as any
  80. const userFormRef = ref()
  81. const state = reactive({
  82. loading: false,
  83. userFormTitle: '',
  84. filterModel: {
  85. name: '',
  86. },
  87. total: 0,
  88. pageInput: {
  89. currentPage: 1,
  90. pageSize: 20,
  91. filter: {
  92. orgId: null,
  93. },
  94. } as PageInputUserGetPageDto,
  95. userListData: [] as Array<UserGetPageOutput>,
  96. })
  97. onMounted(() => {
  98. eventBus.on('refreshUser', async () => {
  99. onQuery()
  100. })
  101. })
  102. onUnmounted(() => {
  103. eventBus.off('refreshUser')
  104. })
  105. const onQuery = async () => {
  106. state.loading = true
  107. const res = await new UserApi().getPage(state.pageInput)
  108. state.userListData = res?.data?.list ?? []
  109. state.total = res.data?.total ?? 0
  110. state.loading = false
  111. }
  112. const onAdd = () => {
  113. state.userFormTitle = '新增用户'
  114. userFormRef.value.open()
  115. }
  116. const onEdit = (row: UserGetPageOutput) => {
  117. state.userFormTitle = '编辑用户'
  118. userFormRef.value.open(row)
  119. }
  120. const onDelete = (row: UserGetPageOutput) => {
  121. proxy.$modal
  122. .confirmDelete(`确定要删除【${row.name}】?`)
  123. .then(async () => {
  124. await new UserApi().delete({ id: row.id }, { loading: true, showSuccessMessage: true })
  125. onQuery()
  126. })
  127. .catch(() => {})
  128. }
  129. const onResetPwd = (row: UserGetPageOutput) => {
  130. proxy.$modal
  131. .prompt(`确定要给【${row.name}】重置密码?`, { inputPlaceholder: '选填,不填则使用系统默认密码', autofocus: false })
  132. .then(async ({ value }: { value: string }) => {
  133. const res = await new UserApi().resetPassword({ id: row.id, password: value } as UserResetPasswordInput, { loading: true })
  134. if (res?.success) {
  135. proxy.$modal.msgSuccess(`重置密码成功,密码为:${res.data}`)
  136. }
  137. onQuery()
  138. })
  139. .catch(() => {})
  140. }
  141. const onSetManager = (row: UserGetPageOutput) => {
  142. if (!((state.pageInput.filter?.orgId as number) > 0)) {
  143. proxy.$modal.msgWarning('请选择部门')
  144. return
  145. }
  146. const title = row.isManager ? `确定要取消【${row.name}】的主管?` : `确定要设置【${row.name}】为主管?`
  147. proxy.$modal
  148. .confirm(title)
  149. .then(async () => {
  150. const input = { userId: row.id, orgId: state.pageInput.filter?.orgId, isManager: !row.isManager } as UserSetManagerInput
  151. await new UserApi().setManager(input, { loading: true, showSuccessMessage: true })
  152. onQuery()
  153. })
  154. .catch(() => {})
  155. }
  156. const onSizeChange = (val: number) => {
  157. state.pageInput.pageSize = val
  158. onQuery()
  159. }
  160. const onCurrentChange = (val: number) => {
  161. state.pageInput.currentPage = val
  162. onQuery()
  163. }
  164. const onOrgNodeClick = (node: OrgListOutput | null) => {
  165. if (state.pageInput.filter) {
  166. state.pageInput.filter.orgId = node?.id
  167. }
  168. onQuery()
  169. }
  170. </script>
  171. <script lang="ts">
  172. import { defineComponent } from 'vue'
  173. export default defineComponent({
  174. name: 'admin/user',
  175. })
  176. </script>
  177. <style scoped lang="scss"></style>