mirror of
https://github.com/rustfs/console.git
synced 2026-09-19 01:47:44 +08:00
feat : user
This commit is contained in:
@@ -56,7 +56,7 @@ const handerGroupStatusChange = async (val: string) => {
|
||||
await getGroupData(group.value.name);
|
||||
};
|
||||
async function openDialog(row: any) {
|
||||
await getGroupData(row.accessKey);
|
||||
await getGroupData(row.name);
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<script setup lang="ts">
|
||||
import { userPolicies, userAccount, userGroups } from './';
|
||||
const visible = ref(false);
|
||||
const { getUser } = useUsers();
|
||||
const { getUser, updateUser } = useUsers();
|
||||
interface UserInfo {
|
||||
accessKey: string;
|
||||
memberOf: string[];
|
||||
@@ -56,6 +56,7 @@ const user = ref<UserInfo>({
|
||||
|
||||
// 用户的状态发生变化
|
||||
const handerUserStatusChange = async (val: string) => {
|
||||
await updateUser(user.value.accessKey, { ...user.value, groups: user.value.memberOf, status: val });
|
||||
await getUserData(user.value.accessKey);
|
||||
};
|
||||
async function openDialog(row: any) {
|
||||
|
||||
@@ -11,12 +11,18 @@
|
||||
action: true,
|
||||
}">
|
||||
<n-card>
|
||||
<n-form ref="newformRef" :model="editForm" label-placement="left" label-align="right" :label-width="130">
|
||||
<n-form
|
||||
ref="newformRef"
|
||||
:model="editForm"
|
||||
label-placement="left"
|
||||
:rules="rules"
|
||||
label-align="right"
|
||||
:label-width="130">
|
||||
<n-grid :cols="24" :x-gap="18">
|
||||
<n-form-item-grid-item :span="24" label="用户名" path="accessKey" required>
|
||||
<n-form-item-grid-item :span="24" label="用户名" path="accessKey">
|
||||
<n-input v-model:value="editForm.accessKey" />
|
||||
</n-form-item-grid-item>
|
||||
<n-form-item-grid-item :span="24" label="秘钥" path="secretKey" required>
|
||||
<n-form-item-grid-item :span="24" label="秘钥" path="secretKey">
|
||||
<n-input v-model:value="editForm.secretKey" type="password" />
|
||||
</n-form-item-grid-item>
|
||||
<n-form-item-grid-item :span="24" label="分组" path="groups">
|
||||
@@ -39,9 +45,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type FormRules } from 'naive-ui';
|
||||
const { listPolicies } = usePolicies();
|
||||
const { listGroup } = useGroups();
|
||||
const messge = useMessage();
|
||||
const message = useMessage();
|
||||
const { createUser } = useUsers();
|
||||
const visible = ref(false);
|
||||
|
||||
const editForm = reactive({
|
||||
@@ -50,21 +58,65 @@ const editForm = reactive({
|
||||
groups: [],
|
||||
policies: [],
|
||||
});
|
||||
|
||||
const rules: FormRules = {
|
||||
accessKey: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户名',
|
||||
},
|
||||
],
|
||||
secretKey: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入秘钥',
|
||||
},
|
||||
// length>=8
|
||||
{
|
||||
type: 'string',
|
||||
pattern: /^.{8,}$/,
|
||||
message: '秘钥长度不能小于8位',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function openDialog() {
|
||||
// getPoliciesList();
|
||||
// getGroupsList();
|
||||
getPoliciesList();
|
||||
getGroupsList();
|
||||
visible.value = true;
|
||||
console.log(1111);
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
visible.value = false;
|
||||
editForm.accessKey = '';
|
||||
editForm.secretKey = '';
|
||||
editForm.groups = [];
|
||||
editForm.policies = [];
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
function submitForm() {}
|
||||
|
||||
const newformRef = ref();
|
||||
const emit = defineEmits(['search']);
|
||||
function submitForm(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
newformRef.value?.validate(async (errors: any) => {
|
||||
if (errors) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await createUser(editForm);
|
||||
message.success('添加成功');
|
||||
emit('search');
|
||||
closeModal();
|
||||
} catch (error) {
|
||||
message.error('添加失败');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取策略列表
|
||||
const policiesList = ref([]);
|
||||
|
||||
@@ -1,14 +1,222 @@
|
||||
<template>
|
||||
<div>
|
||||
accesskey
|
||||
<n-card>
|
||||
<n-form ref="formRef" :model="searchForm" label-placement="left" :show-feedback="false">
|
||||
<n-flex justify="space-between" v-if="!editStatus">
|
||||
<n-form-item class="!w-64" label="" path="name">
|
||||
<n-input placeholder="搜索账号" @input="filterName" />
|
||||
</n-form-item>
|
||||
|
||||
<n-space>
|
||||
<NFlex>
|
||||
<NButton secondary @click="editStatus = true">
|
||||
<template #icon>
|
||||
<Icon name="ri:add-line"></Icon>
|
||||
</template>
|
||||
添加账号
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</n-space>
|
||||
</n-flex>
|
||||
<!-- <n-flex justify="space-between" v-else>
|
||||
<n-form-item class="!w-96" label="选择策略" path="policy">
|
||||
<n-select v-model:value="policy" filterable multiple :options="policyList" />
|
||||
</n-form-item>
|
||||
<n-space>
|
||||
<NFlex>
|
||||
<NButton secondary @click="changeMebers">提交</NButton>
|
||||
</NFlex>
|
||||
</n-space>
|
||||
</n-flex> -->
|
||||
</n-form>
|
||||
</n-card>
|
||||
<n-data-table
|
||||
class="my-4"
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:data="listData"
|
||||
:pagination="false"
|
||||
:bordered="false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
type DataTableColumns,
|
||||
type DataTableInst,
|
||||
type DataTableRowKey,
|
||||
NButton,
|
||||
NPopconfirm,
|
||||
NSpace,
|
||||
} from 'naive-ui';
|
||||
import { Icon } from '#components';
|
||||
const { listAUserServiceAccounts } = useUsers();
|
||||
const { listPolicies } = usePolicies();
|
||||
|
||||
const message = useMessage();
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const searchForm = reactive({
|
||||
name: '',
|
||||
});
|
||||
interface RowData {
|
||||
accessKey: string;
|
||||
expiration: string;
|
||||
name: string;
|
||||
description: string;
|
||||
accountStatus: string;
|
||||
actions: string;
|
||||
}
|
||||
const columns: DataTableColumns<RowData> = [
|
||||
{
|
||||
type: 'selection',
|
||||
},
|
||||
{
|
||||
title: 'Access Key',
|
||||
align: 'center',
|
||||
key: 'accessKey',
|
||||
filter(value, row) {
|
||||
return !!row.accessKey.includes(value.toString());
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '有效期',
|
||||
align: 'center',
|
||||
key: 'expiration',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: 'center',
|
||||
key: 'accountStatus',
|
||||
render: (row: any) => {
|
||||
return row.accountStatus === 'on' ? '可用' : '禁用';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
align: 'center',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
align: 'center',
|
||||
key: 'description',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'actions',
|
||||
align: 'center',
|
||||
width: 180,
|
||||
render: (row: any) => {
|
||||
return h(
|
||||
NSpace,
|
||||
{
|
||||
justify: 'center',
|
||||
},
|
||||
{
|
||||
default: () => [
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
secondary: true,
|
||||
// onClick: () => openEditItem(row),
|
||||
},
|
||||
{
|
||||
default: () => '',
|
||||
icon: () => h(Icon, { name: 'ri:edit-2-line' }),
|
||||
}
|
||||
),
|
||||
h(
|
||||
NPopconfirm,
|
||||
{ onPositiveClick: () => deleteItem(row) },
|
||||
{
|
||||
default: () => '确认删除',
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{ size: 'small', secondary: true },
|
||||
{
|
||||
default: () => '',
|
||||
icon: () => h(Icon, { name: 'ri:delete-bin-5-line' }),
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
],
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// 搜索过滤
|
||||
const tableRef = ref<DataTableInst>();
|
||||
function filterName(value: string) {
|
||||
tableRef.value &&
|
||||
tableRef.value.filter({
|
||||
name: [value],
|
||||
});
|
||||
}
|
||||
const listData = ref([]);
|
||||
const getUserList = async () => {
|
||||
const res = await listAUserServiceAccounts(props.user.accessKey);
|
||||
listData.value = res;
|
||||
};
|
||||
getUserList();
|
||||
|
||||
//
|
||||
const editStatus = ref(false);
|
||||
|
||||
/** ***********************************删除 */
|
||||
async function deleteItem(row: any) {
|
||||
try {
|
||||
// const res = await $api.delete('/service-accounts/delete-multi', {
|
||||
// body: [row.accessKey],
|
||||
// });
|
||||
message.success('删除成功');
|
||||
} catch (error) {
|
||||
message.error('删除失败');
|
||||
}
|
||||
}
|
||||
|
||||
/** ************************************批量删除 */
|
||||
function rowKey(row: any): string {
|
||||
return row.accessKey;
|
||||
}
|
||||
|
||||
const checkedKeys = ref<DataTableRowKey[]>([]);
|
||||
function handleCheck(keys: DataTableRowKey[]) {
|
||||
checkedKeys.value = keys;
|
||||
return checkedKeys;
|
||||
}
|
||||
function deleteByList() {
|
||||
// dialog.error({
|
||||
// title: '警告',
|
||||
// content: '你确定要删除所有选中的秘钥吗?',
|
||||
// positiveText: '确定',
|
||||
// negativeText: '取消',
|
||||
// onPositiveClick: async () => {
|
||||
// if (!checkedKeys.value.length) {
|
||||
// message.error('请至少选择一项');
|
||||
// return;
|
||||
// }
|
||||
// try {
|
||||
// // const res = await $api.delete('/service-accounts/delete-multi', {
|
||||
// // body: checkedKeys.value,
|
||||
// // });
|
||||
// message.success('删除成功');
|
||||
// } catch (error) {
|
||||
// message.error('删除失败');
|
||||
// }
|
||||
// },
|
||||
// });
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,7 +1,127 @@
|
||||
<template>
|
||||
<div>groups</div>
|
||||
<div>
|
||||
<n-card>
|
||||
<n-form ref="formRef" :model="searchForm" label-placement="left" :show-feedback="false">
|
||||
<n-flex justify="space-between" v-if="!editStatus">
|
||||
<n-form-item class="!w-64" label="" path="name">
|
||||
<n-input placeholder="搜索分组" @input="filterName" />
|
||||
</n-form-item>
|
||||
|
||||
<n-space>
|
||||
<NFlex>
|
||||
<NButton secondary @click="editStatus = true">
|
||||
<template #icon>
|
||||
<Icon name="ri:add-line"></Icon>
|
||||
</template>
|
||||
编辑分组
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</n-space>
|
||||
</n-flex>
|
||||
<n-flex justify="space-between" v-else>
|
||||
<n-form-item class="!w-96" label="选择分组" path="group">
|
||||
<n-select v-model:value="group" filterable multiple :options="groupList" />
|
||||
</n-form-item>
|
||||
<n-space>
|
||||
<NFlex>
|
||||
<NButton secondary @click="changeMebers">提交</NButton>
|
||||
</NFlex>
|
||||
</n-space>
|
||||
</n-flex>
|
||||
</n-form>
|
||||
</n-card>
|
||||
<n-data-table
|
||||
class="my-4"
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:data="listData"
|
||||
:pagination="false"
|
||||
:bordered="false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
<script setup lang="ts">
|
||||
import { type DataTableColumns, type DataTableInst, NButton, NSpace } from 'naive-ui';
|
||||
const { listGroup } = useGroups();
|
||||
const { updateUserGroups } = useUsers();
|
||||
|
||||
const messge = useMessage();
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const searchForm = reactive({
|
||||
name: '',
|
||||
});
|
||||
interface RowData {
|
||||
name: string;
|
||||
}
|
||||
const columns: DataTableColumns<RowData> = [
|
||||
{
|
||||
title: '名称',
|
||||
align: 'left',
|
||||
key: 'name',
|
||||
filter(value, row) {
|
||||
return !!row.name.includes(value.toString());
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// 搜索过滤
|
||||
const tableRef = ref<DataTableInst>();
|
||||
function filterName(value: string) {
|
||||
tableRef.value &&
|
||||
tableRef.value.filter({
|
||||
name: [value],
|
||||
});
|
||||
}
|
||||
const listData = computed(() => {
|
||||
return (
|
||||
props.user.memberOf.map((item: string) => {
|
||||
return {
|
||||
name: item,
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
});
|
||||
|
||||
/********************编辑****************/
|
||||
const editStatus = ref(false);
|
||||
// 用户组
|
||||
const groupList = ref([]);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'search'): void;
|
||||
}>();
|
||||
const getGroupList = async () => {
|
||||
const res = await listGroup();
|
||||
console.log(res);
|
||||
groupList.value = res.groups.map((item: any) => {
|
||||
return {
|
||||
label: item,
|
||||
value: item,
|
||||
};
|
||||
});
|
||||
};
|
||||
getGroupList();
|
||||
|
||||
const group = ref(props.user.memberOf);
|
||||
const changeMebers = async () => {
|
||||
try {
|
||||
await updateUserGroups(props.user.accessKey, {
|
||||
...props.user,
|
||||
groups: group.value,
|
||||
});
|
||||
messge.success('修改成功');
|
||||
editStatus.value = false;
|
||||
emit('search');
|
||||
} catch {
|
||||
messge.error('修改失败');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,7 +1,128 @@
|
||||
<template>
|
||||
<div>policy</div>
|
||||
<div>
|
||||
<n-card>
|
||||
<n-form ref="formRef" :model="searchForm" label-placement="left" :show-feedback="false">
|
||||
<n-flex justify="space-between" v-if="!editStatus">
|
||||
<n-form-item class="!w-64" label="" path="name">
|
||||
<n-input placeholder="搜索策略" @input="filterName" />
|
||||
</n-form-item>
|
||||
|
||||
<n-space>
|
||||
<NFlex>
|
||||
<NButton secondary @click="editStatus = true">
|
||||
<template #icon>
|
||||
<Icon name="ri:add-line"></Icon>
|
||||
</template>
|
||||
编辑策略
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</n-space>
|
||||
</n-flex>
|
||||
<n-flex justify="space-between" v-else>
|
||||
<n-form-item class="!w-96" label="选择策略" path="policy">
|
||||
<n-select v-model:value="policy" filterable multiple :options="policyList" />
|
||||
</n-form-item>
|
||||
<n-space>
|
||||
<NFlex>
|
||||
<NButton secondary @click="changeMebers">提交</NButton>
|
||||
</NFlex>
|
||||
</n-space>
|
||||
</n-flex>
|
||||
</n-form>
|
||||
</n-card>
|
||||
<n-data-table
|
||||
class="my-4"
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:data="listData"
|
||||
:pagination="false"
|
||||
:bordered="false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
<script setup lang="ts">
|
||||
import { type DataTableColumns, type DataTableInst, NButton, NSpace } from 'naive-ui';
|
||||
const { listPolicies } = usePolicies();
|
||||
const { setPolicy } = useUsers();
|
||||
|
||||
const messge = useMessage();
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const searchForm = reactive({
|
||||
name: '',
|
||||
});
|
||||
interface RowData {
|
||||
name: string;
|
||||
}
|
||||
const columns: DataTableColumns<RowData> = [
|
||||
{
|
||||
title: '名称',
|
||||
align: 'left',
|
||||
key: 'name',
|
||||
filter(value, row) {
|
||||
return !!row.name.includes(value.toString());
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// 搜索过滤
|
||||
const tableRef = ref<DataTableInst>();
|
||||
function filterName(value: string) {
|
||||
tableRef.value &&
|
||||
tableRef.value.filter({
|
||||
name: [value],
|
||||
});
|
||||
}
|
||||
const listData = computed(() => {
|
||||
return (
|
||||
props.user.policy.map((item: string) => {
|
||||
return {
|
||||
name: item,
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
});
|
||||
|
||||
/********************编辑****************/
|
||||
const editStatus = ref(false);
|
||||
// 策略列表
|
||||
const policyList = ref([]);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'search'): void;
|
||||
}>();
|
||||
const getPoliciesList = async () => {
|
||||
const res = await listPolicies();
|
||||
console.log(res);
|
||||
policyList.value = res.policies.map((item: any) => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.name,
|
||||
};
|
||||
});
|
||||
};
|
||||
getPoliciesList();
|
||||
|
||||
const policy = ref(props.user.policy);
|
||||
const changeMebers = async () => {
|
||||
try {
|
||||
await setPolicy({
|
||||
name: policy.value,
|
||||
entityType: 'user',
|
||||
entityName: props.user.accessKey,
|
||||
});
|
||||
messge.success('修改成功');
|
||||
editStatus.value = false;
|
||||
emit('search');
|
||||
} catch {
|
||||
messge.error('修改失败');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
Reference in New Issue
Block a user