# one **Repository Path**: tdg/one ## Basic Information - **Project Name**: one - **Description**: 为满足政企单位对办公自动化(OA)及企业资源计划(ERP)的综合性需求,需要构建一套模块化、可拆装、信创兼容的大型管理系统。系统需支持组织管理、公文流转、会议管理、事务审批、台账管理、档案管理、内部通知、资源空间、学习专区等业务,并允许客户按需选配模块,实现从轻量级办公到全功能企业管理的平滑扩展。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-25 - **Last Updated**: 2026-05-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 一站式平台项目 本仓库当前已经从“工程骨架”进入“可联调基础平台 + 首批真实模块接入”阶段:后端核心宿主能力、网关、用户中心、系统管理中心、模块可插拔链路,以及本地 PostgreSQL + Nacos 验证路径均已落地,`message` 与 `user` 的一批真实前后端闭环也已经打通,可用于持续往更多业务能力上叠加。 项目设计来源于 [`/docs`](./docs) 下的需求、系统设计、概要设计、数据库设计和前端设计文档。当前代码实现遵循“模块化、可拆装、前端三端分离、核心能力下沉、待办前端聚合”的总体方向;主设计文档也已按当前真实实现逻辑完成一轮同步修正。 ## 设计文档 - [`docs/01-需求设计文档.md`](./docs/01-%E9%9C%80%E6%B1%82%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3.md):业务目标、模块边界、依赖关系、非功能要求 - [`docs/02-系统设计文档.md`](./docs/02-%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3.md):总体技术架构与系统分层 - [`docs/03-系统概设文档.md`](./docs/03-%E7%B3%BB%E7%BB%9F%E6%A6%82%E8%AE%BE%E6%96%87%E6%A1%A3.md):模块内部结构、接口约定、模块启用流程 - [`docs/04-系统详设文档.md`](./docs/04-%E7%B3%BB%E7%BB%9F%E8%AF%A6%E8%AE%BE%E6%96%87%E6%A1%A3.md):详细设计说明 - [`docs/05-数据库设计文档.md`](./docs/05-%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3.md):数据库模型与演进设计 - [`docs/06-前端设计文档.md`](./docs/06-%E5%89%8D%E7%AB%AF%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3.md):维护端、业务 PC 端、移动端的前端架构设计 说明: `docs/授权服务生成工具设计文档.md` 暂不在当前阶段范围内,后续单独推进。 ## 当前阶段说明 当前仓库的开发进度可以概括为:平台基础设施主链路已经打通,真实业务能力仍在逐步接入。 ### 当前已落地能力 - 后端采用 `.NET 8` 多项目解决方案,按 `building-blocks`、`shared`、`services` 分层组织。 - 前端采用 `pnpm workspace` 单仓结构,已提供 `oa-admin`、`oa-biz`、`oa-mobile` 三个壳应用。 - `OnePlatform.Core` 已统一收口宿主基础能力:运行时模式、Nacos 配置/注册、统一响应、统一异常、请求日志、健康检查、JWT、模块启用校验。 - `OnePlatform.Core` 已落地内部接口鉴权和统一平台能力: - `X-OnePlatform-Internal-Key` - 统一任务执行入口 `/api/internal/jobs/{jobCode}/execute` - 统一审计客户端 `IOnePlatformAuditWriter` - 异常自动审计 - `OnePlatform.Gateway` 已支持按 `/api/*` 路由前缀代理下游服务,优先使用 Nacos 服务发现,必要时回退本地固定地址。 - `SystemAdminService` 已完成从静态模块注册表到“Nacos 发现 + 数据库模块画像”模型的切换。 - `SystemAdminService` 已落地正式中心能力: - 模块聚合与启停 - 系统目录、路由资源、菜单树管理 - 系统参数与字典管理 - Quartz 调度中心 - 数据生命周期规则管理 - 统一审计接收与查询 - `UserService` 已切到 `PostgreSql + FreeSql` 主路径,`user-service-init.sql` 是当前库表与默认管理员初始化的事实来源。 - `UserService` 已落地真实认证链路: - 账号密码登录 - JWT 签发 - Refresh Token 轮换 - 退出登录 - 当前权限读取 - 权限批量校验 - `UserService` 已具备真实用户中心管理域能力: - 部门、账号、岗位、角色、权限管理接口 - 通讯录树浏览与联系人资料查询 - 角色菜单授权与角色成员直绑 - 独立关系表主路径:`user_role`、`user_permission`、`user_role_permission`、`user_account_role`、`user_position_role`、`user_position_permission`、`user_role_menu` - `refresh token` 已统一改为数据库持久化,只保存 `token_hash`,不落库明文 token。 - `user_account` 与 `user_session` 已补齐账号状态、锁定、认证版本、会话失效等字段,为后续更完整的会话治理预留了真实表结构。 - 平台任务与中心审计已打通首个真实闭环: - `user.token-cleanup` - `system-admin.audit-log-retention` - 前端已落地两个真实模块包: - `oa-module-message`:`oa-biz` 注入收件箱、发通知、已发送、通知详情,`oa-mobile` 注入收件箱、通知详情 - `oa-module-user`:`oa-admin` 注入部门、用户、岗位、角色、权限页面,`oa-biz` / `oa-mobile` 注入通讯录,角色页已升级为按系统授权菜单和绑定成员的工作区 - 三端运行时菜单链路已打通:前端直接读取 `system-admin` 菜单树,再结合 `user-service` 当前用户菜单 ID 本地合并,`oa-admin` / `oa-biz` / `oa-mobile` 均可按角色实时裁剪导航 - `/docs` 下主设计文档已完成一轮按真实实现逻辑的同步修正,当前主文档与代码口径保持一致。 ### 当前边界 - `MessageService` 已交付首个真实业务闭环: - `oa-biz` 可发布并消费内部通知 - `oa-biz` 可查看“已发送”并按发送人统计阅读情况 - `oa-mobile` 可消费内部通知 - `oa-admin` 只保留模块启停、角色与权限配置职责 - 除 `UserService`、`SystemAdminService`、`MessageService` 外,其余业务服务仍以占位接口或骨架能力为主,尚未全面切入真实数据库和业务流程。 - 统一待办接口仍处于规划保留状态,当前未落地后端待办聚合。 - OAuth2/OIDC、单点登录、外部身份源联动尚未实现。 - 独立 `log_*` 日志服务尚未落地,正式审计当前统一进入 `SystemAdminService`。 - `Mapper` 与多数据库访问栈已具备基础能力,但当前完整主路径已落在 `UserService`、`SystemAdminService` 与 `MessageService`。 对应设计与实施计划见: - [`docs/plans/2026-03-27-multi-database-mapper-design.md`](docs/plans/2026-03-27-multi-database-mapper-design.md) - [`docs/plans/2026-03-27-multi-database-mapper-implementation.md`](docs/plans/2026-03-27-multi-database-mapper-implementation.md) - [`docs/plans/2026-03-27-multi-database-mapper-handoff.md`](docs/plans/2026-03-27-multi-database-mapper-handoff.md) - [`docs/plans/2026-03-29-system-admin-nacos-discovery-design.md`](docs/plans/2026-03-29-system-admin-nacos-discovery-design.md) - [`docs/plans/2026-03-29-system-admin-nacos-discovery-implementation.md`](docs/plans/2026-03-29-system-admin-nacos-discovery-implementation.md) 下一阶段建议优先把更多业务服务迁到统一数据访问栈,并继续扩展中心调度、中心审计和真实业务闭环。 当前阶段明确不包含以下能力: - 除 `UserService`、`SystemAdminService`、`MessageService` 外,其余业务服务尚未全面接入真实数据库 - 未接入单点登录与外部身份源联动 - 未实现收藏、公文、事务、台账等完整真实业务逻辑 - 当前部分页面和接口仍以占位实现为主,重点仍是先固化平台能力和模块边界 ## 仓库结构 ```text . ├─ backend/ # .NET 8 后端工程 │ ├─ src/building-blocks/ # 基础核心能力,后续可沉淀为 NuGet 包 │ ├─ src/shared/ # 共享默认配置与公共设施 │ ├─ src/services/ # 各独立服务与模块 │ └─ local/ # 本地机器专用配置 ├─ frontend/ # pnpm workspace 前端工程 │ ├─ apps/ # oa-admin / oa-biz / oa-mobile │ ├─ packages/ # 通用共享包 │ └─ modules/ # 各业务模块前端包,后续可独立 npm 发布 ├─ docs/ # 需求、设计、数据库、前端设计文档 └─ scripts/ # 本地启动脚本 ``` ## 架构约定 ### 后端 - `OnePlatform.Core` 承担模块注册表、模块状态评估、健康检查、公共启动约定,以及基于 SDK 的 Nacos 配置加载与服务注册能力。 - 当前 Core 已提供两层接口约定: - 宿主级约定:`app.MapOnePlatformModuleEndpoints()` 负责 `/api/meta` 和 `/api/{moduleCode}/ping` - 服务级约定:`app.MapOnePlatformServiceApi()` 负责后续服务自定义接口的统一分组、统一模块启用校验和统一返回元数据声明 - 每个模块保持独立服务边界,后续可以独立部署、独立拆仓、独立发布。 - 测试按模块自管理,测试工程直接放在各模块自己的 `tests` 目录下。 - `onePlatform.moduleRegistry` 当前只在 `mode = Local` 时使用本地 JSON 注册表 `backend/src/services/OnePlatform.SystemAdminService/modules/modules.json`;`mode = Nacos` 时,Core 的模块状态改由 `SystemAdminService` 提供。 ### 当前统一接口约定 后续服务新增 Minimal API 时,推荐固定采用下面的模式: ```csharp app.MapOnePlatformModuleEndpoints(); var api = app.MapOnePlatformServiceApi(); api.MapGet("/items", () => OnePlatformResults.ApiOk(data)) .WithOnePlatformApi>(); ``` 失败场景不直接手写 `BadRequest` / `NotFound` 结果,而是抛标准异常交给 Core 统一处理中间件: - `ValidationException` -> `400` - `BusinessException` -> `400` - `KeyNotFoundException` -> `404` - `ForbiddenException` -> `403` 统一成功响应结构为: - `success` - `code` - `message` - `data` - `traceId` - `timestamp` 统一异常响应结构为: - `success` - `code` - `message` - `traceId` - `timestamp` ### 当前 Nacos 约定 - 系统隔离通过 `namespace` 完成,不在 `dataId` 上加项目名前缀 - 同一系统内统一使用一个 `group` - 配置分两层: - `common.json` - 服务专属配置,如 `user-service.json`、`system-admin-service.json` - 业务服务引用 `OnePlatform.Core` 后,在 `onePlatform.runtime.mode = Nacos` 时会自动: - 通过 `nacos.config` 加载两层配置 - 通过 `nacos.discovery` 注册服务实例 - 当前标准鉴权方式为 `userName` / `password` - 配置优先级固定为:环境变量 > Nacos > `appsettings.*` - 当 `mode = Nacos` 时,`nacos.config` 和 `nacos.discovery` 都必须提供完整的 `userName` / `password` - 当 `mode = Nacos` 且 Nacos 鉴权缺失或 Nacos 不可用时,服务启动直接失败 - 非 `system-admin` 服务会通过 `SystemAdminService` 读取模块状态,并用它做模块启用校验 - `SystemAdminService` 在 `mode = Nacos` 时,会根据 Nacos 已注册实例生成运行态模块列表,并自动补齐尚未入库的模块画像,默认 `configuredEnabled = false` - 已存在但当前未上线的模块画像不会丢失,维护端仍可修改其启用状态、依赖关系和前端可见范围 - 当 `mode = Local` 时,模块注册表与模块管理都读取本地 `modules.json` - `OnePlatform.Core` 的目标形态是 DLL / NuGet 包,不是独立部署服务 ### 前端 - `oa-admin` 对应维护系统,负责模块管理和全局配置入口。 - `oa-biz` 对应业务 PC 端。 - `oa-mobile` 对应业务移动端。 - `message` 现已成为第一个真实模块化前端闭环: - `oa-biz` 注入收件箱、发通知、已发送、通知详情 - `oa-mobile` 注入收件箱、通知详情 - `oa-admin` 不提供通知业务入口 - `user` 已成为第二个真实模块化前端包: - `oa-admin` 注入部门、用户、岗位、角色、权限页面 - `oa-admin` 额外提供系统管理页、菜单管理页,与角色页联动完成按系统菜单授权 - `oa-biz` 注入通讯录浏览页 - `oa-mobile` 注入通讯录浏览页与联系人详情抽屉 - 三端运行时导航已完成同一套角色菜单模型接入: - `system-admin` 负责系统目录、路由资源与菜单树 - `user-service` 负责角色菜单绑定与当前用户有效菜单 ID - `oa-admin` / `oa-biz` / `oa-mobile` 前端负责本地合并并裁剪最终导航 - `packages/oa-shared` 提供模块状态获取、路由装配、前端鉴权存储、登录页和路由守卫等共享逻辑。 - 前端共享请求层现在默认只使用网关相对路径: - `UserService` -> `/api/user` - `SystemAdminService` -> `/api/system-admin` - `modules/*` 下的模块包按设计稿拆开,后续可以继续演进为独立 npm 包或独立仓库。 - 三端当前统一走 `UserService` 登录链路,但 token 存储 key 已按壳隔离: - `oneplatform:admin:auth` - `oneplatform:biz:auth` - `oneplatform:mobile:auth` ### 当前网关入口与前端调试代理 - 浏览器默认请求统一走网关: - `/api/user/**` - `/api/system-admin/**` - `OnePlatform.Gateway` 当前已支持按路径前缀转发到下游服务,优先使用 Nacos 服务发现,必要时按路由配置回退到本地固定地址。 - 三个 Vite 应用都已默认把 `/api` 代理到网关,默认目标是 `http://127.0.0.1:5080`。 - 本地调试时可以通过环境变量按路径前缀旁路到固定端口: ```bash VITE_GATEWAY_TARGET=http://127.0.0.1:5080 VITE_API_PROXY_RULES=/api/user=http://127.0.0.1:5081,/api/system-admin=http://127.0.0.1:5082 ``` 说明: - `VITE_API_PROXY_RULES` 使用 `前缀=目标地址` 的逗号分隔格式 - 更长的路径前缀优先级更高,例如 `/api/user` 会优先于默认的 `/api` - 不配置 `VITE_API_PROXY_RULES` 时,所有 `/api` 请求都会先到网关 ### 当前模块可插拔验证方式 当前模块插拔链路已经支持两种配置来源: 1. `onePlatform.runtime.mode = Nacos` 时,`SystemAdminService` 通过 Nacos 服务发现读取已注册实例,并优先使用实例元数据中的 `moduleCode`、`displayName` 生成运行态模块列表。 2. 发现到的新服务会自动在系统管理库中创建模块画像,默认 `configuredEnabled = false`;模块启用状态、依赖关系、前端可见范围等管理属性持久化在系统管理库中,而不是回写到 Nacos。 3. 已入库但当前没有在线实例的模块会继续保留,健康状态显示为 `Offline`,仍可在维护端修改启用状态和依赖配置。 4. `onePlatform.runtime.mode = Local` 时,系统管理服务退回本地 `modules.json` 文件,沿用原有纯本地模块注册表模式。 5. 后端通过模块状态计算逻辑,综合 `configuredEnabled`、依赖状态、`/health` 检查结果,得出 `effectiveEnabled`。 6. 前端维护端通过 `GET /api/system-admin/modules` 展示模块状态,并通过 `PUT /api/system-admin/modules/{code}/status` 更新启用状态。 7. 三个前端壳应用根据模块状态决定是否注入对应模块路由,从而验证“模块插拔”和“前端按状态装配”。 这个方案的目的是先把接口和职责边界固化下来。前端调用方式不受配置来源影响。 ### 当前 Nacos 启动参数 最小验证子集的后端服务 `appsettings.json` 已预留以下配置: ```json { "onePlatform": { "runtime": { "mode": "Local" }, "data": { "defaultConnection": "main", "connections": { "main": { "provider": "PostgreSql", "connectionString": "Host=127.0.0.1;Port=5432;Database=oneplatform_user;Username=postgres;Password=change-me", "autoSyncStructure": false } } }, "moduleRegistry": { "localFilePath": "../OnePlatform.SystemAdminService/modules/modules.json", "dataId": "modules.json", "group": "DEFAULT_GROUP" } }, "nacos": { "config": { "serverAddresses": [ "http://127.0.0.1:8848/" ], "namespace": "", "userName": "", "password": "", "listeners": [ { "dataId": "common.json", "group": "DEFAULT_GROUP", "optional": false }, { "dataId": "user-service.json", "group": "DEFAULT_GROUP", "optional": false } ] }, "discovery": { "serverAddresses": [ "http://127.0.0.1:8848/" ], "namespace": "", "userName": "", "password": "", "serviceName": "OnePlatform.UserService", "groupName": "DEFAULT_GROUP", "clusterName": "DEFAULT", "ip": "127.0.0.1", "port": 5081, "registerEnabled": true } } } ``` 如果要启用 Nacos 模式,至少需要在 Nacos 中准备: - `common.json` - 每个服务自己的配置文件,例如: - `gateway.json` - `user-service.json` - `system-admin-service.json` - `form-service.json` - `process-service.json` - `doc-service.json` - `tz-service.json` `modules.json` 只在 `Local` 模式保留;`mode = Nacos` 时,模块状态统一来自 `SystemAdminService`,不再需要在 Nacos 中额外维护模块注册表配置。 Nacos 初始模板已放在 `backend/local/nacos/`,可直接作为控制台建配置时的初始内容。 ### 当前 Gateway 路由配置 `OnePlatform.Gateway` 目前通过 `onePlatform:gateway:routes` 管理路径前缀和目标服务映射,典型配置如下: ```json { "onePlatform": { "gateway": { "routes": [ { "pathPrefix": "/api/user", "serviceName": "OnePlatform.UserService", "fallbackBaseUrl": "http://127.0.0.1:5081", "allowLocalFallback": true }, { "pathPrefix": "/api/system-admin", "serviceName": "OnePlatform.SystemAdminService", "fallbackBaseUrl": "http://127.0.0.1:5082", "allowLocalFallback": true } ] } } } ``` 说明: - `mode = Nacos` 时,网关优先按 `serviceName` 从 Nacos 获取实例 - 找不到可用实例且 `allowLocalFallback = true` 时,网关回退到 `fallbackBaseUrl` - 匹配不到路由前缀时返回 `404` - 下游无法解析或请求失败时返回 `502` ### 本地凭据约定 真实的 Nacos 账号密码不进入仓库。默认在仓库根目录使用不入库文件 `.env.local`: ```env NACOS_USERNAME=nacos NACOS_PASSWORD=change-me USER_SERVICE_MAIN_DB_CONNECTIONSTRING=Host=127.0.0.1;Port=5432;Database=oneplatform_user;Username=postgres;Password=change-me USER_SERVICE_MAIN_DB_AUTOSYNCSTRUCTURE=false SYSTEM_ADMIN_SERVICE_MAIN_DB_CONNECTIONSTRING=Host=127.0.0.1;Port=5432;Database=oneplatform;Username=postgres;Password=change-me SYSTEM_ADMIN_SERVICE_MAIN_DB_AUTOSYNCSTRUCTURE=false FORM_SERVICE_MAIN_DB_CONNECTIONSTRING=Host=127.0.0.1;Port=5432;Database=oneplatform_form;Username=postgres;Password=change-me FORM_SERVICE_MAIN_DB_AUTOSYNCSTRUCTURE=false ``` 仓库内已提供示例文件 [`.env.local.example`](/d:/Study/one/.env.local.example)。 - `publish-local-nacos-config.ps1` 和 `start-backend.ps1` 都会优先读取这个文件。 - `start-backend.ps1` 会把 `USER_SERVICE_MAIN_DB_CONNECTIONSTRING`、`USER_SERVICE_MAIN_DB_AUTOSYNCSTRUCTURE` 注入到 `UserService` 进程,不需要把真实数据库密码写进仓库内 `appsettings.json`。 - `start-backend.ps1` 也会把 `SYSTEM_ADMIN_SERVICE_MAIN_DB_CONNECTIONSTRING`、`SYSTEM_ADMIN_SERVICE_MAIN_DB_AUTOSYNCSTRUCTURE` 注入到 `SystemAdminService` 进程。 - `start-backend.ps1` 也支持把 `FORM_SERVICE_MAIN_DB_CONNECTIONSTRING`、`FORM_SERVICE_MAIN_DB_AUTOSYNCSTRUCTURE` 注入到 `FormService` 进程。 - 如果你显式传了脚本参数,则脚本参数优先于 `.env.local`。 ## 快速启动 ### 环境要求 - `.NET SDK 8.0` - `PostgreSQL 14+` - `Node.js 20+` - `pnpm 8+` ### 启动后端 ```powershell dotnet build .\backend\OnePlatform.sln .\scripts\start-backend.ps1 ``` 启动 `UserService` 和 `SystemAdminService` 前,请先确认 PostgreSQL 已启动,并且 `onePlatform:data:connections:main` 指向可访问的库;本地推荐直接在 `.env.local` 中提供对应的 `*_MAIN_DB_CONNECTIONSTRING`。 如果你不想使用 `Code First` 自动建表,可以先执行仓库内脚本: ```sql \i backend/local/postgresql/user-service-init.sql \i backend/local/postgresql/system-admin-service-init.sql \i backend/local/postgresql/form-service-init.sql ``` 然后把 `onePlatform:data:connections:main:autoSyncStructure` 设为 `false`,例如在 `.env.local` 中写: ```env USER_SERVICE_MAIN_DB_AUTOSYNCSTRUCTURE=false FORM_SERVICE_MAIN_DB_AUTOSYNCSTRUCTURE=false ``` 这种模式下,`UserService`、`SystemAdminService` 和 `FormService` 都不再在启动时补元数据表或改表,库表与基础数据统一由各自的 `init.sql` 初始化。 `FormService` 的 `init.sql` 只负责初始化元数据表;业务运行期动态创建的 `form_{module}_{seq}` 实体表仍由服务按表单定义实时维护。 当前脚本会启动最小验证子集: - `Gateway`:`http://127.0.0.1:5080` - `UserService`:`http://127.0.0.1:5081` - `SystemAdminService`:`http://127.0.0.1:5082` - `FormService`:`http://127.0.0.1:5083` - `ProcessService`:`http://127.0.0.1:5090` - `DocService`:`http://127.0.0.1:5091` - `TzService`:`http://127.0.0.1:5092` 可直接验证的接口示例: - `http://127.0.0.1:5080/api/meta` - `http://127.0.0.1:5082/api/system-admin/modules` - `http://127.0.0.1:5081/health` - `http://127.0.0.1:5090/health` - `http://127.0.0.1:5081/api/user/departments` - `http://127.0.0.1:5081/api/user/departments/hr` - `http://127.0.0.1:5081/api/user/reports/department-user-counts` - `http://127.0.0.1:5081/api/user/auth/login` 当前已补的服务自定义接口样板: - `UserService` - `GET /api/user/departments` - `GET /api/user/departments/{id}` - `GET /api/user/reports/department-user-counts` - `POST /api/user/departments` - `POST /api/user/auth/login` - `POST /api/user/auth/refresh` - `POST /api/user/auth/logout` - `GET /api/user/permissions/current` - `POST /api/user/permissions/check` - `SystemAdminService` - `GET /api/system-admin/modules` - `POST /api/system-admin/modules/refresh` - `GET /api/system-admin/modules/{code}/health` - `PUT /api/system-admin/modules/{code}/status` - `GET /api/system-admin/system-params` - `GET /api/system-admin/dict-types` - `GET /api/system-admin/scheduler/jobs` - `GET /api/system-admin/scheduler/executions` - `GET /api/system-admin/audit/operation-logs` - `GET /api/system-admin/audit/login-logs` - `GET /api/system-admin/audit/exception-logs` - `GET /api/system-admin/audit/job-logs` - `POST /api/internal/audit/events` - `ArchiveService` - `GET /api/archive/categories` - `GET /api/archive/categories/{code}` - `POST /api/archive/records` - `WorkflowService` - `GET /api/workflow/templates` - `GET /api/workflow/templates/{code}` - `POST /api/workflow/definitions` 当前接口状态说明: - `UserService` 的组织、权限与登录能力已经改为数据库主路径:账号、部门、最后登录时间以及默认管理员初始化都来自 PostgreSQL 与 `user-service-init.sql`。 - `UserService` 的 `refresh token` 已统一存储在数据库中。 - `SystemAdminService` 已具备正式的模块聚合、Quartz 调度、审计接收与审计查询能力。 - `ArchiveService`、`WorkflowService` 仍是内存占位数据,主要用于验证统一接口约定。 这些接口当前的主要目标是验证: - 服务自定义接口是否走统一响应 - 业务异常是否走统一异常 - 后续真实业务接入时是否可以直接复用 Core 约定 默认最小登录账号: - `account`: `admin` - `password`: `Admin@123` 默认管理员由 `backend/local/postgresql/user-service-init.sql` 初始化;如果数据库中已存在该账号,脚本通过 `ON CONFLICT DO NOTHING` 保持幂等。 ### 使用本地 Nacos 启动后端 如果你要验证 `Nacos` 模式,而不是本地 `modules.json` 模式,可以直接使用仓库内模板: ```powershell Copy-Item .\.env.local.example .\.env.local .\scripts\publish-local-nacos-config.ps1 -ServerAddress http://127.0.0.1:8848/ -NamespaceId "" .\scripts\start-backend.ps1 -Mode Nacos -NacosServerAddress http://127.0.0.1:8848/ -NacosNamespace "" ``` 说明: - `publish-local-nacos-config.ps1` 会把 `backend/local/nacos/` 下的配置模板发布到本地 Nacos - 两个脚本都会优先从仓库根目录 `.env.local` 读取 `NACOS_USERNAME` / `NACOS_PASSWORD`,`start-backend.ps1` 还会读取 `USER_SERVICE_*` 本地数据库覆盖项 - `start-backend.ps1 -Mode Nacos` 会通过环境变量覆盖当前服务的运行模式、Nacos 地址、命名空间和鉴权信息 - `SystemAdminService` 的模块管理页会基于当前已注册到 Nacos 的实例生成运行态模块列表,并叠加系统管理库中的启用状态与依赖配置 - 其他服务会通过 `SystemAdminService` 的模块状态接口执行模块启用校验,因此 Nacos 配置中心里不再需要 `modules.json` - 如果直接手工执行 `dotnet run`,也需要先提供 `nacos__config__userName/password` 和 `nacos__discovery__userName/password`,否则 Core 会在启动前直接失败 - 如果直接手工执行 `dotnet run` 启动 `UserService`,可以改用标准 .NET 环境变量键,例如 `onePlatform__data__connections__main__connectionString` - 这样可以避免直接修改各服务 `appsettings.json` - 如果同一配置项同时存在于环境变量、Nacos 和 `appsettings.json`,最终以“环境变量 > Nacos > `appsettings.*`”为准 ### 启动前端 ```powershell cd .\frontend pnpm install pnpm build cd .. .\scripts\start-frontend.ps1 ``` 前端入口: - `oa-admin`:`http://127.0.0.1:5173` - `oa-biz`:`http://127.0.0.1:5174` - `oa-mobile`:`http://127.0.0.1:5175` 前端当前可直接验证的能力: - 三端都会先进入 `/login` - 未登录访问业务页会被守卫重定向到登录页 - 登录成功后会回跳原目标页或首页 - 壳应用顶部会显示当前用户和退出登录按钮 - 三端会话彼此隔离,不共享本地 token 如果要验证“三端同时登录不同账号”,需要先在 `UserService` 数据库中准备多个可用账号;当前仓库默认会通过 `user-service-init.sql` 初始化 `admin / Admin@123` 这一组管理员账号。 ## 模块插拔验证步骤 1. 执行 `.\scripts\start-backend.ps1` 和 `.\scripts\start-frontend.ps1` 2. 打开 `http://127.0.0.1:5173/modules` 3. 在模块管理页启用或禁用 `process`、`doc`、`tz` 4. 观察维护端页面中的“配置启用 / 实际生效 / 健康状态 / 强依赖”是否符合预期 5. 刷新 `http://127.0.0.1:5174` 或 `http://127.0.0.1:5175`,确认对应模块路由是否出现或消失 例如: - `process`、`doc`、`tz` 当前都强依赖 `form` - 如果依赖模块未启用,或服务健康检查失败,则模块不会进入 `effectiveEnabled` - 前端只会装配 `effectiveEnabled = true` 且匹配当前壳应用的模块路由 - 当前还可以额外验证 `message`: - `oa-biz` 出现 `/biz/message`、`/biz/message/compose`、`/biz/message/sent` - `oa-mobile` 只出现 `/mobile/message` 与 `/mobile/message/notices/:id` 如果要验证 Nacos 路径,可以把第 1 步替换为: 1. 启动本地 Nacos 2. 在仓库根目录准备 `.env.local` 3. 执行 `.\scripts\publish-local-nacos-config.ps1` 4. 执行 `.\scripts\start-backend.ps1 -Mode Nacos` 5. 再执行 `.\scripts\start-frontend.ps1` ## 后续演进 下一阶段建议按以下顺序继续推进: - 将 `UserService` 的数据库模型继续扩展到更完整的用户中心领域对象和自定义接口 - 为核心服务补充真实配置模型、数据库接入和持久化 - 将除 `message` 外的占位页继续替换为真正的业务页面和接口实现 - 逐步把基础能力工程和前端共享包沉淀为可独立发布的 NuGet/npm 包 如果后续继续增强 Nacos 集成,原则上不需要推翻当前结构,主要是继续补强“配置来源”和“服务发现实现”: - 健康检查和服务地址改为通过注册中心获取 - 前端仍然继续只调用系统管理服务暴露出的模块状态接口 ## 本轮验证 本轮改动已完成以下验证: - `dotnet test backend/src/building-blocks/OnePlatform.Core/tests/OnePlatform.Core.Tests/OnePlatform.Core.Tests.csproj -m:1` - `dotnet test backend/src/services/OnePlatform.UserService/tests/OnePlatform.UserService.Tests/OnePlatform.UserService.Tests.csproj -m:1` - `dotnet test backend/src/services/OnePlatform.SystemAdminService/tests/OnePlatform.SystemAdminService.Tests/OnePlatform.SystemAdminService.Tests.csproj -m:1` - `dotnet build backend/OnePlatform.sln -m:1` - `pnpm --filter oa-shared test` - `pnpm --filter oa-admin test` - `pnpm --filter oa-biz test` - `pnpm --filter oa-mobile test`