feat(product): 新增产品管理模块与字典组件功能

- 新增产品管理相关路由和页面(dashboard、list、requirement、setting)
- 实现产品基础信息编辑弹窗组件(base-info-dialog.vue)
- 添加运行时字典功能(dict-select、dict-text、dict-tag组件)
- 集成字典管理store和API调用
- 规范ID类型定义为string避免精度丢失问题
- 完善国际化资源文件支持中英文对照
- 新增对象上下文业务域入口页导航实现说明
- 添加Vue DevTools浮动入口注释说明
- 统一权限控制支持全局和对象作用域区分
- 规范分页查询参数类型定义与使用方式
This commit is contained in:
2026-04-23 09:05:55 +08:00
parent c5911ea34b
commit 4122dfa50d
95 changed files with 9581 additions and 801 deletions

View File

@@ -54,10 +54,6 @@ const { fromUserIndex = false, deptId = 100, orgType = 'company' } = defineProps
*
* @param data 节点数据
*/
function isRootNode(data: Api.SystemManage.UserManagementRelationTreeRespVO): boolean {
return treeData.value.some(node => node.userId === data.userId);
}
/**
* 判断母节点的编辑按钮是否应该隐藏
*
@@ -89,11 +85,15 @@ const userList = ref<Api.SystemManage.UserSimple[]>([]);
const relationTreeRef = ref<InstanceType<typeof ElTree>>();
// 已选中的节点 ID 列表
const checkedNodeKeys = ref<number[]>([]);
const checkedNodeKeys = ref<string[]>([]);
// 树形数据
const treeData = ref<Api.SystemManage.UserManagementRelationTreeRespVO[]>([]);
function isRootNode(data: Api.SystemManage.UserManagementRelationTreeRespVO): boolean {
return treeData.value.some(node => node.userId === data.userId);
}
// 加载状态
const loading = ref(false);
@@ -225,7 +225,8 @@ function openAdd(item?: Api.SystemManage.UserManagementRelationTreeRespVO) {
operateType.value = 'add';
// 如果是从某一行的新增按钮触发,则默认管理者为当前节点用户
// 否则默认管理者为当前登录用户(在对话框组件中处理)
editingData.value = item ? {
editingData.value = item
? {
id: null,
managerUserId: item.userId,
subordinateUserId: null,
@@ -233,7 +234,8 @@ function openAdd(item?: Api.SystemManage.UserManagementRelationTreeRespVO) {
effectiveUntil: null,
remark: null,
createTime: Date.now()
} : null;
}
: null;
openOperateModal();
}
@@ -245,7 +247,8 @@ function openAdd(item?: Api.SystemManage.UserManagementRelationTreeRespVO) {
function openEdit(item: Api.SystemManage.UserManagementRelationTreeRespVO) {
operateType.value = 'edit';
// 构建树节点数据为编辑所需格式
editingData.value = item.id ? {
editingData.value = item.id
? {
id: item.id,
managerUserId: item.managerUserId,
subordinateUserId: item.userId,
@@ -253,7 +256,8 @@ function openEdit(item: Api.SystemManage.UserManagementRelationTreeRespVO) {
effectiveUntil: null,
remark: null,
createTime: Date.now()
} : null;
}
: null;
openOperateModal();
}
@@ -300,7 +304,9 @@ async function handleBatchDelete() {
* @param checkedInfo 包含 checkedKeys 和 halfCheckedKeys 的对象
*/
function handleNodeCheck(checkedData: any, checkedInfo: any) {
checkedNodeKeys.value = checkedInfo.checkedNodes.map((node: any) => node.id);
checkedNodeKeys.value = checkedInfo.checkedNodes
.map((node: any) => node.id)
.filter((id: string | null): id is string => Boolean(id));
}
/**
@@ -308,7 +314,7 @@ function handleNodeCheck(checkedData: any, checkedInfo: any) {
*
* @param relationId 提交后的关系 ID
*/
function handleSubmitted(relationId: number) {
function handleSubmitted(_relationId: string) {
closeOperateModal();
reloadTreeData();
}
@@ -411,14 +417,20 @@ onMounted(async () => {
<span>{{ node.label }}</span>
<!-- <ElTag v-if="data.managerNickname" size="small" type="info">上级{{ data.managerNickname }}</ElTag>-->
</span>
<div class="flex items-center" style="min-width: 200px;">
<div class="flex items-center" style="min-width: 200px">
<ElButton link type="primary" size="default" @click.stop="openAdd(data)">
<template #icon>
<icon-ic-round-plus class="text-icon" />
</template>
新增
</ElButton>
<ElButton v-if="!(isRootNode(data) && shouldHideRootEdit)" 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>
<icon-ic-round-edit class="text-icon" />
</template>