Skip to content

Commit 93cb618

Browse files
perf: API key validity period setting
1 parent 4637c81 commit 93cb618

8 files changed

Lines changed: 298 additions & 30 deletions

File tree

ui/src/layout/layout-header/avatar/APIKeyDialog.vue

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<el-dialog
33
:title="$t('layout.apiKey')"
44
v-model="dialogVisible"
5-
width="800"
5+
width="1080"
66
:close-on-click-modal="false"
77
:close-on-press-escape="false"
88
align-center
@@ -22,11 +22,14 @@
2222
<el-button type="primary" class="mb-16" @click="createApiKey">
2323
{{ $t('common.create') }}
2424
</el-button>
25-
<el-table
25+
<app-table
2626
:data="apiKey"
2727
:loading="loading"
2828
style="min-height: 300px"
2929
:max-height="420"
30+
:pagination-config="paginationConfig"
31+
@sizeChange="handleSizeChange"
32+
@changePage="getApiKeyList"
3033
>
3134
<el-table-column prop="secret_key" label="API Key">
3235
<template #default="{ row }">
@@ -38,24 +41,55 @@
3841
</el-button>
3942
</template>
4043
</el-table-column>
41-
<el-table-column :label="$t('common.status.label')" width="80">
44+
<el-table-column :label="$t('views.document.enableStatus.label')" width="100">
4245
<template #default="{ row }">
43-
<div @click.stop>
44-
<el-switch size="small" v-model="row.is_active" @change="changeState($event, row)" />
46+
<div v-if="row.is_active" class="flex align-center">
47+
<el-icon class="color-success mr-8" style="font-size: 16px">
48+
<SuccessFilled />
49+
</el-icon>
50+
<span class="color-text-primary">
51+
{{ $t('common.status.enabled') }}
52+
</span>
53+
</div>
54+
<div v-else class="flex align-center">
55+
<AppIcon iconName="app-disabled" class="color-secondary mr-8"></AppIcon>
56+
<span class="color-text-primary">
57+
{{ $t('common.status.disabled') }}
58+
</span>
4559
</div>
4660
</template>
4761
</el-table-column>
48-
<el-table-column prop="name" :label="$t('common.createDate')" width="170">
62+
<el-table-column :label="$t('layout.crossSettings')" width="100">
63+
<template #default="{ row }">
64+
<el-tag type="info" class="info-tag">
65+
{{ $t('views.system.authentication.scanTheQRCode.alreadyTurnedOn') }}
66+
</el-tag>
67+
<el-tag class="blue-tag">
68+
{{ $t('views.system.authentication.scanTheQRCode.notEnabled') }}
69+
</el-tag>
70+
</template>
71+
</el-table-column>
72+
73+
<el-table-column :label="$t('layout.about.expiredTime')" width="170">
74+
<template #default="{ row }">
75+
<!-- {{ datetimeFormat(row.create_time) }} -->
76+
</template>
77+
</el-table-column>
78+
<el-table-column :label="$t('common.createDate')" width="170" prop="create_time" sortable>
4979
<template #default="{ row }">
5080
{{ datetimeFormat(row.create_time) }}
5181
</template>
5282
</el-table-column>
53-
<el-table-column :label="$t('common.setting')" align="left" width="80">
83+
<el-table-column :label="$t('common.operation')" align="left" width="130">
5484
<template #default="{ row }">
85+
<span @click.stop>
86+
<el-switch size="small" v-model="row.is_active" @change="changeState($event, row)" />
87+
</span>
88+
<el-divider direction="vertical" />
5589
<span class="mr-4">
5690
<el-tooltip effect="dark" :content="$t('common.setting')" placement="top">
5791
<el-button type="primary" text @click.stop="settingApiKey(row)">
58-
<AppIcon iconName="app-setting"></AppIcon>
92+
<AppIcon iconName="app-edit"></AppIcon>
5993
</el-button>
6094
</el-tooltip>
6195
</span>
@@ -66,19 +100,19 @@
66100
</el-tooltip>
67101
</template>
68102
</el-table-column>
69-
</el-table>
103+
</app-table>
70104
<SettingAPIKeyDialog ref="SettingAPIKeyDialogRef" @refresh="refresh" />
71105
</el-dialog>
72106
</template>
73107
<script setup lang="ts">
74-
import { ref, watch } from 'vue'
108+
import { ref, watch, reactive } from 'vue'
75109
import { useRoute } from 'vue-router'
76110
import { copyClick } from '@/utils/clipboard'
77111
import systemKeyApi from '@/api/system/api-key'
78112
import { datetimeFormat } from '@/utils/time'
79113
import { MsgSuccess, MsgConfirm } from '@/utils/message'
80114
import { t } from '@/locales'
81-
import SettingAPIKeyDialog from '@/views/application-overview/component/SettingAPIKeyDialog.vue'
115+
import SettingAPIKeyDialog from '@/views/application-overview/component/SettingAPIKeyDrawer.vue'
82116
83117
const route = useRoute()
84118
const {
@@ -91,6 +125,7 @@ const props = defineProps({
91125
default: '',
92126
},
93127
})
128+
94129
const emit = defineEmits(['addData'])
95130
96131
const apiUrl = window.location.origin + `${window.MaxKB.prefix}/api-doc/`
@@ -99,12 +134,23 @@ const dialogVisible = ref<boolean>(false)
99134
const loading = ref(false)
100135
const apiKey = ref<any>(null)
101136
137+
const paginationConfig = reactive({
138+
current_page: 1,
139+
page_size: 20,
140+
total: 0,
141+
})
142+
102143
watch(dialogVisible, (bool) => {
103144
if (!bool) {
104145
apiKey.value = null
105146
}
106147
})
107148
149+
function handleSizeChange() {
150+
paginationConfig.current_page = 1
151+
getApiKeyList()
152+
}
153+
108154
function settingApiKey(row: any) {
109155
SettingAPIKeyDialogRef.value.open(row, 'USER')
110156
}
@@ -140,9 +186,10 @@ function changeState(bool: boolean, row: any) {
140186
}
141187
142188
function createApiKey() {
143-
systemKeyApi.postAPIKey(loading).then((res) => {
144-
getApiKeyList()
145-
})
189+
// systemKeyApi.postAPIKey(loading).then((res) => {
190+
// getApiKeyList()
191+
// })
192+
SettingAPIKeyDialogRef.value.open(null, 'USER')
146193
}
147194
148195
const open = () => {

ui/src/locales/lang/en-US/layout.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export default {
77
apiServiceAddress: 'API Service Address',
88
language: 'Language',
99
isExpire: 'License not uploaded or expired',
10+
crossSettings: 'Cross-Origin Settings',
1011
about: {
1112
title: 'About',
1213
expiredTime: 'Expiration Date',
@@ -32,9 +33,9 @@ export default {
3233
daysLater: 'days later',
3334
hoursLater: 'hours later',
3435
expired: 'expired',
35-
expiringSoon: 'expiring soon'
36+
expiringSoon: 'expiring soon',
3637
},
3738
copyright: 'Copyright © 2014-2026 FIT2CLOUD, All rights reserved.',
3839
userManualUrl: 'http://docs.maxkb.hk/',
39-
forumUrl: 'https://github.com/1Panel-dev/MaxKB/discussions'
40+
forumUrl: 'https://github.com/1Panel-dev/MaxKB/discussions',
4041
}

ui/src/locales/lang/zh-CN/layout.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export default {
77
apiServiceAddress: 'API 服务地址',
88
language: '语言',
99
isExpire: '未上传 License 或 License 已过期。',
10+
crossSettings: '跨域设置',
1011
about: {
1112
title: '关于',
1213
expiredTime: '到期时间',
@@ -32,7 +33,10 @@ export default {
3233
daysLater: '天后',
3334
hoursLater: '小时后',
3435
expired: '已过期',
35-
expiringSoon: '即将到期'
36+
expiringSoon: '即将到期',
37+
neverExpires: '永不过期',
38+
daysValid: '天有效',
39+
3640
},
3741
copyright: '版权所有 © 2014-2026 杭州飞致云信息科技有限公司',
3842
userManualUrl: 'https://maxkb.cn/docs/v2/',

ui/src/locales/lang/zh-Hant/layout.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ export default {
33
wiki: '使用者手冊',
44
forum: '論壇求助',
55
logout: '登出',
6-
76
apiKey: 'API Key 管理',
87
apiServiceAddress: 'API 服務地址',
98
language: '語言',
109
isExpire: '未上傳 License 或 License 已過期。',
10+
crossSettings: '跨域設定',
1111
about: {
1212
title: '關於',
1313
expiredTime: '到期時間',
1414
edition: {
1515
label: '版本',
1616
community: '社群版',
1717
professional: '專業版',
18-
enterprise: '企業版'
18+
enterprise: '企業版',
1919
},
2020
version: '版本號',
2121
serialNo: '序列號',
@@ -33,9 +33,9 @@ export default {
3333
daysLater: '天後',
3434
hoursLater: '小時後',
3535
expired: '已過期',
36-
expiringSoon: '即將到期'
36+
expiringSoon: '即將到期',
3737
},
3838
copyright: '版權所有 © 2014-2026 杭州飛致雲信息科技有限公司',
39-
userManualUrl:'https://maxkb.cn/docs/v2/',
40-
forumUrl: 'https://github.com/1Panel-dev/MaxKB/discussions'
39+
userManualUrl: 'https://maxkb.cn/docs/v2/',
40+
forumUrl: 'https://github.com/1Panel-dev/MaxKB/discussions',
4141
}

ui/src/utils/time.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ import moment from 'moment'
22
import 'moment/dist/locale/zh-cn'
33

44
moment.locale('zh-cn')
5-
import {t} from '@/locales'
5+
import { t } from '@/locales'
6+
7+
export const expiredTimeList = {
8+
'never': t('layout.time.neverExpires'),
9+
'7': '7 ' + t('layout.time.daysValid'),
10+
'30': '30 ' + t('layout.time.daysValid'),
11+
'90': '90 ' + t('layout.time.daysValid'),
12+
'180': '180 ' + t('layout.time.daysValid'),
13+
'custom': t('common.custom'),
14+
}
615

716
// 当天日期 YYYY-MM-DD
817
export const nowDate = moment().format('YYYY-MM-DD')
@@ -11,6 +20,18 @@ export const nowDate = moment().format('YYYY-MM-DD')
1120
export function beforeDay(n: number | string) {
1221
return moment().subtract(n, 'days').format('YYYY-MM-DD')
1322
}
23+
// 当前时间的n天后的时间戳
24+
export function AfterTimestamp(n: number | string) {
25+
return Number(moment().add(parseInt(n as string), 'days').format('x'))
26+
}
27+
28+
export function formatEndDate(date: any) {
29+
return Number(moment(date).endOf('day').format('x'));
30+
} // date的23点59分
31+
32+
export function formatStartDate(date: any) {
33+
return Number(moment(date).startOf('day').format('x'));
34+
} // date的0点
1435

1536
const getCheckDate = (timestamp: any) => {
1637
if (!timestamp) return false
@@ -43,7 +64,6 @@ export const dateFormat = (timestamp: any) => {
4364
return `${y}-${m}-${d}`
4465
}
4566

46-
4767
export function fromNowDate(time: any) {
4868
// 拿到当前时间戳和发布时的时间戳,然后得出时间戳差
4969
const curTime = new Date()

ui/src/views/application-overview/component/APIKeyDialog.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
import { ref, watch, computed } from 'vue'
6868
import { useRoute } from 'vue-router'
6969
import { copyClick } from '@/utils/clipboard'
70-
import SettingAPIKeyDialog from './SettingAPIKeyDialog.vue'
70+
import SettingAPIKeyDialog from './SettingAPIKeyDrawer.vue'
7171
import { datetimeFormat } from '@/utils/time'
7272
import { MsgSuccess, MsgConfirm } from '@/utils/message'
7373
import { t } from '@/locales'

ui/src/views/application-overview/component/SettingAPIKeyDialog.vue

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ const loading = ref(false)
6868
6969
const APIKeyId = ref('')
7070
const APIType = ref('APPLICATION')
71+
const isCreate = ref(false)
7172
7273
watch(dialogVisible, (bool) => {
7374
if (!bool) {
@@ -79,12 +80,17 @@ watch(dialogVisible, (bool) => {
7980
})
8081
8182
const open = (data: any, type: string) => {
82-
APIKeyId.value = data.id
83+
if (data) {
84+
isCreate.value = false
85+
APIKeyId.value = data.id
86+
form.value.allow_cross_domain = data.allow_cross_domain
87+
form.value.cross_domain_list = data.cross_domain_list?.length
88+
? data.cross_domain_list?.join('\n')
89+
: ''
90+
} else {
91+
isCreate.value = true
92+
}
8393
APIType.value = type
84-
form.value.allow_cross_domain = data.allow_cross_domain
85-
form.value.cross_domain_list = data.cross_domain_list?.length
86-
? data.cross_domain_list?.join('\n')
87-
: ''
8894
dialogVisible.value = true
8995
}
9096

0 commit comments

Comments
 (0)