feat : user

This commit is contained in:
cxymds
2024-12-24 19:05:22 +08:00
parent 0bbc1985b7
commit 8fef3c758f
7 changed files with 536 additions and 22 deletions
+1 -1
View File
@@ -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;
}
+2 -1
View File
@@ -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) {
+60 -8
View File
@@ -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>