Next TJWater

Next TJWater 是供水管网 WebGIS Agent 工作台的前端项目。界面以地图为主视图,集成供水管网图层、调度状态、事件处置、Agent 对话和受控前端动作。

项目使用 Vite、React 19、TypeScript 和 Tailwind CSS 4。地图与流向效果基于 MapLibre GL,Agent 消息支持代码高亮、数学公式和 Mermaid 图表。

样式规范统一见 样式设计指南,Agent 功能与报告交互见 交互设计,形象、配色与状态动画见 Persona 设计。

主要功能

  • 供水管网地图、业务图层和设备状态展示
  • 地图缩放、测量、绘制、图层控制和视图导出
  • 异常工况列表、详情分析和调度任务跟踪
  • Agent 流式对话、推荐问题、会话管理和权限批准
  • 经过 Schema 校验的 UI Envelope 和前端动作执行
  • 运行时配置注入、MSW 本地模拟和开发面板

开发环境

需要安装 Node.js、Corepack 和 pnpm。项目声明的包管理器版本为 pnpm 11.8.0。

corepack enable
pnpm install
cp .env.example .env.local
pnpm dev

开发服务器默认地址为 http://127.0.0.1:5173。

Agent 服务默认地址为 http://127.0.0.1:8787。需要完整对话能力时,请同时启动对应的 Agent 后端。

运行时配置

浏览器配置通过 /runtime-config.js 注入,不使用 VITE_ 或 NEXT_PUBLIC_ 前缀。可在 .env.local 中设置以下变量:

开发环境使用内网认证服务时,仅在被 Git 忽略的 .env.development.local 中覆盖 TJWATER_KEYCLOAK_ISSUER,保留 .env.local 的 HTTPS issuer。Vite 默认开发模式读取 此覆盖,正常 production 构建不读取。登录 issuer 必须与 Agent、Server MCP 及 worker 一致;更改后重新加载开发服务器并重新登录,不复用旧 issuer 的令牌。

变量 默认值 说明
TJWATER_AUTH_MODE required Keycloak 认证模式;本地测试可显式设为 disabled
TJWATER_KEYCLOAK_ISSUER 无 Keycloak Realm issuer,例如 https://keycloak.example.com/realms/tjwater
TJWATER_KEYCLOAK_CLIENT_ID next-tjwater Keycloak public client ID
TJWATER_MAPBOX_ACCESS_TOKEN 空 Mapbox 底图访问令牌
TJWATER_TIANDITU_TOKEN 空 天地图矢量、影像及中文注记访问令牌
TJWATER_MAP_URL https://geoserver.waternetwork.cn/geoserver GeoServer 服务地址
TJWATER_GEOSERVER_WORKSPACE tjwater_next GeoServer 工作区
TJWATER_SERVER_API_BASE_URL http://127.0.0.1:8000 浏览器访问的 TJWater 后端 API 地址
TJWATER_AGENT_URL http://127.0.0.1:8787 浏览器访问的 Agent API 地址
TJWATER_WORKBENCH_RUNTIME_MODE auto 工作台时间模式:工况始终使用 mock,预约工单只读取后端投影;auto 和 backend 使用当天日期;demo 与 history 定位到最近一个有后端预约工单的日期,并在同一天生成 mock 工况,其中 demo 标记为演示时间。分析成果和后端任务状态不作为工况或日期依据
TJWATER_PERIPHERAL_SAMPLE_API_BASE_URL /peripheral 外围系统模拟服务地址;生产推荐使用同源代理路径,留空时不发起连接
TJWATER_PERIPHERAL_SAMPLE_TIME_MODE demo 历史回放默认时间模式:demo 使用固定有数据窗口,recent 使用最近时段
TJWATER_PERIPHERAL_SAMPLE_DEMO_START 2026-09-17T00:00:00Z 演示历史窗口开始时间(UTC、带时区)
TJWATER_PERIPHERAL_SAMPLE_DEMO_END 2026-09-17T12:00:00Z 演示历史窗口结束时间(UTC、最长 7 天)
TJWATER_PERIPHERAL_SAMPLE_RECENT_HOURS 8 实时时间模式回看小时数,范围 1—168
TJWATER_ENABLE_DEV_PANEL false 是否显示开发面板
TJWATER_ENABLE_MSW false 是否启用浏览器端 Mock Service Worker

.env.local 已被 Git 忽略,请勿提交令牌或生产环境配置。Mapbox 和天地图令牌会随底图请求发送到浏览器,应在服务商控制台限制允许的来源域名。

浏览器使用 Keycloak Standard Flow 和 PKCE S256,不需要也不能配置 client secret。生产环境必须提供 Realm issuer;未认证用户会跳转到 Keycloak,同一 Realm 中已有登录会话时会直接完成单点登录。

Keycloak 中的 next-tjwater Client 应关闭 Client Authentication,开启 Standard Flow,并关闭 Implicit Flow 与 Direct Access Grants。Valid Redirect URIs 和 Web Origins 只配置实际使用的前端地址。

业务数据与 Agent 请求分别由浏览器直接访问 TJWATER_SERVER_API_BASE_URL 和 TJWATER_AGENT_URL,部署环境需要为前端来源配置 CORS。外围样板推荐配置 TJWATER_PERIPHERAL_SAMPLE_API_BASE_URL=/peripheral;线上 NPMplus 在现有前端 Proxy Host 中增加 /peripheral Custom Location,保留该前缀并转发到主 Server 8000。开发和预览模式提供同路径代理,默认使用 TJWATER_SERVER_API_BASE_URL。语音播放始终请求同源 /api/tts/edge;开发和预览由 Vite 中间件处理,生产镜像会启动仅监听容器回环地址的 Edge TTS 适配器。无需配置 TTS 服务 URL,可选的服务端变量 EDGE_TTS_VOICE 用于覆盖默认中文语音。

Agent 模型目录由 Agent 服务提供,页面重新获得焦点或网络重连时刷新;发送指令前再次读取当前目录。仍有效的用户选择会保留,失效时改用目录中的默认模型或首个可用模型,并同步更新菜单。目录为空时提示错误并阻止生成请求。前端始终提交目录返回的完整模型 ID。

Agent 运行时仍可发送消息,底栏可选择“引导”(steer,默认)或“排队”(queue)。右下角只有一个操作位置:运行中输入为空时停止,有内容时发送追加消息;空闲时发送新消息。待处理消息并入输入组件顶部,每条展示正文预览、处理方式和消息菜单;长内容可展开全文,菜单可切换处理方式、退回编辑或关闭排队。编辑需服务端确认撤回,保留已有草稿并等待手动重发。处理状态由 Agent 的原生收件箱决定,已处理后不再允许修改;追加消息和模式切换复用当前会话归属及授权,不会先中断执行。

常用命令

pnpm dev          # 启动开发服务器
pnpm build        # 类型检查并生成生产构建
pnpm preview      # 预览生产构建
pnpm typecheck    # 运行 TypeScript 检查
pnpm lint         # 运行 ESLint
pnpm format       # 使用 Prettier 格式化文件
pnpm test         # 运行 Vitest 单元测试
pnpm test:watch   # 监听模式运行单元测试
pnpm test:browser # 运行 Playwright 浏览器测试

Docker

生产镜像使用 Node.js 构建静态文件,并通过 Caddy 提供服务。容器启动时会根据环境变量生成 /runtime-config.js,同时启动 Edge TTS 适配器。 奉贤三维建筑资源随仓库中的 public/city-model/ 一起进入镜像:浏览器先读取 /city-model/manifest.json,再通过 HTTP Range 按需读取 /city-model/buildings.pmtiles。清单中的 tiles.buildings.sha256 必须与归档内容一致, 客户端以该摘要隔离 IndexedDB 持久缓存版本。

docker build -t next-tjwater .
docker run --rm -p 8080:80 --env-file .env.local next-tjwater

启动后访问 http://localhost:8080。

CI/CD

Gitea Actions 通过 .gitea/workflows/package.yml 复用 OrgTJWater/ci-templates 的容器发布流程。手动触发只构建镜像并在 Dev 服务器运行候选验证;从 main 创建并推送 v* tag 后,候选验证通过才会 提升为正式 frontend 服务。

仓库需要配置 REGISTRY_USERNAME、REGISTRY_PASSWORD 和 DEV_DEPLOY_SSH_KEY 三个 Gitea Secrets。生产运行时配置由 Dev 服务器的 env/frontend.env 注入,不写入镜像或仓库 Secret。

项目结构

src/
├── app/                 应用入口、Provider 和浏览器回归测试
├── features/
│   ├── agent/           Agent 协议、会话、动作执行和界面组件
│   ├── map/             地图核心控件
│   └── workbench/       调度工作台、业务面板和地图编排
├── mocks/               MSW handlers 和测试数据
├── shared/              通用 UI、AI 元素、配置和工具
├── test/                Vitest 测试环境
└── styles.css           Tailwind CSS 入口和全局样式

构建说明

调查任务支持样板反馈的人工复核草稿。在“外围样板”显式导入反馈证据后,可读取同一来源的完整反馈集合、确认并保存新修订;已保存草稿也可从“调查任务”的历史草稿中再次打开,不依赖外围服务在线。页面区分待重分析、冲突证据及前后修订,不代表已经重新计算。接口与存储边界见 复核修订说明。

“分析成果”面板只读取当前项目 BizDB 中已持久化的分析历史,不启动分析任务。外围样板面板可对 synthetic 测试工单和测试数据执行 CRUD,历史监测回放仍为只读。部署所需表和边界见 Server 的外围样板说明。

生产构建可能提示 Shiki、Mermaid 语言包超过 Rollup 默认的 500 kB 阈值。当前构建和浏览器测试可以正常完成,这些提示不影响产物生成。

S
Description
No description provided
Readme
41 MiB
Languages
TypeScript 96.4%
CSS 2.5%
JavaScript 0.9%
Shell 0.1%