From edd4a85f98bb81ec9f3a2691924fb3ca77fc5910 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 1 Oct 2026 00:32:10 +0800 Subject: [PATCH] =?UTF-8?q?refactor(gerp):=20=E9=83=A8=E9=97=A8=E5=91=98?= =?UTF-8?q?=E5=B7=A5=E5=85=B3=E8=81=94=E9=80=89=E6=8B=A9=E5=99=A8=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=8A=BD=E6=88=90=E5=8D=95=E4=B8=80=E6=9D=A5=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 DEPT_TREE_GROUP / DEPT_EMPLOYEE_PICKER / DEPT_EMPLOYEE_PICKER_BY_USER_ROLE 三个常量并加注释说明使用点,三处(eHRM 员工档案 / 工作组新增成员 / 部门挂靠)改为引用,禁止再就地复制 entityPicker 配置。eHRM 员工档案的「部门员工关联」取值不变(仍为 UserRoleDepartmentUUID),UI 换成工作组的部门树分组浏览面板(treeGroup + secondaryField + dependCompany)。 --- gvsds/apps/gerp/form_service.py | 95 +++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/gvsds/apps/gerp/form_service.py b/gvsds/apps/gerp/form_service.py index b71ec1b9..a7559bb6 100644 --- a/gvsds/apps/gerp/form_service.py +++ b/gvsds/apps/gerp/form_service.py @@ -113,6 +113,58 @@ def create_tenant_admin_role(tenant): return RoleManager.EnsureTenantAdminRole(tenant.TenantUUID) +# ==================== 「部门员工关联 / 部门树分组」选择器配置(单一来源) ==================== +# GERP 内多处"选人/选成员"表单用的是同一个 EntityPicker 组件(部门树 → 成员两级浏览面板), +# 只是取值列与是否多选不同,必须共用下面这份配置,禁止就地另写一套 entityPicker 配置 +# (避免"功能相同、配置两套"的重复实现)。新增使用点请复用常量,不要复制 dict。 +# +# 使用点: +# 1) EmployeeProfile.UserRoleDepartmentUUID(eHRM 员工档案):取值 = 具体部门员工关联, +# 落库时再解析出 UserUUID / DeptUUID / DeptName(一人一份档案) +# 2) UserRoleWorkgroup.UserRoleUUID(工作组新增成员):取值 = 用户-角色对 +# (工作组关系表只存 UserRoleUUID,故按 UserRole 去重,并支持多选批量新增) +# 3) UserRoleDepartment.UserRoleUUID(部门挂靠,表单隐藏):仅复用 DEPT_TREE_GROUP + +#: 「按部门树分组」浏览面板的公共 treeGroup 配置(EntityPicker): +#: 下拉里先展示部门树、点部门看该部门成员,未挂部门的归入 ungroupedTitle +DEPT_TREE_GROUP = { + 'groupField': 'DeptUUID', + 'treeField': 'tree', + 'ungroupedTitle': '未分配部门', +} + +#: 「部门员工关联」选择器(取 UserRoleDepartmentUUID) +#: 数据源 /API/FormAPI/DeptEmployeeSearch:一项 = 一条 UserRoleDepartment +#: (部门 + 该用户在本公司的"用户-角色对"),响应带 DeptEmployeeLabel("部门名 · 用户名")、 +#: RoleName 与(tree=1 时)部门树;EntityPicker 配置 treeGroup 后会自动附带 tree=1。 +DEPT_EMPLOYEE_PICKER = { + 'api': '/API/FormAPI/DeptEmployeeSearch', + 'labelField': 'DeptEmployeeLabel', + 'secondaryField': 'RoleName', + 'valueField': 'UserRoleDepartmentUUID', + 'placeholder': '选择部门员工关联(按部门分组展示)', + 'treeGroup': dict(DEPT_TREE_GROUP), + 'dependCompany': True, +} + +#: 同上,但取「用户-角色对」:Dedup=UserRole 让同一"用户-角色"在多个部门时只出现一条; +#: 并启用多选暂存(点成员进暂存区、全部提交批量新增)与成员/负责人类型选项 +DEPT_EMPLOYEE_PICKER_BY_USER_ROLE = { + **DEPT_EMPLOYEE_PICKER, + 'api': '/API/FormAPI/DeptEmployeeSearch?Dedup=UserRole', + 'valueField': 'UserRoleUUID', + 'treeGroup': { + **DEPT_TREE_GROUP, + 'multiSelect': True, + # 暂存区成员类型:默认 0=成员,1=负责人,随 submit-multi 返回写入 RoleType + 'roleTypeOptions': [ + {'value': 0, 'label': '成员'}, + {'value': 1, 'label': '负责人'}, + ], + }, +} + + class FormService(FormServiceBase): TABLE_MAP = { 'User': User, @@ -668,42 +720,21 @@ class FormService(FormServiceBase): # 表单隐藏——改用下方两级级联"用户→角色"选择 if table_name == 'UserRoleWorkgroup' and pascal_name == 'UserRoleUUID': col['type'] = 'entityPicker' - # 数据源用真正的「部门员工关联」(UserRoleDepartment),而非"用户-角色对": - # 选项带部门名(部门 · 员工)并按部门树分组;Dedup=UserRole 让同一员工 - # 属于多个部门时只出现一条(工作组关系表只存 UserRoleUUID,值仍取该列) - col['entityPicker'] = { - 'api': '/API/FormAPI/DeptEmployeeSearch?Dedup=UserRole', - 'labelField': 'DeptEmployeeLabel', - 'secondaryField': 'RoleName', - 'valueField': 'UserRoleUUID', - 'placeholder': '选择部门员工关联(按部门分组展示)', - 'treeGroup': { - 'groupField': 'DeptUUID', - 'treeField': 'tree', - 'ungroupedTitle': '未分配部门', - 'multiSelect': True, # 支持多选暂存:点成员进暂存区,全部提交批量新增 - # 暂存区成员类型选项:默认 0=成员,1=负责人,随 submit-multi 返回写入 RoleType - 'roleTypeOptions': [ - {'value': 0, 'label': '成员'}, - {'value': 1, 'label': '负责人'}, - ], - }, - } + # 复用「部门员工关联」选择器(单一来源,见 DEPT_EMPLOYEE_PICKER*): + # 取值是"用户-角色对"(关系表只存 UserRoleUUID),故按 UserRole 去重, + # 并启用多选暂存(批量加入工作组)与成员/负责人类型 + col['entityPicker'] = dict(DEPT_EMPLOYEE_PICKER_BY_USER_ROLE) col['editable'] = True - col['entityPicker'] = {**col['entityPicker'], 'dependCompany': True} if table_name == 'UserRoleDepartment' and pascal_name == 'UserRoleUUID': col['type'] = 'entityPicker' + # 复用公共部门树分组配置(取值仍是 UserRoleUUID,数据源为 UserRoleSearch) col['entityPicker'] = { 'api': '/API/FormAPI/UserRoleSearch', 'labelField': 'UserName', 'secondaryField': 'RoleName', 'valueField': 'UserRoleUUID', 'placeholder': '选择部门员工关联(按部门分组展示)', - 'treeGroup': { - 'groupField': 'DeptUUID', - 'treeField': 'tree', - 'ungroupedTitle': '未分配部门', - }, + 'treeGroup': dict(DEPT_TREE_GROUP), } col['editable'] = True col['hideInForm'] = True @@ -1075,19 +1106,15 @@ class FormService(FormServiceBase): columns = virtual_cols + columns # EmployeeProfile(员工档案)虚拟列"部门员工关联":直接选一条用户-角色-部门关系 # (UserRoleDepartment),选中即同时确定员工(UserUUID)与部门(DeptUUID/DeptName); - # 写库由 add_record / modify_record 解析该 UUID,列表仍展示真实列(员工/部门) + # 写库由 add_record / modify_record 解析该 UUID,列表仍展示真实列(员工/部门)。 + # 选择器复用 DEPT_EMPLOYEE_PICKER(与工作组新增成员同一组件:按部门树分组浏览) if table_name == 'EmployeeProfile': columns = [{ 'field': 'UserRoleDepartmentUUID', 'title': '部门员工关联', 'titleEn': 'UserRoleDepartmentUUID', 'type': 'entityPicker', - 'entityPicker': { - 'api': '/API/FormAPI/DeptEmployeeSearch', - 'labelField': 'DeptEmployeeLabel', - 'valueField': 'UserRoleDepartmentUUID', - 'placeholder': '搜索部门员工关联(部门 · 姓名)', - }, + 'entityPicker': dict(DEPT_EMPLOYEE_PICKER), 'editable': True, 'sortable': False, 'filterable': False,