# na_ai **Repository Path**: pg_apps/na_ai ## Basic Information - **Project Name**: na_ai - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-23 - **Last Updated**: 2026-10-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # na · 多租户 RBAC 权限管理平台 > 版本 **3.0.0** | 后端 Java 17 + Spring Boot 3.5 + Spring Cloud 2025 | 前端 Vue 3 + Vite 6 + Element Plus 一套面向 SaaS 场景的多租户权限中台:以**租户**为隔离单位,提供租户开通、RBAC 权限、菜单授权与审批工作流能力,前后端分离,适配 PC 与 H5。 > [!IMPORTANT] > **版权与授权**:本项目仅供**个人学习、研究**使用,**禁止任何形式的商业用途**。 > 如需商用,请先联系 **pg_tech@163.com** 获取书面授权。完整条款见 [版权声明与授权](#版权声明与授权) 与 [LICENSE.md](./LICENSE.md)。 --- ## 目录 - [项目简介](#项目简介) - [功能特性](#功能特性) - [技术栈](#技术栈) - [系统架构](#系统架构) - [模块说明](#模块说明) - [目录结构](#目录结构) - [快速开始](#快速开始) - [配置说明](#配置说明) - [实时通信(WebSocket)](#实时通信websocket) - [登录态与 Token](#登录态与-token) - [权限模型速览](#权限模型速览) - [数据库](#数据库) - [前端说明](#前端说明) - [常见问题](#常见问题) - [贡献指南](./CONTRIBUTING.md) - [安全策略](./SECURITY.md) - [版权声明与授权](#版权声明与授权) --- ## 项目简介 na 是一套**多租户 RBAC 权限管理平台**,核心设计目标: - **租户级隔离**:所有租户内实体(用户、角色)强制归属当前登录租户,列表查询强制按租户过滤;只有系统用户(`userType='00'`)可跨租户操作。 - **平台级管控**:租户、菜单等系统级实体的创建 / 编辑仅限系统用户,租户侧不提供入口。 - **两级菜单授权**:菜单先授权给**租户**(`sys_map_tenant_menu`),租户下的**角色**再从已授权的菜单中挑选(`sys_map_role_menu`),恒有「角色菜单 ⊆ 租户菜单」。 - **开箱即用的工作流**:集成 Flowable 7.2.0,支持流程定义、流程实例、待办 / 已办 / 抄送、任务审批。 - **统一入口**:前端只面向网关(na-gateway),由网关完成路由转发、跨域处理与接口文档聚合。 ## 功能特性 ### 平台管理(na-upms) | 模块 | 能力 | |---|---| | 登录认证 | 图形验证码、短 token 签发与 Redis 会话校验、登出、租户到期时间校验 | | 租户管理 | 分页查询、开通租户(同一事务内创建**默认角色 + 默认用户**)、编辑、租户菜单授权 | | 用户管理 | 分页查询、新增 / 编辑、绑定角色、绑定部门、绑定岗位、个人中心 | | 角色管理 | 分页查询、新增 / 编辑、角色 - 菜单授权(含租户菜单范围校验) | | 菜单管理 | 菜单树维护,支持目录 `M` / 菜单 `C` / 按钮 `F` / 接口 `A` 四种形态 | | 部门 / 岗位 | 组织标签维护(当前仅作标签使用,不参与业务逻辑) | | 系统配置 | 租户级参数配置(`system_config`,租户内唯一) | | 日志与监控 | 操作日志查询、服务信息监控、缓存面板、键值树查看 | ### 流程管理(na-flow) | 模块 | 能力 | |---|---| | 流程定义 | 流程模型保存 / 更新、详情查询、动态部署(不扫描 classpath 流程文件) | | 流程分组 | 流程分组增删查 | | 流程实例 | 发起流程、我的待办、我的已办、我发起的、抄送我的、实例详情 | | 任务处理 | 任务查询、完成任务、转办(设置办理人)、终止流程、任务变量查询 | | 抄送 | 抄送记录明细查询 | | 组合分组 | 常用流程组合分组、当前用户可发起流程分组 | ### 前端(web) - PC + H5 双端自适应布局(侧边栏 / 移动端抽屉) - 登录后按**后端菜单**动态生成路由,按钮级权限指令 `v-hasPermi` - 请求统一封装(Token 注入、会话失效跳转、错误提示、业务静默调用) - WebSocket 客户端(登录 token 握手、心跳保活、断线重连、按 type 订阅) - Element Plus 组件与 Vue / Vue Router / Pinia / VueUse API 全自动按需导入 ## 技术栈 ### 后端 | 分类 | 组件 | 版本 | |---|---|---| | 语言 / 构建 | Java、Maven | 17、≥ 3.8 | | 基础框架 | Spring Boot | 3.5.16 | | 微服务 | Spring Cloud / Spring Cloud Alibaba | 2025.0.0 / 2025.0.0.0 | | 网关 | Spring Cloud Gateway(WebFlux) | 随 Spring Cloud | | 注册 / 配置中心 | Nacos(discovery + config) | Spring Cloud Alibaba 2025.0.0.0 | | 持久层 | MyBatis-Plus(含 jsqlparser 分页) | 3.5.9 | | 数据库 | MySQL 8.x(`mysql-connector-j`) | 8.0.33 | | 连接池 | Druid(Spring Boot 3 版 starter) | 1.2.27 | | 缓存 / 分布式 | Redis、Redisson | 3.52.0 | | 工作流 | Flowable | 7.2.0 | | 接口文档 | SpringDoc OpenAPI 3 + Knife4j(网关聚合) | 4.5.0 | | 实时通信 | Spring WebSocket(原生,未引入 STOMP) | 随 Spring Framework | | 登录态 | 短 token(22 字符)+ Redis 会话 | — | | Web 容器 | Undertow(na-upms / na-flow,已排除 Tomcat) | 随 Spring Boot | | 外部私有构件 | `io.github.na-tool`:`na-common` / `na-auth` / `na-log` | 3.0.0 | ### 前端 | 分类 | 组件 | 版本 | |---|---|---| | 框架 | Vue | 3.5 | | 构建 | Vite | 6.x | | 语言 | TypeScript | 5.7 | | UI | Element Plus + Icons | 2.9 | | 状态 | Pinia(+ 持久化插件) | 3.x | | 路由 | Vue Router | 4.5 | | 请求 | Axios | 1.7 | | 工具 | VueUse、Day.js、NProgress | — | ## 系统架构 ```text ┌─────────────────────────┐ │ 浏览器 / H5(web) │ 开发端口 5173,生产由 Nginx 同源托管 └───────────┬─────────────┘ │ /api/** ▼ ┌─────────────────────────┐ │ na-gateway :10060 │ Spring Cloud Gateway(WebFlux) │ · 路由转发 /na-upms/** │ 统一跨域(CORS)、响应头去重 │ · 路由转发 /na-flow/** │ Knife4j 文档聚合 └───────────┬─────────────┘ │ lb://(Nacos 服务发现 + 负载均衡) ┌────────┴─────────┐ ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ na-upms │ │ na-flow │ │ :10061 │ │ :10062 │ │ 平台管理服务 │ │ 工作流服务 │ └──────┬───────┘ └──────┬───────┘ │ │ ├──── MySQL(na_app)────────┐ │ └─ MySQL(na_flow,Flowable ACT_* 表) ├──── Redis(db6) └──── Nacos(配置中心 + 注册中心) ``` ### 端口一览 | 模块 | 端口 | 说明 | |---|---|---| | `na-gateway` | 10060 | 统一入口网关 | | `na-upms` | 10061 | 平台管理服务 | | `na-flow` | 10062 | 工作流服务 | | `web` | 5173 | 前端开发服务器(监听 `0.0.0.0`,便于 H5 真机联调) | ### 路由与路径约定 - 后端接口统一以 `/api/{模块名}/**` 开头: - `/api/na-upms/**`(如 `/api/na-upms/login`、`/api/na-upms/sysuser/list-paging`) - `/api/na-flow/**`(如 `/api/na-flow/process/save`) - 前端始终请求上述路径,网关与 Nginx 都按模块名分流: - **开发环境**:Vite 把 `/api/na-upms/**`、`/api/na-flow/**` 原样转发到网关;如需绕过网关,把 `vite.config.ts` 的 target 分别改成 `10061`、`10062` 即可。 - **生产环境**:Nginx 把 `/api/na-upms/**` 代理到网关或直连 `na-upms`,`/api/na-flow/**` 代理到网关或直连 `na-flow`。 - 无论经过网关还是直连,后端 Controller 映射始终是 `/api/na-upms/**`、`/api/na-flow/**`,代理层不做路径改写。 - WebSocket 仍使用 `/na-upms/ws`、`/na-flow/ws`;网关旧的 `/na-upms/**`、`/na-flow/**` 路由保留,用于剥离前缀。 ## 模块说明 | 模块 | 类型 | 职责 | |---|---|---| | `na-parent` | pom | 统一依赖版本管理(Spring Boot / Cloud / Alibaba、MyBatis-Plus、Druid、Redisson、Flowable 等),多环境 profile 与 Nacos 地址等构建属性 | | `na-common` | jar | 跨模块通用能力:统一返回体 `Result`、状态枚举 `MyStatus`、常量(缓存键、服务名)、`TokenUtil`、`RequestParamsValidUtil`、Feign 配置、WebSocket 自动配置(`com.na.common.websocket`) | | `na-entity` | jar | 实体 / 模型 / 入参:`com.na.entity`(表实体)、`com.na.model`、`com.na.params` | | `na-core` | jar | 持久层:`mapper`(MyBatis-Plus Mapper,XML 位于 `resources/mapper/mysql`)、`repo` 及其实现(仓储层封装) | | `na-upms` | jar | 平台管理服务:启动类 `AdminApplication`,包含 controller / service / formatter(入参-实体转换层)/ VO | | `na-flow` | jar | 工作流服务:启动类 `FlowApplication`,含 Flowable 引擎集成、节点 / 监听器 / 表达式扩展、任务与流程实例服务 | | `na-gateway` | jar | 网关服务:启动类 `GatewayApplication`,路由、全局过滤器(`GlobalFilterHandle`)、跨域、文档聚合 | | `web` | 前端工程 | Vue 3 + Vite 单页应用 | ## 目录结构 ```text na/ ├── pom.xml # 聚合 POM(com.na:na:3.0.0) ├── na-parent/ # 依赖版本管理 + 构建属性(Nacos 地址、profile) ├── na-common/ # 通用工具、常量、枚举、统一返回体 ├── na-entity/ # 实体 / Model / Params ├── na-core/ # Mapper 与仓储实现(resources/mapper/mysql/*.xml) ├── na-upms/ # 平台管理服务(端口 10061) │ └── src/main/java/com/na/admin/{controller,service,formatter,config,enmus} ├── na-flow/ # 工作流服务(端口 10062) │ └── src/main/java/com/na/flow/{controller,service,core,node,listeners,task,expression} ├── na-gateway/ # 网关(端口 10060,bootstrap.yaml) ├── ai-model/ # 豆包 ASR / LLM 两个 C++ 工程(模型文件默认不入库,见 .gitignore) ├── web/ # 前端工程(Vue 3 + Vite) │ └── src/{api,views,router,store,layout,components,composables,directives,utils,styles} ├── doc/ # 数据库脚本与专项文档 │ ├── na_app.sql # 业务库脚本(过期快照,以线上库为准) │ ├── nacos-config-example/ # 脱敏 Nacos 配置示例 │ ├── websocket.md # WebSocket 使用文档 │ └── login-token.md # 登录态与 Token 文档 ├── .github/ # Issue / PR 模板与 CI ├── CLAUDE.md # 项目开发规则(权限模型核心约束,改权限相关代码前必读) ├── AGENTS.md # AOCI 仓库认知索引接入说明 ├── CONTRIBUTING.md # 贡献指南 ├── SECURITY.md # 安全策略 ├── LICENSE.md # 授权条款 └── README.md # 本文档 ``` ## 快速开始 ### 1. 环境要求 | 依赖 | 版本要求 | 说明 | |---|---|---| | JDK | 17 | 编译与运行基线 | | Maven | ≥ 3.8 | 支持 `-P` 多环境 profile | | MySQL | 8.x | 需自建 `na_app`、`na_flow` 两个库 | | Redis | 5.x+ | 默认使用 `db6` | | Nacos | 2.x | 同时作为配置中心与注册中心 | | Node.js | ≥ 18(推荐 20 LTS) | 前端构建 | | npm | 随 Node | 前端依赖管理 | > 后端依赖外部构件 `io.github.na-tool:na-common / na-auth / na-log:3.0.0`,请确保本机 Maven 能解析到该构件(私有仓库或已配置的镜像)。 ### 2. 准备中间件 1. **创建数据库**:新建 `na_app`(业务库)与 `na_flow`(Flowable 引擎库),字符集建议 `utf8mb4`。 2. **初始化表结构**:参考 `doc/na_app.sql` 导入业务表;`na_flow` 的 `ACT_*` 引擎表由 Flowable 按配置创建(见 [配置说明](#配置说明))。 3. **启动 Redis**。 4. **启动 Nacos 并在 `dev` 命名空间下创建配置**:按 `doc/nacos-config-example/` 中的 `na-gateway.yaml`、`na-upms.yaml`、`na-flow.yaml` 创建配置,替换其中的数据库、Redis 占位值。 > 数据源地址、账号密码、Redis 地址等敏感连接串存放在 Nacos 配置中,不在仓库源码里。 > **不要把包含真实密码的 Nacos 导出包提交到仓库**(`.gitignore` 已忽略 `doc/nacos_config_export*.zip`)。 ### 3. 修改 Nacos 地址 开发 / 测试 / 生产的 Nacos 连接参数集中在 `na-parent/pom.xml` 的 `` 中,按需修改: ```xml 192.168.0.56:8848 dev ``` 这些 `${...}` 属性通过 Maven 资源过滤写入各模块 `application-{profile}.yml` 的 `@nacos.dev.server-addr@` 占位符。 ### 4. 启动后端 ```bash # 在项目根目录执行;-Pdev 为默认激活的 profile(可选 dev / qa / prod) mvn clean package -Pdev -DskipTests # 三个服务无强启动顺序,注册到 Nacos 后即可通过网关访问 java -jar na-upms/target/na-upms-3.0.0.jar java -jar na-flow/target/na-flow-3.0.0.jar java -jar na-gateway/target/na-gateway-3.0.0.jar ``` 启动后: | 入口 | 地址 | |---|---| | 网关(对外统一入口) | `http://localhost:10060` | | na-upms 直连接口文档(Knife4j) | `http://localhost:10061/doc.html` | | na-gateway 聚合文档 | `http://localhost:10060/doc.html` | | na-upms 直连 Swagger UI | `http://localhost:10061/swagger-ui.html` | | Druid SQL 监控 | `http://localhost:10061/druid/`(默认 `admin` / `123456`,生产务必修改) | ### 5. 启动前端 ```bash cd web npm install npm run dev # 开发服务器 http://localhost:5173 ``` 前端脚本一览: | 命令 | 作用 | |---|---| | `npm run dev` | 启动开发服务器(监听 `0.0.0.0`,可手机真机联调) | | `npm run build` | 生产构建,产物输出到 `web/dist` | | `npm run build:strict` | 先执行 `vue-tsc` 类型检查再构建 | | `npm run type-check` | 仅做 TypeScript 类型检查 | | `npm run preview` | 预览构建产物 | 生产部署:将 `web/dist` 交由 Nginx 同源托管,并按 `doc/nginx.conf`(经过网关)或 `doc/nginx-direct.conf`(直连服务)配置反向代理;`web/.env.production` 中 `VITE_API_BASE_URL` 留空即为同源。 ## 配置说明 ### 多环境 profile `na-parent` 定义了 `dev`(默认激活)/ `qa` / `prod` 三个 Maven profile,通过 `-P` 选择,决定加载哪一组 `application-{profile}.yml` 与 Nacos 命名空间。 ### 配置文件加载方式(两代写法并存,注意区分) | 模块 | 加载方式 | 说明 | |---|---|---| | `na-upms` / `na-flow` | `spring.config.import: "nacos:{服务名}"` | Spring Boot 3 去 bootstrap 化写法。**`spring.config.import` 必须与 `server-addr` 写在同一个 `application-{profile}.yml` 中**,否则解析 import 时读不到地址,会退化成默认值 `127.0.0.1:8848` | | `na-gateway` | `spring-cloud-starter-bootstrap` + `bootstrap{,-dev,-prod}.yaml` | 网关保留 bootstrap 模式,优先级最高 | ### 关键配置项 | 配置 | 位置 | 说明 | |---|---|---| | `flowable.database-schema-update` | na-flow | 当前为 `false`(引擎表须已存在),首次建表时需设为 `true` | | `flowable.database-catalog: na_flow` | na-flow | **勿删**。把引擎表存在性检查限定在 `na_flow` 库内,否则会跨库误判并报 `couldn't upgrade db schema` | | `flowable.history-level: audit` | na-flow | 记录活动明细,待办 / 已办 / 审批时间线依赖 | | `flowable.check-process-definitions: false` | na-flow | 不扫描 classpath,流程定义统一由接口动态部署 | | `na.*` 开关 | upms / flow | Redis、Redisson、Redis 消息与监听、Jackson 等能力的启停开关 | | `na.file.*` | upms / flow | 本地文件资源映射:`request-prefixes` 指定 URL 前缀,`windows-path` / `linux-path` 按操作系统自动选择本地目录 | | `spring.data.redis` | upms / flow | Redis 连接参数,默认 `database: 6` | | `na.websocket.*` | upms / flow | WebSocket 开关、路径、发送器(local / redis)、token 复核间隔与 Redis 广播频道 | | `na.login.single-token` | upms / flow | 是否开启单点登录:`true` 同账号仅保留最新登录,`false` 允许多端同时在线(默认) | | `druid.stat-view-servlet` | upms / flow | Druid 监控页账号密码,生产环境必须修改并配置 IP 白名单 | ### 前端配置 | 文件 | 说明 | |---|---| | `web/.env.development` | `VITE_API_BASE_URL` / `VITE_WS_BASE_URL` 留空走 Vite 代理;`VITE_APP_TITLE` 为应用标题 | | `web/.env.production` | 同源部署,`VITE_API_BASE_URL` / `VITE_WS_BASE_URL` 留空 | | `web/vite.config.ts` | 代理规则(`/api` 与 WebSocket `/na-upms`、`/na-flow` → 网关 10060)、别名 `@` → `src`、Element Plus 自动导入、构建分包 | ## 流程分支与自动节点 流程设计器支持: - **条件分支**:按表单字段/发起人条件选择一条路径,支持条件组 AND/OR、默认分支 - **并行分支**:多个分支同时审批,全部完成后汇聚继续 - **延时器**:等待固定时长或到指定日期时间后继续 - **触发器**:可配置在发起人后、审批人后、抄送人后及分支内;同步调用外部 HTTP 接口,自动携带流程数据,支持返回值映射回表单和异常策略;审批后的触发器可选择「审批通过 / 审批拒绝」触发时机;调用失败默认最多尝试 3 次,可在 `na.flow.retry.trigger` 配置 - **失败记录**:触发器重试耗尽后,把流程实例、节点、请求、响应和异常等完整数据写入 `process_call_failure` 配置入口:流程设计器第 3 步「审批流程」→ `+` → 对应节点类型。 完整的配置步骤、条件字段与运算符、延时/触发器说明、运行规则、限制和排障说明见 **[doc/flow-branch.md](./doc/flow-branch.md)**。 ## 实时通信(WebSocket) 平台内置浏览器 WebSocket 推送能力,代码位于 `na-common` 的 `com.na.common.websocket`,`na-upms` 与 `na-flow` 默认启用: - **握手鉴权**:复用登录 token 与 Redis 登录缓存,`/ws` 由握手拦截器校验,未登录返回 401 - **消息协议**:`{"type":"...","content":"..."}`,按 `type` 路由到 `WebSocketMessageListener` - **发送目标**:按连接 / 用户 / 租户 / 用户类型 / 广播 - **多实例**:`sender-type=redis` 时通过 Redis Pub/Sub 广播;Redis 容器缺失时自动降级 local - **前端客户端**:`web/src/utils/websocket.ts`,内置心跳、指数退避重连与 4001 鉴权失效处理 连接地址(经网关): | 服务 | 地址 | |---|---| | na-upms | `ws://host:10060/na-upms/ws?token=<登录 token>` | | na-flow | `ws://host:10060/na-flow/ws?token=<登录 token>` | > **[doc/websocket.md](./doc/websocket.md)** 包含:端到端使用流程、参数速查、消息协议、发送 API、并发与性能、Nginx 部署、上线检查清单与排障说明。 ## 登录态与 Token 登录成功后签发 **22 字符短 token**(128 位安全随机数),登录态以 Redis 为准,不再使用 JWT: | 内容 | 说明 | |---|---| | token 格式 | 22 字符 Base64 URL,随机且不可解析 | | 索引 key | `token:login:index:{token}` → `userId` | | 会话 key | 多点:`token:login:{userId}:{token}`;单点:`token:login:{userId}` | | 会话内容 | `ResLoginVO`(userId、tenantId、userType、token 等) | | 单点开关 | `na.login.single-token`(默认 `false`,允许多端在线) | | 统一实现 | `na-common` 的 `LoginSessionService` | - HTTP 接口使用 `Authorization: Bearer `;WebSocket 使用 `?token=`(纯 token,不带 `Bearer`)。 - 登出会清理该用户的所有会话;单点模式下新登录会立即使旧 token 失效。 - upms 与 flow 必须连接同一个 Redis,并使用相同的 `single-token` 配置。 > 完整说明(Redis key、登录 / 鉴权 / 登出流程、单点模式、迁移与排障)见 **[doc/login-token.md](./doc/login-token.md)**。 ## 权限模型速览 > 完整的类型码约定、字段取值陷阱、数据隔离模式与已知缺陷,见 **[CLAUDE.md](./CLAUDE.md)**(改动租户 / 角色 / 用户 / 菜单相关代码前必读)。 ### 类型码(`sys_user.user_type`、`sys_role.role_type`、`sys_menu.sys_menu_type` 共用) | 码 | 含义 | 说明 | |---|---|---| | `00` | 系统默认 | 系统内置数据,绝对保护,任何入口不可增删改 | | `01` | 系统管理员 | | | `02` | 租户默认 | 租户开通时自动生成的内置数据,租户侧只读 | | `03` | 普通 | 用户 / 租户自建数据,建表默认值 | ### 数据隔离三原则 1. **系统级实体(租户、菜单)**:创建 / 编辑仅限 `00` 用户,其他用户返回 `USER_NO_ACCESS`。 2. **租户内实体(用户、角色)**:创建 / 编辑时强制把 `tenantId` 覆写为当前登录租户。 3. **列表 / 分页(全部实体)**:非 `00` 用户强制按当前租户过滤,忽略入参 `tenantId`。 ### 租户开通(同一事务) 开通租户会同时创建三样东西,任一步失败整体回滚: 1. 租户记录(`sys_tenant`,`tenant_type='03'`) 2. 默认角色(`sys_role`,`role_type='02'`,`data_scope='2'`) 3. 默认用户(`sys_user`,`user_type='02'`)并绑定到默认角色(`sys_map_role_user`) 默认用户的账号 / 初始密码 / 昵称由开通时录入;账号全局唯一。 ### 菜单授权链 ```text sys_menu ──(系统用户授权)──▶ sys_map_tenant_menu ──(租户内授权)──▶ sys_map_role_menu ──▶ 角色 ▲ 以租户为单位 ▲ 只能从租户已授权菜单中挑选 ``` > 注意:`sys_role.data_scope='1'`(全部数据权限)会让登录鉴权走「全库菜单」分支,**租户侧角色绝不能给该值**,默认角色使用 `2`。详见 CLAUDE.md。 ## 数据库 | 库 | 用途 | 主要表 | |---|---|---| | `na_app` | 业务库 | `sys_user`、`sys_role`、`sys_menu`、`sys_tenant`、`sys_dept`、`sys_post`、`sys_map_role_user`、`sys_map_role_menu`、`sys_map_tenant_menu`、`sys_map_user_dept`、`sys_map_user_post`、`system_config`、`sys_log` | | `na_flow` | 工作流库 | Flowable 引擎表(`ACT_*`)及流程业务表 | 唯一约束要点(**刻意不统一,勿改**): | 表 | 索引 | 语义 | |---|---|---| | `sys_role` | `uk_tenant_role_code (tenant_id, role_code)` | 租户内唯一 | | `sys_user` | `uk_sys_user_user_name (user_name)` | **全局唯一**,逻辑删除后账号名仍永久占用 | > `doc/na_app.sql` 是**过期快照**,不代表线上库实际结构;判断约束请以线上库 `SHOW INDEX` 为准。 ## 前端说明 ### 目录职责 | 目录 | 说明 | |---|---| | `src/api` | 接口封装与类型定义(`http/request.ts` 为 axios 实例与拦截器) | | `src/views` | 页面:`login`、`dashboard`、`tenant`、`user`、`role`、`menu`、`dept`、`post`、`sysConfig`、`logs`、`monitor`、`task`(待办 / 已办 / 我发起的 / 抄送)、`profile`、`error` | | `src/router` | 固定路由(`routes.ts`)、动态路由生成(`dynamic.ts`)、导航守卫(`guard.ts`) | | `src/store` | Pinia:`user`(Token 持久化到 localStorage,键名 `na-user`)、`permission`(菜单与动态路由)、`app` | | `src/layout` | 布局:侧边栏、导航栏、面包屑、移动端抽屉 | | `src/directives` | `v-hasPermi` 按钮级权限指令 | | `src/composables` | `useTable`(分页表格通用逻辑)、`useDevice`(PC / H5 判定) | | `src/utils` | 格式化、树处理、校验、验证码、ID 生成 | | `src/styles` | 全局样式、Element Plus 覆盖、响应式、过渡与滚动条 | ### 流程设计器 - 第 1 步「基础信息」支持配置流程管理员(无人审批时可转交)和高级设置中的流程ID;流程ID不填写自动生成,发布后不可修改。 - 第 2 步「表单设计」为三栏拖拽设计器:左侧组件面板、中间画布、右侧字段/表单配置。 - 画布顶部工具栏提供 PC / 平板 / 手机三种设备宽度预览、撤销 / 重做、保存、表单预览和清空;清空后可通过撤销恢复,表单预览支持在弹窗内切换设备。 - 基础组件:输入框、多行输入框、密码输入框、计数器、单选框、多选框、选择器、开关、评分、时间、时间区间、滑块、日期、日期区间、颜色选择器。 - 业务组件:人员、部门、上传、富文本、手写签名。 - 展示组件:标题、文字、提示、按钮、分割线、标签、图片。 - 拖拽左侧组件到画布新增字段;拖动字段手柄调整顺序;点击字段编辑名称、英文值、必填、选项和占位提示。 - 英文值作为表单数据和回调报文的 key,要求唯一(大小写不敏感判重),失焦立即提示,下一步/保存再次强校验。 - 表单级配置(标签位置、标签宽度)保存在 `process.settings.formConfig`,发起流程时生效。 - 点击「保存并发布」前会自动检查基础信息、表单设计和流程设计;检查不通过时弹出「流程检查」窗口,列出全部问题并可跳转到对应步骤修改。 - 每个组件都支持**样式配置**(ID / Class、外边距、内边距、宽高、颜色、背景、边框、圆角、字号、对齐、阴影、定位、透明度、缩放),设计器预览与发起流程表单共用 `buildFormItemStyle` 渲染。 - 每个组件都支持**事件配置**(`click` / `hook_mounted` / `hook_value`),事件代码在发起人浏览器中执行,`$inject` 提供 `field`、`formData`、`getValue(key)`、`setValue(key, value)`。 - 上传组件支持上传地址、数量限制、单文件大小、上传类型预设(默认/图片/文档/压缩包)、文件类型、上传目录、自动上传、提示与禁用配置;默认上传到 `/api/na-upms/sys-file/upload`,由 `SysFileController` 保存到 `na.file` 目录并返回可访问 URL。 - 富文本组件基于 `@wangeditor-next`(wangEditor 5),支持标题、加粗、颜色、列表、对齐、链接、图片、视频、表格、代码块、全屏等工具栏能力;图片/视频编辑时直接上传到同一接口,内容以 HTML 字符串保存,审批与详情页按纯文本展示。 - 手写签名组件平时显示虚线占位框,点击后弹出手写板(支持鼠标与触屏),确认后输出白底 PNG dataURL 写入表单数据;可配置签名提示文字、弹窗标题、线条颜色和禁用,审批与详情页显示「已签名」。 - 图片上传以外的富文本内嵌图片、视频同样走 `SysFileController`;后端允许的扩展名包含常用图片、Office 文档、压缩包以及 `mp4/webm/ogg/mov` 视频格式。 - 地区、字典、流水号、数据表格、子表单、级联/树形等复杂组件暂未开放。 ### 顶栏功能 - **主题设置**:顶栏画笔图标或用户下拉「主题设置」打开「布局配置」抽屉,支持: - 布局切换:左侧 / 左顶 / 横向 / 分栏 - 全局主题:主题色、深色模式、组件大小 - 顶栏:背景、字体颜色、背景渐变 - 菜单:背景、字体颜色、高亮背景、背景渐变 - 分栏:一级菜单背景/字体、背景渐变、鼠标悬停预加载 - 界面设置:菜单水平折叠、菜单手风琴、固定 Header、经典布局顶部菜单、锁屏入口 - 界面显示:侧边栏 Logo、Breadcrumb 及图标、TagsView 及图标/缓存/拖拽/共用、Footer、灰色/色弱模式、水印、AI 助手/超级助手入口 - 其它:TagsView 风格、主页面切换动画、分栏高亮风格、分栏布局风格 - 配置持久化,支持恢复默认与一键复制配置 JSON - **TagsView**:多标签页、右键刷新/关闭其他/关闭全部、可选拖拽排序、keep-alive 页面缓存。 - **水印**:canvas 平铺文字水印,文案可配置。 - **全屏**:浏览器 Fullscreen API,支持进入 / 退出全屏。 - **简体中文 / English**:基于 `vue-i18n`,同时切换 Element Plus 组件语言;语言保存在本地。目前覆盖布局、用户菜单、锁屏等框架文案,业务菜单与页面文案仍为中文,可后续逐步补充字典。 - **锁屏**:点击后显示全屏遮罩,输入当前用户登录密码解锁;密码由后端 `POST /api/na-upms/sysuser/verifyPassword` 校验。锁屏状态持久化,刷新后保持锁定;登录成功或登出后自动清除。 ### 请求约定 - 所有请求经 `src/api/http/request.ts` 的 axios 实例发出,自动注入 `Authorization: Bearer {token}`。 - 会话失效(401)时统一清理本地状态并整页跳转登录页,且有并发去重保护。 - 业务错误默认弹 `ElMessage` 提示;传 `silent: true` 可关闭自动提示由调用方处理。 ### 动态路由 登录后由 `permission` store 拉取后端菜单,经 `src/router/dynamic.ts` 转换为路由并挂载到 Layout 下;`profile`、`monitor` 为固定的隐藏页面。 ## 常见问题 **Q1:启动时 Nacos 连接不上 / 读不到配置?** 检查 `spring.config.import` 与 `server-addr` 是否写在**同一个** `application-{profile}.yml` 中(na-upms / na-flow),以及 `na-parent/pom.xml` 中的 Nacos 地址是否已按环境修改、Maven 是否重新执行过资源过滤(`mvn clean package`)。 **Q2:na-flow 首次启动报 `couldn't upgrade db schema` 或找不到引擎表?** - 空库首次启动需将 `flowable.database-schema-update` 设为 `true`,让 Flowable 自动建表;表建好后可改回 `false`。 - 不要删除 `flowable.database-catalog: na_flow` 配置:缺少它时会跨库误判引擎表是否已存在(本机只要任何库存在 `ACT_GE_PROPERTY` 就会误判,因为表名中的 `_` 在 `LIKE` 中是通配符)。 **Q3:创建租户 / 用户时报「账号已存在」或直接 500?** `sys_user.user_name` 全局唯一且**逻辑删除后仍占位**,同名账号无法重建。查重 SQL 一律不过滤 `is_del`,不能「优化」成带过滤的写法(否则应用层放行、数据库撞唯一索引报 500)。 **Q4:登录时 500 且堆栈指向租户到期时间?** `sys_tenant.expire_time` 为 `NULL` 时曾触发 NPE,现已修复为「判空即永不过期」。若仍复现,检查是否使用了未更新的旧包。 **Q5:为什么租户默认角色不能设置 `data_scope = '1'`?** `data_scope='1'` 会让登录鉴权走 `queryMenuAll` 分支,该 SQL 没有任何租户条件,等于把全库菜单(含其他租户)下发。租户默认角色固定用 `2`。详见 CLAUDE.md。 **Q6:前端请求 404?** 确认开发环境代理规则:流程相关接口前缀(`process` / `process-instance` / `processGroup` / `processCopy` / `task` / `combination`)会被转发到 na-flow,其余 `/api/**` 转发到 na-upms;同时确认网关已把 `/na-upms/**`、`/na-flow/**` 前缀剥离后转发。 ## 版权声明与授权 版权所有 © 2025-2026 pg_tech。保留所有权利。 本项目采用**源码可见(Source-Available)**的授权方式,**不是**开源许可,请务必遵守以下条款: | 使用场景 | 是否允许 | |---|---| | 个人学习、研究、技术交流 | ✅ 允许,免费,无需授权 | | 个人非商业目的的二次开发 / 修改 | ✅ 允许,但必须保留本版权声明 | | 任何形式的商业用途 | ❌ **禁止**,须事先取得书面授权 | **「商业用途」包括但不限于:** - 将本项目(或其衍生代码)用于任何对外经营的产品或服务; - 以 SaaS / PaaS / 私有化交付等形式向第三方提供; - 企业内部生产环境使用,或随硬件、软件产品捆绑销售; - 以本项目为内容载体开展付费培训、付费咨询等营利行为。 **商用授权**:请发送邮件至 **pg_tech@163.com**,说明使用场景、使用规模与授权期限,取得书面授权后方可使用。 **免责声明**:本项目按「现状」提供,不附带任何明示或默示的担保。因使用本项目造成的任何直接或间接损失,作者不承担任何责任。 完整法律条款见 [LICENSE.md](./LICENSE.md)。 > GitHub 会将本项目的许可证识别为 **Other**(自定义 Source-Available 条款,非 OSI 开源许可)。如果希望真正开源,需要将 `LICENSE.md` 替换为 MIT、Apache-2.0 等标准许可证。