mirror of
https://github.com/rustfs/console.git
synced 2026-09-18 09:10:17 +08:00
feat:ak
This commit is contained in:
@@ -1,65 +1,67 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
const message = useMessage();
|
||||
const emit = defineEmits<Emits>();
|
||||
const { getServiceAccount, updateServiceAccount } = useAccessKeys();
|
||||
import { ref } from "vue"
|
||||
const message = useMessage()
|
||||
const emit = defineEmits<Emits>()
|
||||
const { getServiceAccount, updateServiceAccount } = useAccessKeys()
|
||||
|
||||
const visible = ref(false);
|
||||
const visible = ref(false)
|
||||
|
||||
const defaultFormModal = {
|
||||
accesskey: '',
|
||||
secretkey: '',
|
||||
name: '',
|
||||
description: '',
|
||||
accesskey: "",
|
||||
secretkey: "",
|
||||
name: "",
|
||||
description: "",
|
||||
expiry: null,
|
||||
policy: '',
|
||||
status: 'on',
|
||||
};
|
||||
const formModel = ref({ ...defaultFormModal });
|
||||
policy: "",
|
||||
status: "on",
|
||||
}
|
||||
const formModel = ref({ ...defaultFormModal })
|
||||
|
||||
const accessKey = ref<string>('');
|
||||
const accessKey = ref<string>("")
|
||||
async function openDialog(row: any) {
|
||||
accessKey.value = row.accessKey;
|
||||
accessKey.value = row.accessKey
|
||||
|
||||
try {
|
||||
const res = await getServiceAccount(row.accessKey);
|
||||
formModel.value = res;
|
||||
formModel.value.accesskey = row.accessKey;
|
||||
formModel.value.expiry = res.expiration;
|
||||
formModel.value.status = res.accountStatus;
|
||||
visible.value = true;
|
||||
const res = await getServiceAccount(row.accessKey)
|
||||
formModel.value = res
|
||||
formModel.value.accesskey = row.accessKey
|
||||
formModel.value.expiry = res.expiration
|
||||
formModel.value.status = res.accountStatus
|
||||
visible.value = true
|
||||
} catch (error) {
|
||||
message.error('获取数据失败');
|
||||
message.error("获取数据失败")
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ openDialog });
|
||||
defineExpose({ openDialog })
|
||||
|
||||
interface Emits {
|
||||
(e: 'search'): void;
|
||||
(e: "search"): void
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
visible.value = false;
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
function dateDisabled(ts: number) {
|
||||
const date = new Date(ts);
|
||||
return date < new Date();
|
||||
const date = new Date(ts)
|
||||
return date < new Date()
|
||||
}
|
||||
|
||||
async function submitForm() {
|
||||
try {
|
||||
const res = await updateServiceAccount(accessKey.value, {
|
||||
...formModel.value,
|
||||
policy: formModel.value.policy || '{}',
|
||||
expiry: new Date(formModel.value.expiry || '').toISOString(),
|
||||
});
|
||||
message.success('修改成功');
|
||||
closeModal();
|
||||
emit('search');
|
||||
newPolicy: formModel.value.policy || "{}", // 可选,新策略
|
||||
newStatus: formModel.value.status, // 可选,新状态
|
||||
newName: formModel.value.name, // 可选,新名称
|
||||
newDescription: formModel.value.description, // 可选,新描述
|
||||
newExpiration: new Date(formModel.value.expiry || "").toISOString(), // 可选,新过期时间
|
||||
})
|
||||
message.success("修改成功")
|
||||
closeModal()
|
||||
emit("search")
|
||||
} catch (error) {
|
||||
message.error('修改失败');
|
||||
message.error("修改失败")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -78,7 +80,10 @@ async function submitForm() {
|
||||
<n-card>
|
||||
<n-form label-placement="left" :model="formModel" label-align="right" :label-width="90">
|
||||
<n-grid :cols="24" :x-gap="18">
|
||||
<n-form-item-grid-item :span="24" label="Access Key" path="policy">
|
||||
<n-form-item-grid-item :span="24" label="Access Key" path="accesskey">
|
||||
<n-input v-model:value="formModel.accesskey" disabled />
|
||||
</n-form-item-grid-item>
|
||||
<n-form-item-grid-item :span="24" label="策略" path="policy">
|
||||
<json-editor v-model="formModel.policy" />
|
||||
</n-form-item-grid-item>
|
||||
<!-- TODO: 时间格式有问题 -->
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { name } from './../node_modules/@jsep-plugin/regex/types/tsd.d'
|
||||
import { name } from "./../node_modules/@jsep-plugin/regex/types/tsd.d"
|
||||
export const useAccessKeys = () => {
|
||||
const { $api } = useNuxtApp()
|
||||
|
||||
const listUserServiceAccounts = async (params: object) => {
|
||||
return await $api.get('/list-service-accounts', { params })
|
||||
return await $api.get("/list-service-accounts", { params })
|
||||
}
|
||||
|
||||
const createServiceAccount = async (data: any) => {
|
||||
return await $api.put('/add-service-accounts', data)
|
||||
return await $api.put("/add-service-accounts", data)
|
||||
}
|
||||
|
||||
// const deleteMultipleServiceAccounts = async (data: any) => {
|
||||
@@ -15,20 +15,15 @@ export const useAccessKeys = () => {
|
||||
// }
|
||||
|
||||
const getServiceAccount = async (name: string) => {
|
||||
return await $api.get(
|
||||
`/info-service-account?accessKey=${encodeURIComponent(name)}`
|
||||
)
|
||||
return await $api.get(`/info-service-account?accessKey=${encodeURIComponent(name)}`)
|
||||
}
|
||||
|
||||
const updateServiceAccount = async (name: string, data: any) => {
|
||||
return await $api.post(`/update-service-account`, data)
|
||||
return await $api.post(`/update-service-account?accessKey=${encodeURIComponent(name)}`, data)
|
||||
}
|
||||
|
||||
const deleteServiceAccount = async (name: string) => {
|
||||
return await $api.delete(
|
||||
`/delete-service-accounts?accessKey==${encodeURIComponent(name)}`,
|
||||
{}
|
||||
)
|
||||
return await $api.delete(`/delete-service-accounts?accessKey=${encodeURIComponent(name)}`, {})
|
||||
}
|
||||
|
||||
const createServiceAccountCreds = async (data: any) => {
|
||||
@@ -41,7 +36,7 @@ export const useAccessKeys = () => {
|
||||
deleteServiceAccount,
|
||||
createServiceAccountCreds,
|
||||
updateServiceAccount,
|
||||
getServiceAccount
|
||||
getServiceAccount,
|
||||
// deleteMultipleServiceAccounts
|
||||
}
|
||||
}
|
||||
|
||||
+60
-89
@@ -6,10 +6,7 @@
|
||||
</template>
|
||||
<template #actions>
|
||||
<NFlex>
|
||||
<NButton
|
||||
:disabled="!checkedKeys.length"
|
||||
secondary
|
||||
@click="deleteByList">
|
||||
<NButton :disabled="!checkedKeys.length" secondary @click="deleteByList">
|
||||
<template #icon>
|
||||
<Icon name="ri:delete-bin-5-line"></Icon>
|
||||
</template>
|
||||
@@ -32,12 +29,7 @@
|
||||
</page-header>
|
||||
|
||||
<page-content>
|
||||
<n-form
|
||||
class="mb-4"
|
||||
ref="formRef"
|
||||
:model="searchForm"
|
||||
label-placement="left"
|
||||
:show-feedback="false">
|
||||
<n-form class="mb-4" ref="formRef" :model="searchForm" label-placement="left" :show-feedback="false">
|
||||
<n-flex justify="space-between">
|
||||
<n-form-item label="" path="name">
|
||||
<n-input placeholder="搜索访问秘钥" @input="filterName" />
|
||||
@@ -58,33 +50,17 @@
|
||||
:row-key="rowKey"
|
||||
@update:checked-row-keys="handleCheck" />
|
||||
</page-content>
|
||||
<NewItem
|
||||
ref="newItemRef"
|
||||
v-model:visible="newItemVisible"
|
||||
@search="getDataList"
|
||||
@notice="noticeDialog" />
|
||||
<NewItem ref="newItemRef" v-model:visible="newItemVisible" @search="getDataList" @notice="noticeDialog" />
|
||||
<EditItem ref="editItemRef" @search="getDataList" />
|
||||
<ChangePassword
|
||||
ref="changePasswordModalRef"
|
||||
v-model:visible="changePasswordVisible"
|
||||
@search="getDataList" />
|
||||
<users-user-notice
|
||||
ref="noticeRef"
|
||||
@search="getDataList"></users-user-notice>
|
||||
<ChangePassword ref="changePasswordModalRef" v-model:visible="changePasswordVisible" @search="getDataList" />
|
||||
<users-user-notice ref="noticeRef" @search="getDataList"></users-user-notice>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
type DataTableColumns,
|
||||
type DataTableInst,
|
||||
type DataTableRowKey,
|
||||
NButton,
|
||||
NPopconfirm,
|
||||
NSpace
|
||||
} from 'naive-ui'
|
||||
import { Icon } from '#components'
|
||||
import { ChangePassword, EditItem, NewItem } from '~/components/access-keys'
|
||||
import { type DataTableColumns, type DataTableInst, type DataTableRowKey, NButton, NPopconfirm, NSpace } from "naive-ui"
|
||||
import { Icon } from "#components"
|
||||
import { ChangePassword, EditItem, NewItem } from "~/components/access-keys"
|
||||
|
||||
const { $api } = useNuxtApp()
|
||||
const dialog = useDialog()
|
||||
@@ -92,7 +68,7 @@ const message = useMessage()
|
||||
const { listUserServiceAccounts, deleteServiceAccount } = useAccessKeys()
|
||||
|
||||
const searchForm = reactive({
|
||||
name: ''
|
||||
name: "",
|
||||
})
|
||||
interface RowData {
|
||||
accessKey: string
|
||||
@@ -105,85 +81,85 @@ interface RowData {
|
||||
|
||||
const columns: DataTableColumns<RowData> = [
|
||||
{
|
||||
type: 'selection'
|
||||
type: "selection",
|
||||
},
|
||||
{
|
||||
title: 'Access Key',
|
||||
align: 'center',
|
||||
key: 'accessKey',
|
||||
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: "expiration",
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: 'center',
|
||||
key: 'accountStatus',
|
||||
title: "状态",
|
||||
align: "center",
|
||||
key: "accountStatus",
|
||||
render: (row: any) => {
|
||||
return row.accountStatus === 'on' ? '可用' : '禁用'
|
||||
}
|
||||
return row.accountStatus === "on" ? "可用" : "禁用"
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
align: 'center',
|
||||
key: 'name'
|
||||
title: "名称",
|
||||
align: "center",
|
||||
key: "name",
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
align: 'center',
|
||||
key: 'description'
|
||||
title: "描述",
|
||||
align: "center",
|
||||
key: "description",
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'actions',
|
||||
align: 'center',
|
||||
title: "操作",
|
||||
key: "actions",
|
||||
align: "center",
|
||||
width: 180,
|
||||
render: (row: any) => {
|
||||
return h(
|
||||
NSpace,
|
||||
{
|
||||
justify: 'center'
|
||||
justify: "center",
|
||||
},
|
||||
{
|
||||
default: () => [
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
size: "small",
|
||||
secondary: true,
|
||||
onClick: () => openEditItem(row)
|
||||
onClick: () => openEditItem(row),
|
||||
},
|
||||
{
|
||||
default: () => '',
|
||||
icon: () => h(Icon, { name: 'ri:edit-2-line' })
|
||||
default: () => "",
|
||||
icon: () => h(Icon, { name: "ri:edit-2-line" }),
|
||||
}
|
||||
),
|
||||
h(
|
||||
NPopconfirm,
|
||||
{ onPositiveClick: () => deleteItem(row) },
|
||||
{
|
||||
default: () => '确认删除',
|
||||
default: () => "确认删除",
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{ size: 'small', secondary: true },
|
||||
{ size: "small", secondary: true },
|
||||
{
|
||||
default: () => '',
|
||||
icon: () => h(Icon, { name: 'ri:delete-bin-5-line' })
|
||||
default: () => "",
|
||||
icon: () => h(Icon, { name: "ri:delete-bin-5-line" }),
|
||||
}
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
]
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
// 搜索过滤
|
||||
@@ -191,7 +167,7 @@ const tableRef = ref<DataTableInst>()
|
||||
function filterName(value: string) {
|
||||
tableRef.value &&
|
||||
tableRef.value.filter({
|
||||
accessKey: [value]
|
||||
accessKey: [value],
|
||||
})
|
||||
}
|
||||
const listData = ref<any[]>([])
|
||||
@@ -203,14 +179,9 @@ onMounted(() => {
|
||||
const getDataList = async () => {
|
||||
try {
|
||||
const res = await listUserServiceAccounts({})
|
||||
listData.value =
|
||||
res.accounts.map((item: string) => {
|
||||
return {
|
||||
name: item
|
||||
}
|
||||
}) || []
|
||||
listData.value = res.accounts || []
|
||||
} catch (error) {
|
||||
message.error('获取数据失败')
|
||||
message.error("获取数据失败")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,10 +223,10 @@ async function deleteItem(row: any) {
|
||||
try {
|
||||
const res = deleteServiceAccount(row.accessKey)
|
||||
|
||||
message.success('删除成功')
|
||||
message.success("删除成功")
|
||||
getDataList()
|
||||
} catch (error) {
|
||||
message.error('删除失败')
|
||||
message.error("删除失败")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,25 +242,25 @@ function handleCheck(keys: DataTableRowKey[]) {
|
||||
}
|
||||
function deleteByList() {
|
||||
dialog.error({
|
||||
title: '警告',
|
||||
content: '你确定要删除所有选中的秘钥吗?',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
title: "警告",
|
||||
content: "你确定要删除所有选中的秘钥吗?",
|
||||
positiveText: "确定",
|
||||
negativeText: "取消",
|
||||
onPositiveClick: async () => {
|
||||
if (!checkedKeys.value.length) {
|
||||
message.error('请至少选择一项')
|
||||
message.error("请至少选择一项")
|
||||
return
|
||||
}
|
||||
try {
|
||||
const res = await $api.delete('/service-accounts/delete-multi', {
|
||||
body: checkedKeys.value
|
||||
const res = await $api.delete("/service-accounts/delete-multi", {
|
||||
body: checkedKeys.value,
|
||||
})
|
||||
message.success('删除成功')
|
||||
message.success("删除成功")
|
||||
getDataList()
|
||||
} catch (error) {
|
||||
message.error('删除失败')
|
||||
message.error("删除失败")
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user