mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-25 17:22:55 +00:00
feat: Custom sorting function style
This commit is contained in:
parent
d8d15c8902
commit
f7b3cc9ae0
|
|
@ -1,34 +1,31 @@
|
|||
import { t } from '@/locales'
|
||||
|
||||
|
||||
export const SORT_TYPES = {
|
||||
CREATE_TIME_ASC: 'createTime-asc',
|
||||
CREATE_TIME_DESC: 'createTime-desc',
|
||||
NAME_ASC: 'name-asc',
|
||||
NAME_DESC: 'name-desc',
|
||||
CUSTOM: 'custom'
|
||||
CUSTOM: 'custom',
|
||||
} as const
|
||||
|
||||
export type SortType = typeof SORT_TYPES[keyof typeof SORT_TYPES]
|
||||
export type SortType = (typeof SORT_TYPES)[keyof typeof SORT_TYPES]
|
||||
|
||||
export const SORT_MENU_CONFIG = [
|
||||
{
|
||||
title: 'time',
|
||||
title: 'time',
|
||||
items: [
|
||||
{ label: t('components.folder.ascTime', '按创建时间升序'), value: SORT_TYPES.CREATE_TIME_ASC},
|
||||
{ label: t('components.folder.descTime', '按创建时间降序'), value: SORT_TYPES.CREATE_TIME_DESC },
|
||||
]
|
||||
{ label: t('components.folder.ascTime'), value: SORT_TYPES.CREATE_TIME_ASC },
|
||||
{ label: t('components.folder.descTime'), value: SORT_TYPES.CREATE_TIME_DESC },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'name',
|
||||
items: [
|
||||
{ label: t('components.folder.ascName', '按名称升序'), value: SORT_TYPES.NAME_ASC },
|
||||
{ label: t('components.folder.descName', '按名称降序'), value: SORT_TYPES.NAME_DESC },
|
||||
]
|
||||
{ label: t('components.folder.ascName'), value: SORT_TYPES.NAME_ASC },
|
||||
{ label: t('components.folder.descName'), value: SORT_TYPES.NAME_DESC },
|
||||
],
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{ label: t('components.folder.custom', '按用户拖拽排序'), value: SORT_TYPES.CUSTOM },
|
||||
]
|
||||
}
|
||||
]
|
||||
items: [{ label: t('components.folder.sortDrop'), value: SORT_TYPES.CUSTOM }],
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,27 +1,29 @@
|
|||
<template>
|
||||
<div class="folder-tree">
|
||||
<div class="flex ml-4 p-8 pb-0 items-start">
|
||||
<div class="flex ml-4 p-8 pb-0">
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
:placeholder="$t('common.search')"
|
||||
prefix-icon="Search"
|
||||
clearable
|
||||
class="flex-[5]"
|
||||
/>
|
||||
<el-dropdown trigger="click" :teleported="false" @command="switchSortMethod">
|
||||
<el-button class="flex-1 ml-4">
|
||||
<el-button class="ml-4">
|
||||
<el-icon><Operation /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-menu class="w-180">
|
||||
<template v-for="(group, index) in SORT_MENU_CONFIG" :key="index">
|
||||
<el-dropdown-item
|
||||
v-for="obj in group.items"
|
||||
:key="obj.value"
|
||||
:command="obj.value"
|
||||
class="mr-2"
|
||||
:class="`${currentSort === obj.value ? 'active' : ''} flex-between`"
|
||||
>
|
||||
{{ obj.label }}
|
||||
<span>
|
||||
{{ obj.label }}
|
||||
</span>
|
||||
|
||||
<el-icon v-if="currentSort === obj.value" class="ml-4">
|
||||
<Check />
|
||||
</el-icon>
|
||||
|
|
@ -272,7 +274,7 @@ function addOrderToTree(nodes: any, parentId: string): Node[] {
|
|||
return nodes
|
||||
}
|
||||
|
||||
let positions = getPositions(parentId)
|
||||
const positions = getPositions(parentId)
|
||||
let needSave = false
|
||||
|
||||
nodes.forEach((node: any) => {
|
||||
|
|
|
|||
|
|
@ -61,9 +61,6 @@ const noMore = computed(
|
|||
props.size > 0 && props.size === props.total && props.total > props.page_size && !props.loading,
|
||||
)
|
||||
const disabledScroll = computed(() => props.size > 0 && (props.loading || noMore.value))
|
||||
console.log(props.size)
|
||||
console.log(props.total)
|
||||
console.log(props.page_size)
|
||||
function loadData() {
|
||||
if (props.total > props.page_size) {
|
||||
current.value += 1
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@
|
|||
</div>
|
||||
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu style="width: 180px">
|
||||
<el-dropdown-menu class="w-180">
|
||||
<el-dropdown-item
|
||||
v-for="(lang, index) in langList"
|
||||
:key="index"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<el-col :xs="24" :sm="24" :md="14" :lg="14" :xl="14" class="right-container flex-center">
|
||||
<el-dropdown trigger="click" type="primary" class="lang" v-if="lang">
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu style="width: 180px">
|
||||
<el-dropdown-menu class="w-180">
|
||||
<el-dropdown-item
|
||||
v-for="(lang, index) in langList"
|
||||
:key="index"
|
||||
|
|
|
|||
|
|
@ -17,5 +17,10 @@ export default {
|
|||
folderNamePlaceholder: 'Please enter a name',
|
||||
requiredMessage: 'Please select a folder',
|
||||
deleteConfirmMessage: 'Folders with resources will be deleted, please be cautious.',
|
||||
ascTime: 'Sort by creation time ascending',
|
||||
descTime: 'Sort by creation time descending',
|
||||
ascName: 'Sort by name ascending',
|
||||
descName: 'Sort by name descending',
|
||||
custom: 'Sort by user drag-and-drop',
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,5 +17,10 @@ export default {
|
|||
folderNamePlaceholder: '请输入名称',
|
||||
requiredMessage: '请选择文件夹',
|
||||
deleteConfirmMessage: '文件夹下的资源会被删除,请谨慎操作。',
|
||||
ascTime: '按创建时间升序',
|
||||
descTime: '按创建时间降序',
|
||||
ascName: '按名称升序',
|
||||
descName: '按名称降序',
|
||||
sortDrop: '按用户拖拽排序',
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,5 +17,10 @@ export default {
|
|||
folderNamePlaceholder: '請輸入名稱',
|
||||
requiredMessage: '請選擇文件夾',
|
||||
deleteConfirmMessage: '文件夹下的資源會被刪除,請謹慎操作。',
|
||||
ascTime: '按創建時間升序',
|
||||
descTime: '按創建時間降序',
|
||||
ascName: '按名稱升序',
|
||||
descName: '按名稱降序',
|
||||
sortDrop: '按用戶拖拽排序',
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,9 @@ h5 {
|
|||
.w-120 {
|
||||
width: 120px;
|
||||
}
|
||||
.w-180 {
|
||||
width: 180px;
|
||||
}
|
||||
.w-240 {
|
||||
width: 240px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,9 +150,9 @@
|
|||
<div class="mb-16">
|
||||
<el-select
|
||||
v-model="history_day"
|
||||
class="mr-12"
|
||||
class="mr-12 w-180"
|
||||
@change="changeDayHandle"
|
||||
style="width: 180px"
|
||||
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dayOptions"
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@
|
|||
style="height: 120px"
|
||||
@submitDialog="submitNoReferencesPromptDialog"
|
||||
:placeholder="
|
||||
$t('views.application.form.roleSettings.placeholder', {
|
||||
$t('views.application.form.prompt.placeholder', {
|
||||
data: '{data}',
|
||||
question: '{question}',
|
||||
})
|
||||
|
|
@ -288,7 +288,7 @@
|
|||
style="height: 150px"
|
||||
@submitDialog="submitPromptDialog"
|
||||
:placeholder="
|
||||
$t('views.application.form.roleSettings.placeholder', {
|
||||
$t('views.application.form.prompt.placeholder', {
|
||||
data: '{data}',
|
||||
question: '{question}',
|
||||
})
|
||||
|
|
|
|||
|
|
@ -25,9 +25,8 @@
|
|||
</div>
|
||||
<el-select
|
||||
v-model="history_day"
|
||||
class="ml-12"
|
||||
class="ml-12 w-180"
|
||||
@change="changeDayHandle"
|
||||
style="width: 180px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dayOptions"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,13 @@
|
|||
<div class="authentication-setting__main main-calc-height">
|
||||
<el-scrollbar>
|
||||
<div class="form-container p-24" v-loading="loading">
|
||||
<el-form ref="authFormRef" :model="form" label-position="top"
|
||||
require-asterisk-position="right" @submit.prevent>
|
||||
<el-form
|
||||
ref="authFormRef"
|
||||
:model="form"
|
||||
label-position="top"
|
||||
require-asterisk-position="right"
|
||||
@submit.prevent
|
||||
>
|
||||
<!-- 登录方式选择框 -->
|
||||
<el-form-item
|
||||
:label="$t('views.system.default_login')"
|
||||
|
|
@ -17,8 +22,11 @@
|
|||
prop="default_value"
|
||||
style="padding-top: 16px"
|
||||
>
|
||||
<el-radio-group v-model="form.default_value" class="radio-group"
|
||||
style="margin-left: 10px;">
|
||||
<el-radio-group
|
||||
v-model="form.default_value"
|
||||
class="radio-group"
|
||||
style="margin-left: 10px"
|
||||
>
|
||||
<el-radio
|
||||
v-for="method in loginMethods"
|
||||
:key="method.value"
|
||||
|
|
@ -41,13 +49,13 @@
|
|||
]"
|
||||
prop="max_attempts"
|
||||
>
|
||||
<el-row :gutter="16" style="margin-left: 10px;">
|
||||
<el-row :gutter="16" style="margin-left: 10px">
|
||||
<el-col :span="24">
|
||||
<span style="font-size: 13px;">
|
||||
{{ $t('views.system.loginFailed') }}
|
||||
</span>
|
||||
<span style="font-size: 13px">
|
||||
{{ $t('views.system.loginFailed') }}
|
||||
</span>
|
||||
<el-input-number
|
||||
style="margin-left: 8px;"
|
||||
style="margin-left: 8px"
|
||||
v-model="form.max_attempts"
|
||||
:min="-1"
|
||||
:max="10"
|
||||
|
|
@ -55,20 +63,20 @@
|
|||
controls-position="right"
|
||||
@change="onMaxAttemptsChange"
|
||||
/>
|
||||
<span style="margin-left: 8px; font-size: 13px;">
|
||||
{{ $t('views.system.loginFailedMessage') }}
|
||||
</span>
|
||||
<span style="margin-left: 8px; color: #909399; font-size: 12px;">
|
||||
({{ $t('views.system.display_codeTip') }})
|
||||
</span>
|
||||
<span style="margin-left: 8px; font-size: 13px">
|
||||
{{ $t('views.system.loginFailedMessage') }}
|
||||
</span>
|
||||
<span style="margin-left: 8px; color: #909399; font-size: 12px">
|
||||
({{ $t('views.system.display_codeTip') }})
|
||||
</span>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" style="margin-top: 8px;">
|
||||
<span style="font-size: 13px;">
|
||||
{{ $t('views.system.loginFailed') }}
|
||||
</span>
|
||||
<el-col :span="24" style="margin-top: 8px">
|
||||
<span style="font-size: 13px">
|
||||
{{ $t('views.system.loginFailed') }}
|
||||
</span>
|
||||
<el-input-number
|
||||
style="margin-left: 8px;"
|
||||
style="margin-left: 8px"
|
||||
v-model="form.failed_attempts"
|
||||
:min="-1"
|
||||
:max="10"
|
||||
|
|
@ -76,42 +84,42 @@
|
|||
controls-position="right"
|
||||
@change="onFailedAttemptsChange"
|
||||
/>
|
||||
<span style="margin-left: 8px; font-size: 13px;">
|
||||
{{ $t('views.system.failedTip') }}
|
||||
</span>
|
||||
<span style="margin-left: 8px; font-size: 13px">
|
||||
{{ $t('views.system.failedTip') }}
|
||||
</span>
|
||||
<el-input-number
|
||||
style="margin-left: 8px;"
|
||||
style="margin-left: 8px"
|
||||
v-model="form.lock_time"
|
||||
:min="1"
|
||||
:step="1"
|
||||
controls-position="right"
|
||||
/>
|
||||
<span style="margin-left: 8px; font-size: 13px;">
|
||||
{{ $t('views.system.minute') }}
|
||||
</span>
|
||||
<span style="margin-left: 8px; font-size: 13px">
|
||||
{{ $t('views.system.minute') }}
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('views.system.third_party_user_default_role')"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: $t('views.system.thirdPartyUserDefaultRoleRequired'),
|
||||
trigger: 'change',
|
||||
},
|
||||
]">
|
||||
<el-row :gutter="16" style="margin-left: 10px;">
|
||||
{
|
||||
required: true,
|
||||
message: $t('views.system.thirdPartyUserDefaultRoleRequired'),
|
||||
trigger: 'change',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<el-row :gutter="16" style="margin-left: 10px">
|
||||
<el-col :span="12">
|
||||
<div style="display: flex; align-items: center; gap: 8px; min-width: 0;">
|
||||
<span style="font-size: 13px; white-space: nowrap;">
|
||||
{{ $t('views.role.member.role') }}
|
||||
</span>
|
||||
<div style="display: flex; align-items: center; gap: 8px; min-width: 0">
|
||||
<span style="font-size: 13px; white-space: nowrap">
|
||||
{{ $t('views.role.member.role') }}
|
||||
</span>
|
||||
<el-select
|
||||
v-model="form.role_id"
|
||||
:placeholder="`${$t('common.selectPlaceholder')}${$t('views.role.member.role')}`"
|
||||
style="flex: 1; min-width: 180px;"
|
||||
style="flex: 1; min-width: 180px"
|
||||
@change="handleRoleChange"
|
||||
>
|
||||
<el-option
|
||||
|
|
@ -119,20 +127,19 @@
|
|||
:key="role.id"
|
||||
:label="role.name"
|
||||
:value="role.id"
|
||||
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12" v-if="user.isEE() && showWorkspaceSelector">
|
||||
<div style="display: flex; align-items: center; gap: 8px; min-width: 0;">
|
||||
<span style="font-size: 13px; white-space: nowrap;">
|
||||
{{ $t('views.role.member.workspace') }}
|
||||
</span>
|
||||
<div style="display: flex; align-items: center; gap: 8px; min-width: 0">
|
||||
<span style="font-size: 13px; white-space: nowrap">
|
||||
{{ $t('views.role.member.workspace') }}
|
||||
</span>
|
||||
<el-select
|
||||
v-model="form.workspace_id"
|
||||
:placeholder="`${$t('common.selectPlaceholder')}${$t('views.role.member.workspace')}`"
|
||||
style="flex: 1; min-width: 180px;"
|
||||
style="flex: 1; min-width: 180px"
|
||||
>
|
||||
<el-option
|
||||
v-for="workspace in workspaceOptions"
|
||||
|
|
@ -144,21 +151,20 @@
|
|||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="margin-top:16px;">
|
||||
<span
|
||||
v-hasPermission="
|
||||
new ComplexPermission([RoleConst.ADMIN], [PermissionConst.LOGIN_AUTH_EDIT], [], 'OR')
|
||||
"
|
||||
class="mr-12"
|
||||
>
|
||||
<!-- 直接调用 submit,不传参 -->
|
||||
<el-button @click="submit" type="primary" :disabled="loading">
|
||||
{{ $t('common.save') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<div style="margin-top: 16px">
|
||||
<span
|
||||
v-hasPermission="
|
||||
new ComplexPermission([RoleConst.ADMIN], [PermissionConst.LOGIN_AUTH_EDIT], [], 'OR')
|
||||
"
|
||||
class="mr-12"
|
||||
>
|
||||
<!-- 直接调用 submit,不传参 -->
|
||||
<el-button @click="submit" type="primary" :disabled="loading">
|
||||
{{ $t('common.save') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
|
|
@ -166,20 +172,20 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref, onMounted, computed} from "vue";
|
||||
import {ComplexPermission} from "@/utils/permission/type";
|
||||
import {PermissionConst, RoleConst} from "@/utils/permission/data";
|
||||
import type {FormInstance} from 'element-plus';
|
||||
import {t} from "@/locales";
|
||||
import authApi from "@/api/system-settings/auth-setting.ts";
|
||||
import {MsgSuccess} from "@/utils/message.ts";
|
||||
import WorkspaceApi from "@/api/workspace/workspace.ts";
|
||||
import useStore from "@/stores";
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { ComplexPermission } from '@/utils/permission/type'
|
||||
import { PermissionConst, RoleConst } from '@/utils/permission/data'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { t } from '@/locales'
|
||||
import authApi from '@/api/system-settings/auth-setting.ts'
|
||||
import { MsgSuccess } from '@/utils/message.ts'
|
||||
import WorkspaceApi from '@/api/workspace/workspace.ts'
|
||||
import useStore from '@/stores'
|
||||
|
||||
const loginMethods = ref<Array<{ label: string; value: string }>>([]);
|
||||
const loading = ref(false);
|
||||
const loginMethods = ref<Array<{ label: string; value: string }>>([])
|
||||
const loading = ref(false)
|
||||
// 明确允许 null,避免未挂载时访问出错
|
||||
const authFormRef = ref<FormInstance | null>(null);
|
||||
const authFormRef = ref<FormInstance | null>(null)
|
||||
|
||||
const form = ref<any>({
|
||||
default_value: 'LOCAL',
|
||||
|
|
@ -192,35 +198,35 @@ const form = ref<any>({
|
|||
|
||||
const normalizeInputValue = (val: number | null): number => {
|
||||
// 若输入为空或无法转换为有效数字,默认设为 1
|
||||
let normalizedVal = typeof val === 'number' ? Math.trunc(val) : NaN;
|
||||
let normalizedVal = typeof val === 'number' ? Math.trunc(val) : NaN
|
||||
if (!Number.isFinite(normalizedVal)) {
|
||||
normalizedVal = 1;
|
||||
normalizedVal = 1
|
||||
}
|
||||
|
||||
if (normalizedVal === 0) {
|
||||
normalizedVal = 1;
|
||||
normalizedVal = 1
|
||||
} else if (normalizedVal < -1) {
|
||||
normalizedVal = -1;
|
||||
normalizedVal = -1
|
||||
}
|
||||
|
||||
return normalizedVal;
|
||||
};
|
||||
return normalizedVal
|
||||
}
|
||||
|
||||
const onFailedAttemptsChange = (val: number | null) => {
|
||||
form.value.failed_attempts = normalizeInputValue(val);
|
||||
};
|
||||
form.value.failed_attempts = normalizeInputValue(val)
|
||||
}
|
||||
|
||||
const onMaxAttemptsChange = (val: number | null) => {
|
||||
form.value.max_attempts = normalizeInputValue(val);
|
||||
};
|
||||
form.value.max_attempts = normalizeInputValue(val)
|
||||
}
|
||||
|
||||
// 提交:使用 authFormRef.value.validate() 的 Promise 风格,并保证 loading 在 finally 中恢复
|
||||
const submit = async () => {
|
||||
const formRef = authFormRef.value;
|
||||
if (!formRef) return;
|
||||
const formRef = authFormRef.value
|
||||
if (!formRef) return
|
||||
try {
|
||||
await formRef.validate();
|
||||
loading.value = true;
|
||||
await formRef.validate()
|
||||
loading.value = true
|
||||
const params = {
|
||||
default_value: form.value.default_value,
|
||||
max_attempts: form.value.max_attempts,
|
||||
|
|
@ -228,85 +234,92 @@ const submit = async () => {
|
|||
lock_time: form.value.lock_time,
|
||||
role_id: form.value.role_id,
|
||||
workspace_id: form.value.workspace_id,
|
||||
};
|
||||
await authApi.putLoginSetting(params);
|
||||
MsgSuccess(t('common.saveSuccess'));
|
||||
}
|
||||
await authApi.putLoginSetting(params)
|
||||
MsgSuccess(t('common.saveSuccess'))
|
||||
} catch (err) {
|
||||
// 验证或请求失败:按需处理,避免未捕获异常
|
||||
// console.error(err);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
loading.value = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const roleOptions = ref<Array<{ id: string; name: string, type?: string }>>([]);
|
||||
const workspaceOptions = ref<Array<{ id: string; name: string }>>([]);
|
||||
const {user} = useStore();
|
||||
const selectedRoleType = ref<string>(''); // 存储选中角色类型,用于控制 workspace 显示
|
||||
const showWorkspaceSelector = computed(() => selectedRoleType.value !== 'ADMIN');
|
||||
const roleOptions = ref<Array<{ id: string; name: string; type?: string }>>([])
|
||||
const workspaceOptions = ref<Array<{ id: string; name: string }>>([])
|
||||
const { user } = useStore()
|
||||
const selectedRoleType = ref<string>('') // 存储选中角色类型,用于控制 workspace 显示
|
||||
const showWorkspaceSelector = computed(() => selectedRoleType.value !== 'ADMIN')
|
||||
|
||||
// 当角色变更时更新 selectedRoleType
|
||||
const handleRoleChange = (roleId: string) => {
|
||||
const selectedRole = roleOptions.value.find(role => role.id === roleId);
|
||||
selectedRoleType.value = selectedRole?.type || '';
|
||||
};
|
||||
const selectedRole = roleOptions.value.find((role) => role.id === roleId)
|
||||
selectedRoleType.value = selectedRole?.type || ''
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loading.value = true;
|
||||
loading.value = true
|
||||
try {
|
||||
const isEE = typeof user?.isEE === 'function' ? user.isEE() : false;
|
||||
const isEE = typeof user?.isEE === 'function' ? user.isEE() : false
|
||||
|
||||
// 并行请求:角色列表 + 登录设置;若为 EE 同时请求 workspace 列表
|
||||
const roleP = WorkspaceApi.getWorkspaceRoleList().then(r => r).catch(() => ({data: []}));
|
||||
const settingP = authApi.getLoginSetting().then(r => r).catch(() => ({data: {}}));
|
||||
const tasks: Promise<any>[] = [roleP, settingP];
|
||||
const roleP = WorkspaceApi.getWorkspaceRoleList()
|
||||
.then((r) => r)
|
||||
.catch(() => ({ data: [] }))
|
||||
const settingP = authApi
|
||||
.getLoginSetting()
|
||||
.then((r) => r)
|
||||
.catch(() => ({ data: {} }))
|
||||
const tasks: Promise<any>[] = [roleP, settingP]
|
||||
if (isEE) {
|
||||
tasks.push(WorkspaceApi.getWorkspaceList().then(r => r).catch(() => ({data: []})));
|
||||
tasks.push(
|
||||
WorkspaceApi.getWorkspaceList()
|
||||
.then((r) => r)
|
||||
.catch(() => ({ data: [] })),
|
||||
)
|
||||
}
|
||||
|
||||
const results = await Promise.all(tasks);
|
||||
const roleRes = results[0] ?? {data: []};
|
||||
const settingRes = results[1] ?? {data: {}};
|
||||
const workspaceRes = isEE ? results[2] ?? {data: []} : null;
|
||||
const results = await Promise.all(tasks)
|
||||
const roleRes = results[0] ?? { data: [] }
|
||||
const settingRes = results[1] ?? { data: {} }
|
||||
const workspaceRes = isEE ? (results[2] ?? { data: [] }) : null
|
||||
|
||||
// 处理角色列表(尽早回显)
|
||||
const rolesData = Array.isArray(roleRes?.data) ? roleRes.data : [];
|
||||
const rolesData = Array.isArray(roleRes?.data) ? roleRes.data : []
|
||||
roleOptions.value = rolesData.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
type: item.type
|
||||
}));
|
||||
type: item.type,
|
||||
}))
|
||||
|
||||
// 处理 setting(合并默认值,避免访问未定义)
|
||||
const data = settingRes?.data ?? {};
|
||||
const data = settingRes?.data ?? {}
|
||||
form.value = {
|
||||
...form.value,
|
||||
...data,
|
||||
failed_attempts: data.failed_attempts ?? form.value.failed_attempts ?? 5,
|
||||
lock_time: data.lock_time ?? form.value.lock_time ?? 10,
|
||||
role_id: data.role_id ?? form.value.role_id ?? 'USER',
|
||||
workspace_id: data.workspace_id ?? form.value.workspace_id ?? 'default'
|
||||
};
|
||||
loginMethods.value = Array.isArray(data.auth_types) ? data.auth_types : [];
|
||||
workspace_id: data.workspace_id ?? form.value.workspace_id ?? 'default',
|
||||
}
|
||||
loginMethods.value = Array.isArray(data.auth_types) ? data.auth_types : []
|
||||
|
||||
// 处理 workspace 列表(如果需要)
|
||||
if (isEE && workspaceRes) {
|
||||
const wks = Array.isArray(workspaceRes.data) ? workspaceRes.data : [];
|
||||
workspaceOptions.value = wks.map((item: any) => ({id: item.id, name: item.name}));
|
||||
const wks = Array.isArray(workspaceRes.data) ? workspaceRes.data : []
|
||||
workspaceOptions.value = wks.map((item: any) => ({ id: item.id, name: item.name }))
|
||||
}
|
||||
|
||||
// 初始化 selectedRoleType(基于当前回显的 role_id 与已加载的 roleOptions)
|
||||
const initRole = roleOptions.value.find(r => r.id === form.value.role_id);
|
||||
selectedRoleType.value = initRole?.type || '';
|
||||
|
||||
const initRole = roleOptions.value.find((r) => r.id === form.value.role_id)
|
||||
selectedRoleType.value = initRole?.type || ''
|
||||
} catch (e) {
|
||||
// overall error, 保持默认回显
|
||||
// console.error(e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
loading.value = false
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@
|
|||
<div>
|
||||
<el-select
|
||||
v-model="history_day"
|
||||
class="mr-12"
|
||||
class="mr-12 w-180"
|
||||
@change="changeDayHandle"
|
||||
style="width: 180px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dayOptions"
|
||||
|
|
|
|||
Loading…
Reference in New Issue