From c97d5ffb9993a29c7a511caa10bb823551ceebd6 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 2 Oct 2026 12:56:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(gerp):=20=E9=83=A8=E9=97=A8=E5=91=98?= =?UTF-8?q?=E5=B7=A5=E7=82=B9=E5=87=BB=E6=95=B4=E8=A1=8C=E5=BC=B9=E5=87=BA?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=AF=A6=E6=83=85=E6=8A=BD=E5=B1=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 部门详情的部门员工子表:点击行内任意位置弹出 60% 宽抽屉,抽屉内容与 /system/user-detail 页面完全一致。 为此把用户详情页内容抽成可嵌入组件 UserDetailPanel(props: userUUID, emit: loaded/loading/navigate,defineExpose: handleEdit): - views/system/UserDetail.vue 退化为页面外壳(路由取 UUID + DetailPage 标题/ 加载态/编辑按钮),内容由面板提供,页面表现与改动前一致 - DepartmentDetail 的抽屉复用同一面板,因此抽屉里看到的就是同一份内容 顺带修掉一个既有 bug:CrudTable 原先绑定的 @row-click 在 vxe-table 上并不存在 (事件表只有 cell-click),该绑定从未触发过。现改为 cell-click,并放过 复选/单选/序号/展开列与行内按钮,避免勾选行或点操作按钮时误触发行点击。 --- src/components/CrudTable.vue | 27 +- src/components/UserDetailPanel.vue | 844 +++++++++++++++++++++++++ src/views/company/DepartmentDetail.vue | 47 +- src/views/system/UserDetail.vue | 843 +----------------------- 4 files changed, 940 insertions(+), 821 deletions(-) create mode 100644 src/components/UserDetailPanel.vue diff --git a/src/components/CrudTable.vue b/src/components/CrudTable.vue index fa47b27..a3a739b 100644 --- a/src/components/CrudTable.vue +++ b/src/components/CrudTable.vue @@ -252,6 +252,31 @@ async function onHandleSubmit(): Promise { } } +/** + * 单元格点击 → 行点击回调(props.onRowClick) + * + * 用 cell-click 而不是 row-click:vxe-table 没有 row-click 事件(事件表里只有 + * cell-click),原先的 @row-click 绑定从未触发过。 + * 两类点击必须放过,否则会误触发行点击行为: + * - 复选/单选/展开列:勾选行不应该弹出详情 + * - 行内按钮(查看/编辑/删除):按钮有自己的动作 + */ +function handleCellClick(params: { + row: T + column?: { type?: string } + $event?: MouseEvent + triggerCheckbox?: boolean + triggerRadio?: boolean +}): void { + if (!props.onRowClick) return + const columnType = params.column?.type + if (columnType && ['checkbox', 'radio', 'seq', 'expand'].includes(columnType)) return + if (params.triggerCheckbox || params.triggerRadio) return + const target = params.$event?.target as HTMLElement | null | undefined + if (target?.closest('button, a, .el-checkbox, .el-switch')) return + handleRowClick(params.row) +} + // 查询条件变化(如工单管理页的状态筛选):重置到第一页并重新加载。 // 父组件传响应式 query(computed)时触发;无 query 的页面不受影响。 watch( @@ -559,7 +584,7 @@ defineExpose({ :row-config="{ isHover: true }" :column-config="{ resizable: true }" :checkbox-config="{ range: true }" - @row-click="(params: { row: T }) => handleRowClick(params.row)" + @cell-click="handleCellClick" @checkbox-change="onCheckboxChange" @checkbox-all="onCheckboxChange" > diff --git a/src/components/UserDetailPanel.vue b/src/components/UserDetailPanel.vue new file mode 100644 index 0000000..3219e8f --- /dev/null +++ b/src/components/UserDetailPanel.vue @@ -0,0 +1,844 @@ + + + + + diff --git a/src/views/company/DepartmentDetail.vue b/src/views/company/DepartmentDetail.vue index 93534e2..d7fc80a 100644 --- a/src/views/company/DepartmentDetail.vue +++ b/src/views/company/DepartmentDetail.vue @@ -25,6 +25,7 @@ import InfoGrid from '@/components/InfoGrid.vue' import CrudTable from '@/components/CrudTable.vue' import EntityPicker from '@/components/EntityPicker.vue' import BatchPositionDialog from '@/components/BatchPositionDialog.vue' +import UserDetailPanel from '@/components/UserDetailPanel.vue' import { formApi } from '@/api/form' import { useResolveUUIDs } from '@/composables/useResolveUUIDs' import { setPageTitle } from '@/utils/serverScope' @@ -185,11 +186,27 @@ async function handleSubmit(): Promise { // === 子表跳转 === -/** UserRole 子表查看 → 用户详情 */ +/** UserRole 子表查看按钮 → 用户详情页 */ function goUserDetail(row: Record): void { router.push({ path: '/system/user-detail', query: { UserUUID: row.UserUUID || '' } }) } +// === 行点击 → 用户详情抽屉 === +// 整行任意位置点击即弹出 60% 宽抽屉,内容与 /system/user-detail 页面完全一致 +// (同一个 UserDetailPanel 组件);「查看」按钮仍保持跳转到整页。 +const userDrawerVisible = ref(false) +const userDrawerUUID = ref('') +const userDrawerTitle = ref('用户详情') + +/** 打开用户详情抽屉(行内没有 UserUUID 时忽略,避免打开空抽屉) */ +function openUserDrawer(row: Record): void { + const uuid = String(row.UserUUID || '') + if (!uuid) return + userDrawerTitle.value = row.UserUUID_label ? String(row.UserUUID_label) : '用户详情' + userDrawerUUID.value = uuid + userDrawerVisible.value = true +} + // === 批量调整职务 === const deptTableRef = ref() const batchDialogVisible = ref(false) @@ -275,6 +292,7 @@ watch(deptUUID, () => { pageable :max-height="400" :on-view="goUserDetail" + :on-row-click="openUserDrawer" > + + +
+ +
+
+ { - + diff --git a/src/views/system/UserDetail.vue b/src/views/system/UserDetail.vue index 2241bf3..9c64b2c 100644 --- a/src/views/system/UserDetail.vue +++ b/src/views/system/UserDetail.vue @@ -1,843 +1,50 @@ - -