ims-front/src/views/admin/acl/users/user-list.vue
my_ong 2ffb3ae55c
Some checks failed
Release / lint (push) Successful in 44s
Release / Release (push) Failing after 56s
bug: 🐛 用户名校验
2025-03-14 16:20:47 +08:00

275 lines
7.6 KiB
Vue

<template>
<page-container :title="$t(String($route.meta.title))" :sub-title="$t('pages.acl.user.subTitle')">
<template #ops>
<a-row>
<a-col :span="18">
<a-input-search
v-model:value="searchKey"
:placeholder="$t('pages.acl.user.search.placeholder')"
allow-clear
enter-button
@search="loadUsers()"
>
<template #addonBefore>
<a-select
v-model:value="selectedSex"
allow-clear
:placeholder="$t('pages.acl.user.sex.placeholder')"
style="width: 80px"
>
<a-select-option v-for="sex in sexes" :key="sex.code" :value="sex.name">
{{ useAppStore().isCN ? sex.description : sex.code }}
</a-select-option>
</a-select>
</template>
</a-input-search>
</a-col>
<a-col :span="6">
<a-button type="primary" style="margin-left: 10px" @click="addOrEditUser()">
<template #icon>
<icon-font type="icon-plus" />
</template>
{{ $t('pages.acl.user.add') }}
</a-button>
</a-col>
</a-row>
</template>
<div style="min-height: calc(100vh - 305px)">
<a-table
:columns="columns"
:data-source="userPage?.records"
bordered
:pagination="pagination"
:loading="loading"
row-key="name"
@expand="tryLoadPermissions"
>
<template #expandedRowRender="{ record }">
<permission-info-panel
type="user"
:ref-key="record.name"
:name="record.fullName"
:permissions="record.permissions"
></permission-info-panel>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'sex'">
<icon-font v-if="record.sex === 'MALE'" type="icon-male" :title="record.sexInfo?.description"></icon-font>
<icon-font v-else type="icon-female" :title="record.sexInfo.description"></icon-font>
</template>
<template v-if="column.dataIndex === 'operation'">
<a-button type="link" @click="addOrEditUser(record)">
<template #icon>
<icon-font type="icon-edit" />
</template>
{{ $t('pages.acl.user.edit') }}
</a-button>
<a-popconfirm @confirm="resetPassword(record.name)">
<template #title>
<p>
{{ $t('pages.acl.user.confirm.reset.title', { name: record.name }) }}
</p>
<p>{{ $t('pages.acl.user.confirm.reset.description') }}</p>
</template>
<a-button type="link" style="margin-left: 10px">
<template #icon>
<icon-font type="icon-reset-password" />
</template>
{{ $t('pages.acl.user.reset') }}
</a-button>
</a-popconfirm>
<a-popconfirm
:title="$t('pages.acl.user.confirm.delete.title', { name: record.name })"
@confirm="deleteUser(record.id)"
>
<a-button type="link" danger style="margin-left: 10px">
<template #icon>
<icon-font type="icon-delete" />
</template>
{{ $t('pages.acl.user.delete') }}
</a-button>
</a-popconfirm>
</template>
</template>
</a-table>
</div>
<!-- 重置密码的回显框 -->
<a-modal
v-model:open="passwordModalShow"
:title="$t('pages.acl.user.modal.reset.title')"
@ok="passwordModalShow = false"
>
<a-alert
:message="$t('pages.acl.user.modal.reset.title')"
:description="$t('pages.acl.user.modal.reset.description')"
type="success"
show-icon
></a-alert>
<a-typography-paragraph copyable>{{ newPassword }}</a-typography-paragraph>
</a-modal>
<!-- 添加编辑用户弹窗 -->
<form-drawer
ref="modalForm"
v-model="user"
:form-items="items"
:config="formConfig"
:hidden-fields="hiddenFields"
:disabled-fields="disabledFields"
:title="modalTitle"
@ok="doAddUser"
/>
</page-container>
</template>
<script lang="ts" setup>
import { api } from '@/api'
import type { Codebook, IPage } from '@/api/api'
import PermissionInfoPanel from '../components/permission-info-panel.vue'
import { notification } from 'ant-design-vue'
import { useI18n } from 'vue-i18n'
import { useAppStore } from '@/stores/app'
import FormDrawer from '@/components/form-render/form-drawer.vue'
import { config, formItems } from './userForm'
import { FormDataType } from '@/components/form-render/form-render-types'
const { t } = useI18n()
const sexes = ref<Codebook[]>([])
api.aclApi.user.sexes((data) => {
sexes.value = data
})
const searchKey = ref('')
const selectedSex = ref<'MALE' | 'FEMALE' | undefined>()
const userPage = ref<IPage<acl.User>>()
const loading = ref(false)
const loadUsers = (sex: 'MALE' | 'FEMALE' | undefined = undefined, page = 1, size = 10) => {
loading.value = true
api.aclApi.user.users(
{
page: page || userPage.value?.current,
size: size || userPage.value?.size,
key: searchKey.value,
sex: sex || selectedSex.value,
},
(data) => {
loading.value = false
userPage.value = data
},
)
}
loadUsers()
//表格列
const columns = [
{
title: t('pages.acl.user.table.columns.name'),
dataIndex: 'name',
},
{
title: t('pages.acl.user.table.columns.fullName'),
dataIndex: 'fullName',
},
{
title: t('pages.acl.user.table.columns.mobile'),
dataIndex: 'mobile',
},
{
title: t('pages.acl.user.table.columns.email'),
dataIndex: 'email',
},
{
title: t('pages.acl.user.table.columns.sex'),
dataIndex: 'sex',
},
{
title: t('pages.acl.user.table.columns.operation'),
dataIndex: 'operation',
},
]
//分页信息
const pagination = computed(() => {
return {
current: userPage.value?.current,
pageSize: userPage.value?.size,
total: userPage.value?.total,
onChange: (page: number, pageSize: number) => {
console.log(page, pageSize)
loadUsers(undefined, page, pageSize)
},
}
})
//待添加/编辑的用户
const user = ref<Partial<acl.User>>({})
//表单
const modalForm = ref<typeof FormDrawer>()
const formConfig = computed(() => {
return config
})
//表单配置
const items = computed(() => {
return formItems(sexes.value)
})
//禁用字段
const disabledFields = computed(() => {
return user.value.id ? ['name'] : []
})
const hiddenFields = computed(() => {
return user.value.id ? ['password'] : []
})
//弹窗标题
const modalTitle = computed(() => {
return t(user.value.id ? 'pages.acl.user.edit' : 'pages.acl.user.add')
})
const addOrEditUser = (u?: Record<string, unknown>) => {
user.value = { ...(u ?? { sex: 'FEMALE' }) }
modalForm.value?.show()
}
//添加/编辑用户接口调用
const doAddUser = (user: FormDataType) => {
api.aclApi.user.saveOrUpdateUser(user as unknown as acl.User, () => {
modalForm.value?.close()
notification.success({
message: t('pages.acl.user.notification.success'),
description: t('pages.acl.user.notification.addOrEdit.description'),
onClose: () => {
loadUsers(undefined, 1)
},
})
})
}
const newPassword = ref('')
const passwordModalShow = ref(false)
//重置密码
const resetPassword = (name: string) => {
api.aclApi.user.resetPassword(name, (data) => {
newPassword.value = data
passwordModalShow.value = true
})
}
const deleteUser = (id: number) => {
api.aclApi.user.deleteUser(id, () => {
notification.success({
message: t('pages.acl.user.notification.success'),
description: t('pages.acl.user.notification.delete.description'),
onClose: () => {
loadUsers(undefined, 1)
},
})
})
}
const tryLoadPermissions = (expanded: boolean, record: acl.User & { permissions?: acl.Permission[] }) => {
if (expanded && !record.permissions) {
api.aclApi.user.permissions(record.name, (data) => {
record.permissions = data
})
}
}
</script>