feat(gerp): 部门/公司详情员工卡片标题显示角色数与用户数
部门详情卡片标题改为「部门员工(角色数:x/用户数:y)」, 公司详情改为「员工(角色数:x/用户数:y)」: 角色数取列表 total(用户-角色关系条数),用户数取后端新增的 user_count(去重用户数)。 计数与子表同源:复用 List 接口带 WithUserCount=1 只取 1 行拿计数,保证与表格 完全相同的 DeptUUID/CompanyUUID 过滤;批量调整职务成功后与子表一起刷新。 PagedData 类型补充可选的 user_count 字段。
This commit is contained in:
1 parent
dfed6ef8bc
commit
66304f9c5e
3 files changed
+79
-6
No files matched your search
@@ -21,6 +21,12 @@ export interface PagedData<T> {
|
||||
page: number
|
||||
/** 每页大小 */
|
||||
pageSize: number
|
||||
/**
|
||||
* 去重用户数(仅请求带 WithUserCount=1 时后端才返回)
|
||||
*
|
||||
* 员工卡片标题「角色数:x/用户数:y」用:total 是角色(关系)条数,本字段是去重用户数。
|
||||
*/
|
||||
user_count?: number
|
||||
}
|
||||
|
||||
/** statusMap 单个状态的渲染配置 */
|
||||
|
||||
@@ -70,6 +70,10 @@ const resolvedNames = ref<Record<string, Record<string, string>>>({})
|
||||
/** 从路由 query 读取公司 UUID(computed 响应式:同一 tab 复用且 query 变化时自动更新) */
|
||||
const companyUUID = computed(() => (route.query.CompanyUUID as string) || '')
|
||||
|
||||
// 员工计数(卡片标题「角色数:x/用户数:y」)
|
||||
// 角色数 = 用户-角色关系条数;用户数 = 去重用户数(同一人挂多个角色只算一个)
|
||||
const empCounts = ref<{ roles: number; users: number }>({ roles: 0, users: 0 })
|
||||
|
||||
/** 公司主键字段名 */
|
||||
const PK_FIELD = 'CompanyUUID'
|
||||
|
||||
@@ -150,6 +154,8 @@ async function loadCompany(): Promise<void> {
|
||||
}
|
||||
companyData.value = data
|
||||
setPageTitle(asStr(data.CompanyName) || '公司详情')
|
||||
// 员工计数与子表同源(同样的 CompanyUUID 过滤),随主数据一起刷新
|
||||
void loadEmpCounts()
|
||||
|
||||
// 解析 ParentCompanyUUID(Company 表)与 TenantUUID(Tenant 表)
|
||||
const uuidMap: Record<string, { table: string; uuids: string[] }> = {}
|
||||
@@ -169,6 +175,33 @@ async function loadCompany(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载「员工(角色数:x/用户数:y)」
|
||||
*
|
||||
* 计数必须与子表同源(同样的 CompanyUUID 过滤条件),所以复用 List 接口:
|
||||
* 只要 1 行数据,靠 total 拿角色数、user_count 拿去重用户数(后端按 WithUserCount 现算)。
|
||||
*/
|
||||
async function loadEmpCounts(): Promise<void> {
|
||||
if (!companyUUID.value) return
|
||||
try {
|
||||
const result = await formApi.list<RowData>('UserRole', {
|
||||
CompanyUUID: companyUUID.value,
|
||||
WithUserCount: 1,
|
||||
pageSize: 1,
|
||||
})
|
||||
const paged = result as unknown as { total?: number; user_count?: number }
|
||||
empCounts.value = { roles: paged?.total ?? 0, users: paged?.user_count ?? 0 }
|
||||
} catch {
|
||||
// 计数失败不影响页面主体(错误提示已由响应拦截器统一处理)
|
||||
}
|
||||
}
|
||||
|
||||
/** 刷新员工子表 + 计数(计数与子表同源,必须一起更新) */
|
||||
function refreshEmployees(): void {
|
||||
empTableRef.value?.refresh?.()
|
||||
void loadEmpCounts()
|
||||
}
|
||||
|
||||
// ===== 子表行跳转(onView)=====
|
||||
/** 跳转部门详情 */
|
||||
function goDeptDetail(row: RowData): void {
|
||||
@@ -475,7 +508,7 @@ watch(companyUUID, () => {
|
||||
<template #header>
|
||||
<div class="detail-card-header">
|
||||
<el-icon><User /></el-icon>
|
||||
<span>员工</span>
|
||||
<span>员工(角色数:{{ empCounts.roles }}/用户数:{{ empCounts.users }})</span>
|
||||
</div>
|
||||
</template>
|
||||
<CrudTable
|
||||
@@ -489,7 +522,7 @@ watch(companyUUID, () => {
|
||||
pk-field="UserRoleUUID"
|
||||
:on-view="goEmployeeDetail"
|
||||
>
|
||||
<template #toolbar="{ refresh }">
|
||||
<template #toolbar>
|
||||
<el-button type="warning" @click="openBatchDialog">
|
||||
<el-icon><Edit /></el-icon>批量调整职务
|
||||
</el-button>
|
||||
@@ -499,7 +532,7 @@ watch(companyUUID, () => {
|
||||
:context="{ CompanyUUID: companyUUID }"
|
||||
:preselected="batchPreselected"
|
||||
title="员工批量调整职务"
|
||||
@success="refresh"
|
||||
@success="refreshEmployees"
|
||||
/>
|
||||
</template>
|
||||
</CrudTable>
|
||||
|
||||
@@ -51,6 +51,10 @@ const editSubmitting = ref(false)
|
||||
const columns = ref<ColumnSchema[]>([])
|
||||
const editForm = reactive<Record<string, any>>({})
|
||||
|
||||
// 部门员工计数(卡片标题「角色数:x/用户数:y」)
|
||||
// 角色数 = 用户-角色关系条数;用户数 = 去重用户数(同一人挂多个角色只算一个)
|
||||
const empCounts = ref<{ roles: number; users: number }>({ roles: 0, users: 0 })
|
||||
|
||||
// 主键字段
|
||||
const PK_FIELD = 'DeptUUID'
|
||||
|
||||
@@ -89,11 +93,41 @@ async function loadData(): Promise<void> {
|
||||
setPageTitle(row.DeptName || '部门详情')
|
||||
// 解析上级部门 UUID → 名称
|
||||
await resolveParentDept(row.ParentDeptUUID)
|
||||
// 计数依赖 row.CompanyUUID,必须等主数据就位后再取
|
||||
await loadEmpCounts()
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载「部门员工(角色数:x/用户数:y)」
|
||||
*
|
||||
* 计数必须与子表同源(同样的 DeptUUID + CompanyUUID 过滤条件),所以复用 List 接口:
|
||||
* 只要 1 行数据,靠 total 拿角色数、user_count 拿去重用户数(后端按 WithUserCount 现算)。
|
||||
*/
|
||||
async function loadEmpCounts(): Promise<void> {
|
||||
if (!deptUUID.value) return
|
||||
try {
|
||||
const result = await formApi.list<Record<string, unknown>>('UserRoleDepartment', {
|
||||
DeptUUID: deptUUID.value,
|
||||
CompanyUUID: data.value?.CompanyUUID || '',
|
||||
WithUserCount: 1,
|
||||
pageSize: 1,
|
||||
})
|
||||
const paged = result as unknown as { total?: number; user_count?: number }
|
||||
empCounts.value = { roles: paged?.total ?? 0, users: paged?.user_count ?? 0 }
|
||||
} catch {
|
||||
// 计数失败不影响页面主体(错误提示已由响应拦截器统一处理)
|
||||
}
|
||||
}
|
||||
|
||||
/** 刷新子表 + 计数(计数与子表同源,必须一起更新) */
|
||||
function refreshEmployees(): void {
|
||||
deptTableRef.value?.refresh?.()
|
||||
void loadEmpCounts()
|
||||
}
|
||||
|
||||
/** 解析 ParentDeptUUID → DeptName */
|
||||
async function resolveParentDept(parentUUID?: string): Promise<void> {
|
||||
if (!parentUUID) {
|
||||
@@ -224,7 +258,7 @@ watch(deptUUID, () => {
|
||||
<template #header>
|
||||
<div class="detail-card-header">
|
||||
<el-icon><User /></el-icon>
|
||||
<span>部门员工</span>
|
||||
<span>部门员工(角色数:{{ empCounts.roles }}/用户数:{{ empCounts.users }})</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 部门成员须走入职流程(EmployeeProfile → UserRole/UserRoleDepartment),
|
||||
@@ -242,7 +276,7 @@ watch(deptUUID, () => {
|
||||
:max-height="400"
|
||||
:on-view="goUserDetail"
|
||||
>
|
||||
<template #toolbar="{ refresh }">
|
||||
<template #toolbar>
|
||||
<el-button type="warning" @click="openBatchDialog">
|
||||
<el-icon><Edit /></el-icon>批量调整职务
|
||||
</el-button>
|
||||
@@ -252,7 +286,7 @@ watch(deptUUID, () => {
|
||||
:context="{ DeptUUID: deptUUID, CompanyUUID: data?.CompanyUUID || '' }"
|
||||
:preselected="batchPreselected"
|
||||
title="部门员工批量调整职务"
|
||||
@success="refresh"
|
||||
@success="refreshEmployees"
|
||||
/>
|
||||
</template>
|
||||
</CrudTable>
|
||||
|
||||
Reference in new issue
Block a user