Skip to content

jerryxiaosa/ems4j

Repository files navigation

EMS4J

Java Spring Boot License

English

EMS4J是一款基于Spring Boot多模块架构的能源管理系统,支持预付费和能耗分析两种模式。系统具有远程设备的控制能力,支持按需、合并、包月等多种计费方式。支持微信支付与线下支付。提供尖峰平谷计量、阶梯电价、账户管理与财务核算等完整功能,兼容多协议设备接入。代码结构清晰,易于二次开发与功能扩展。

动机

在AI能快速生成代码的今天,单纯“能运行”的代码正在贬值,而代码的品味与设计愈发珍贵。这种品味并非一蹴而就,它来自长期的架构锤炼与深刻的设计思考。

本项目正是这样一次实践:我对原有生产代码的架构进行了重构与精炼——通过清晰的层次划分和彻底的模块解耦,使核心逻辑更纯粹、更适应多变需求。

代码中融入了一些设计巧思,希望它能带来启发。正如“授人以鱼,不如授人以渔”,我更愿意分享的,是其中蕴含的设计思维与架构之道。

如果本项目对你有所帮助,欢迎点个 Star ⭐️ 作为支持,我将深感荣幸。

功能特性

  • 多协议设备接入
  • 计费模式(按需付费 / 合并付费 / 包月付费)
  • 计量计费(尖峰平谷 / 阶梯电价)
  • 账户管理(开户 / 销户 / 充值)
  • 远程控制(合闸 / 分闸 / 复费率设置)
  • 财务核算(账单 / 流水 / 对账)

系统截图

账户管理

页面 截图
账户列表 账户列表
账户详情 账户详情
销户结算 销户结算

设备管理

页面 截图
电表列表 电表列表
电表详情 电表详情
网关列表 网关列表
网关详情 网关详情
设备品类 设备品类

告警与订单

页面 截图
预警方案列表 预警方案列表
预警方案详情 预警方案详情
订单列表 订单列表
订单创建 订单创建

计费配置

页面 截图
电价方案列表 电价方案列表
电价方案详情 电价方案详情
尖峰平谷时段 尖峰平谷时段

预付费模式说明

系统支持按需、合并与包月三种计费模式。其中按需与合并模式都是根据实际的使用对余额扣费。按需模式每个水电表独立核算。合并模式是把金额充值在一个水电表上,其他的表都用这个金额。包月按周期固定金额结算。

典型流程为开户后进行充值,扣费并持续更新余额,余额不足或触达预警阈值时可联动通知与远程断闸。全量销户时会进行清算并生成结算订单,产生退费或补缴。

环境要求

组件 版本 必需
JDK 17+
Maven 3.8+
MySQL 8.0+
Redis 6.0+
RabbitMQ 4.1+
Node.js 18.18+ 前端开发/构建需要
pnpm 10.32+ 前端开发/构建需要

快速开始

先克隆项目:

git clone <repository-url>
cd ems4j

方式 A:Docker 本地开发模式

后端依赖中间件可使用 Docker Compose 拉起:

cp deploy/env.example .env
docker compose -f deploy/compose/docker-compose.infra.yml up -d

然后分别启动后端和前端:

# 后端
mvn clean package -DskipTests
java -jar ems-bootstrap/target/ems-0.1.0.jar --spring.profiles.active=dev

# 前端
cd frontend-web
pnpm install
pnpm dev

默认访问地址:

  • 后端 API 文档:http://127.0.0.1:8080/doc.html
  • 前端页面:http://127.0.0.1:4173

方式 B:Docker 全量运行

cp deploy/env.example .env
### 改模式运行模式使用:`ems-bootstrap/src/main/resources/application-docker.yml`
docker compose -f deploy/compose/docker-compose.full.yml up -d --build

说明:

  • deploy/compose/docker-compose.infra.yml:只启动 MySQL / Redis / RabbitMQ
  • deploy/compose/docker-compose.full.yml:同时启动 backend / frontend / middleware
  • RabbitMQ 镜像已集成 x-delayed-message 插件

方式 C:手工搭建环境

### 导入数据库
mysql -u <user> -p <db> < sql/ems.sql

### 安装RabbitMQ x-delayed-message 插件
### @see https://github.com/rabbitmq/rabbitmq-delayed-message-exchange

编辑 ems-bootstrap/src/main/resources/application-dev.yml

  • 数据库连接(spring.datasource
  • Redis 连接(spring.data.redis
  • RabbitMQ 连接(spring.rabbitmq,可选)

前端代理目标默认是 http://127.0.0.1:8080,可通过环境变量覆盖:

cd frontend-web
VITE_PROXY_TARGET=http://127.0.0.1:18080 pnpm dev

构建并启动:

mvn clean package -DskipTests
java -jar ems-bootstrap/target/ems-0.1.0.jar --spring.profiles.active=dev

构建与测试

# 全量构建(跳过测试)
mvn clean install -DskipTests

# 运行测试
mvn test

# 模块级构建/测试(示例)
mvn -pl ems-business/ems-business-device -am test

# 前端
cd frontend-web
pnpm typecheck
pnpm test:unit
pnpm test:unit:coverage
pnpm test:e2e

技术栈

类别 技术
语言/框架 Java 17 / Spring Boot 3.5
持久层 MyBatis-Plus / MySQL 8.0
缓存 Redis / Redisson
消息队列 RabbitMQ(可选)
IoT 接入 Netty
认证 Sa-Token + JWT
API 文档 Knife4j / SpringDoc OpenAPI

模块分层架构

+-------------------------------+          +-------------------------------+
|        ems-bootstrap          |          |           ems-iot             |
|       (Web Service Entry)     |          |      (IoT Service Standalone) |
+-------------------------------+          +-------------------------------+
               |                                          |
   +-----------+-----------+-----------+                  |
   |           |           |           |                  |
+--v-----+ +---v----+ +----v-------+   |                  |
| ems-web| | ems-mq | |ems-schedule|   |                  |
|(HTTP   | | (Msg)  | |  (Schedule)|   |                  |
| API)   | |        | |            |   |                  |
+--+-----+ +---+----+ +-----+------+   |                  |
   |           |            |          |                  |
   +-----------+------------+----------+------------------+
               |
+------------------------------------------------------------------+
|                        ems-business                               |
|    +------------+  +------------+  +------------+  +------------+ |
|    |   device   |  |  account   |  |  billing   |  |    order   | |
|    | (Device Mgmt)| | (Account   |  | (Balance & |  | (Trade &   | |
|    |            |  |  Mgmt)     |  |  Consume)  |  |  Payment)  | |
|    +------------+  +------------+  +------------+  +------------+ |
|    |    lease   |  |    plan    |  | aggregation|                 |
|    | (Owner &   |  | (Pricing   |  | (Cross-    |                 |
|    |  Space)    |  |  Plan)     |  | domain)    |                 |
|    +------------+  +------------+  +------------+                 |
+------------------------------------------------------------------+
               |
   +-----------+-----------+
   |                       |
+--v-------------------+  +v-----------------------+
|    ems-foundation    |  |    ems-components      |
| +------+ +---------+ |  | +----------+ +------+  |
| | user | |integrat.| |  | |datasource| | lock |  |
| +------+ +---------+ |  | +----------+ +------+  |
| +------+ +---------+ |  | +---------+ +-------+  |
| | space| | system  | |  | | context | | redis |  |
| +------+ +---------+ |  | +---------+ +-------+  |
| +------+ +---------+ |  +------------------------+
| | org  | | notifi. | |
| +------+ +---------+ |
+----------------------+
               |
       +-------v-------+
       |  ems-common   |
       | (Common Utils)|
       +---------------+

说明:

  • ems-web 可直接依赖 ems-business 与 ems-foundation(用户/组织/空间/系统等基础域)。
  • ems-web 仅依赖 service/dto,避免直接引用 repository/entity/mapper。
  • ems-foundation 不反向依赖 ems-business/ems-web,保持基础域可复用。

数据流向

+----------+    命令下发    +----------+    协议转换    +----------+
|  ems-web |-------------->|  ems-iot |-------------->|   设备    |
+----------+               +----------+               +----------+
     ^                          |                          |
     |                          | 数据上报                  |
     |                          v                          |
     |                   +----------+                      |
     +-------------------|  业务层   |<---------------------+
        业务结果          +----------+
                              |
                              v
                        +----------+
                        |   MySQL  |
                        +----------+

模块说明

模块 职责
ems-bootstrap 应用启动入口(Spring Boot)
ems-web HTTP 接口层
ems-business-device 电表、网关、设备档案管理
ems-business-account 开户、销户、余额、充值
ems-business-billing 余额、抄表消费、补正、账务流水
ems-business-order 订单创建、支付回调、订单查询与完成处理
ems-business-lease 主体与空间租赁关系、租赁查询与退租校验
ems-business-plan 计费方案、费率、尖峰平谷时段
ems-business-aggregation 跨域读聚合与应用层编排
ems-foundation-user 用户认证、权限、角色
ems-foundation-organization 多租户、组织架构
ems-foundation-space 空间/区域管理
ems-foundation-system 系统配置
ems-foundation-integration 第三方平台对接
ems-components-* 通用组件(数据源/锁/上下文)
ems-mq-* 消息基础设施 API(ems-mq-api)与业务消息应用层实现(ems-mq-rabbitmq)
ems-iot Netty 设备接入、协议解析
ems-schedule 定时任务
frontend-web NEW Vue 3 + TypeScript 前端管理台,含 Vitest 单测与 Playwright 冒烟回归
deploy NEW TRY IT Docker Compose、Dockerfile、初始化 SQL 与环境示例,提供本地基础设施和全量部署编排

说明:

  • ems-mq-api 提供消息契约与基础服务接口(基础设施层)。
  • ems-mq-rabbitmq 属于业务消息应用层实现,承载业务消息监听与编排。
  • 前端详细说明见 frontend-web/README.md

已支持设备

厂商 类型
安科瑞 (Acrel) 电表 / 网关
斯菲尔 (Sfere) 电表
仪歌 (Yige) 电表
燕赵 (Yke) 电表

IoT 平台对接

对接方式可分为两类:

  1. 设备直连(自有平台)
  1. 第三方 IoT 平台接入
  • 建议在 ems-foundation/integration 侧实现平台对接与数据同步,再与 ems-iot/业务域协同。
  • 推荐参考:

详细平台集成解决方案请参见:

开发文档

文档 说明
开发实践指南 代码风格、命名约定及开发实践
业务模块文档 业务模块文档(设备、账户、财务、方案)
基础模块文档 基础模块文档(用户、组织、空间、系统、集成)
IoT 模块文档 IoT 模块文档,用于设备接入和协议集成
测试指南 单元测试和集成测试标准及最佳实践

许可证

本项目采用 MIT 许可证,详见 LICENSE

联系方式

  • 添加我的微信,请注名“ems4j”:

    微信二维码

About

EMS4J是一款基于Spring Boot多模块架构的能源管理系统,支持预付费和能耗分析两种模式。系统具有远程设备的控制能力,支持按需、合并、包月等多种计费方式。支持微信支付与线下支付。提供尖峰平谷计量、阶梯电价、账户管理与财务核算等完整功能,兼容多协议设备接入。代码结构清晰,易于二次开发与功能扩展。

Topics

Resources

License

Stars

Watchers

Forks

Contributors