# 共享医疗设备修理小程序 - 技术参考文档

> 规范同步：以 `momo-kit/specs/通用规范.md` 为准。  
> 本文档中的技术选型、部署与成本口径需与 `doc/README.md`、`doc/business_logic.md`、`doc/api_list.md` 保持一致。

---

## 1. 概述

本文档提供共享医修通（省级医疗设备维修共享平台）所需的外部 API 服务、开源项目和技术方案参考，包括核心技术选型与成本估算。平台服务范围覆盖 300–500 家医院，连接设备报修方与持证维修工程师，实现工单智能派发、实时轨迹追踪、配件供应链对接与全流程电子化闭环。

数据表前缀：`medfix_`  
推荐部署档位：**L2 增强（集群）**

---

## 2. 技术栈总览

| 组件 | 技术选型 | 版本 | 说明 |
|------|---------|------|------|
| 后端框架 | Cool Admin Node (Midway.js) | v8.x | API 服务，IoC + 装饰器驱动 |
| 管理前端 | Cool Admin Vue (Vue 3 + Element Plus) | v8.x | 运营管理后台 |
| 小程序 | Cool Unix (uni-app x) | v8.x | 微信小程序（报修端 + 工程师端） |
| 数据库 | MySQL | 8.0 | 主数据存储，一主两从 |
| 缓存 | Redis | 7.x | 会话、缓存、BullMQ 队列、分布式锁 |
| 对象存储 | 阿里云 OSS / 腾讯云 COS | - | 故障照片、维修报告、资质证书 |
| 消息推送 | 微信订阅消息 | - | 工单状态变更、派单、评价通知 |
| 实时通信 | WebSocket（Cool Admin 内建） | - | 工单状态推送、工程师位置上报 |
| 地图服务 | 腾讯地图 / 高德地图 | - | 工程师定位、智能派单、路线规划 |
| 短信服务 | 阿里云 SMS | - | 验证码、紧急告警、工单超时通知 |
| 可观测性 | Sentry + Midway Logger | - | 错误捕获、链路追踪、告警 |

### 2.1 数据架构与文档索引（四类架构之数据层）

| 内容 | 载体 |
|------|------|
| 表结构、字段、索引 | `doc/database_schema.md` / `database_schema.html` |
| ER 关系图 | `doc/database_er.html` |
| 冷热分层、归档、缓存一致性策略 | 工单数据 90 天热存 → 归档至 `medfix_order_archive`；缓存写后失效 + TTL 双保险 |

---

## 2.2 架构参考基线（默认组合）

> 默认推荐组合：**C4 + 4+1 + ISO42010**。  
> 说明：C4 用于分层沟通，4+1 用于覆盖逻辑/进程/部署/场景，ISO42010 用于约束文档完整性与干系人关注点。

| 参考框架 | 本项目用途 | 交付要求 |
|------|------|------|
| C4 Model | 输出 Context/Container 视图，对齐系统边界（报修端、工程师端、管理端、派单引擎） | 阶段二完成 Context + Container |
| 4+1 视图 | 输出 Logical/Process/Physical + 场景（报修→派单→维修→验收→结算） | 阶段二明确关键场景，阶段三展示关键图 |
| ISO42010 | 约束"干系人-关注点-视图"映射，医院管理者关注 SLA、工程师关注派单公平性 | 每张架构图需注明用途与关注点 |

### 2.2.1 行业互联网售后基座能力映射（技术侧）

> 与 `需求评估文档.md` §1.5.4 业务对标表配套：本表从**技术实现与中间件**角度列出行业同类系统常见基座，并映射到本项目已选型栈。

| 行业基座能力 | 典型实现要点 | 本项目落点 |
|-------------|-------------|-----------|
| 多渠道身份与会话 | OAuth2/微信 code2session、多端 token 隔离 | Midway JWT + Redis 会话；科室/工程师/厂家端分端鉴权 |
| 消息与触达 | 订阅消息、短信、站内信、可选 WebSocket | 微信订阅消息 + 阿里云 SMS + Cool Admin WebSocket |
| 异步与削峰 | 派工计算、通知发送、报表聚合异步化 | BullMQ on Redis；派工与统计任务入队 |
| 地理与轨迹 | GCJ02 坐标、电子围栏、轨迹批量写入 | 腾讯/高德 API；工程师轨迹表 + 批量落库策略 |
| 文件与合规留痕 | OSS 私有读、预签名 URL、操作审计 | OSS/COS；工单日志表 + 关键字段审计 |
| 可观测与高可用 | 日志、指标、错误预算、集群部署 | Sentry + Logger + 云监控；L2 Nginx 多节点 + Redis 哨兵/集群 |
| 开放集成 | 院方 HIS/ERP 回调与幂等 | 预留开放 API 网关路由 + 幂等键（见 `api_list` 扩展节） |

### 2.3 技术架构（分层总览）

```mermaid
flowchart TB
    subgraph presentationLayer [展现层]
        webAdmin[Web管理端<br/>Cool Admin Vue]
        miniRepair[报修端小程序]
        miniEngineer[工程师端小程序]
        openApi[开放API<br/>医院HIS对接]
    end
    subgraph accessLayer [接入层]
        cdnNode[CDN<br/>阿里云/腾讯云]
        nginx[Nginx集群<br/>2节点负载均衡]
        gateway[API网关<br/>JWT鉴权 + RBAC]
        rateLimit[限流与熔断<br/>令牌桶 + 熔断降级]
    end
    subgraph serviceLayer [服务层]
        userSvc[用户与认证服务<br/>医院/工程师/管理员]
        orderSvc[工单服务<br/>报修/派单/验收/结算]
        dispatchSvc[智能派单引擎<br/>距离+技能+负载]
        partsSvc[配件供应链服务<br/>库存/采购/出库]
        msgSvc[消息与推送服务<br/>订阅消息/SMS/WebSocket]
        asyncQueue[异步任务队列<br/>BullMQ on Redis]
        observability[可观测性<br/>Sentry + Logger + Metrics]
    end
    subgraph dataLayer [数据层]
        mysqlPrimary[(MySQL主库)]
        mysqlReplica1[(MySQL从库1)]
        mysqlReplica2[(MySQL从库2)]
        redisCluster[(Redis Sentinel<br/>3节点)]
        ossStorage[(OSS对象存储<br/>图片/文件)]
        thirdMap[腾讯/高德地图API]
        thirdSms[阿里云SMS]
        thirdWx[微信开放平台]
    end

    webAdmin --> cdnNode
    miniRepair --> nginx
    miniEngineer --> nginx
    openApi --> gateway
    cdnNode --> nginx
    nginx --> gateway
    gateway --> rateLimit
    rateLimit --> userSvc
    rateLimit --> orderSvc
    rateLimit --> dispatchSvc
    rateLimit --> partsSvc
    rateLimit --> msgSvc
    userSvc --> mysqlPrimary
    userSvc --> redisCluster
    orderSvc --> mysqlPrimary
    orderSvc --> asyncQueue
    dispatchSvc --> redisCluster
    dispatchSvc --> thirdMap
    partsSvc --> mysqlPrimary
    msgSvc --> thirdSms
    msgSvc --> thirdWx
    mysqlPrimary --> mysqlReplica1
    mysqlPrimary --> mysqlReplica2
    orderSvc --> ossStorage
    asyncQueue --> observability
```

### 2.4 数据架构总览（主题域 + 存储分层）

```mermaid
flowchart LR
    subgraph sourceLayer [数据来源]
        srcOrder[工单事务数据<br/>报修/派单/维修/验收/结算]
        srcUser[用户行为数据<br/>登录/浏览/操作轨迹]
        srcLocation[位置事件数据<br/>工程师GPS上报]
        srcExternal[外部集成数据<br/>HIS设备台账/配件供应商]
    end
    subgraph processLayer [数据处理层]
        etlBatch[批处理ETL<br/>日终对账/月度统计]
        streamRealtime[实时流处理<br/>工程师位置聚合/工单超时检测]
        qualityGate[数据质量校验<br/>字段完整性/业务规则]
    end
    subgraph storageLayer [数据存储层]
        mysqlOLTP[(事务库MySQL<br/>medfix_order/user/engineer)]
        redisHot[(热数据Redis<br/>会话/排行/位置缓存)]
        archiveCold[(归档表<br/>medfix_order_archive)]
        odsDetail[(ODS明细层<br/>工单全生命周期快照)]
        dwsSummary[(DWS汇总层<br/>日/周/月维修统计)]
    end
    subgraph appLayer [数据应用层]
        dashOps[运营看板<br/>工单量/响应时效/满意度]
        alertSys[告警与风控<br/>超时/异常结算/刷单检测]
        reportAudit[报表与审计<br/>医院月度维修报告]
    end

    srcOrder --> etlBatch
    srcUser --> streamRealtime
    srcLocation --> streamRealtime
    srcExternal --> etlBatch
    etlBatch --> qualityGate
    streamRealtime --> qualityGate
    qualityGate --> mysqlOLTP
    qualityGate --> redisHot
    qualityGate --> odsDetail
    odsDetail --> dwsSummary
    mysqlOLTP --> archiveCold
    mysqlOLTP --> dashOps
    redisHot --> alertSys
    dwsSummary --> reportAudit
```

### 2.5 数据架构 ER 关系总览

```mermaid
erDiagram
    medfix_user ||--o{ medfix_order : "报修"
    medfix_user ||--o{ medfix_address : "管理地址"
    medfix_user {
        int id PK
        string openId
        string phone
        string realName
        int hospitalId FK
        int roleType
    }

    medfix_hospital ||--o{ medfix_user : "所属医院"
    medfix_hospital ||--o{ medfix_device : "拥有设备"
    medfix_hospital {
        int id PK
        string name
        string province
        string city
        string address
        string contactPhone
    }

    medfix_device ||--o{ medfix_order : "关联工单"
    medfix_device {
        int id PK
        int hospitalId FK
        string deviceName
        string deviceModel
        string serialNo
        int categoryId FK
        date warrantyExpire
    }

    medfix_device_category ||--o{ medfix_device : "分类"
    medfix_device_category {
        int id PK
        string name
        int parentId
    }

    medfix_engineer ||--o{ medfix_order : "接单"
    medfix_engineer ||--o{ medfix_engineer_cert : "持有资质"
    medfix_engineer ||--o{ medfix_engineer_skill : "具备技能"
    medfix_engineer {
        int id PK
        int userId FK
        string realName
        string phone
        decimal lng
        decimal lat
        int status
        decimal rating
    }

    medfix_order ||--o{ medfix_order_log : "操作日志"
    medfix_order ||--o{ medfix_order_part : "使用配件"
    medfix_order ||--o{ medfix_order_photo : "现场照片"
    medfix_order ||--|{ medfix_order_evaluate : "验收评价"
    medfix_order ||--o| medfix_order_payment : "结算记录"
    medfix_order {
        int id PK
        string orderNo
        int userId FK
        int hospitalId FK
        int deviceId FK
        int engineerId FK
        int status
        string faultDesc
        int urgencyLevel
        datetime dispatchTime
        datetime arriveTime
        datetime completeTime
    }

    medfix_part ||--o{ medfix_order_part : "被使用"
    medfix_part ||--o{ medfix_part_stock : "库存记录"
    medfix_part {
        int id PK
        string partName
        string partNo
        string brand
        decimal price
        int categoryId
    }
```

---

## 3. 外部服务

### 3.1 地图与定位服务

**服务商对比**：

| 服务商 | 特性 | 免费额度 | 超出收费 | 推荐指数 |
|--------|------|----------|----------|----------|
| 腾讯地图 | 微信生态深度整合，小程序原生支持 | 1万次/日 | ¥2/千次 | ★★★★★ |
| 高德地图 | 路径规划精度高，企业级服务成熟 | 5千次/日 | ¥2/千次 | ★★★★☆ |

**推荐方案**：腾讯地图 - 与微信小程序生态无缝集成，工程师定位与路线规划场景覆盖完善。

**核心API**：

| API | 用途 | 免费额度 | 文档地址 |
|-----|------|----------|----------|
| 逆地理编码 | GPS坐标转地址 | 1万次/日 | https://lbs.qq.com/service/webService/webServiceGuide/webServiceGcoder |
| 距离计算（批量） | 派单时计算工程师与医院距离 | 1万次/日 | https://lbs.qq.com/service/webService/webServiceGuide/webServiceMatrix |
| 路径规划 | 工程师导航至医院 | 1万次/日 | https://lbs.qq.com/service/webService/webServiceGuide/webServiceRoute |
| 地点搜索 | 医院地址联想输入 | 1万次/日 | https://lbs.qq.com/service/webService/webServiceGuide/webServiceSuggestion |

**集成代码示例**：

```typescript
import { Config, Provide } from '@midwayjs/core';
import axios from 'axios';

@Provide()
export class MapService {
  @Config('map')
  mapConfig: { key: string };

  async batchDistance(from: { lat: number; lng: number }, toList: { lat: number; lng: number }[]) {
    const toStr = toList.map(t => `${t.lat},${t.lng}`).join(';');
    const { data } = await axios.get('https://apis.map.qq.com/ws/distance/v1/matrix', {
      params: {
        mode: 'driving',
        from: `${from.lat},${from.lng}`,
        to: toStr,
        key: this.mapConfig.key,
      },
    });
    return data.result.rows[0].elements;
  }
}
```

### 3.2 短信服务

**服务商对比**：

| 服务商 | 特性 | 免费额度 | 超出收费 | 推荐指数 |
|--------|------|----------|----------|----------|
| 阿里云 SMS | 到达率高、审核快、SDK完善 | 无（按量付费） | ¥0.045/条 | ★★★★★ |
| 腾讯云 SMS | 微信生态配合好 | 100条/月 | ¥0.050/条 | ★★★★☆ |

**推荐方案**：阿里云 SMS - 到达率稳定 99%+，签名审核 1-2 小时，模板丰富。

**核心API**：

| API | 用途 | 免费额度 | 文档地址 |
|-----|------|----------|----------|
| SendSms | 发送验证码 / 工单通知 | 按量 | https://help.aliyun.com/document_detail/419298.html |
| QuerySendDetails | 查询发送状态 | 按量 | https://help.aliyun.com/document_detail/419299.html |

### 3.3 微信开放能力

| 能力 | 用途 | 文档 |
|------|------|------|
| 微信登录 | 用户认证（医院人员 / 工程师） | https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html |
| 手机号获取 | 绑定手机号（工程师实名） | https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html |
| 订阅消息 | 工单状态推送（派单/接单/完成/评价） | https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html |
| 微信支付 | 维修费用结算（医院→平台→工程师） | https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/payment.html |
| 地理位置 | 工程师实时位置上报 | https://developers.weixin.qq.com/miniprogram/dev/api/location/wx.getLocation.html |
| 图片/相机 | 故障现场拍照、维修前后对比 | https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.chooseImage.html |
| 扫码 | 扫描设备铭牌二维码快速报修 | https://developers.weixin.qq.com/miniprogram/dev/api/device/scan/wx.scanCode.html |

### 3.4 对象存储（OSS）

| API | 用途 | 免费额度 | 文档地址 |
|-----|------|----------|----------|
| PutObject | 上传故障照片、维修报告 | 5GB 存储/月（免费试用） | https://help.aliyun.com/document_detail/31978.html |
| GetObject | 查看/下载维修文档 | 按流量 | https://help.aliyun.com/document_detail/31980.html |
| STS 临时授权 | 小程序直传 OSS | - | https://help.aliyun.com/document_detail/100624.html |

---

## 4. 开源项目参考

### 4.1 Cool Admin 全栈框架

| 属性 | 内容 |
|------|------|
| **项目地址** | https://cool-js.com |
| **用途** | 后端 API 框架 + 管理端 + 移动端全栈基座 |
| **License** | MIT |
| **适用场景** | 项目核心基座，提供 CRUD 生成器、RBAC 权限、文件空间、任务调度 |

### 4.2 BullMQ

| 属性 | 内容 |
|------|------|
| **项目地址** | https://github.com/taskforcesh/bullmq |
| **用途** | 基于 Redis 的任务队列，处理异步派单、超时检测、通知推送 |
| **License** | MIT |
| **适用场景** | 工单超时自动升级、批量推送、定时对账、工程师排班计算 |

### 4.3 node-cron / @midwayjs/cron

| 属性 | 内容 |
|------|------|
| **项目地址** | Midway.js 内建定时任务 |
| **用途** | 定时任务调度（日终对账、工单超时扫描、统计报表生成） |
| **License** | MIT |
| **适用场景** | 每 5 分钟扫描超时工单、每日凌晨生成维修统计、每周生成医院报告 |

---

## 5. 运营成本估算

### 5.1 固定成本

| 项目 | 说明 | 月费用 |
|------|------|--------|
| 云服务器（ECS） | 4台 2核4G（API集群），PM2 cluster 模式 | ¥2,000/月 |
| MySQL RDS | 4核8G 高可用版，1主2从 | ¥800/月 |
| Redis | 2G 主从高可用（Sentinel 3节点） | ¥300/月 |
| OSS 存储 | 预估 50GB 图片/文件，标准存储 | ¥100/月 |
| CDN | 静态资源加速，预估 100GB/月流量 | ¥100/月 |
| 域名 | medfix.com 或类似 | ¥5/月（¥60/年） |
| SSL证书 | Let's Encrypt 免费自动续期 | ¥0/月 |
| 小程序认证 | 微信小程序年审 | ¥25/月（¥300/年） |

### 5.2 按量成本

| 项目 | 单价 | 预估月用量 | 月费用 |
|------|------|-----------|--------|
| 短信（验证码+通知） | ¥0.045/条 | 4,000条 | ¥180 |
| 地图 API | ¥2/千次 | 10万次 | ¥200 |
| OSS 流量 | ¥0.50/GB | 100GB | ¥50 |
| 微信订阅消息 | 免费 | 不限 | ¥0 |
| 微信支付手续费 | 0.6% | 月交易额¥50万 | ¥3,000 |

### 5.3 成本汇总

| 方案 | 月固定成本 | 月按量成本 | 月总成本 |
|------|-----------|-----------|---------|
| L1 标准版（单点+基础缓存） | ¥1,200 | ¥300 | ¥1,500 |
| L2 增强版（集群+主从+Sentinel） | ¥3,330 | ¥430 | ¥3,760 |
| L2 增强版含支付手续费 | ¥3,330 | ¥3,430 | ¥6,760 |
| L3 企业版（多活+跨区容灾） | ¥8,000 | ¥1,000 | ¥9,000 |

---

## 6. 部署方案

> **四类架构**：本章整体对应**技术架构**（选型、中间件、非功能）；拓扑与分档对应 **4+1 中的物理视图**（部署视图）。**业务/应用/逻辑**见 `business_logic.md`；**数据模型**见 `database_schema.md` / ER 图。术语与映射以 `momo-kit/specs/通用规范.md` 阶段二为准。

### 6.0 架构路线候选与客户选择

#### 6.0.1 候选路线总览（示意图 + 简介）

| 路线ID | 路线名称 | 简介 | 适用场景 | 复杂度 | 成本区间（月） |
|------|------|------|------|------|------|
| R1 | 单体增强（Monolith Plus） | 单体 Midway + Redis 缓存 + 基础监控 | 试点期 50 家以下医院，快速验证 | 低 | ¥800–¥1,500 |
| R2 | 服务拆分（Modular Services） | 工单/派单/用户模块拆分 + BullMQ 异步 | 100–300 家医院，日工单 500+ | 中 | ¥2,000–¥4,000 |
| R3 | 云原生弹性（Cloud Native） | PM2 Cluster / K8s 容器编排 + 自动扩缩容 + Sentry | 300–500 家医院，日工单 1,000+ | 中高 | ¥4,000–¥7,000 |
| R4 | 多租户多活（Enterprise HA） | 多省份租户隔离 + 跨区容灾 + 合规审计 | 全国多省运营，强监管要求 | 高 | ¥9,000+ |

#### 6.0.2 路线示意图与简介卡片

#### R1 - 单体增强（Monolith Plus）

```mermaid
flowchart LR
    miniApp[微信小程序] --> nginx[Nginx]
    adminWeb[管理端] --> nginx
    nginx --> midway[Midway.js 单体应用]
    midway --> mysql[(MySQL 单实例)]
    midway --> redis[(Redis 单实例)]
    midway --> sentry[Sentry 错误上报]
```

- 适用：试点阶段 ≤50 家医院，日均工单 <100。
- 优势：1 周内上线，运维成本最低。
- 限制：单点故障风险，扩展需重构。
- 推荐档位：L0/L1。

#### R2 - 服务拆分（Modular Services）

```mermaid
flowchart LR
    client[客户端] --> nginx[Nginx]
    nginx --> userSvc[用户服务]
    nginx --> orderSvc[工单服务]
    nginx --> dispatchSvc[派单服务]
    orderSvc --> bullmq[BullMQ 任务队列]
    userSvc --> mysql[(MySQL 主从)]
    orderSvc --> mysql
    dispatchSvc --> redis[(Redis)]
    dispatchSvc --> mapApi[地图API]
```

- 适用：增长期 100–300 家医院，日工单 500+。
- 优势：核心域独立扩展，派单引擎可独立优化。
- 限制：调用链变长，需引入链路追踪。
- 推荐档位：L1/L2。

#### R3 - 云原生弹性（Cloud Native）

```mermaid
flowchart LR
    client[客户端] --> lb[Nginx 负载均衡 x2]
    lb --> pods[Node.js 集群 x4<br/>PM2 Cluster / K8s Pods]
    pods --> mysqlPrimary[(MySQL 主库)]
    mysqlPrimary --> mysqlReplica1[(MySQL 从库1)]
    mysqlPrimary --> mysqlReplica2[(MySQL 从库2)]
    pods --> sentinel[Redis Sentinel x3]
    pods --> bullmq[BullMQ 队列]
    pods --> oss[(OSS 对象存储)]
    pods --> sentry[Sentry + Grafana]
    oss --> cdn[CDN 加速]
```

- 适用：省级运营 300–500 家医院，日工单 1,000+。
- 优势：自动扩缩容，故障自愈，完整可观测性。
- 限制：容器与平台治理门槛较高。
- 推荐档位：**L2（本项目推荐）**。

#### R4 - 多租户多活（Enterprise HA）

```mermaid
flowchart LR
    client[客户端] --> dns[全局流量调度<br/>DNS + GTM]
    dns --> regionA[华东集群]
    dns --> regionB[华南集群]
    regionA --> tenantDbA[(租户数据库A<br/>Schema隔离)]
    regionB --> tenantDbB[(租户数据库B<br/>Schema隔离)]
    regionA --> auditCenter[审计与合规中心]
    regionB --> auditCenter
```

- 适用：全国多省运营，强医疗监管合规要求。
- 优势：高可用 99.99%，租户数据物理隔离，审计留痕。
- 限制：建设周期 6+ 月，预算 ¥9,000+/月。
- 推荐档位：L3。

#### 6.0.3 客户选择区

| 项目 | 填写值 |
|------|------|
| 候选路线清单 | R1, R2, R3 |
| 主推荐路线 | R3（云原生弹性） |
| 次推荐路线 | R2（服务拆分，作为过渡方案） |
| 客户最终选择 | R3 |
| 未选原因 | R4 成本过高且当前仅覆盖单省，无跨区容灾刚需 |

### 6.1 推荐配置（L2 增强档位）

| 组件 | 配置 | 说明 |
|------|------|------|
| Nginx 负载均衡 | 2台 1核2G ECS，Keepalived 主备 | 前端静态 + API 反向代理 |
| Node.js API 集群 | 4台 2核4G ECS，PM2 cluster 模式 | 每实例 2 worker，共 8 worker |
| MySQL RDS | 4核8G 高可用版，1主+2只读副本 | 写主读从，自动故障切换 |
| Redis | 2G 内存，Sentinel 3节点 | 会话、缓存、BullMQ |
| OSS | 标准存储，预估 50GB | 故障照片、维修报告、资质证书 |
| CDN | 全国节点加速 | 管理端静态资源 + 小程序静态资源 |
| Sentry | SaaS 版 Team Plan 或自建 | 错误捕获与链路追踪 |

### 6.2 部署拓扑 / 物理视图（4+1，L2 增强）

```mermaid
flowchart TB
    subgraph userLayer [用户层]
        miniRepair[报修端小程序]
        miniEngineer[工程师端小程序]
        adminBrowser[管理端浏览器]
    end

    subgraph edgeLayer [边缘层]
        cdn[CDN<br/>阿里云/腾讯云全国节点]
    end

    subgraph lbLayer [接入层]
        nginx1[Nginx-1<br/>1核2G 主]
        nginx2[Nginx-2<br/>1核2G 备]
        keepalived[Keepalived VIP]
    end

    subgraph appLayer [应用层]
        node1[Node.js-1<br/>2核4G PM2 x2]
        node2[Node.js-2<br/>2核4G PM2 x2]
        node3[Node.js-3<br/>2核4G PM2 x2]
        node4[Node.js-4<br/>2核4G PM2 x2]
    end

    subgraph dataLayer [数据层]
        mysqlPri[(MySQL Primary<br/>4核8G)]
        mysqlRep1[(MySQL Replica-1<br/>4核8G)]
        mysqlRep2[(MySQL Replica-2<br/>4核8G)]
        redisSentinel1[(Redis Sentinel-1)]
        redisSentinel2[(Redis Sentinel-2)]
        redisSentinel3[(Redis Sentinel-3)]
        redisMaster[(Redis Master<br/>2G)]
        redisSlave[(Redis Slave<br/>2G)]
    end

    subgraph storageLayer [存储层]
        oss[(OSS 对象存储<br/>故障照片/维修报告)]
    end

    subgraph obsLayer [观测层]
        sentry[Sentry<br/>错误追踪]
        grafana[Grafana<br/>指标看板]
        alertWebhook[钉钉/企微<br/>告警WebHook]
    end

    miniRepair --> cdn
    miniEngineer --> cdn
    adminBrowser --> cdn
    cdn --> keepalived
    keepalived --> nginx1
    keepalived --> nginx2
    nginx1 --> node1
    nginx1 --> node2
    nginx2 --> node3
    nginx2 --> node4
    node1 --> mysqlPri
    node2 --> mysqlPri
    node3 --> mysqlPri
    node4 --> mysqlPri
    mysqlPri --> mysqlRep1
    mysqlPri --> mysqlRep2
    node1 --> redisMaster
    node2 --> redisMaster
    redisMaster --> redisSlave
    redisSentinel1 --> redisMaster
    redisSentinel2 --> redisMaster
    redisSentinel3 --> redisMaster
    node1 --> oss
    node1 --> sentry
    sentry --> alertWebhook
    grafana --> alertWebhook
```

**升级路径与触发阈值**：

| 当前档位 | 目标档位 | 触发条件 | 关键动作 |
|---------|---------|---------|---------|
| L0 入门 | L1 标准 | 日工单 >50 或 QPS >10 | 增加 Redis 缓存、幂等键、错误分级 |
| L1 标准 | L2 增强 | 日工单 >300 或 QPS >50 或 P95 >500ms | 扩至 4 节点集群、MySQL 主从、Redis Sentinel |
| L2 增强 | L3 企业 | 跨省运营 或 医院 >500 或 监管合规要求 | K8s 编排、多租户隔离、跨区容灾、审计中心 |

### 6.3 可观测性与埋点方案

| 维度 | 采集来源 | 指标样例 | 说明 |
|------|------|------|------|
| 前端埋点（小程序） | wx.reportAnalytics + 自定义事件 | 报修提交转化率、扫码报修占比、页面停留时长 | 用户行为漏斗与转化分析 |
| 后端埋点 | Midway.js Logger + 自定义中间件 | QPS、P95 延迟、接口错误率、派单耗时 | API 性能与业务指标 |
| 错误捕获 | Sentry SDK（小程序 + Node.js） | JS 异常、未捕获 Promise 拒绝、接口 5xx | 统一错误聚合、堆栈追踪、影响用户数 |
| 链路追踪 | traceId 中间件（请求ID贯穿前后端） | 慢请求链路、数据库瓶颈节点 | 支撑故障定位，P95 >500ms 自动采样 |
| 业务指标 | BullMQ 队列 + MySQL 统计 | 工单响应时间中位数、工程师接单率、超时率 | 运营决策与 SLA 监控 |
| 告警通道 | 钉钉 / 企业微信 WebHook | 接口错误率 >1%、P95 >800ms、队列积压 >100 | 分级告警：P0 电话 + 短信，P1 钉钉群，P2 邮件 |

**SLA 目标**：

| 指标 | 目标值 |
|------|--------|
| 可用性 | 99.9%（月宕机 <43 分钟） |
| P95 延迟 | <500ms |
| 接口错误率 | <0.1% |
| 工单推送延迟 | <3 秒 |
| 故障恢复时间（MTTR） | <30 分钟 |

### 6.4 异常数据保全与恢复策略

| 策略项 | 默认要求 | 说明 |
|------|------|------|
| 错误保全字段 | `traceId`、hospitalId、engineerId、接口路径、脱敏参数快照 | 工单相关操作额外保存 orderNo |
| 自动恢复 | 重试（BullMQ 3次指数退避）、熔断（连续失败 >5 次）、降级（地图 API 失败时按缓存距离派单）、限流（令牌桶 200 req/s） | 降低故障扩散，保障核心派单链路 |
| 人工接管 | P0 级告警 5 分钟内响应，值班工程师电话通知，手动回滚支持 | 自动策略失效时兜底 |
| 演练频率 | 每月一次故障注入（MySQL 主库切换、Redis 节点摘除） | 验证恢复链路有效性 |

### 6.5 容量与稳定性阈值

| 指标 | 预警阈值 | 处理动作 |
|------|-----------------|---------|
| 接口错误率 | > 0.5% 持续 3 分钟 | 钉钉告警 + 自动降级非核心接口 |
| P95 延迟 | > 500ms 持续 5 分钟 | 触发 PM2 扩容 worker、检查慢 SQL |
| Redis 命中率 | < 90% | 检查热 key 分布，调整 TTL 策略 |
| BullMQ 队列积压 | 待处理任务 >200 持续 10 分钟 | 增加消费者并发数，必要时限流入口 |
| MySQL 主库 CPU | > 80% 持续 10 分钟 | 读请求切从库，检查慢查询并优化 |
| 节点健康（PM2） | 连续 restart >3 次/5 分钟 | 自动摘除节点，触发钉钉 P0 告警 |
| OSS 上传失败率 | > 5% | 切换备用 Region 或降级为本地暂存 |
| 磁盘使用率 | > 85% | 触发日志归档与历史工单冷存 |

### 6.6 分级能力矩阵（负载/稳定性/数据库安全/合规）

| 档位 | 负载能力 | 稳定性能力 | 数据库安全 | 合规能力 |
|------|---------|-----------|-----------|---------|
| L0 入门 | 单点部署，日工单 <50 | 基础日志 + 人工恢复 | 最小权限 + 日备份 | 可选 |
| L1 标准 | 增强单点 + Redis 缓存，日工单 <300 | Sentry 错误分级 + 重试降级 | MySQL TLS + 脱敏导出 | 基础内审 |
| L2 增强 | 4节点集群 + 主从读写分离，日工单 <2,000 | 熔断/降级/月度恢复演练 | AES-256 敏感字段加密 + SQL 审计 | 审计闭环，可追溯 |
| L3 企业 | 多租户 + 跨区多活，日工单 >2,000 | 错误预算 + 金丝雀发布 | 行列级权限 + KMS + 跨区容灾 | 医疗监管合规 |

### 6.7 数据库安全选项（与分级联动）

| 维度 | L0 | L1 | L2 | L3 |
|------|----|----|----|----|
| 权限模型 | 最小权限（app 账号仅读写 medfix_ 业务表） | 读写分离账号（主库写账号 + 从库只读账号） | 审批流（DDL 变更需审批） | 行列级权限（按医院隔离数据） |
| 加密策略 | 可选 TLS | 强制 MySQL TLS 连接 | AES-256 加密手机号、身份证号、银行卡号 | 字段加密 + 阿里云 KMS 托管密钥 |
| 审计日志 | 登录/DDL 记录 | 关键 DML（工单状态变更、结算操作） | 审计联动告警（异常批量删除触发 P0） | 防篡改留存（写入一次性存储） |
| 备份恢复 | 每日全量备份，RPO=24h | 每日全量 + binlog 增量，RPO=1h，RTO=4h | 3-2-1 备份策略（3份/2种介质/1份异地），月度恢复演练 | 跨区只读副本 + 秒级 RPO |

### 6.8 问卷选型与模板入口

- 问卷与评分：`阶段2-3客户问卷与方案选择模板.template.md`
- 方案对比矩阵：`阶段2-3方案选择矩阵模板.template.md`
- 门禁检查：`阶段2-3流程门禁检查单模板.template.md`
- 报价映射：`阶段2-3报价与工期映射模板.template.md`
- 数据库安全：`阶段2-3数据库安全分级模板.template.md`

### 6.9 默认推荐规则（环境 + 项目特征驱动）

| 输入维度 | 当前值 | 对推荐的影响 |
|------|------|------|
| 部署环境 | 阿里云单区域（华东2） | 优先 R3 云原生弹性，无需跨区 |
| 项目类型 | 交易型 + 实时交互型（工单+位置） | 核心链路需低延迟，优先集群 + 异步解耦 |
| 负载目标 | L2，QPS 50–100，P95 <500ms | R3 可覆盖，R1/R2 存在瓶颈风险 |
| 合规等级 | 审计增强（医疗设备维修记录需留痕） | 需 SQL 审计 + 操作日志，R3 满足 |
| 团队能力 | 中等（熟悉 PM2，Docker 经验有限） | PM2 Cluster 优先于 K8s，降低运维门槛 |

**推荐输出**：

| 推荐顺位 | 路线ID | 推荐理由 | 命中条件 | 不适用条件 | 升级触发点 |
|------|------|------|------|------|------|
| 主推荐 | R3 | PM2 Cluster 集群 + MySQL 主从 + Redis Sentinel，兼顾性能与运维成本 | 300–500 医院、日工单 1,000+、审计增强 | 跨省多租户、强监管需 R4 | 医院 >500 或跨省运营 |
| 次推荐 | R2 | 服务拆分作为渐进过渡方案，试点期可快速启动 | 试点期 <200 医院、预算有限 | 日工单 >500 后需尽快升级至 R3 | QPS >50 或 P95 >500ms |

### 6.10 SLI/SLO 与错误预算门禁

| SLI 指标 | 口径定义 | SLO 目标 | 预警阈值 | 严重阈值 | 门禁动作 |
|------|------|------|------|------|------|
| 可用性 | 成功请求(2xx+3xx) / 总请求 | 99.9% | 99.5% | 99.0% | 禁止继续放量，冻结发布 |
| 延迟 | P95 响应时延 | 300ms | 500ms | 800ms | 扩容 worker / 热点 SQL 隔离 |
| 错误率 | 5xx / 总请求 | <0.1% | 0.5% | 1% | 自动降级非核心接口，触发回滚 |
| 派单延迟 | 工单创建到派单完成耗时 P95 | <30s | 60s | 120s | 增加派单消费者并发数 |
| 队列健康 | BullMQ 待处理任务积压量 | <50 | 100 | 200 | 扩消费者 / 限流入口 |
| 缓存命中率 | Redis GET 命中 / 总 GET | >95% | 90% | 85% | 检查热 key，调整缓存策略 |

| 发布阶段 | 默认流量比例 | 通过条件 | 回滚条件 |
|------|------|------|------|
| 金丝雀一阶段 | 5%（1 个 PM2 worker） | SLI 无明显退化，观察 15 分钟 | 错误率 >0.5% 或 P95 >500ms |
| 金丝雀二阶段 | 25%（2 个 PM2 worker） | 连续 30 分钟观察窗口达标 | 任一核心 SLI 越线 |
| 全量发布 | 100% | 阶段二通过且错误预算可用 | 回滚开关触发（钉钉一键回滚） |

### 6.11 支付安全与高并发支付

| 维度 | 默认要求 | 备注 |
|------|------|------|
| 状态机 | `INIT -> PAYING -> SUCCESS/FAIL/CLOSED` | 工单结算专用，禁止逆向流转 |
| 支付幂等 | `orderNo + payAttemptNo` 唯一索引 | 重复请求返回同一结果 |
| 回调安全 | 微信支付签名验证 + 时间戳 + nonce + 白名单 IP | 防重放与伪造 |
| 金额一致性 | 工单报价金额 = 支付下单金额 = 回调金额 = 入账金额 | 不一致进入差错处理队列 |
| 对账 | 微信支付账单 / 平台订单 / 工程师结算单三方日对账 | 每日凌晨 T+1 自动对账，差异生成工单 |
| 风控 | 同一工程师频控（每日结算 ≤20 笔） + 大额人工审核（单笔 >¥5,000） | 降低刷单与异常结算风险 |
| 退款 | refundNo 幂等 + 累计退款 ≤ 原订单金额 | 退款需管理员审批 |
| 分账 | 平台抽佣 10–15% → 工程师结算 | T+7 自动结算至工程师微信钱包 |

### 6.12 模板入口（治理与支付）

- `阶段2-3高可用治理矩阵模板.template.md`：高可用六张矩阵汇总。
- `阶段2-3支付安全与高并发支付问答模板.template.md`：支付场景澄清问答。
- `阶段2-3高负载与稳定性填写模板.template.md`：基础治理策略与阈值。

---

## 7. 外部服务集成汇总

| 服务 | 服务商 | 用途 | 月成本估算 |
|------|--------|------|-----------|
| 微信小程序 | 腾讯 | 用户入口（报修端 + 工程师端） | 免费 |
| 微信订阅消息 | 腾讯 | 工单状态推送通知 | 免费（配额限制） |
| 微信支付 | 腾讯 | 维修费结算与分账 | 0.6% 手续费 |
| 地图 API | 腾讯地图 | 工程师定位、智能派单、路线规划 | ~¥500/月 |
| 短信 | 阿里云 SMS | 验证码、紧急告警、工单超时通知 | ~¥200/月 |
| 对象存储 | 阿里云 OSS | 故障照片、维修报告、资质证书 | ~¥100/月 |
| 云服务器 | 阿里云 ECS | API 集群 4 节点 | ~¥2,000/月 |
| 数据库 | 阿里云 RDS MySQL | 1 主 2 从高可用 | ~¥800/月 |
| 缓存 | 阿里云 Redis | Sentinel 模式 2G | ~¥300/月 |
| CDN | 阿里云 CDN | 管理端 + 小程序静态资源加速 | ~¥100/月 |
| SSL 证书 | Let's Encrypt | HTTPS 加密传输 | 免费 |
| 错误追踪 | Sentry (SaaS) | 前后端异常聚合与告警 | ~¥100/月（Team Plan） |

**L2 增强档位月度总成本**：~¥4,100（不含微信支付手续费）

---

## 8. 性能与容量规划

### 8.1 业务规模假设（省级覆盖）

| 维度 | 数值 | 说明 |
|------|------|------|
| 覆盖医院数 | 300–500 家 | 含三甲、二甲、社区卫生中心 |
| 注册工程师 | 500–1,000 人 | 持证维修工程师，覆盖全省地市 |
| 设备台账 | 5–10 万台 | CT、MRI、超声、呼吸机、监护仪等 |
| 日均工单 | 800–1,500 单 | 含报修、维保、巡检类工单 |
| 峰值工单 | 3,000 单/日 | 节假日后设备集中报修 |
| 月活用户（MAU） | 5,000–8,000 | 报修人员 + 工程师 + 管理员 |

### 8.2 接口性能目标

| 接口类别 | QPS 目标 | P95 延迟 | P99 延迟 | 说明 |
|---------|---------|---------|---------|------|
| 用户登录/鉴权 | 30 | <200ms | <500ms | Redis 缓存 session |
| 工单创建 | 20 | <300ms | <600ms | 写主库 + 异步推送 |
| 工单列表查询 | 50 | <200ms | <500ms | 读从库 + Redis 缓存 |
| 智能派单 | 10 | <500ms | <1,000ms | 地图 API + 距离计算 |
| 工程师位置上报 | 100 | <100ms | <200ms | Redis GEO 写入 |
| 文件上传（OSS 直传） | 20 | <1,000ms | <2,000ms | STS 临时凭证 + 直传 |
| 管理端报表 | 5 | <1,000ms | <2,000ms | 读从库 + 结果缓存 |

### 8.3 数据存储容量估算

| 数据类型 | 年增量 | 单条大小 | 年存储量 | 保留策略 |
|---------|--------|---------|---------|---------|
| 工单主表 | 36–55 万条 | 2KB | ~1GB | 热存 90 天，归档至 archive 表 |
| 工单日志（状态变更） | 200–300 万条 | 0.5KB | ~1.5GB | 热存 180 天，归档 |
| 故障/维修照片 | 150–250 万张 | 500KB | ~1TB | OSS 存储，180 天后转低频 |
| 工程师位置轨迹 | 5,000–8,000 万条 | 0.1KB | ~5GB | Redis GEO 实时 + MySQL 日汇总 |
| 配件出入库记录 | 50–80 万条 | 1KB | ~0.5GB | 永久保留 |
| 操作审计日志 | 100–150 万条 | 1KB | ~1GB | 永久保留（合规要求） |

### 8.4 并发与连接池规划

| 资源 | 配置值 | 说明 |
|------|--------|------|
| MySQL 最大连接数 | 200（主库）/ 100（每从库） | 4 Node 实例 × 单实例 50 连接 |
| Redis 最大连接数 | 500 | 4 Node 实例 × 单实例 100 连接 + BullMQ |
| PM2 Worker 数 | 8（4 节点 × 2 worker/节点） | 单 worker 处理约 50 并发 |
| Nginx upstream | 权重轮询，max_fails=3 | 失败 3 次自动摘除节点 30 秒 |
| BullMQ 并发消费者 | 每节点 5 并发 × 4 节点 = 20 | 工单派单、通知推送、超时检测 |

### 8.5 缓存策略

| 缓存 Key 模式 | TTL | 更新策略 | 说明 |
|--------------|-----|---------|------|
| `medfix:session:{userId}` | 7 天 | 登录时写入，登出时删除 | 用户会话 |
| `medfix:order:detail:{orderId}` | 10 分钟 | 写后失效（状态变更时 DEL） | 工单详情 |
| `medfix:order:list:{hospitalId}:{page}` | 5 分钟 | 写后失效 | 医院工单列表 |
| `medfix:engineer:geo` | 实时 | GPS 上报时 GEOADD | 工程师位置（Redis GEO） |
| `medfix:engineer:online:{engineerId}` | 5 分钟 | 心跳续期 | 工程师在线状态 |
| `medfix:dispatch:lock:{orderId}` | 30 秒 | SETNX 分布式锁 | 防止工单重复派发 |
| `medfix:stats:daily:{date}` | 24 小时 | 凌晨定时任务生成 | 每日统计快照 |

---

**文档版本**：v1.0
**创建日期**：2026-04-16
**最后更新**：2026-04-16
