From cf7660ed689f2f24b27626308f9123a7632e25a2 Mon Sep 17 00:00:00 2001 From: kiki1373639299 Date: Fri, 21 Nov 2025 18:20:48 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat(client):=20=E6=96=B0=E5=A2=9E=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF=E5=8F=82=E6=95=B0=E6=8B=93=E5=B1=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/system/type.ts | 11 ++ src/views/system/config/client/AddModal.vue | 122 +++++++++++++++++- .../system/config/client/DetailDrawer.vue | 22 +++- src/views/system/config/client/index.vue | 52 +++++++- 4 files changed, 195 insertions(+), 12 deletions(-) diff --git a/src/apis/system/type.ts b/src/apis/system/type.ts index 3c0f665..d1fc317 100644 --- a/src/apis/system/type.ts +++ b/src/apis/system/type.ts @@ -295,12 +295,18 @@ export interface ClientResp { activeTimeout: string timeout: string status: string + isConcurrent: boolean + isShare: boolean + maxLoginCount: number + replacedRange: string + overflowLogoutMode: string createUser: string createTime: string updateUser: string updateTime: string createUserString: string updateUserString: string + disabled: boolean } export interface ClientDetailResp { id: string @@ -310,6 +316,11 @@ export interface ClientDetailResp { activeTimeout: string timeout: string status: string + isConcurrent: boolean + isShare: boolean + maxLoginCount: number + replacedRange: string + overflowLogoutMode: string createUser: string createTime: string updateUser: string diff --git a/src/views/system/config/client/AddModal.vue b/src/views/system/config/client/AddModal.vue index 901c6ce..f3a27c1 100644 --- a/src/views/system/config/client/AddModal.vue +++ b/src/views/system/config/client/AddModal.vue @@ -32,16 +32,45 @@ const visible = ref(false) const isUpdate = computed(() => !!dataId.value) const title = computed(() => (isUpdate.value ? '修改客户端' : '新增客户端')) const formRef = ref>() -const { client_type, auth_type_enum } = useDict('auth_type_enum', 'client_type') +const { client_type, auth_type_enum, replaced_range_enum, logout_mode_enum } = useDict('auth_type_enum', 'client_type', 'replaced_range_enum', 'logout_mode_enum') const [form, resetForm] = useResetReactive({ activeTimeout: 1800, timeout: 86400, - isConcurrent: 1, - isShare: 1, + isConcurrent: true, + isShare: true, + maxLoginCount: -1, + replacedRange: 'ALL_DEVICE_TYPE', + overflowLogoutMode: 'KICKOUT', status: 1, }) +// 监听 isConcurrent 和 isShare 的变化,处理字段互斥逻辑 +watch( + () => form.isConcurrent, + (newVal) => { + if (!newVal) { + // 当 isConcurrent=false 时,禁用相关字段 + form.isShare = false + form.maxLoginCount = -1 + // replacedRange 只有在 isConcurrent=false 时才有意义 + } else if (newVal && form.isShare) { + // 当 isConcurrent=true 且 isShare=true 时,清空 maxLoginCount + form.maxLoginCount = -1 + } + }, +) + +watch( + () => form.isShare, + (newVal) => { + if (form.isConcurrent && newVal) { + // 当 isConcurrent=true 且 isShare=true 时,清空 maxLoginCount + form.maxLoginCount = -1 + } + }, +) + const columns: ColumnItem[] = reactive([ { label: '客户端类型', @@ -87,7 +116,7 @@ const columns: ColumnItem[] = reactive([ { label: () => ( - Token 有效期  + Token 有效期 ), @@ -104,6 +133,91 @@ const columns: ColumnItem[] = reactive([ }, rules: [{ required: true, message: '请输入 Token 有效期' }], }, + { + label: '是否允许同一账号多地同时登录', + field: 'isConcurrent', + type: 'switch', + span: 12, + props: { + type: 'round', + checkedValue: true, + uncheckedValue: false, + checkedText: '允许', + uncheckedText: '不允许', + }, + }, + { + label: '是否共用 token', + field: 'isShare', + type: 'switch', + span: 12, + props: { + type: 'round', + checkedValue: true, + uncheckedValue: false, + checkedText: '共用', + uncheckedText: '不共用', + }, + disabled: () => { + return !form.isConcurrent + }, + }, + { + label: () => ( + + 最大登录数量 + + + ), + field: 'maxLoginCount', + type: 'input-number', + span: 12, + slots: { + append: () => ( + + ), + }, + props: { + placeholder: '请输入最大登录数量', + min: -1, + }, + disabled: () => { + return !form.isConcurrent || form.isShare + }, + rules: [ + { + validator: (value: number, callback: (errorMessage?: string) => void) => { + if (value === 0) { + callback('最大登录数量不能为0,请输入-1或正整数') + } + callback() + }, + }, + ], + }, + { + label: '顶人下线的范围', + field: 'replacedRange', + type: 'select', + span: 12, + props: { + options: replaced_range_enum, + placeholder: '请选择顶人下线的范围', + }, + disabled: () => { + return form.isConcurrent + }, + }, + { + label: '溢出人数的注销方式', + field: 'overflowLogoutMode', + type: 'select', + span: 24, + props: { + options: logout_mode_enum, + placeholder: '请选择溢出人数的注销方式', + }, + }, { label: '状态', field: 'status', diff --git a/src/views/system/config/client/DetailDrawer.vue b/src/views/system/config/client/DetailDrawer.vue index f915e50..efbc8bf 100644 --- a/src/views/system/config/client/DetailDrawer.vue +++ b/src/views/system/config/client/DetailDrawer.vue @@ -17,6 +17,23 @@ 启用 禁用 + + 允许 + 不允许 + + + 共用 + 不共用 + + + {{ dataDetail?.maxLoginCount === -1 ? '不限' : dataDetail?.maxLoginCount }} + + + + + + + {{ dataDetail?.createUserString }} {{ dataDetail?.createTime }} {{ dataDetail?.updateUserString }} @@ -29,11 +46,14 @@ import { useWindowSize } from '@vueuse/core' import { type ClientDetailResp, getClient as getDetail } from '@/apis/system/client' import { useDict } from '@/hooks/app' +import GiCellTag from '@/components/GiCell/GiCellTag.vue' const { client_type, auth_type_enum, -} = useDict('client_type', 'auth_type_enum') + replaced_range_enum, + logout_mode_enum, +} = useDict('client_type', 'auth_type_enum', 'replaced_range_enum', 'logout_mode_enum') const { width } = useWindowSize() diff --git a/src/views/system/config/client/index.vue b/src/views/system/config/client/index.vue index e37db58..0d6610b 100644 --- a/src/views/system/config/client/index.vue +++ b/src/views/system/config/client/index.vue @@ -60,7 +60,7 @@