2026-07-26 17:23:07 +08:00
|
|
|
|
# 技术实现规划(多端系统架构)
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 架构原则
|
|
|
|
|
|
|
|
|
|
|
|
首期采用“模块化单体 + 独立 Worker/Iot 进程”形态:核心业务在一个 Go 后端仓中按领域清晰分层,HTTP API、异步 Worker 与 IoT 接入可独立部署和弹性扩缩。该方案能以较低复杂度交付跨域闭环,同时为后续按设备安全、交易、履约、资金和通知拆分服务保留边界。
|
|
|
|
|
|
|
|
|
|
|
|
- 所有管理系统统一使用 Vue 3 + TypeScript,减少多套 Web 技术栈的组件、权限和运维成本。
|
2026-08-02 23:26:28 +08:00
|
|
|
|
- 现有 Vue 管理端和 Go 后端分别作为同类新模块的工程基线。新项目应沿用其规范、公共能力和质量要求,不应复制后形成不可维护的分叉。
|
2026-07-26 17:23:07 +08:00
|
|
|
|
- 所有外部 API 与事件契约版本化;关键业务事件使用可重放的持久化消息,不能依赖 Redis Pub/Sub 的临时广播语义。
|
|
|
|
|
|
- PostgreSQL 保存交易、设备、安全和资金事实;Redis 仅保存缓存、会话、限流、延迟任务与异步事件流,不替代业务事实库。
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 技术选型
|
|
|
|
|
|
|
|
|
|
|
|
| 层级 | 推荐技术 | 用途 |
|
|
|
|
|
|
| --- | --- | --- |
|
2026-07-30 21:47:41 +08:00
|
|
|
|
| 用户端 App | Flutter 3 / Dart 3 | 首期首页内容、服务归属、商城、订单、合同、工单、钱包、地址和个人中心 |
|
|
|
|
|
|
| 服务端 App | Flutter 3 / Dart 3 | 配送、安装维修、安检三类单角色账号工作台、现场取证与受控离线草稿 |
|
2026-07-26 17:23:07 +08:00
|
|
|
|
| 平台总后台 | Vue 3 + TypeScript | 全局治理、运营、财务、安全、审计等高密度管理页面 |
|
|
|
|
|
|
| 可燃气体站管理系统 | Vue 3 + TypeScript | 站点商品、订单、服务、库存与经营管理 |
|
|
|
|
|
|
| 配送点管理系统 | Vue 3 + TypeScript | 调度、配送仓、路线、人员和配送运营工作台 |
|
|
|
|
|
|
| 生产管理系统 | Vue 3 + TypeScript | 生产计划、设备身份、质检、批次、固件和出厂追溯 |
|
|
|
|
|
|
| API 中心管理系统 | Vue 3 + TypeScript | API 产品、调用方、凭证、流量、文档与审计门户 |
|
2026-07-28 07:08:07 +08:00
|
|
|
|
| 核心后端 | Go | REST、领域服务、权限、订单、工单、资金、规则执行 |
|
2026-07-26 17:23:07 +08:00
|
|
|
|
| IoT 通道 | MQTT(TLS)+ Go 接入服务 | 设备连接、遥测、命令下发、回执、在线状态;协议适配层屏蔽厂商差异 |
|
2026-07-28 07:08:07 +08:00
|
|
|
|
| 关系数据 | PostgreSQL | 事务数据、地理空间(PostGIS) |
|
2026-07-26 17:23:07 +08:00
|
|
|
|
| 缓存与任务 | Redis | 限流、会话、幂等、短期状态、延迟任务;关键事实仍落 PostgreSQL |
|
|
|
|
|
|
| 消息/事件 | Redis Streams + Consumer Group | 遥测流、告警、订单状态、通知、对账异步化;使用消费组、重试、死信与幂等消费者保障可恢复处理 |
|
2026-07-28 07:08:07 +08:00
|
|
|
|
| 文件与证据 | 本地存储,S3 兼容对象存储 | 先本地存储,后期上OSS,包括:商品图、安装/安检证据、签收图片、视频和合同;采用短期签名 URL 与生命周期策略 |
|
2026-07-26 18:06:14 +08:00
|
|
|
|
| 移动端离线与定位 | Flutter 安全存储 + 本地加密数据库 + 地图/定位 SDK | 服务端 App 的已分配任务、现场材料和配送轨迹可弱网暂存;保留原始采集时间并按幂等键补传 |
|
2026-07-26 17:23:07 +08:00
|
|
|
|
| Web 入口与部署 | Caddy + Shell 脚本 | TLS 终止、反向代理、静态文件、压缩、健康检查与受控发布;配置和脚本纳入版本控制 |
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 推荐部署拓扑
|
|
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
flowchart LR
|
|
|
|
|
|
APP[Flutter Apps] --> GW[API Gateway / BFF]
|
|
|
|
|
|
WEB[Vue 3 管理系统] --> GW
|
|
|
|
|
|
GW --> CORE[Go Core API]
|
|
|
|
|
|
CORE --> PG[(PostgreSQL + PostGIS)]
|
|
|
|
|
|
CORE --> R[(Redis Cache / Streams)]
|
|
|
|
|
|
CORE --> OSS[Object Storage]
|
|
|
|
|
|
DEV[智能瓶阀设备] --> MQTT[MQTT TLS 接入]
|
|
|
|
|
|
MQTT --> IOT[Go IoT Adapter]
|
|
|
|
|
|
IOT --> R
|
|
|
|
|
|
R --> WORKER[Go Worker]
|
|
|
|
|
|
WORKER --> RULE[告警规则、工单、通知、对账]
|
|
|
|
|
|
CORE --> EXT[支付/合同/短信/地图]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 运行进程职责
|
|
|
|
|
|
|
|
|
|
|
|
| 进程 | 职责 | 扩缩与可靠性要求 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `api` | 用户端和五个管理系统的 HTTP API、鉴权、同步业务事务 | 无状态部署;所有写操作支持幂等键、事务和审计 |
|
|
|
|
|
|
| `worker` | 事件消费、告警、派单、推送、对账、超时扫描、轨迹异常识别 | Redis Streams 消费组;重试、死信、幂等消费和可观测的积压告警 |
|
|
|
|
|
|
| `iot` | MQTT 设备会话、协议适配、遥测校验、命令下发与回执 | 保持设备会话一致性;命令/回执持久化;协议版本和设备身份校验 |
|
|
|
|
|
|
|
|
|
|
|
|
关键业务采用“数据库事务 + Outbox 事件表 + Worker 投递”的模式:先在 PostgreSQL 提交业务事实与待投递事件,再异步写入 Redis Streams。这样 Redis 故障或 Worker 重启不会丢失订单、告警、支付或设备命令的业务事实。
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 前后端项目标准库
|
|
|
|
|
|
|
|
|
|
|
|
| 基线 | 路径 | 使用要求 |
|
|
|
|
|
|
| --- | --- | --- |
|
2026-08-02 23:26:28 +08:00
|
|
|
|
| 前端工程基线 | 现有 Vue 管理端 | Vue 管理系统统一前端框架、路由、状态管理、请求封装、权限指令、表格表单、主题、错误处理、国际化与测试规范 |
|
|
|
|
|
|
| 后端工程基线 | `backend/{api,worker,iot}` | Go API、Worker、IoT 进程统一沿用配置、日志、错误码、认证、数据库访问、任务、测试和发布规范 |
|
2026-07-26 17:23:07 +08:00
|
|
|
|
|
|
|
|
|
|
业务项目应通过共享包、模板或上游同步机制复用标准库,禁止将标准库目录复制到每个子项目后自行漂移。标准库升级需要记录版本、影响范围、兼容策略和回滚方式。
|
|
|
|
|
|
|
2026-07-26 18:06:14 +08:00
|
|
|
|
### 4.1 移动端定位、离线与取证基线
|
|
|
|
|
|
|
|
|
|
|
|
- 服务端 App 仅在配送或现场任务执行期间申请并采集定位;必须显式展示定位授权、后台运行、最后更新时间和权限失效状态。用户端仅消费本人订单所需的简化轨迹。
|
|
|
|
|
|
- 已分配任务、轨迹点、照片/视频元数据、签名、扫描结果和收款确认可在弱网下加密暂存。补传必须携带原始采集时间、服务端接收时间、任务 `identity`、操作者 `identity`、来源、完整性标记与幂等键,禁止以补传时间覆盖采集时间。
|
|
|
|
|
|
- 后端负责乱序校正、重复去除、异常速度/精度标记、证据哈希与状态机校验;前端离线缓存、按钮禁用或页面显示不能替代服务端权限、金额、地理围栏和完成条件校验。
|
|
|
|
|
|
|
2026-07-30 21:47:41 +08:00
|
|
|
|
### 4.2 Flutter 工程落地基线
|
|
|
|
|
|
|
2026-08-02 01:30:07 +08:00
|
|
|
|
- 生产工程已落在 `apps/user_app` 与 `apps/service_app`,生成 Android、iOS、Web 平台目录;`ui` 继续作为视觉和交互原型,不作为运行时依赖。Web 构建通过仓库根目录 `scripts/build-apps.sh` 输出,生产环境必须注入 HTTPS `API_BASE_URL`。
|
2026-07-30 21:47:41 +08:00
|
|
|
|
- 两个 App 使用 `MaterialApp.router`、`go_router`、MVVM + Repository 与注入的平台 Service。HTTP 根地址通过 `--dart-define=API_BASE_URL=...` 注入;用户端和工作人员端分别固定访问 `/heqi/client/v1/user` 与 `/heqi/client/v1/staff`,JWT 请求头沿用当前服务端原始令牌契约。
|
2026-08-02 01:30:07 +08:00
|
|
|
|
- 访问令牌保存在 Android Keystore / iOS Keychain 支持的安全存储;Web 使用浏览器安全存储,且只能部署在 HTTPS 域名。服务端 App 的现场草稿和附件按账号使用 AES-GCM 加密;Web 仅保存密文,恢复网络后才上传并执行最终业务提交。浏览器端不承担 Android/iOS 的后台定位保障。
|
2026-07-30 21:47:41 +08:00
|
|
|
|
- 充值 Mock 确认只允许 Debug/开发联调,Release UI 不注册该入口;未落地的设备控制、收藏、押金、消息和发票能力不得以静态成功状态替代。
|
|
|
|
|
|
|
2026-07-26 17:23:07 +08:00
|
|
|
|
## 5. 研发目录规划(建议)
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
platforms/
|
|
|
|
|
|
docs/ # 本需求文档集
|
|
|
|
|
|
apps/
|
|
|
|
|
|
user_app/ # Flutter 用户端 App
|
|
|
|
|
|
service_app/ # Flutter 服务端 App:安装维修、安检、配送能力包
|
|
|
|
|
|
frontend/
|
|
|
|
|
|
platform_admin/ # Vue:平台总后台
|
|
|
|
|
|
gas_admin/ # Vue:气站管理系统
|
|
|
|
|
|
delivery_admin/ # Vue:配送点管理系统
|
|
|
|
|
|
product_admin/ # Vue:生产管理系统
|
|
|
|
|
|
openapi/ # Vue:API 中心管理系统
|
|
|
|
|
|
site/ # HTML:官网land页
|
|
|
|
|
|
backend/
|
|
|
|
|
|
api/ # Go HTTP API、BFF、同步领域事务
|
|
|
|
|
|
worker/ # Go 异步任务:派单、告警、通知、对账、超时扫描
|
|
|
|
|
|
iot/ # Go MQTT 协议适配、设备命令、遥测与回执
|
|
|
|
|
|
contracts/
|
|
|
|
|
|
openapi/ # HTTP API 契约及生成配置
|
|
|
|
|
|
asyncapi/ # MQTT/Redis Streams 事件契约与 Schema
|
|
|
|
|
|
deploy/
|
|
|
|
|
|
caddy/ # Caddy 配置、站点与证书策略
|
|
|
|
|
|
scripts/ # 服务器部署、启停、健康检查、回滚 Shell 脚本
|
|
|
|
|
|
scripts/ # 本地开发、生成、编译、质量检查 Shell 脚本
|
|
|
|
|
|
tests/
|
|
|
|
|
|
rest/ # HTTP API 集成与回归测试
|
|
|
|
|
|
contract/ # OpenAPI/AsyncAPI 兼容性测试
|
|
|
|
|
|
e2e/ # 关键端到端流程
|
|
|
|
|
|
performance/ # 遥测、订单、轨迹与消息积压压测
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-07-30 21:47:41 +08:00
|
|
|
|
其中 `apps/user_app`、`apps/service_app`、`backend/{api,worker,iot}` 与当前管理端目录已经落地;其余标记为规划的目录仍不得因局部任务提前创建空壳。
|
2026-07-26 17:23:07 +08:00
|
|
|
|
|
|
|
|
|
|
## 6. 后端领域划分
|
|
|
|
|
|
|
2026-07-31 09:54:17 +08:00
|
|
|
|
- `backend/api/internal/logic/common`:承载跨平台后台、气站、配送点以及两个 Client 复用的鉴权、账户解析、资源响应和钱包记账能力;不再保留 `logic/client/common` 同义公共包。
|
2026-07-26 17:23:07 +08:00
|
|
|
|
- `identity`:登录、验证码、账号、RBAC、组织、数据范围、协议同意。
|
|
|
|
|
|
- `organization`:气站、配送点、服务区域、人员归属、用户服务关系和邀请注册二维码。
|
|
|
|
|
|
- `device`:设备注册/绑定、设备模型、遥测、命令、在线状态、固件。
|
|
|
|
|
|
- `catalog`:分类、商品、SKU、库存、优惠券、收藏、购物车。
|
|
|
|
|
|
- `order`:订单、支付、合同、配送、安装、售后、评价。
|
|
|
|
|
|
- `dispatch`:服务人员、区域、班次、任务、派单、导航、配送轨迹与现场取证。
|
|
|
|
|
|
- `wallet`:充值、余额流水、分账、结算、提现、对账。
|
|
|
|
|
|
- `content`:轮播、公告、协议、视频、客服配置。
|
|
|
|
|
|
- `notification`:站内信、推送、短信、语音、模板、触达回执。
|
|
|
|
|
|
- `audit`:不可变操作日志、敏感数据访问记录、导出记录。
|
|
|
|
|
|
- `manufacturing`:设备型号、生产工单、序列号、证书注入、质检、批次、固件和出厂追溯。
|
|
|
|
|
|
- `openapi`:API 产品、调用方应用、凭证、订阅、配额、网关策略、Webhook 和调用审计。
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 工程质量基线
|
|
|
|
|
|
|
|
|
|
|
|
### 7.1 数据模型与命名强制规范
|
|
|
|
|
|
|
|
|
|
|
|
- 每个业务模块的关系表必须使用模块前缀,格式为 `<模块前缀>_<实体名>`,全小写蛇形命名。禁止使用无领域归属的通用表名,如 `users`、`orders`、`records`。
|
|
|
|
|
|
- 文件名、表名、模型名和接口 Schema 必须以同一“模块前缀 + 单数实体词根”为唯一标识;禁止因为语言、层次或集合含义改变实体名称,也禁止使用复数形式造成不一致。
|
|
|
|
|
|
|
|
|
|
|
|
| 模块 | 表前缀 | 典型表 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| 身份与权限 | `idn_` | `idn_account`、`idn_role`、`idn_permission` |
|
2026-07-26 18:06:14 +08:00
|
|
|
|
| 组织与服务关系 | `org_` | `org_gas_station`、`org_delivery_point`、`org_service_person`、`org_user_service_relation`、`org_invitation_qr_code` |
|
2026-07-26 17:23:07 +08:00
|
|
|
|
| 设备与物联网 | `dev_` | `dev_device`、`dev_telemetry`、`dev_command` |
|
|
|
|
|
|
| 商品与营销 | `cat_` | `cat_product`、`cat_sku`、`cat_coupon`、`cat_cart` |
|
|
|
|
|
|
| 订单与履约 | `ord_` | `ord_order`、`ord_payment`、`ord_service_task`、`ord_delivery_track` |
|
|
|
|
|
|
| 调度与配送 | `dsp_` | `dsp_assignment`、`dsp_shift`、`dsp_delivery_track_point` |
|
2026-07-26 18:06:14 +08:00
|
|
|
|
| 钱包与结算 | `wal_` | `wal_wallet_ledger`、`wal_settlement`、`wal_withdrawal` |
|
2026-07-27 15:31:22 +08:00
|
|
|
|
| 内容管理 | `cms_` | `cms_content` |
|
2026-07-26 17:23:07 +08:00
|
|
|
|
| 生产与质量 | `mfg_` | `mfg_work_order`、`mfg_batch`、`mfg_quality_check` |
|
|
|
|
|
|
| 开放接口 | `api_` | `api_product`、`api_client`、`api_subscription` |
|
2026-07-27 15:31:22 +08:00
|
|
|
|
| 平台任务 | `sys_` | `sys_outbox_event`、`sys_dead_letter_event` |
|
2026-07-26 17:23:07 +08:00
|
|
|
|
|
2026-07-30 21:47:41 +08:00
|
|
|
|
- 每张表必须包含数据库内部使用的 `id bigint` 自增主键;主表还必须包含由应用生成、带唯一索引的 UUID V7 `identity varchar(36)`。HTTP、消息、审计日志、Flutter/Vue 模型和跨服务引用只使用 `identity`,不得暴露或接受内部 `id`。
|
|
|
|
|
|
- 数据库内部关联优先使用 `<实体词根>_id` 指向自增主键;跨服务契约、异步事件和审计关联使用 `<实体词根>_identity`。业务展示编号另设唯一字段,不能替代 `id` 或 `identity`。
|
2026-07-26 17:23:07 +08:00
|
|
|
|
- 每个主表还应按需要包含 `created_at`、`updated_at`、`created_by_identity`、`updated_by_identity`、`status`、`version` 等审计/并发字段;资金流水、安全事件、审计日志等不可变记录不得被物理删除。
|
2026-07-27 00:18:42 +08:00
|
|
|
|
- 数据库表、字段、索引、约束和枚举必须编写中文注释;注释说明业务含义、取值/单位、脱敏或留存要求。模型注释与接口契约必须同步维护,禁止只在设计文档中说明。
|
2026-07-26 17:23:07 +08:00
|
|
|
|
|
|
|
|
|
|
#### 实体名、文件名、表名、模型名一致性
|
|
|
|
|
|
|
|
|
|
|
|
以 `org_gas_station` 为例,同一业务实体必须按下表命名:
|
|
|
|
|
|
|
|
|
|
|
|
| 产物 | 强制命名 | 禁止示例 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| 数据库表 | `org_gas_station` | `org_gas_stations`、`gas_stations`、`station` |
|
|
|
|
|
|
| Go 模型文件/类型 | `org_gas_station.go` / `OrgGasStation` | `gas_station.go`、`GasStations`、`StationModel` |
|
|
|
|
|
|
| Flutter 模型文件/类型 | `org_gas_station.dart` / `OrgGasStation` | `gas_stations.dart`、`GasStationEntity` |
|
|
|
|
|
|
| Vue 模型文件/类型 | `org_gas_station.ts` / `OrgGasStation` | `gasStation.ts`、`GasStations` |
|
|
|
|
|
|
| OpenAPI/AsyncAPI Schema | `org_gas_station` | `GasStationDto`、`gas_stations` |
|
|
|
|
|
|
|
|
|
|
|
|
- 所有实体一律使用单数:一个 `org_gas_station` 既可表示单个站点模型,也可作为列表返回项的模型名称。列表、批量和分页仅在 API 动词或响应字段表达,例如 `GET /org/gas-station/list`、`items: []`;不改变实体名。
|
|
|
|
|
|
- 关联表使用参与实体的单数词根和明确关系词,例如 `org_user_service_relation`、`idn_account_role_relation`,不得使用 `users_roles`、`user_roles` 等复数或含糊名称。
|
2026-07-26 18:06:14 +08:00
|
|
|
|
- `ord_delivery_track` 是配送任务的状态轨迹主表,`dsp_delivery_track_point` 是其定位点明细表;二者均为独立实体,不得再创建同义的 `delivery_tracks`、`track_points` 等表或模型。定位点通过 `delivery_track_identity` 关联主表。
|
|
|
|
|
|
- 钱包事实流水的唯一实体名为 `wal_wallet_ledger`;用户和服务人员的资金归属通过关联对象字段区分,禁止另建同义的 `wal_ledger`、`wallet_ledgers` 或 `service_wallet_ledger`。
|
2026-07-27 00:18:42 +08:00
|
|
|
|
- 文件目录可以按业务模块组织,但目录名不参与实体命名;模型、契约、测试文件都必须能从其文件名唯一定位到同名的数据库表和模型。
|
|
|
|
|
|
- 新增实体前应先登记规范名称;重命名须同时修改表、模型、文件、契约和中文注释,并进行全仓引用检查,禁止仅改其中一层。
|
2026-07-26 17:23:07 +08:00
|
|
|
|
|
|
|
|
|
|
### 7.2 代码与模型中文注释规范
|
|
|
|
|
|
|
|
|
|
|
|
- Go、Flutter 和 Vue 代码中的业务类型、领域模型、枚举、公开接口、复杂规则、状态机、金额计算、权限判断和异步事件必须使用中文注释说明业务意图。
|
|
|
|
|
|
- 中文注释应解释“为什么”和业务口径,不重复代码字面含义;对外 API 的字段说明、OpenAPI/AsyncAPI Schema 描述和错误码说明同样必须为中文。
|
2026-07-27 00:18:42 +08:00
|
|
|
|
- 模型注释应与数据库注释和接口契约保持一致。需求变更导致字段、状态或规则变化时,代码、模型和契约注释必须在同一变更中更新。
|
2026-07-26 17:23:07 +08:00
|
|
|
|
- 注释中应使用与表名/模型名一致的中文业务名称,例如“气站”对应 `org_gas_station`,不能在同一业务语境混用“站点”“气站信息”“GasStations”等不同实体名。
|
|
|
|
|
|
- 禁止以无意义拼音、英文缩写或临时注释代替业务说明;第三方库、协议标准和专有名词可保留其原文,并在首次出现处附中文解释。
|
|
|
|
|
|
|
|
|
|
|
|
- API 使用 OpenAPI;IoT/事件使用 AsyncAPI 或明确的版本化 Schema;客户端由契约生成类型。
|
|
|
|
|
|
- Redis Streams 的生产者、消费者、重试和死信处理均须有监控;任何消费者可安全重复执行,Redis 不可用时由 Outbox 补偿投递。
|
2026-08-02 23:26:28 +08:00
|
|
|
|
- 所有管理端统一沿用现有管理端的鉴权、数据权限、错误处理和审计埋点;所有 Go 进程统一沿用现有后端的配置、日志和健康检查规范。
|
2026-07-26 17:23:07 +08:00
|
|
|
|
- 单元测试覆盖规则、金额、状态机、权限;集成测试覆盖支付回调、设备回执、派单和并发库存;端到端测试覆盖高风险安全闭环。
|
2026-07-27 00:18:42 +08:00
|
|
|
|
- CI 必须执行静态检查、依赖漏洞扫描、契约兼容性检查和关键路径自动化测试;CD 必须执行健康检查和可回滚发布。
|