Commit Graph
211 Commits
Author SHA1 Message Date
TermiNexus b44dddd857 fix(gerp): 介绍类字段表单统一按多行输入渲染
WorkgroupIntroduction(工作组介绍)等 CharField 介绍字段此前被映射成单行 text,编辑时不好输入长文本。现按「字段名以 Introduction 结尾 或 verbose_name 含"介绍"」统一置为 textarea(TextField 类介绍字段本就已是 textarea,不受影响)。
2026-10-01 13:48:11 +08:00
TermiNexus 3859aa1762 docs(gerp): 新增实体选择器标准文档
记录 EntityPicker/MultiEntityPicker 的分层与单一来源、Search 接口数据契约、配置字段(含 treeGroup 与多选暂存)、部门员工关联常量的取值与落库对应、el-tree 自绘场景的 useDeptEmployeeTree,以及新增/改动时必须遵守的约定与变更检查清单。
2026-10-01 12:37:15 +08:00
TermiNexus edd4a85f98 refactor(gerp): 部门员工关联选择器配置抽成单一来源
新增 DEPT_TREE_GROUP / DEPT_EMPLOYEE_PICKER / DEPT_EMPLOYEE_PICKER_BY_USER_ROLE 三个常量并加注释说明使用点,三处(eHRM 员工档案 / 工作组新增成员 / 部门挂靠)改为引用,禁止再就地复制 entityPicker 配置。eHRM 员工档案的「部门员工关联」取值不变(仍为 UserRoleDepartmentUUID),UI 换成工作组的部门树分组浏览面板(treeGroup + secondaryField + dependCompany)。
2026-10-01 00:32:10 +08:00
TermiNexus 29031de724 feat(ehrm): 员工档案一人一份,新增与改绑均拦截重复建档
EmployeeProfile 与员工一一对应:add_record 解析出 UserUUID 后先查重(前端在已有档案时已隐藏新增入口,这里兜住直接调接口/并发提交);modify_record 改绑到已有档案的员工时同样拦截(排除当前档案自身),避免编辑换员工绕过约束。
2026-09-30 23:38:01 +08:00
TermiNexus 90c7c3403a feat(gerp): 租户详情编辑仅允许修改租户名称
- 列配置:Tenant 的 TenantStatus/TenantExpireTime/ReviewStatus/ReviewRemark/ReviewerUUID/ReviewTime
  统一 editable=False + hideInForm=True(位置在 entityPicker 强制可编辑之后,避免被改回)
- 写路径白名单:modify_record 对 Tenant 仅保留 Table/PK/Action/UUID/TenantName,其余字段丢弃,
  防绕过前端直接提交;审核仍走 /API/TenantReview 专用接口
2026-09-30 18:25:23 +08:00
TermiNexus 228fa993c8 feat(gerp): 工作组「部门员工关联」编辑回显带部门
UserRoleWorkgroup 的表单选择器(visible=False 的 UserRoleUUID 列)编辑回显标签由角色名改为「部门 · 员工」:关系表不存部门,故按 UserRoleUUID 取主部门关联(同当前公司优先,否则首条,与批量调整职务取法一致)。仅影响工作组的该标签,UserRoleDepartment 的同类标签不变。

冒烟(真库,工作组 255599f6):回显标签为「运维部 · 耀月」「运维部 · felix/余凤」;列配置标题=部门员工关联、api=DeptEmployeeSearch?Dedup=UserRole、treeGroup 保留多选批量。
2026-09-30 11:03:20 +08:00
TermiNexus d503a28fae feat(gerp): 工作组新增改用真「部门员工关联」数据源
工作组详情「新增」的成员选择器由 UserRoleSearch(用户-角色对)换成 DeptEmployeeSearch(UserRoleDepartment 部门员工关联):选项展示「部门 · 员工」并按部门树分组,仍支持多选暂存批量新增;值取 UserRoleUUID(工作组关系表只存该列,写入路径不变)。

DeptEmployeeSearch 配套增强:Dedup=UserRole 按用户-角色对去重(同一员工多部门只出现一条,避免同值重复选项);tree=1 返回部门树;每项补 RoleName(副文本)与 UserRoleUUID。

冒烟(真库):全量 20 条含 RoleName;Dedup 后 20 条唯一值 20;tree=1 返回 5 个部门节点、非树请求不含 tree 字段;关键字=工程 命中 8 条(同名不同角色各一条,符合预期)。
2026-09-30 11:01:46 +08:00
TermiNexus 59d72af7a5 refactor(gerp): 统一「部门员工关联」叫法(工作组新增 + 员工档案)
工作组详情「新增」表单里原「用户-角色关联」字段(UserRoleWorkgroup.UserRoleUUID 选择器)标题与占位文案改为「部门员工关联」,与员工档案新增的同类选择器叫法一致;员工档案虚拟列标题由「部门-员工」改为「部门员工关联」,相关校验提示同步改为该叫法。
2026-09-30 10:59:33 +08:00
TermiNexus 9a2d1be1b2 feat(gerp): 员工档案直接绑定「部门-员工」关系
档案表单原来要分别选「员工」(UserSearch) 与「部门」(DepartmentSearch),易出现员工与部门不匹配;现改为一个「部门-员工」选择框,直接绑定一条 UserRoleDepartment 关系,选中即同时确定员工与部门,表结构不变(仍写 UserUUID/DeptUUID/DeptName)。

新增 GET /API/FormAPI/DeptEmployeeSearch:数据源为 UserRoleDepartment,返回 UserRoleDepartmentUUID/DeptUUID/DeptName/UserUUID/UserName 与标签「部门 · 员工」;keyword 同时匹配用户名与部门名;显式 CompanyUUID 优先,否则用当前角色公司,无公司上下文返回空。EmployeeProfile 注入虚拟列 UserRoleDepartmentUUID(仅表单可见),表单内隐藏 UserUUID/DeptUUID/DeptName(列表仍展示);get_table 按 (UserUUID, DeptUUID) 反查关系回填 UUID 与标签保证编辑回显;add_record/modify_record 解析该 UUID 写三列(新增未选时提示「请选择部门-员工」,跨公司关系拒绝)。

顺带修复:/Modify/ 与 /ModifyItem/ 补错误字典透出(原来错误被当成功返回);add_record/modify_record 返回主键由 bytes repr 归一化为标准 UUID 字符串。
2026-09-30 10:39:30 +08:00
TermiNexus 8d2e389e04 chore(部署): 同步 GVSite 构建产物(index-CEf7BUYR.js) 2026-09-30 00:02:13 +08:00
TermiNexus d500509d82 chore(部署): 同步 GVSite 构建产物(index-BRfB7xqD.js) 2026-09-29 23:57:03 +08:00
TermiNexus 74ad6143cd chore(部署): 同步 GVSite 构建产物(index-IWFpVeOm.js) 2026-09-29 23:54:02 +08:00
TermiNexus 7728535b9e chore(部署): 同步 GVSite 构建产物(index-N7G4X2ty.js) 2026-09-29 23:51:39 +08:00
TermiNexus d5598e7846 chore(部署): 同步 GVSite 构建产物(index-DN44jXnz.js) 2026-09-29 23:48:30 +08:00
TermiNexus c957fafee0 chore(部署): 同步 GVSite 构建产物(index-3-4D0mYL.js) 2026-09-29 23:42:42 +08:00
TermiNexus 3276dedb3d chore(部署): 同步 GVSite 构建产物(index-W2o18l9k.js) 2026-09-29 23:40:02 +08:00
TermiNexus e893f262bb chore(部署): 同步 GVSite 构建产物(index-Crj6GnMn.js) 2026-09-29 23:23:12 +08:00
TermiNexus deaa24da1d chore(部署): 同步 GVSite 构建产物(index-xsLn3QnS.js) 2026-09-29 23:13:46 +08:00
TermiNexus 8c18f6d386 feat(gerp): 新增按公司查询已启用应用接口 /API/App/CompanyApps
公司详情页需要展示该公司启用的应用并支持卸载/配置,原 /API/App/ManageCompanies 是反向(按应用查公司安装状态),故补正查接口:AppManager.ListCompanyEnabledApps 按公司列出 InstallStatus=1 的应用,AppCompanyAppsView 按可管理范围校验(super=全部 / tenant=本租户 / company=被授权公司)。
2026-09-29 18:50:10 +08:00
TermiNexus 772798a45c chore(部署): 同步 GVSite 构建产物(index-ChcQqzKc.js) 2026-09-29 15:10:35 +08:00
TermiNexus 652b1122cb chore(部署): 同步 GVSite 构建产物(index-DTdY4Pdj.js) 2026-09-29 15:05:27 +08:00
TermiNexus c5ed8b604f chore(部署): 同步 GVSite 构建产物(index-niIICfbh.js) 2026-09-29 14:26:18 +08:00
TermiNexus a1f52f921b chore(部署): 同步 GVSite 构建产物(Viper 底层篇幅 / index-Kj6tcCYs.js) 2026-09-29 14:21:16 +08:00
TermiNexus a7c9c5c196 chore(template): 同步 GVSite 构建入口 hash
Viper 专题编译器源码链接改指 TransPyV 后重新构建的入口 hash 同步。
2026-09-29 14:17:59 +08:00
TermiNexus 95ce6da346 chore(template): 同步 GVSite 构建入口 hash
Viper 排序示例改为引用传参后重新构建的入口 hash 同步。
2026-09-29 14:13:48 +08:00
TermiNexus dcb5553be9 chore(template): 同步 GVSite 构建入口 hash
Viper 排序示例改用 len() 后重新构建的入口 hash 同步。
2026-09-29 14:12:07 +08:00
TermiNexus bac4b0dedc chore(template): 同步 GVSite 构建入口 hash
Viper 专题新增五语言排序对照后重新构建的入口 hash 同步。
2026-09-29 14:09:45 +08:00
TermiNexus db047a0b27 chore(template): 同步 GVSite 构建入口 hash
GVSite 首页新增 Viper 专题区块、撤销独立页后重新构建的入口 hash 同步(assets 回到 59)。
2026-09-29 14:05:07 +08:00
TermiNexus 06353fc63e chore(template): 同步 GVSite 构建入口 hash
GVSite 新增 Viper 语言专题页后重新构建的入口 hash 同步(assets 59 → 60)。
2026-09-29 14:01:45 +08:00
TermiNexus 0e9c325bd8 chore(template): 同步 GVSite 构建入口 hash
GVSite 介绍文案更新后重新构建的入口 hash 同步。
2026-09-29 13:58:21 +08:00
TermiNexus 2d0e2a8e2c chore(template): 同步 GVSite 构建入口 hash
GVSite 移除顶栏底边线后重新构建的入口 hash 同步。
2026-09-29 13:51:48 +08:00
TermiNexus 2d937041fd chore(template): 同步 GVSite 构建入口 hash
品牌幕布改为蓝底白字并居中后重新构建的入口 hash 同步。
2026-09-29 13:42:24 +08:00
TermiNexus 0db5789d87 chore(template): 同步 GVSite 构建入口 hash
GVSite 本轮改动(翻牌老虎机翻页钟动效、footer 后品牌幕布)构建后的入口 hash 与 backup 快照一起同步。
2026-09-29 13:33:40 +08:00
TermiNexus 51d6e220ee perf(core): 构建产物静态资源改 72h 强缓存
- _serve_file 识别 Vite 内容 hash 文件名(-<hash>.<ext>,hash 段须含大写或数字)

- hash 产物: public, max-age=259200, immutable(72h,路径随版本变化不影响新版本生效)

- 非 hash 的传统资源保持 1h/24h,index.html 仍 no-cache
2026-09-29 11:32:35 +08:00
TermiNexus 24db976efd feat(gerp): 授权审批限定公司/租户/平台管理员,并按其级别收窄数据范围
- 菜单 app-pending 加权限属性 admin:company(迁移 0047):公司管理员 + 租户管理员 + 平台管理员可见

- AppPendingView/AppApproveView 权限放宽到 IsCompanyAdminUser,按管理员级别解析可管辖公司

- ApproveUserApp 增加越权校验;返回值统一为三元组(失败原为 2 元组,视图解包会抛 ValueError)

- CheckAdmin 下发 is_company_admin 供前端判定
2026-09-28 18:23:13 +08:00
TermiNexus 5236821c97 fix(core): 子域未命中时不再回退站点根 HTML,修复部署空窗期串台
- _resolve_file 原先在专属目录未命中时回退 TempLate/<path>,deploy 删除

  index.html 的窗口期内 gerp.gvsds.com 会命中根目录 index.html(www/GVSite)

- 改为:专属目录已落盘时仅放行 assets/ 与 pages/ 共享前缀,其余不回退

- 目录未落盘的别名子域(nav/history)沿用旧回退,避免误伤
2026-09-28 18:03:13 +08:00
TermiNexus cdf843e640 refactor(gerp): 清理 dingcalc-finance 清单冗余空 LegacySrc
- 缺失与空串等价(app_manifests 用 \or ''\),删除后与其它清单保持一致
2026-09-28 17:53:51 +08:00
TermiNexus 428bea8c74 chore(gerp): product_order 补 models.py 说明纯清单应用
- 该应用无自有数据表,复用 gvsdsdk.order,转发层在 form_service.TABLES

- 为「每应用含 models」规约补齐形式一致性
2026-09-28 17:53:49 +08:00
TermiNexus 26acf832a0 chore(template): 同步 GVSite 构建入口 hash
GVSite deploy.ps1 步骤 1 会把 TempLate/index.html 复制进 backup/www/index.html,本次复跑后入口由 index-fDcrBwZt.js 前进为 4JBzxmTF.js,同步该 1 行变更。
2026-09-28 17:48:41 +08:00
TermiNexus 2684490dd0 fix(talk): 修正成员搜索的 Manager 调用并把成员判定归一为 bytes
- SearchCompanyUsers 与 _IsCompanyUser 改用 RoleManager.GetCompanyUserUUIDs
  (原误用 CompanyManager,该类没有此方法,成员搜索接口 500)
- _IsCompanyUser 统一转 bytes 后再比对(GetCompanyUserUUIDs 返回 UUIDObj 集合,
  UUIDObj 与 bytes 的 hash 不同,原写法成员判定恒为 False,导致邀请成员必失败)
- 菜单链接由 pages/talk/index.html 改为 pages/talk.html
  (前端 normalizeMenuPath 只去 pages/ 前缀与 .html 后缀,原写法规范化为 /talk/index 会 404)
2026-09-28 17:29:15 +08:00
TermiNexus e8d85034e8 chore(template): 同步 GVSite 构建产物入口
TempLate/index.html 与 backup/www/index.html 更新为新构建的入口 hash(含新增的两个计划页 chunk)
2026-09-27 12:01:49 +08:00
TermiNexus fbf1bb7d6e refactor(gerp): 应用按子应用目录规约重组,清单外置并拆分路由
- 新增 gvsds/apps/gerp/apps/<appid>/:talk/mailbox/gitea/oa/ehrm/dingcalc_finance/
  product_order/shop/store_value/wallet/enterprise,各应用自带 models/manager/views/urls
  与 apps.gerp_manifests(JSON 清单,$schema 指向 apps/gerp_manifests.schema.json)
- 删除 app_manifests.py 内联 _LEGACY_MANIFESTS,改为扫描各应用清单文件(未知键/缺必填键即判非法并跳过)
- 路由按应用拆:/API/Mail/、/API/Gitea/、/API/Oa/ 由扁平直挂改为 include 子应用 urls.py
  (reverse() 断言 19 个 name 的路径逐字不变)
- AppConfig 移至 gerp_app.py 并改显式点分路径注册,规避 apps/ 目录与 Django <app>.apps 同名冲突
- gerp/models.py 裁剪已搬迁模型(保留 _NewUuidBytes 与平台模型),修复 views/__init__.py 与 oidc.py 导入
- AssetDownloadView:优先按 FileAsset.StoragePath 定位并回退 ./resource 旧布局,修上传成功却下载 404
- 同批落地 Talk 应用后端(app 已迁入 apps/talk,gerp.0046 状态认领迁移)
- 注意:app.ini 被 .gitignore 忽略,INSTALLED_APPS 需在部署环境手工同步 gvsds.apps.gerp.gerp_app.GerpConfig
2026-09-26 23:46:00 +08:00
TermiNexus 00b8e32b22 chore(tempLate): 同步 GVSite 最新构建产物(入口 hash 更新与备份滚动)
- TempLate/index.html 指向新产物 index-_HpjdiZK.js / index-BqAy3wb4.css(旧产物已随构建删除)

- backup/www/index.html 备份副本滚动到上一版入口 index-3r1fnTcU.js

- 源码改动见 GVSite 仓 5c08306
2026-09-15 14:17:19 +08:00
TermiNexus b1d9758923 refactor(form_service): 写路径裸 ORM 收敛进 SDK Manager
- get_tables 表行数改用 SDK CachedTableCount(带 300 秒缓存)

- add_record:用户-角色规则拦截、URD 同步建关联委托 RoleManager

- modify_record:UserRole 查重(排除自身)、URD 同步委托 RoleManager

- delete_record:部门成员计数、batch_positions 5 个分支解析委托 RoleManager

- 净减约 80 行;get_table 三表 sha1 快照与改造前逐字节一致
2026-09-15 14:15:11 +08:00
TermiNexus 048001b5de refactor(form_service): get_table 富化块裸 ORM 收敛进 SDK Manager
三处富化逻辑改调 SDK 批量方法:UserRoleWorkgroup/UserRoleDepartment 的 UserRole 反查与人名/角色名映射、UserRoleDepartment 的职务多值聚合、UserRole 的部门/职务虚拟列,分别改用 RoleManager.GetUserRolesByUUIDs / GetRoleNameMap / GetUserRoleDepartmentsForUserRoles、AuthManager.GetUserNames、PositionManager.GetUrdPositionRowsForUrds / GetPositionNameMap、DepartmentManager.GetDepartmentNameMap;员工详情页子表 UserUUID 过滤改用 RoleManager.ListUserRoleUUIDs。get_table 内已无裸 ORM(仅保留基础 model.objects.all())。

新增 _StrKeyMap 适配层:SDK 批量映射统一以 UUID 字节为键(避免 UUIDObj 与 bytes 的 hash 不等陷阱),本模块历史代码以字符串为键,此处显式转换。业务语义(标签列名、逗号聚合、覆盖名 RoleNameCover)完全留在 gvsds 侧。

等价性已用改造前快照校验:UserRole / UserRoleDepartment / UserRoleWorkgroup 三表 get_table 记录 sha1 与改造前逐字节一致(abc1f5820bcb5671 / 6344295216b39cfc / ac03fc8eacfe526a),员工详情页子表按 UserUUID 过滤与非法 UUID 空结果行为不变。
2026-09-15 13:34:28 +08:00
TermiNexus 34a7e21c2b refactor(form_service): 删除已下沉 SDK 的 entityPicker 两个方法
删除本地重复实现 _get_entity_picker_fields / _enrich_entity_labels(约 170 行),改由 FormServiceBase 继承:调用点更新为 _GetEntityPickerFields / _EnrichEntityLabels(get_table 的 entityPicker 分支),两处注释同步更名。

行为不变:仍按 ENTITY_PICKER_MAP/UUID_FIELD_ENTITY_MAP 识别字段,仍按 db_column 前缀回填 _label 与 extraFields。
2026-09-15 13:31:43 +08:00
TermiNexus 042b9ed989 refactor(form_service): get_table 查询链复用 SDK 公共辅助
精确字段过滤(含 UUID/FK 转字节)、关键字模糊过滤、分页参数解析、entityPicker 的 select_related、实例转 PascalCase 字典共 5 段重复实现改调 FormServiceBase 的 ApplyExactFilters/ApplyKeyword/ParsePagination/ApplySelectRelated/BuildRecords,get_table 净减约 60 行。

顺带:去掉 model.objects.all() 外层的 try/except(构造 QuerySet 不会抛错,异常实际发生在求值处,包裹只会掩盖问题);分页控制参数集合补入 pageSize;清理不再使用的 Q 与 _PascalizeRecord import。
2026-09-14 19:28:54 +08:00
TermiNexus 605a892a98 refactor(gerp): viewsets 方法内公司隔离查询收敛进 SDK Manager
DepartmentViewSet.search / WorkgroupViewSet.search / UserRoleViewSet.search 的「显式 CompanyUUID 强制收窄」与 FileAssetViewSet.get_queryset 的全量取数,分别改走 DepartmentManager / WorkgroupManager / RoleManager / AssetManager。

UserRoleViewSet.search 内的两处函数级 RoleManager import 上提至方法顶部,与新增的 DepartmentManager 合并为一行。
2026-09-14 16:01:54 +08:00
TermiNexus d637c3bfe0 refactor(gerp): 清除最后 4 处跨 app 裸 ORM
mail/gitea 管理员列表的 CoreUser 批量取名改走 AuthManager.GetUserNames,同时省掉原先「先占位再回填」的两轮循环;viewsets 用户-角色搜索已与相邻的 RoleManager.GetRoleNameMap 用法对齐,一并统一。

asset.py 的公司归属校验改用 CompanyManager.BelongsToTenant,不再直接持有 Company ORM。
2026-09-14 15:46:52 +08:00
TermiNexus a7c70401c2 refactor(gerp): 种子/清理命令裸 ORM 收敛进 SDK Manager
CleanAuditLogs 改用 AuditManager.QueryBefore/PurgeBefore;SeedPositions、SeedPositionCategories 改用 TenantManager.ListAllTenants 与 PositionManager 的 ListPositionCodes/CreatePosition/GetCategoriesForTenant/CreateCategory。

SeedPositionCategories 建通用部门时由「逐个 get 已存在编码」改为一次性取回按 CategoryCode 建索引,减少 N 次查询;顺带移除两处已失效的 import uuid。
2026-09-14 15:38:12 +08:00