lilyzhou
3 years ago
committed by
GitHub
9 changed files with 837 additions and 7 deletions
@ -0,0 +1,277 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
import { ref, watch, computed, InjectionKey } from 'vue' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import { useMessage } from 'naive-ui' |
||||||
|
import { queryTenantList } from '@/service/modules/tenants' |
||||||
|
import { queryList } from '@/service/modules/queues' |
||||||
|
import { |
||||||
|
createUser, |
||||||
|
updateUser, |
||||||
|
delUserById, |
||||||
|
verifyUserName |
||||||
|
} from '@/service/modules/users' |
||||||
|
import regexUtils from '@/utils/regex' |
||||||
|
export type Mode = 'add' | 'edit' | 'delete' |
||||||
|
|
||||||
|
export type UserModalSharedStateType = ReturnType< |
||||||
|
typeof useSharedUserModalState |
||||||
|
> & { |
||||||
|
onSuccess?: (mode: Mode) => void |
||||||
|
} |
||||||
|
|
||||||
|
export const UserModalSharedStateKey: InjectionKey<UserModalSharedStateType> = |
||||||
|
Symbol() |
||||||
|
|
||||||
|
export function useSharedUserModalState() { |
||||||
|
return { |
||||||
|
show: ref(false), |
||||||
|
mode: ref<Mode>('add'), |
||||||
|
user: ref() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export function useModal({ |
||||||
|
onSuccess, |
||||||
|
show, |
||||||
|
mode, |
||||||
|
user |
||||||
|
}: UserModalSharedStateType) { |
||||||
|
const message = useMessage() |
||||||
|
const { t } = useI18n() |
||||||
|
const formRef = ref() |
||||||
|
const formValues = ref({ |
||||||
|
userName: '', |
||||||
|
userPassword: '', |
||||||
|
tenantId: 0, |
||||||
|
email: '', |
||||||
|
queue: '', |
||||||
|
phone: '', |
||||||
|
state: 1 |
||||||
|
}) |
||||||
|
const tenants = ref<any[]>([]) |
||||||
|
const queues = ref<any[]>([]) |
||||||
|
const optionsLoading = ref(false) |
||||||
|
const confirmLoading = ref(false) |
||||||
|
|
||||||
|
const formRules = computed(() => { |
||||||
|
return { |
||||||
|
userName: { |
||||||
|
required: true, |
||||||
|
message: t('security.user.username_rule_msg'), |
||||||
|
trigger: 'blur' |
||||||
|
}, |
||||||
|
userPassword: { |
||||||
|
required: mode.value === 'add', |
||||||
|
validator(rule: any, value?: string) { |
||||||
|
if (mode.value !== 'add' && !value) { |
||||||
|
return true |
||||||
|
} |
||||||
|
const msg = t('security.user.user_password_rule_msg') |
||||||
|
if (!value || !regexUtils.password.test(value)) { |
||||||
|
return new Error(msg) |
||||||
|
} |
||||||
|
return true |
||||||
|
}, |
||||||
|
trigger: ['blur', 'input'] |
||||||
|
}, |
||||||
|
tenantId: { |
||||||
|
required: true, |
||||||
|
validator(rule: any, value?: number) { |
||||||
|
const msg = t('security.user.tenant_id_rule_msg') |
||||||
|
if (typeof value === 'number') { |
||||||
|
return true |
||||||
|
} |
||||||
|
return new Error(msg) |
||||||
|
}, |
||||||
|
trigger: 'blur' |
||||||
|
}, |
||||||
|
email: { |
||||||
|
required: true, |
||||||
|
validator(rule: any, value?: string) { |
||||||
|
const msg = t('security.user.email_rule_msg') |
||||||
|
if (!value || !regexUtils.email.test(value)) { |
||||||
|
return new Error(msg) |
||||||
|
} |
||||||
|
return true |
||||||
|
}, |
||||||
|
trigger: ['blur', 'input'] |
||||||
|
}, |
||||||
|
phone: { |
||||||
|
validator(rule: any, value?: string) { |
||||||
|
const msg = t('security.user.phone_rule_msg') |
||||||
|
if (value && !regexUtils.phone.test(value)) { |
||||||
|
return new Error(msg) |
||||||
|
} |
||||||
|
return true |
||||||
|
}, |
||||||
|
trigger: ['blur', 'input'] |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
const titleMap: Record<Mode, string> = { |
||||||
|
add: t('security.user.create_user'), |
||||||
|
edit: t('security.user.update_user'), |
||||||
|
delete: t('security.user.delete_user') |
||||||
|
} |
||||||
|
|
||||||
|
const setFormValues = () => { |
||||||
|
const defaultValues = { |
||||||
|
userName: '', |
||||||
|
userPassword: '', |
||||||
|
tenantId: tenants.value[0]?.value, |
||||||
|
email: '', |
||||||
|
queue: queues.value[0]?.value, |
||||||
|
phone: '', |
||||||
|
state: 1 |
||||||
|
} |
||||||
|
if (!user.value) { |
||||||
|
formValues.value = defaultValues |
||||||
|
} else { |
||||||
|
const v: any = {} |
||||||
|
Object.keys(defaultValues).map((k) => { |
||||||
|
v[k] = user.value[k] |
||||||
|
}) |
||||||
|
v.userPassword = '' |
||||||
|
formValues.value = v |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const prepareOptions = async () => { |
||||||
|
optionsLoading.value = true |
||||||
|
Promise.all([queryTenantList(), queryList()]) |
||||||
|
.then((res) => { |
||||||
|
tenants.value = |
||||||
|
res[0]?.map((d: any) => ({ |
||||||
|
label: d.tenantCode, |
||||||
|
value: d.id |
||||||
|
})) || [] |
||||||
|
queues.value = |
||||||
|
res[1]?.map((d: any) => ({ |
||||||
|
label: d.queueName, |
||||||
|
value: d.queue |
||||||
|
})) || [] |
||||||
|
}) |
||||||
|
.finally(() => { |
||||||
|
optionsLoading.value = false |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const onDelete = () => { |
||||||
|
confirmLoading.value = true |
||||||
|
delUserById({ id: user.value.id }) |
||||||
|
.then( |
||||||
|
() => { |
||||||
|
onSuccess?.(mode.value) |
||||||
|
onModalCancel() |
||||||
|
}, |
||||||
|
() => { |
||||||
|
message.error(t('security.user.delete_error_msg')) |
||||||
|
} |
||||||
|
) |
||||||
|
.finally(() => { |
||||||
|
confirmLoading.value = false |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const onCreateUser = () => { |
||||||
|
confirmLoading.value = true |
||||||
|
verifyUserName({ userName: formValues.value.userName }) |
||||||
|
.then( |
||||||
|
() => createUser(formValues.value), |
||||||
|
(error) => { |
||||||
|
if (`${error.message}`.includes('exists')) { |
||||||
|
message.error(t('security.user.username_exists')) |
||||||
|
} |
||||||
|
return false |
||||||
|
} |
||||||
|
) |
||||||
|
.then( |
||||||
|
(res) => { |
||||||
|
if (res) { |
||||||
|
onSuccess?.(mode.value) |
||||||
|
onModalCancel() |
||||||
|
} |
||||||
|
}, |
||||||
|
() => { |
||||||
|
message.error(t('security.user.save_error_msg')) |
||||||
|
} |
||||||
|
) |
||||||
|
.finally(() => { |
||||||
|
confirmLoading.value = false |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const onUpdateUser = () => { |
||||||
|
confirmLoading.value = true |
||||||
|
updateUser({ id: user.value.id, ...formValues.value }) |
||||||
|
.then( |
||||||
|
() => { |
||||||
|
onSuccess?.(mode.value) |
||||||
|
onModalCancel() |
||||||
|
}, |
||||||
|
() => { |
||||||
|
message.error(t('security.user.save_error_msg')) |
||||||
|
} |
||||||
|
) |
||||||
|
.finally(() => { |
||||||
|
confirmLoading.value = false |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const onConfirm = () => { |
||||||
|
if (mode.value === 'delete') { |
||||||
|
onDelete() |
||||||
|
} else { |
||||||
|
formRef.value.validate((errors: any) => { |
||||||
|
if (!errors) { |
||||||
|
user.value ? onUpdateUser() : onCreateUser() |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const onModalCancel = () => { |
||||||
|
show.value = false |
||||||
|
} |
||||||
|
|
||||||
|
watch([show, mode], () => { |
||||||
|
show.value && mode.value !== 'delete' && prepareOptions() |
||||||
|
}) |
||||||
|
|
||||||
|
watch([queues, tenants, user], () => { |
||||||
|
setFormValues() |
||||||
|
}) |
||||||
|
|
||||||
|
return { |
||||||
|
show, |
||||||
|
mode, |
||||||
|
user, |
||||||
|
titleMap, |
||||||
|
onModalCancel, |
||||||
|
formRef, |
||||||
|
formValues, |
||||||
|
formRules, |
||||||
|
tenants, |
||||||
|
queues, |
||||||
|
optionsLoading, |
||||||
|
onConfirm, |
||||||
|
confirmLoading |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
import { defineComponent, inject } from 'vue' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import { |
||||||
|
NInput, |
||||||
|
NForm, |
||||||
|
NFormItem, |
||||||
|
NSelect, |
||||||
|
NRadio, |
||||||
|
NRadioGroup, |
||||||
|
NSpace, |
||||||
|
NAlert |
||||||
|
} from 'naive-ui' |
||||||
|
|
||||||
|
import Modal from '@/components/modal' |
||||||
|
import { |
||||||
|
useModal, |
||||||
|
useSharedUserModalState, |
||||||
|
UserModalSharedStateKey |
||||||
|
} from './use-modal' |
||||||
|
|
||||||
|
export const UserModal = defineComponent({ |
||||||
|
name: 'user-modal', |
||||||
|
setup() { |
||||||
|
const { t } = useI18n() |
||||||
|
const sharedState = |
||||||
|
inject(UserModalSharedStateKey) || useSharedUserModalState() |
||||||
|
const modalState = useModal(sharedState) |
||||||
|
|
||||||
|
return { |
||||||
|
t, |
||||||
|
...modalState |
||||||
|
} |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t } = this |
||||||
|
return ( |
||||||
|
<Modal |
||||||
|
show={this.show} |
||||||
|
title={this.titleMap?.[this.mode || 'add']} |
||||||
|
onCancel={this.onModalCancel} |
||||||
|
confirmLoading={this.confirmLoading} |
||||||
|
onConfirm={this.onConfirm} |
||||||
|
> |
||||||
|
{{ |
||||||
|
default: () => { |
||||||
|
if (this.mode === 'delete') { |
||||||
|
return ( |
||||||
|
<NAlert type='error' title={t('security.user.delete_confirm')}> |
||||||
|
{t('security.user.delete_confirm_tip')} |
||||||
|
</NAlert> |
||||||
|
) |
||||||
|
} |
||||||
|
return ( |
||||||
|
<NForm |
||||||
|
ref='formRef' |
||||||
|
model={this.formValues} |
||||||
|
rules={this.formRules} |
||||||
|
labelPlacement='left' |
||||||
|
labelAlign='left' |
||||||
|
labelWidth={80} |
||||||
|
> |
||||||
|
<NFormItem label={t('security.user.username')} path='userName'> |
||||||
|
<NInput |
||||||
|
inputProps={{ autocomplete: 'off' }} |
||||||
|
v-model:value={this.formValues.userName} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem |
||||||
|
label={t('security.user.user_password')} |
||||||
|
path='userPassword' |
||||||
|
> |
||||||
|
<NInput |
||||||
|
inputProps={{ autocomplete: 'off' }} |
||||||
|
type='password' |
||||||
|
v-model:value={this.formValues.userPassword} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem |
||||||
|
label={t('security.user.tenant_code')} |
||||||
|
path='tenantId' |
||||||
|
> |
||||||
|
<NSelect |
||||||
|
options={this.tenants} |
||||||
|
v-model:value={this.formValues.tenantId} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('security.user.queue')} path='queue'> |
||||||
|
<NSelect |
||||||
|
options={this.queues} |
||||||
|
v-model:value={this.formValues.queue} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('security.user.email')} path='email'> |
||||||
|
<NInput v-model:value={this.formValues.email} /> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('security.user.phone')} path='phone'> |
||||||
|
<NInput v-model:value={this.formValues.phone} /> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('security.user.state')} path='state'> |
||||||
|
<NRadioGroup v-model:value={this.formValues.state}> |
||||||
|
<NSpace> |
||||||
|
<NRadio value={1}>启用</NRadio> |
||||||
|
<NRadio value={0}>停用</NRadio> |
||||||
|
</NSpace> |
||||||
|
</NRadioGroup> |
||||||
|
</NFormItem> |
||||||
|
</NForm> |
||||||
|
) |
||||||
|
} |
||||||
|
}} |
||||||
|
</Modal> |
||||||
|
) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
export default UserModal |
@ -0,0 +1,144 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
import { defineComponent, provide } from 'vue' |
||||||
|
import { |
||||||
|
NCard, |
||||||
|
NButton, |
||||||
|
NInputGroup, |
||||||
|
NInput, |
||||||
|
NIcon, |
||||||
|
NSpace, |
||||||
|
NGrid, |
||||||
|
NGridItem, |
||||||
|
NDataTable, |
||||||
|
NPagination, |
||||||
|
NSkeleton |
||||||
|
} from 'naive-ui' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import { SearchOutlined } from '@vicons/antd' |
||||||
|
import { useTable } from './use-table' |
||||||
|
import UserModal from './components/user-modal' |
||||||
|
import { |
||||||
|
useSharedUserModalState, |
||||||
|
UserModalSharedStateKey, |
||||||
|
Mode |
||||||
|
} from './components/use-modal' |
||||||
|
|
||||||
|
const UsersManage = defineComponent({ |
||||||
|
name: 'user-manage', |
||||||
|
setup() { |
||||||
|
const { t } = useI18n() |
||||||
|
const { show, mode, user } = useSharedUserModalState() |
||||||
|
const tableState = useTable({ |
||||||
|
onEdit: (u) => { |
||||||
|
show.value = true |
||||||
|
mode.value = 'edit' |
||||||
|
user.value = u |
||||||
|
}, |
||||||
|
onDelete: (u) => { |
||||||
|
show.value = true |
||||||
|
mode.value = 'delete' |
||||||
|
user.value = u |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
const onSuccess = (mode: Mode) => { |
||||||
|
if (mode === 'add') { |
||||||
|
tableState.resetPage() |
||||||
|
} |
||||||
|
tableState.getUserList() |
||||||
|
} |
||||||
|
|
||||||
|
const onAddUser = () => { |
||||||
|
show.value = true |
||||||
|
mode.value = 'add' |
||||||
|
user.value = undefined |
||||||
|
} |
||||||
|
|
||||||
|
provide(UserModalSharedStateKey, { show, mode, user, onSuccess }) |
||||||
|
|
||||||
|
return { |
||||||
|
t, |
||||||
|
onAddUser, |
||||||
|
...tableState |
||||||
|
} |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t, onSearchValOk, onSearchValClear, userListLoading } = this |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<NGrid cols={1} yGap={16}> |
||||||
|
<NGridItem> |
||||||
|
<NCard> |
||||||
|
<NSpace justify='space-between'> |
||||||
|
<NButton onClick={this.onAddUser} type='primary'> |
||||||
|
{t('security.user.create_user')} |
||||||
|
</NButton> |
||||||
|
<NInputGroup> |
||||||
|
<NInput |
||||||
|
v-model:value={this.searchInputVal} |
||||||
|
clearable |
||||||
|
onClear={onSearchValClear} |
||||||
|
onKeyup={(e) => { |
||||||
|
if (e.key === 'Enter') { |
||||||
|
onSearchValOk() |
||||||
|
} |
||||||
|
}} |
||||||
|
/> |
||||||
|
<NButton type='primary' onClick={onSearchValOk}> |
||||||
|
<NIcon> |
||||||
|
<SearchOutlined /> |
||||||
|
</NIcon> |
||||||
|
</NButton> |
||||||
|
</NInputGroup> |
||||||
|
</NSpace> |
||||||
|
</NCard> |
||||||
|
</NGridItem> |
||||||
|
<NGridItem> |
||||||
|
<NCard> |
||||||
|
{userListLoading ? ( |
||||||
|
<NSkeleton text repeat={6}></NSkeleton> |
||||||
|
) : ( |
||||||
|
<NSpace v-show={!userListLoading} vertical size={20}> |
||||||
|
<NDataTable |
||||||
|
columns={this.columns} |
||||||
|
data={this.userList} |
||||||
|
scrollX={this.scrollX} |
||||||
|
bordered={false} |
||||||
|
/> |
||||||
|
<NSpace justify='center'> |
||||||
|
<NPagination |
||||||
|
v-model:page={this.page} |
||||||
|
v-model:page-size={this.pageSize} |
||||||
|
pageCount={this.pageCount} |
||||||
|
pageSizes={this.pageSizes} |
||||||
|
showSizePicker |
||||||
|
/> |
||||||
|
</NSpace> |
||||||
|
</NSpace> |
||||||
|
)} |
||||||
|
</NCard> |
||||||
|
</NGridItem> |
||||||
|
</NGrid> |
||||||
|
<UserModal /> |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
export default UsersManage |
@ -0,0 +1,212 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
import { ref, watch, onBeforeMount } from 'vue' |
||||||
|
import { NSpace, NTooltip, NButton, NIcon, NTag } from 'naive-ui' |
||||||
|
import { EditOutlined, DeleteOutlined } from '@vicons/antd' |
||||||
|
import { queryUserList } from '@/service/modules/users' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
|
||||||
|
type UseTableProps = { |
||||||
|
onEdit: (user: any) => void |
||||||
|
onDelete: (user: any) => void |
||||||
|
} |
||||||
|
|
||||||
|
function useColumns({ onEdit, onDelete }: UseTableProps) { |
||||||
|
const { t } = useI18n() |
||||||
|
const columns: any[] = [ |
||||||
|
{ |
||||||
|
title: t('security.user.index'), |
||||||
|
key: 'index', |
||||||
|
width: 80, |
||||||
|
render: (rowData: any, rowIndex: number) => rowIndex + 1 |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('security.user.username'), |
||||||
|
key: 'userName' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('security.user.tenant_code'), |
||||||
|
key: 'tenantCode' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('security.user.queue'), |
||||||
|
key: 'queue' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('security.user.email'), |
||||||
|
key: 'email' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('security.user.phone'), |
||||||
|
key: 'phone' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('security.user.state'), |
||||||
|
key: 'state', |
||||||
|
render: (rowData: any, rowIndex: number) => { |
||||||
|
return rowData.state === 1 ? ( |
||||||
|
<NTag type='success'>启用</NTag> |
||||||
|
) : ( |
||||||
|
<NTag type='error'>停用</NTag> |
||||||
|
) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('security.user.create_time'), |
||||||
|
key: 'createTime', |
||||||
|
width: 200 |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('security.user.update_time'), |
||||||
|
key: 'updateTime', |
||||||
|
width: 200 |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('security.user.operation'), |
||||||
|
key: 'operation', |
||||||
|
fixed: 'right', |
||||||
|
width: 120, |
||||||
|
render: (rowData: any, rowIndex: number) => { |
||||||
|
return ( |
||||||
|
<NSpace> |
||||||
|
<NTooltip trigger='hover'> |
||||||
|
{{ |
||||||
|
trigger: () => ( |
||||||
|
<NButton |
||||||
|
circle |
||||||
|
type='info' |
||||||
|
size='small' |
||||||
|
onClick={() => { |
||||||
|
onEdit(rowData) |
||||||
|
}} |
||||||
|
> |
||||||
|
{{ |
||||||
|
icon: () => ( |
||||||
|
<NIcon> |
||||||
|
<EditOutlined /> |
||||||
|
</NIcon> |
||||||
|
) |
||||||
|
}} |
||||||
|
</NButton> |
||||||
|
), |
||||||
|
default: () => t('security.user.edit') |
||||||
|
}} |
||||||
|
</NTooltip> |
||||||
|
<NTooltip trigger='hover'> |
||||||
|
{{ |
||||||
|
trigger: () => ( |
||||||
|
<NButton |
||||||
|
circle |
||||||
|
type='error' |
||||||
|
size='small' |
||||||
|
onClick={() => { |
||||||
|
onDelete(rowData) |
||||||
|
}} |
||||||
|
> |
||||||
|
{{ |
||||||
|
icon: () => ( |
||||||
|
<NIcon> |
||||||
|
<DeleteOutlined /> |
||||||
|
</NIcon> |
||||||
|
) |
||||||
|
}} |
||||||
|
</NButton> |
||||||
|
), |
||||||
|
default: () => t('security.user.delete') |
||||||
|
}} |
||||||
|
</NTooltip> |
||||||
|
</NSpace> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
].map((d: any) => ({ ...d, width: d.width || 160 })) |
||||||
|
|
||||||
|
const scrollX = columns.reduce((p, c) => p + c.width, 0) |
||||||
|
|
||||||
|
return { |
||||||
|
columns, |
||||||
|
scrollX |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export function useTable(props: UseTableProps) { |
||||||
|
const page = ref(1) |
||||||
|
const pageCount = ref(0) |
||||||
|
const pageSize = ref(10) |
||||||
|
const searchInputVal = ref() |
||||||
|
const searchVal = ref('') |
||||||
|
const pageSizes = [10, 30, 50] |
||||||
|
const userListLoading = ref(false) |
||||||
|
const userList = ref([]) |
||||||
|
const { columns, scrollX } = useColumns(props) |
||||||
|
|
||||||
|
const getUserList = () => { |
||||||
|
userListLoading.value = true |
||||||
|
queryUserList({ |
||||||
|
pageNo: page.value, |
||||||
|
pageSize: pageSize.value, |
||||||
|
searchVal: searchVal.value |
||||||
|
}) |
||||||
|
.then((res: any) => { |
||||||
|
userList.value = res?.totalList || [] |
||||||
|
pageCount.value = res?.totalPage || 0 |
||||||
|
}) |
||||||
|
.finally(() => { |
||||||
|
userListLoading.value = false |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const resetPage = () => { |
||||||
|
page.value = 1 |
||||||
|
} |
||||||
|
|
||||||
|
const onSearchValOk = () => { |
||||||
|
resetPage() |
||||||
|
searchVal.value = searchInputVal.value |
||||||
|
} |
||||||
|
|
||||||
|
const onSearchValClear = () => { |
||||||
|
resetPage() |
||||||
|
searchVal.value = '' |
||||||
|
} |
||||||
|
|
||||||
|
onBeforeMount(() => { |
||||||
|
getUserList() |
||||||
|
}) |
||||||
|
|
||||||
|
watch([page, pageSize, searchVal], () => { |
||||||
|
getUserList() |
||||||
|
}) |
||||||
|
|
||||||
|
return { |
||||||
|
userList, |
||||||
|
userListLoading, |
||||||
|
getUserList, |
||||||
|
page, |
||||||
|
pageCount, |
||||||
|
pageSize, |
||||||
|
searchVal, |
||||||
|
searchInputVal, |
||||||
|
pageSizes, |
||||||
|
columns, |
||||||
|
scrollX, |
||||||
|
onSearchValOk, |
||||||
|
onSearchValClear, |
||||||
|
resetPage |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue