发布 v1.10 #5
@@ -139,7 +139,51 @@ public class SysAccountController extends BaseCurdController<SysAccountService,
|
|||||||
@Override
|
@Override
|
||||||
@LogRecord("分页查询")
|
@LogRecord("分页查询")
|
||||||
protected Page<SysAccount> queryPage(Page<SysAccount> page, QueryWrapper queryWrapper) {
|
protected Page<SysAccount> queryPage(Page<SysAccount> page, QueryWrapper queryWrapper) {
|
||||||
return service.getMapper().paginateWithRelations(page, queryWrapper);
|
Page<SysAccount> result = service.getMapper().paginateWithRelations(page, queryWrapper);
|
||||||
|
fillRoleNames(result.getRecords());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按当前分页内的角色 ID 批量补全角色名称。
|
||||||
|
*
|
||||||
|
* @param accounts 当前页账号
|
||||||
|
*/
|
||||||
|
private void fillRoleNames(List<SysAccount> accounts) {
|
||||||
|
if (accounts == null || accounts.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Set<BigInteger> roleIds = accounts.stream()
|
||||||
|
.map(SysAccount::getRoleIds)
|
||||||
|
.filter(java.util.Objects::nonNull)
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.filter(java.util.Objects::nonNull)
|
||||||
|
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
|
if (roleIds.isEmpty()) {
|
||||||
|
accounts.forEach(account -> account.setRoleNames(List.of()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<BigInteger, String> roleNameMap = sysRoleService.listByIds(roleIds).stream()
|
||||||
|
.filter(role -> role.getId() != null && StringUtil.hasText(role.getRoleName()))
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
SysRole::getId,
|
||||||
|
SysRole::getRoleName,
|
||||||
|
(first, ignored) -> first
|
||||||
|
));
|
||||||
|
accounts.forEach(account -> {
|
||||||
|
List<BigInteger> accountRoleIds = account.getRoleIds();
|
||||||
|
if (accountRoleIds == null || accountRoleIds.isEmpty()) {
|
||||||
|
account.setRoleNames(List.of());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> roleNames = accountRoleIds.stream()
|
||||||
|
.map(roleNameMap::get)
|
||||||
|
.filter(StringUtil::hasText)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
account.setRoleNames(roleNames);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ public class SysAccount extends SysAccountBase {
|
|||||||
)
|
)
|
||||||
private List<BigInteger> roleIds;
|
private List<BigInteger> roleIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账号关联的角色名称,仅用于列表展示。
|
||||||
|
*/
|
||||||
|
@Column(ignore = true)
|
||||||
|
private List<String> roleNames;
|
||||||
|
|
||||||
@RelationManyToMany(joinTable = "tb_sys_account_position"
|
@RelationManyToMany(joinTable = "tb_sys_account_position"
|
||||||
, joinSelfColumn = "account_id"
|
, joinSelfColumn = "account_id"
|
||||||
, joinTargetColumn = "position_id"
|
, joinTargetColumn = "position_id"
|
||||||
@@ -51,6 +57,24 @@ public class SysAccount extends SysAccountBase {
|
|||||||
this.roleIds = roleIds;
|
this.roleIds = roleIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取账号关联的角色名称。
|
||||||
|
*
|
||||||
|
* @return 角色名称列表
|
||||||
|
*/
|
||||||
|
public List<String> getRoleNames() {
|
||||||
|
return roleNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置账号关联的角色名称。
|
||||||
|
*
|
||||||
|
* @param roleNames 角色名称列表
|
||||||
|
*/
|
||||||
|
public void setRoleNames(List<String> roleNames) {
|
||||||
|
this.roleNames = roleNames;
|
||||||
|
}
|
||||||
|
|
||||||
public List<BigInteger> getPositionIds() {
|
public List<BigInteger> getPositionIds() {
|
||||||
return positionIds;
|
return positionIds;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import {
|
|||||||
ElMessageBox,
|
ElMessageBox,
|
||||||
ElTable,
|
ElTable,
|
||||||
ElTableColumn,
|
ElTableColumn,
|
||||||
|
ElTag,
|
||||||
|
ElTooltip,
|
||||||
} from 'element-plus';
|
} from 'element-plus';
|
||||||
|
|
||||||
import { api } from '#/api/request';
|
import { api } from '#/api/request';
|
||||||
@@ -47,6 +49,7 @@ const selectedRows = ref<any[]>([]);
|
|||||||
const batchActionLoading = ref(false);
|
const batchActionLoading = ref(false);
|
||||||
const dictStore = useDictStore();
|
const dictStore = useDictStore();
|
||||||
const selectedCount = computed(() => selectedRows.value.length);
|
const selectedCount = computed(() => selectedRows.value.length);
|
||||||
|
const maxVisibleRoleCount = 2;
|
||||||
const headerButtons = [
|
const headerButtons = [
|
||||||
{
|
{
|
||||||
key: 'create',
|
key: 'create',
|
||||||
@@ -68,6 +71,30 @@ const headerButtons = [
|
|||||||
function initDict() {
|
function initDict() {
|
||||||
dictStore.fetchDictionary('dataStatus');
|
dictStore.fetchDictionary('dataStatus');
|
||||||
}
|
}
|
||||||
|
function getRoleNames(row: any): string[] {
|
||||||
|
if (!Array.isArray(row?.roleNames)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const roleNames: unknown[] = row.roleNames;
|
||||||
|
return [
|
||||||
|
...new Set(
|
||||||
|
roleNames
|
||||||
|
.filter(
|
||||||
|
(roleName: unknown) =>
|
||||||
|
roleName !== null &&
|
||||||
|
roleName !== undefined &&
|
||||||
|
String(roleName).trim().length > 0,
|
||||||
|
)
|
||||||
|
.map(String),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
function getVisibleRoleNames(row: any) {
|
||||||
|
return getRoleNames(row).slice(0, maxVisibleRoleCount);
|
||||||
|
}
|
||||||
|
function getHiddenRoleCount(row: any) {
|
||||||
|
return Math.max(getRoleNames(row).length - maxVisibleRoleCount, 0);
|
||||||
|
}
|
||||||
const handleSearch = (params: string) => {
|
const handleSearch = (params: string) => {
|
||||||
pageDataRef.value.setQuery({ keyword: params.trim() });
|
pageDataRef.value.setQuery({ keyword: params.trim() });
|
||||||
};
|
};
|
||||||
@@ -353,6 +380,58 @@ function isAdmin(data: any) {
|
|||||||
{{ row.nickname }}
|
{{ row.nickname }}
|
||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
|
<ElTableColumn
|
||||||
|
prop="roleIds"
|
||||||
|
align="center"
|
||||||
|
min-width="260"
|
||||||
|
:label="$t('sysAccount.roleIds')"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<ElTooltip
|
||||||
|
v-if="getRoleNames(row).length > 0"
|
||||||
|
placement="top"
|
||||||
|
popper-class="sys-account-role-tooltip"
|
||||||
|
:show-after="300"
|
||||||
|
>
|
||||||
|
<template #content>
|
||||||
|
<div class="sys-account-role-tooltip__content">
|
||||||
|
<ElTag
|
||||||
|
v-for="roleName in getRoleNames(row)"
|
||||||
|
:key="roleName"
|
||||||
|
effect="plain"
|
||||||
|
type="info"
|
||||||
|
>
|
||||||
|
{{ roleName }}
|
||||||
|
</ElTag>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div
|
||||||
|
class="sys-account-role-summary"
|
||||||
|
tabindex="0"
|
||||||
|
:aria-label="getRoleNames(row).join('、')"
|
||||||
|
>
|
||||||
|
<ElTag
|
||||||
|
v-for="roleName in getVisibleRoleNames(row)"
|
||||||
|
:key="roleName"
|
||||||
|
class="sys-account-role-tag"
|
||||||
|
effect="plain"
|
||||||
|
type="info"
|
||||||
|
>
|
||||||
|
{{ roleName }}
|
||||||
|
</ElTag>
|
||||||
|
<ElTag
|
||||||
|
v-if="getHiddenRoleCount(row) > 0"
|
||||||
|
class="sys-account-role-more"
|
||||||
|
effect="plain"
|
||||||
|
type="info"
|
||||||
|
>
|
||||||
|
+{{ getHiddenRoleCount(row) }}
|
||||||
|
</ElTag>
|
||||||
|
</div>
|
||||||
|
</ElTooltip>
|
||||||
|
<span v-else class="sys-account-role-empty">-</span>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
<ElTableColumn
|
<ElTableColumn
|
||||||
prop="mobile"
|
prop="mobile"
|
||||||
align="center"
|
align="center"
|
||||||
@@ -464,6 +543,48 @@ function isAdmin(data: any) {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sys-account-role-summary {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--space-1);
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 0;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sys-account-role-summary:focus-visible {
|
||||||
|
border-radius: var(--radius-control);
|
||||||
|
box-shadow: 0 0 0 2px hsl(var(--primary) / 24%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sys-account-role-tag {
|
||||||
|
max-width: 88px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sys-account-role-tag :deep(.el-tag__content) {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sys-account-role-more {
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sys-account-role-empty {
|
||||||
|
color: hsl(var(--text-muted));
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.sys-account-role-tooltip) {
|
||||||
|
max-width: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.sys-account-role-tooltip .sys-account-role-tooltip__content) {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: var(--space-1);
|
||||||
|
}
|
||||||
|
|
||||||
.sys-account-batch-inline__actions :deep(.el-button) {
|
.sys-account-batch-inline__actions :deep(.el-button) {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
min-height: 32px;
|
min-height: 32px;
|
||||||
|
|||||||
Reference in New Issue
Block a user