From 9f70409844b92e436f7d62f963c6190bac35e689 Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud Date: Wed, 12 Aug 2026 09:26:41 +0800 Subject: [PATCH] style: format --- ui/src/api/admin/system/platform-source.ts | 25 ++ ui/src/api/types/system-authentication.ts | 15 + ui/src/components/COMPONENT_README.md | 9 +- .../global/mk-view-layout/index.vue | 42 ++- .../global/mk-view-layout/layout-main.ts | 95 ------ ui/src/views/VIEW_README.md | 3 + .../chat/user-groups/GroupsListView.vue | 14 +- .../views/system/chat/users/UserListView.vue | 20 +- .../system/identity/groups/GroupsListView.vue | 17 +- .../system/identity/users/UserListView.vue | 14 +- .../identity/workspaces/WorkspaceListView.vue | 14 +- .../operate-logs/OperateLogListView.vue | 6 +- .../AuthenticationSettingsView.vue | 321 +++--------------- .../component/AuthProviderForm.vue | 130 +++++++ .../settings/authentication/component/CAS.vue | 14 + .../authentication/component/EditModal.vue | 115 +++++++ .../authentication/component/LDAP.vue | 21 ++ .../authentication/component/OAuth2.vue | 19 ++ .../authentication/component/OIDC.vue | 25 ++ .../authentication/component/SCAN.vue | 137 ++++++++ .../authentication/component/Saml2.vue | 33 ++ .../authentication/component/Setting.vue | 140 ++++++++ .../settings/email/EmailSettingsView.vue | 88 ++--- 23 files changed, 865 insertions(+), 452 deletions(-) create mode 100644 ui/src/api/admin/system/platform-source.ts delete mode 100644 ui/src/components/global/mk-view-layout/layout-main.ts create mode 100644 ui/src/views/system/settings/authentication/component/AuthProviderForm.vue create mode 100644 ui/src/views/system/settings/authentication/component/CAS.vue create mode 100644 ui/src/views/system/settings/authentication/component/EditModal.vue create mode 100644 ui/src/views/system/settings/authentication/component/LDAP.vue create mode 100644 ui/src/views/system/settings/authentication/component/OAuth2.vue create mode 100644 ui/src/views/system/settings/authentication/component/OIDC.vue create mode 100644 ui/src/views/system/settings/authentication/component/SCAN.vue create mode 100644 ui/src/views/system/settings/authentication/component/Saml2.vue create mode 100644 ui/src/views/system/settings/authentication/component/Setting.vue diff --git a/ui/src/api/admin/system/platform-source.ts b/ui/src/api/admin/system/platform-source.ts new file mode 100644 index 00000000000..4e716020c81 --- /dev/null +++ b/ui/src/api/admin/system/platform-source.ts @@ -0,0 +1,25 @@ +import { get, post, put } from '../core/request' +import type { QrLoginPlatform, QrLoginPlatformRequest } from '@/api/types' + +const prefix = '/platform' + +/** 获取扫码登录平台配置。 */ +const getQrLoginPlatforms = () => { + return get(prefix) +} + +/** 校验扫码登录平台配置是否可用。 */ +const postQrLoginPlatformConnection = (platform: QrLoginPlatformRequest) => { + return post(`${prefix}/connection`, platform) +} + +/** 保存扫码登录平台配置。 */ +const putQrLoginPlatform = (platform: QrLoginPlatformRequest) => { + return put(prefix, platform) +} + +export default { + getQrLoginPlatforms, + postQrLoginPlatformConnection, + putQrLoginPlatform, +} diff --git a/ui/src/api/types/system-authentication.ts b/ui/src/api/types/system-authentication.ts index 72793abcd9e..843404db582 100644 --- a/ui/src/api/types/system-authentication.ts +++ b/ui/src/api/types/system-authentication.ts @@ -24,3 +24,18 @@ export interface LoginAuthSetting { system_options?: LoginMethodOption[] workspace_id?: string } + +export type QrLoginPlatformType = 'wecom' | 'dingtalk' | 'lark' + +export interface QrLoginPlatform { + auth_type: QrLoginPlatformType + config: Record + is_active: boolean + is_valid: boolean +} + +export interface QrLoginPlatformRequest { + config: Record + isActive: boolean + key: QrLoginPlatformType +} diff --git a/ui/src/components/COMPONENT_README.md b/ui/src/components/COMPONENT_README.md index 91007544242..d3def83a89a 100644 --- a/ui/src/components/COMPONENT_README.md +++ b/ui/src/components/COMPONENT_README.md @@ -51,8 +51,7 @@ src/components/ │ │ └── index.vue # SVG Symbol 与 Element Plus 图标统一入口 │ ├── mk-view-layout/ │ │ ├── index.vue # 路由页面标题、操作区和内容区统一结构 -│ │ ├── layout-aside.vue # 页面可选左侧栏结构 -│ │ └── layout-main.ts # 右侧标题标记提取与滚动内容渲染 +│ │ └── layout-aside.vue # 页面可选左侧栏结构 │ ├── mk-search-input/ │ │ └── index.vue # 带默认搜索图标的输入框 │ ├── mk-status-label/ @@ -253,9 +252,9 @@ Element Plus Dropdown 属性和事件通过 `$attrs` 传入,并暴露 `handleO 路由页面的通用内容结构,统一提供满高弹性布局及可选左侧栏。标题优先使用 `title` Prop,未传入 时读取当前路由的 `meta.title`。`aside` 和默认作用域插槽都提供 `title` 与对应区域的 `Header` -标记组件。默认插槽中的 `Header` 会由布局提取到右侧滚动区上方,其余节点统一放入 -`el-scrollbar`;页面因此可以在同一个插槽中组织标题、内容和空状态,并只写一次业务状态判断。 -传入 `aside` 插槽后才会渲染左侧栏;左右结构上方的独立内容放入 `top` 插槽。页面加载状态通过 +包装组件,页面可以在同一个插槽中组织标题、内容和空状态,并只写一次业务状态判断。组件不统一 +处理内容滚动,需要滚动的页面自行使用 `el-scrollbar`。传入 `aside` 插槽后才会渲染左侧栏;左右 +结构上方的独立内容放入 `top` 插槽。页面加载状态通过 `loading` Prop 传入,由组件将 Element Plus Loading 遮罩绑定到整个布局根节点。默认插槽没有 声明作用域参数时会自动显示当前标题;使用 `#default="{ Header }"` 后则由页面通过 `` 控制标题,空状态分支不会自动补充标题。 diff --git a/ui/src/components/global/mk-view-layout/index.vue b/ui/src/components/global/mk-view-layout/index.vue index 467a24d5a2a..3b181cfeac5 100644 --- a/ui/src/components/global/mk-view-layout/index.vue +++ b/ui/src/components/global/mk-view-layout/index.vue @@ -1,8 +1,7 @@ - - - +
+ +
diff --git a/ui/src/components/global/mk-view-layout/layout-main.ts b/ui/src/components/global/mk-view-layout/layout-main.ts deleted file mode 100644 index 1a611fe193d..00000000000 --- a/ui/src/components/global/mk-view-layout/layout-main.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { - Fragment, - createTextVNode, - defineComponent, - h, - isVNode, - type Component, - type Slots, - type SlotsType, - type VNode, -} from 'vue' -import { ElScrollbar } from 'element-plus' - -type LayoutMainSlotProps = { - Header: Component - title: string -} - -const LayoutMainHeader = defineComponent({ - name: 'MkViewLayoutMainHeader', - setup(_, { slots }) { - return () => slots.default?.() - }, -}) - -function flattenSlotNodes(children: unknown): VNode[] { - const childNodes = Array.isArray(children) ? children : [children] - - return childNodes.flatMap((child) => { - if (child === undefined || child === null || typeof child === 'boolean') return [] - if (!isVNode(child)) return [createTextVNode(String(child))] - if (child.type === Fragment) return flattenSlotNodes(child.children) - return [child] - }) -} - -function getHeaderNodes(headerNode: VNode) { - const headerSlots = headerNode.children as Slots | null - return flattenSlotNodes(headerSlots?.default?.()) -} - -export default defineComponent({ - name: 'MkViewLayoutMain', - props: { - fallbackTitle: { - default: '', - type: String, - }, - title: { - default: '', - type: String, - }, - }, - slots: Object as SlotsType<{ - default?: (props: LayoutMainSlotProps) => VNode[] - }>, - setup(props, { slots }) { - return () => { - const headerNodes: VNode[] = [] - const contentNodes: VNode[] = [] - - flattenSlotNodes(slots.default?.({ Header: LayoutMainHeader, title: props.title })).forEach( - (node) => { - if (node.type === LayoutMainHeader) { - headerNodes.push(...getHeaderNodes(node)) - return - } - - contentNodes.push(node) - }, - ) - - const resolvedHeaderNodes = - headerNodes.length > 0 - ? headerNodes - : props.fallbackTitle - ? [h('h4', props.fallbackTitle)] - : [] - - return h('main', { class: 'flex min-w-0 flex-1 flex-col px-6 mb-6' }, [ - resolvedHeaderNodes.length - ? h('header', { class: 'flex-between shrink-0 py-4' }, resolvedHeaderNodes) - : null, - h( - ElScrollbar, - { - class: 'min-h-0 flex-1', - viewClass: 'flex min-h-full flex-col', - }, - { default: () => contentNodes }, - ), - ]) - } - }, -}) diff --git a/ui/src/views/VIEW_README.md b/ui/src/views/VIEW_README.md index ebb694843ca..f699c16bf99 100644 --- a/ui/src/views/VIEW_README.md +++ b/ui/src/views/VIEW_README.md @@ -28,6 +28,9 @@ - 页面脚本中的状态、计算属性和处理方法按照同一业务流程集中放置,并使用简短的业务备注划分 列表查询、批量操作等流程。流程较长的函数应在确认、请求、刷新等关键阶段添加说明,重点解释 Promise 返回、执行顺序和业务约束,不为含义明确的单行代码逐句添加注释。 +- 页面模板的事件绑定不直接调用 Dialog、Drawer 等组件实例暴露的 `open()` 方法。应在对应业务 + 流程的方法区域定义语义明确的 `handleOpenXxx` 处理函数,由处理函数调用组件实例的 `open()`, + 模板只绑定该处理函数;创建和编辑共用同一浮层时,可通过处理函数的可选参数区分操作场景。 参考结构: diff --git a/ui/src/views/system/chat/user-groups/GroupsListView.vue b/ui/src/views/system/chat/user-groups/GroupsListView.vue index ad687651451..7dc3ce8d614 100644 --- a/ui/src/views/system/chat/user-groups/GroupsListView.vue +++ b/ui/src/views/system/chat/user-groups/GroupsListView.vue @@ -18,6 +18,10 @@ import CreateOrUpdateGroupDialog from './dialog/CreateOrUpdateGroupDialog.vue' const groupDialogRef = useTemplateRef>('groupDialogRef') +function handleOpenGroupDialog(group?: ListItem) { + groupDialogRef.value?.open(group) +} + /* 用户组列表与选择 */ const groupsLoading = ref(false) const chatUserGroups = ref([]) @@ -101,6 +105,10 @@ function handleMemberSearch(query?: RequestParams) { const memberDialogRef = useTemplateRef>('memberDialogRef') +function handleOpenMemberDialog() { + memberDialogRef.value?.open() +} + /* (批量)移除成员 */ const batchSelectedMembers = ref([]) function handleBatchSelectionChange(selection: unknown[]) { @@ -140,7 +148,7 @@ onMounted(() => loadChatUserGroups())

{{ title }}

- + @@ -152,7 +160,7 @@ onMounted(() => loadChatUserGroups()) >