diff --git a/系统设计/xintong-architecture-full.html b/系统设计/xintong-architecture-full.html index 2455399..10b148f 100644 --- a/系统设计/xintong-architecture-full.html +++ b/系统设计/xintong-architecture-full.html @@ -19,6 +19,7 @@ --c-blue:#1d6fff; --c-blue-bg:#e8f1ff; --c-blue-d:#0c4dd1; --c-green:#0d9488; --c-green-bg:#e6f7f5; --c-green-d:#0a7068; --c-purple:#7c3aed; --c-purple-bg:#f0eaff; --c-purple-d:#5b21b6; + --c-teal:#0f766e; --c-teal-bg:#ccfbf1; --c-teal-d:#0d9488; --c-amber:#e0852b; --c-amber-bg:#fef3e2; --c-amber-d:#b5681a; --c-slate:#475569; --c-slate-bg:#f1f5f9; --c-slate-d:#334155; --c-red:#dc2626; --c-red-bg:#fee2e2; @@ -78,8 +79,9 @@ section{padding:40px 0} .dg-block ul li::before{content:"·";font-weight:700;margin-right:4px} .dg-blue{border-color:var(--c-blue);background:var(--c-blue-bg)} .dg-blue .di{background:var(--c-blue)} .dg-blue .dx{color:var(--c-blue-d)} .dg-blue .dt{color:var(--c-blue-d)} -.dg-green{border-color:var(--c-green);background:var(--c-green-bg)} .dg-green .di{background:var(--c-green)} .dg-green .dx{color:var(--c-green-d)} .dg-green .dt{color:var(--c-green-d)} .dg-purple{border-color:var(--c-purple);background:var(--c-purple-bg)} .dg-purple .di{background:var(--c-purple)} .dg-purple .dx{color:var(--c-purple-d)} .dg-purple .dt{color:var(--c-purple-d)} +.dg-teal{border-color:var(--c-teal);background:var(--c-teal-bg)} .dg-teal .di{background:var(--c-teal)} .dg-teal .dx{color:var(--c-teal-d)} .dg-teal .dt{color:var(--c-teal-d)} +.dg-green{border-color:var(--c-green);background:var(--c-green-bg)} .dg-green .di{background:var(--c-green)} .dg-green .dx{color:var(--c-green-d)} .dg-green .dt{color:var(--c-green-d)} .dg-amber{border-color:var(--c-amber);background:var(--c-amber-bg)} .dg-amber .di{background:var(--c-amber)} .dg-amber .dx{color:var(--c-amber-d)} .dg-amber .dt{color:var(--c-amber-d)} .dg-slate{border-color:var(--c-slate);background:var(--c-slate-bg)} .dg-slate .di{background:var(--c-slate)} .dg-slate .dx{color:var(--c-slate-d)} .dg-slate .dt{color:var(--c-slate-d)} .dg-ext{border-style:dashed;border-width:2px} @@ -254,10 +256,11 @@ footer .ft{font-size:13px;color:var(--muted);text-align:center}
JWT 双 Token
多端统一登录态
/admin · /worker
/customer 分组路由
/admin · /ops · /worker
/customer 分组路由
Interceptor 注入过滤
给什么数据看什么
rate-limiter
操作审计 winston
业务数据(customer_id 逻辑隔离)
用电采集数据(按月分区)
TypeORM + 声明式分区
JWT 会话 Token
数据字典/热点配置
BullMQ 队列底层
取证照片(水印)
合同/验收/方案文件
月度报告文档
取证照片(水印)
合同/验收/方案文件
月度报告文档
国产 · S3 兼容 · Apache 2.0
ICC 拉取数据缓冲
报警事件异步处理
基于 Redis 轻量级
鑫潼内部人员使用:业务员、运营管理员
Vue3 + Ant Design Vue运营管理员使用:审批、配置、报表、系统设置
Vue3 + Ant Design Vue业务员移动办公:客户管理、项目跟进、现场勘察回访
uni-app (iOS / Android)共享电工接单、现场拍照取证、报酬查询
uni-app (iOS / Android)客户查看用电/报警/月报、报修申请、评分
uni-app → 微信小程序设备数据采集平台(厂家后台,非自研)
外部系统 · API 对接设备数据采集平台(厂家后台,非自研)· API 对接
外部系统 · HTTP RESTJWT Token 签发与校验,多端统一登录态
Midway Guard + JWT按端区分路由前缀:/admin · /worker · /customer
Midway Controller 分组按端区分路由前缀:/admin · /ops · /worker · /customer
Midway Controller 分组接口决定可见数据范围,APP/小程序给什么看什么
Guard + Interceptor常规 ERP 并发量,请求日志与操作审计
rate-limiter + winston业务数据(逻辑隔离)+ 用电采集数据(按月分区)
TypeORM + 声明式分区会话 Token、数据字典、热点配置、限流计数
ioredis取证照片、合同/验收/方案电子文件、月度报告
MinIO / 阿里云 OSS取证照片、合同/验收/方案电子文件、月度报告
RustFS(国产 · S3 兼容)ICC 拉取数据缓冲、报警事件异步处理
BullMQ (Redis 队列)① 不直接对接硬件:所有设备数据通过大华 ICC 平台 API 拉取,鑫潼系统只做数据消费方。② 四端共享一套后端:Midway.js 统一提供 /admin、/worker、/customer 三组路由,避免重复开发。③ ICC 内部虽实时推送,但鑫潼侧采用主动拉取,通过定时任务按采集频次拉取,进入 BullMQ 队列缓冲后写入分区表。
+① 不直接对接硬件:所有设备数据通过大华 ICC 平台 API 拉取,鑫潼系统只做数据消费方。② 五端共享一套后端:Midway.js 统一提供 /admin(Web管理台)、/ops(运营APP)、/worker(电工APP)、/customer(小程序)四组路由,避免重复开发。③ 运营方双端同一套账号:运营管理平台(Web)和运营管理 APP(业务员)共用 sys_user 表,通过角色区分权限,共用 RBAC 体系。④ ICC 内部虽实时推送,但鑫潼侧采用主动拉取,通过定时任务按采集频次拉取,进入 BullMQ 队列缓冲后写入分区表。
Midway.jsVue 3 + Ant Design Vueuni-appuni-appuni-appuni-app → 微信小程序PostgreSQLTypeORMRedisBullMQMinIO / 阿里云 OSSRustFS(国产)JWT客户信息(省市县分类)、客户部门、客户访问账号分配
建筑/房间、勘察派单、智电方案、合同、安装、验收、回访
客户录入(省市县)、部门、建筑/房间配置、访问账号分配
勘察派单、方案制定上传、合同登记、安装派单、验收管理、回访
全局数据概览、报警总览、派单总览、待办事项
方案审批、合同审批、派单规则配置、数据字典
报警派单(从 ICC 拉取报警)、报修派单、维保派单、评分管理
设备列表、线路分配(部门/房间)、设备状态、报警查询
多维度用电统计、月度报告生成下载、共享电工报酬统计
用户/角色/菜单权限配置、数据字典、日志审计
用户/角色/菜单权限配置、员工管理、日志审计
客户档案查看、联系人管理、客户项目列表(和后台功能一致,移动端适配)
项目跟进、勘察任务、方案查看、合同查看、验收与回访
负责客户的派单进度跟踪、报警处理进度、报修处理进度
现场拍照记录、巡查日志提交、问题上报
派单提醒、报警推送、客户消息、系统通知
个人信息、修改密码、负责客户统计、业绩查看
现阶段权限粗放管理:运营后台采用 RBAC 菜单级权限(角色绑定菜单/按钮);APP 和小程序的数据权限由接口定义——接口返回什么数据,端上就只能看到什么数据,不在端上做复杂权限判断。
+现阶段权限粗放管理:运营方双端(Web + APP)共用 sys_user 表,采用 RBAC 菜单级权限(角色绑定菜单/按钮);共享电工 APP 和客户小程序的数据权限由接口定义——接口返回什么数据,端上就只能看到什么数据,不在端上做复杂权限判断。
运营后台:账号密码
APP:账号密码
小程序:微信 openid
运营方双端:账号密码(sys_user)
电工APP:账号密码(worker)
小程序:微信 openid
Token 携带:userId、role、customerId
双 Token 刷新
Token 携带:userId、user_type、role、customerId
双 Token 刷新
RBAC:角色 → 菜单/按钮
后台根据角色渲染菜单
运营方双端:RBAC 角色 → 菜单
电工APP/小程序:固定功能页
接口根据 Token 身份过滤数据
APP/小程序给什么看什么
接口根据 user_type + role 过滤数据
给什么看什么
| 角色 | 使用端 | 菜单权限(RBAC) | 接口数据权限 | |
|---|---|---|---|---|
| 角色 | 使用端 | 账号表 | 菜单权限(RBAC) | 接口数据权限 |
| 运营管理员 | 运营管理平台 | 全部菜单:客户/项目/派单/设备/报表/系统管理 | 可查看所有客户数据,全量派单管理 | |
| 业务员 | 运营管理平台 | 客户/项目/方案/合同/回访(按需配置) | 仅自己负责的客户(user_id 过滤) | |
| 共享电工 | 共享电工 APP | —(APP 无菜单权限,固定功能) | 仅分配给自己的派单、个人报酬明细 | |
| 客户 | 微信小程序 | —(小程序固定功能页) | 仅本客户设备/用电/报警/月报/报修记录 | |
| 运营管理员 | 运营管理平台(Web) | sys_user | 全部菜单:工作台/审批/派单/设备/报表/系统管理 | 全量数据,所有客户和派单 |
| 业务员 | 运营管理平台(Web)+ 运营管理 APP | sys_user | 客户/项目/派单查看/报表查看(按需配置) | 仅自己负责的客户(salesman_id 过滤) |
| 共享电工 | 共享电工 APP | worker | —(APP 固定功能页) | 仅分配给自己的派单、个人报酬明细 |
| 客户 | 微信小程序 | customer_account | —(小程序固定功能页) | 仅本客户设备/用电/报警/月报/报修记录 |
① 共享电工:查询派单接口自动按 worker_id = 当前用户 过滤;报酬接口只返回本人数据。② 客户:查询设备/用电/报警接口自动按 customer_id = 当前客户 过滤;报修只能提交本客户的。③ 业务员:查询客户/项目接口按 salesman_id = 当前用户 过滤(运营管理员不受限)。通过 Midway Interceptor 统一注入过滤条件,避免每个接口手动处理。
① 共享电工:查询派单接口自动按 worker_id = 当前用户 过滤;报酬接口只返回本人数据。② 客户:查询设备/用电/报警接口自动按 customer_id = 当前客户 过滤;报修只能提交本客户的。③ 业务员(运营管理 APP + Web):查询客户/项目/派单接口按 salesman_id = 当前用户 过滤,只能看自己负责的客户数据(运营管理员不受限)。④ 运营方双端共用一套 RBAC:Web 管理台和运营管理 APP 共用 sys_user 表 + 角色体系,菜单权限由后端统一返回,前端/APP 根据返回动态渲染。通过 Midway Interceptor 统一注入过滤条件,避免每个接口手动处理。