feat(user): 用户页面搜索区新增用户昵称搜索框

- 在用户组件中将用户名搜索框替换为用户昵称搜索框。
- 给岗位设置最小宽度,防止内容缩起来。
fix(user-management-relation): 管理链路树显示问题
- 当组织类型不为公司时(为部门、方向、团队),为防止根节点变更导致下面的子节点出现紊乱,此时隐藏编辑按钮。
- 把用margin扩充宽度改为用min-width。
fix(role): 选中某角色后的操作列的透明显示问题
- 选中某角色后,当页面分辨率不够时(出现滚动条),创建时间等字段的内容会透过操作列
fix(post): 岗位的名称、编码字段的显示问题
- 给这两个字段设置最小宽度,防止它们缩起来。
This commit is contained in:
dk
2026-04-22 14:34:26 +08:00
parent ca1756344c
commit c5911ea34b
8 changed files with 55 additions and 17 deletions

View File

@@ -404,7 +404,7 @@ const local: App.I18n.Schema = {
emptyLeader: '暂无负责人', emptyLeader: '暂无负责人',
userName: '用户名', userName: '用户名',
userGender: '性别', userGender: '性别',
nickName: '昵称', nickName: '用户昵称',
deptName: '所属组织', deptName: '所属组织',
positionName: '岗位', positionName: '岗位',
userPhone: '手机号', userPhone: '手机号',
@@ -422,7 +422,7 @@ const local: App.I18n.Schema = {
form: { form: {
userName: '请输入用户名', userName: '请输入用户名',
userGender: '请选择性别', userGender: '请选择性别',
nickName: '请输入昵称', nickName: '请输入用户昵称',
orgName: '请输入组织名称', orgName: '请输入组织名称',
orgCode: '请输入组织编码', orgCode: '请输入组织编码',
orgTypeLabel: '请选择组织类型', orgTypeLabel: '请选择组织类型',

View File

@@ -104,7 +104,7 @@ export function fetchBatchDeleteDictData(ids: number[]) {
} }
/** 通过岗位编码获取该字典的所有字典数据 */ /** 通过岗位编码获取该字典的所有字典数据 */
export function fetchGetDictDataByCode(code: String) { export function fetchGetDictDataByCode(code: string) {
return request<Api.Dict.PageResult<Api.Dict.DictData>>({ return request<Api.Dict.PageResult<Api.Dict.DictData>>({
url: `${DICT_DATA_PREFIX}/code?code=${code}`, url: `${DICT_DATA_PREFIX}/code?code=${code}`,
method: 'get' method: 'get'

View File

@@ -146,6 +146,7 @@ declare namespace Api {
Pick<User, 'status'> & Pick<User, 'status'> &
Pick<PageParams, 'pageNo' | 'pageSize'> & { Pick<PageParams, 'pageNo' | 'pageSize'> & {
username?: string; username?: string;
nickname?: string;
mobile?: string; mobile?: string;
deptId?: number; deptId?: number;
roleId?: number; roleId?: number;

View File

@@ -89,8 +89,8 @@ const { columns, columnChecks, data, loading, getData, getDataByPage, mobilePagi
columns: () => [ columns: () => [
{ prop: 'selection', type: 'selection', width: 48 }, { prop: 'selection', type: 'selection', width: 48 },
{ prop: 'index', type: 'index', label: '序号', width: 64 }, { prop: 'index', type: 'index', label: '序号', width: 64 },
{ prop: 'name', label: '岗位名称', minWidth: 160, showOverflowTooltip: true }, { prop: 'name', label: '岗位名称', minWidth: 200, showOverflowTooltip: true },
{ prop: 'code', label: '岗位编码', minWidth: 180, showOverflowTooltip: true }, { prop: 'code', label: '岗位编码', minWidth: 330, showOverflowTooltip: true },
{ {
prop: 'postType', prop: 'postType',
label: '岗位类型', label: '岗位类型',

View File

@@ -106,6 +106,7 @@ const { columns, columnChecks, data, loading, getData, getDataByPage, mobilePagi
width: 196, width: 196,
align: 'center', align: 'center',
fixed: 'right', fixed: 'right',
className: 'role-operate-column',
formatter: row => ( formatter: row => (
<BusinessTableActionCell <BusinessTableActionCell
actions={[ actions={[
@@ -326,6 +327,21 @@ getMenuTreeData();
background-color: rgb(64 158 255 / 8%); background-color: rgb(64 158 255 / 8%);
} }
// 修复固定列穿透问题:给操作列添加不透明背景
:deep(.role-operate-column) {
background-color: var(--el-bg-color, #ffffff) !important;
}
// 选中行时操作列保持背景色
:deep(.el-table__row.current-row) {
.role-operate-column {
background-color: var(--el-bg-color, #ffffff) !important;
}
td.el-table__cell.is-fixed-right {
background-color: var(--el-bg-color, #ffffff) !important;
}
}
:deep(.el-row) { :deep(.el-row) {
margin: 0 0 -15px 0; margin: 0 0 -15px 0;
} }

View File

@@ -15,7 +15,7 @@
* - 叶子节点:基层员工,没有下级 * - 叶子节点:基层员工,没有下级
*/ */
import { nextTick, onMounted, reactive, ref } from 'vue'; import { computed, nextTick, onMounted, reactive, ref } from 'vue';
import type { ElTree } from 'element-plus'; import type { ElTree } from 'element-plus';
import { ElButton, ElPopconfirm, ElTag } from 'element-plus'; import { ElButton, ElPopconfirm, ElTag } from 'element-plus';
import { useBoolean } from '@sa/hooks'; import { useBoolean } from '@sa/hooks';
@@ -35,14 +35,37 @@ defineOptions({ name: 'UserManagementRelation' });
* 组件 userQuery 定义 * 组件 userQuery 定义
* *
* @param fromUserIndex 是否不是从管理链路 index 页面访问(从 user 页面访问时为 true * @param fromUserIndex 是否不是从管理链路 index 页面访问(从 user 页面访问时为 true
* @param deptId 部门 ID
* @param orgType 组织类型company/dept/direction/team
*/ */
interface userQuery { interface userQuery {
fromUserIndex?: boolean; fromUserIndex?: boolean;
deptId?: number | null; deptId?: number | null;
orgType?: string;
} }
// 从user的index组件访问管理链路fromUserIndex为true否则false; dept=100是灿能电力的id // 从user的index组件访问管理链路fromUserIndex为true否则false; dept=100是灿能电力的id
const { fromUserIndex = false, deptId = 100 } = defineProps<userQuery>(); const { fromUserIndex = false, deptId = 100, orgType = 'company' } = defineProps<userQuery>();
/**
* 判断节点是否为母节点(根节点)
*
* 母节点是指树形数据中的第一层节点
*
* @param data 节点数据
*/
function isRootNode(data: Api.SystemManage.UserManagementRelationTreeRespVO): boolean {
return treeData.value.some(node => node.userId === data.userId);
}
/**
* 判断母节点的编辑按钮是否应该隐藏
*
* 当组织类型为部门、方向或团队时,隐藏母节点的编辑按钮
*/
const shouldHideRootEdit = computed(() => {
return fromUserIndex && orgType !== 'company';
});
/** /**
* 初始化搜索参数 * 初始化搜索参数
@@ -379,7 +402,6 @@ onMounted(async () => {
:data="treeData" :data="treeData"
:props="treeProps" :props="treeProps"
node-key="userId" node-key="userId"
default-expand-all
:expand-on-click-node="false" :expand-on-click-node="false"
@check="handleNodeCheck" @check="handleNodeCheck"
> >
@@ -389,14 +411,14 @@ onMounted(async () => {
<span>{{ node.label }}</span> <span>{{ node.label }}</span>
<!-- <ElTag v-if="data.managerNickname" size="small" type="info">上级{{ data.managerNickname }}</ElTag>--> <!-- <ElTag v-if="data.managerNickname" size="small" type="info">上级{{ data.managerNickname }}</ElTag>-->
</span> </span>
<div class="flex items-center"> <div class="flex items-center" style="min-width: 200px;">
<ElButton link type="primary" size="default" @click.stop="openAdd(data)"> <ElButton link type="primary" size="default" @click.stop="openAdd(data)">
<template #icon> <template #icon>
<icon-ic-round-plus class="text-icon" /> <icon-ic-round-plus class="text-icon" />
</template> </template>
新增 新增
</ElButton> </ElButton>
<ElButton link type="primary" size="small" @click.stop="openEdit(data)"> <ElButton v-if="!(isRootNode(data) && shouldHideRootEdit)" link type="primary" size="small" @click.stop="openEdit(data)">
<template #icon> <template #icon>
<icon-ic-round-edit class="text-icon" /> <icon-ic-round-edit class="text-icon" />
</template> </template>
@@ -416,7 +438,6 @@ onMounted(async () => {
</ElButton> </ElButton>
</template> </template>
</ElPopconfirm> </ElPopconfirm>
<span v-else-if="hasChildren(data)" style="margin-left: 56px"></span>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -38,7 +38,7 @@ function getInitSearchParams(): Api.SystemManage.UserSearchParams {
return { return {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
username: undefined, nickname: undefined,
mobile: undefined, mobile: undefined,
status: undefined, status: undefined,
deptId: undefined, deptId: undefined,
@@ -211,7 +211,7 @@ const {columns, columnChecks, data, loading, getDataByPage, mobilePagination} =
{ {
prop: 'positionName', prop: 'positionName',
label: $t('page.system.user.positionName'), label: $t('page.system.user.positionName'),
minWidth: 140, minWidth: 200,
showOverflowTooltip: true, showOverflowTooltip: true,
formatter: row => getNullableLabel(row.positionName) formatter: row => getNullableLabel(row.positionName)
}, },
@@ -772,7 +772,7 @@ onMounted(async () => {
:show-footer="false" :show-footer="false"
max-body-height="70vh" max-body-height="70vh"
> >
<UserManagementRelation :from-user-index="true" :dept-id="currentDeptId"/> <UserManagementRelation :from-user-index="true" :dept-id="currentDeptId" :org-type="currentDept?.orgType"/>
</BusinessFormDialog> </BusinessFormDialog>
</div> </div>
</template> </template>

View File

@@ -37,12 +37,12 @@ const model = defineModel<Api.SystemManage.UserSearchParams>('model', { required
@search="$emit('search')" @search="$emit('search')"
> >
<ElCol :lg="6" :md="8" :sm="12"> <ElCol :lg="6" :md="8" :sm="12">
<ElFormItem :label="$t('page.system.user.userName')" prop="username"> <ElFormItem :label="$t('page.system.user.nickName')" prop="nickname">
<ElInput <ElInput
v-model="model.username" v-model="model.nickname"
clearable clearable
:disabled="disabled" :disabled="disabled"
:placeholder="$t('page.system.user.form.userName')" :placeholder="$t('page.system.user.form.nickName')"
/> />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>