From 24d45e48f03338edbb109a6deb0aced64975c7f1 Mon Sep 17 00:00:00 2001 From: yanqs Date: Sun, 14 Apr 2024 17:42:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=AF=8F=E6=97=A5=E6=B5=81=E9=87=8F?= =?UTF-8?q?=E5=86=99=E5=85=A5=EF=BC=9B=E7=99=BB=E5=BD=95=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=B7=AF=E7=94=B1=E5=99=A8=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E8=BF=9E=E6=8E=A5=E8=B7=AF=E7=94=B1=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 19 ++++- .../java/com/bcrjl/miwifi/WebApplication.java | 4 ++ .../miwifi/config/FlywayDbInitializer.java | 45 ++++++++++++ .../miwifi/config/MyBatisPlusConfig.java | 64 +++++++++++++++++ .../miwifi/controller/AuthController.java | 16 +++++ .../java/com/bcrjl/miwifi/job/DeviceJob.java | 31 +++++++++ .../miwifi/mapper/DeviceDayTrafficMapper.java | 14 ++++ .../miwifi/mapper/DeviceDayTrafficMapper.xml | 14 ++++ .../miwifi/model/domain/DeviceDayTraffic.java | 35 ++++++++++ .../service/DeviceDayTrafficService.java | 69 +++++++++++++++++++ src/main/resources/application-mi.yml | 9 ++- src/main/resources/application.yml | 5 +- .../db/migration-sqlite/V1__Base_version.sql | 12 ++++ 13 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/bcrjl/miwifi/config/FlywayDbInitializer.java create mode 100644 src/main/java/com/bcrjl/miwifi/config/MyBatisPlusConfig.java create mode 100644 src/main/java/com/bcrjl/miwifi/job/DeviceJob.java create mode 100644 src/main/java/com/bcrjl/miwifi/mapper/DeviceDayTrafficMapper.java create mode 100644 src/main/java/com/bcrjl/miwifi/mapper/DeviceDayTrafficMapper.xml create mode 100644 src/main/java/com/bcrjl/miwifi/model/domain/DeviceDayTraffic.java create mode 100644 src/main/java/com/bcrjl/miwifi/service/DeviceDayTrafficService.java create mode 100644 src/main/resources/db/migration-sqlite/V1__Base_version.sql diff --git a/pom.xml b/pom.xml index d420823..3365db4 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,7 @@ 1.18.30 5.8.26 + 2.11.0 @@ -61,11 +62,27 @@ sa-token-spring-boot-starter ${sa-token.version} + + + org.xerial + sqlite-jdbc + 3.45.2.0 + + + org.flywaydb + flyway-core + 7.15.0 + + + com.baomidou + mybatis-plus-boot-starter + 3.5.3.1 + commons-io commons-io - 2.11.0 + ${commons.version} diff --git a/src/main/java/com/bcrjl/miwifi/WebApplication.java b/src/main/java/com/bcrjl/miwifi/WebApplication.java index 36b875e..aca84b3 100644 --- a/src/main/java/com/bcrjl/miwifi/WebApplication.java +++ b/src/main/java/com/bcrjl/miwifi/WebApplication.java @@ -1,14 +1,18 @@ package com.bcrjl.miwifi; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; /** * 项目启动类 * * @author yanqs */ +@EnableScheduling @SpringBootApplication +@MapperScan("com.bcrjl.miwifi.mapper") public class WebApplication { public static void main(String[] args) { SpringApplication.run(WebApplication.class, args); diff --git a/src/main/java/com/bcrjl/miwifi/config/FlywayDbInitializer.java b/src/main/java/com/bcrjl/miwifi/config/FlywayDbInitializer.java new file mode 100644 index 0000000..c8b2643 --- /dev/null +++ b/src/main/java/com/bcrjl/miwifi/config/FlywayDbInitializer.java @@ -0,0 +1,45 @@ +package com.bcrjl.miwifi.config; + +import cn.hutool.core.util.StrUtil; +import org.flywaydb.core.Flyway; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.Locale; + +/** + * 数据库初始化 + * + * @author yanqs + */ +@DependsOn("myBatisPlusConfig") +@Configuration +public class FlywayDbInitializer { + @Resource + private DataSource dataSource; + + + /** + * 启动时根据当前数据库类型执行数据库初始化 + */ + @PostConstruct + public void migrateFlyway() { + try { + String databaseProductName = dataSource.getConnection().getMetaData().getDatabaseProductName(); + String dbType = databaseProductName.toLowerCase(Locale.ROOT); + + // 检查当前数据库类型是否支持 + if (!StrUtil.equalsAnyIgnoreCase(dbType, "sqlite")) { + throw new RuntimeException("不支持的数据库类型 [" + dbType + "]"); + } + Flyway load = Flyway.configure().dataSource(dataSource).outOfOrder(true).locations("db/migration-sqlite").load(); + load.migrate(); + } catch (SQLException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/bcrjl/miwifi/config/MyBatisPlusConfig.java b/src/main/java/com/bcrjl/miwifi/config/MyBatisPlusConfig.java new file mode 100644 index 0000000..c0b8fb1 --- /dev/null +++ b/src/main/java/com/bcrjl/miwifi/config/MyBatisPlusConfig.java @@ -0,0 +1,64 @@ +package com.bcrjl.miwifi.config; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.sql.DataSource; +import java.sql.SQLException; + +/** + * mybatis-plus 配置类 + * + * @author yanqs + */ +@Slf4j +@Configuration +public class MyBatisPlusConfig { + @Resource + private DataSource dataSource; + + @Value("${spring.datasource.driver-class-name}") + private String datasourceDriveClassName; + + @Value("${spring.datasource.url}") + private String datasourceUrl; + + /** + * 如果是 sqlite 数据库,自动创建数据库文件所在目录 + */ + @PostConstruct + public void init() { + if (StrUtil.equals(datasourceDriveClassName, "org.sqlite.JDBC")) { + String path = datasourceUrl.replace("jdbc:sqlite:", ""); + String folderPath = FileUtil.getParent(path, 1); + log.info("SQLite 数据库文件所在目录: [{}]", folderPath); + if (!FileUtil.exist(folderPath)) { + FileUtil.mkdir(folderPath); + log.info("检测到 SQLite 数据库文件所在目录不存在, 已自动创建."); + } else { + log.info("检测到 SQLite 数据库文件所在目录已存在, 无需自动创建."); + } + } + } + + /** + * mybatis plus 分页插件配置 + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() throws SQLException { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + String databaseProductName = dataSource.getConnection().getMetaData().getDatabaseProductName(); + DbType dbType = DbType.getDbType(databaseProductName); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(dbType)); + return interceptor; + } +} diff --git a/src/main/java/com/bcrjl/miwifi/controller/AuthController.java b/src/main/java/com/bcrjl/miwifi/controller/AuthController.java index 0eb478e..59d27e9 100644 --- a/src/main/java/com/bcrjl/miwifi/controller/AuthController.java +++ b/src/main/java/com/bcrjl/miwifi/controller/AuthController.java @@ -3,7 +3,9 @@ package com.bcrjl.miwifi.controller; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.crypto.SecureUtil; import com.bcrjl.miwifi.common.response.R; +import com.bcrjl.miwifi.common.util.MiWifiUtil; import com.bcrjl.miwifi.model.param.LoginParam; +import com.bcrjl.miwifi.service.DeviceDayTrafficService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; @@ -11,6 +13,10 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; +import java.util.Map; +import java.util.Objects; + /** * 鉴权服务 * @@ -21,6 +27,11 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/auth") public class AuthController { + @Resource + private DeviceDayTrafficService deviceDayTrafficService; + @Resource + private MiWifiUtil miWifiUtil; + /** * 系统密码 */ @@ -36,7 +47,12 @@ public class AuthController { @PostMapping("/login") public R login(@RequestBody LoginParam param) { if (SecureUtil.md5(PASSWORD).equals(param.getPassword())) { + Map loginInfo = miWifiUtil.getLoginInfo(); + if (Objects.isNull(loginInfo)) { + return R.fail("无法链接路由器信息"); + } StpUtil.login(10001); + deviceDayTrafficService.initTraffic(); return R.data(StpUtil.getTokenInfo()); } else { return R.fail("密码错误:"); diff --git a/src/main/java/com/bcrjl/miwifi/job/DeviceJob.java b/src/main/java/com/bcrjl/miwifi/job/DeviceJob.java new file mode 100644 index 0000000..4a1e1c0 --- /dev/null +++ b/src/main/java/com/bcrjl/miwifi/job/DeviceJob.java @@ -0,0 +1,31 @@ +package com.bcrjl.miwifi.job; + +import com.bcrjl.miwifi.service.DeviceDayTrafficService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 设备任务 + * + * @author yanqs + */ +@Slf4j +@Component +public class DeviceJob { + @Resource + private DeviceDayTrafficService deviceDayTrafficService; + + @Scheduled(cron = "0 0 0 * * ?") + public void writeEverydayDeviceTraffic() { + log.info("每日凌晨执行写入设备流量开始"); + try { + deviceDayTrafficService.writeEverydayDeviceTraffic(); + } catch (Exception e) { + log.error("每日写入数据异常", e); + } + log.info("每日凌晨执行写入设备流量结束"); + } +} diff --git a/src/main/java/com/bcrjl/miwifi/mapper/DeviceDayTrafficMapper.java b/src/main/java/com/bcrjl/miwifi/mapper/DeviceDayTrafficMapper.java new file mode 100644 index 0000000..b914bb8 --- /dev/null +++ b/src/main/java/com/bcrjl/miwifi/mapper/DeviceDayTrafficMapper.java @@ -0,0 +1,14 @@ +package com.bcrjl.miwifi.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.bcrjl.miwifi.model.domain.DeviceDayTraffic; +import org.apache.ibatis.annotations.Mapper; + +/** + * 设备每日统计表 Mapper 接口 + * + * @author yanqs + */ +@Mapper +public interface DeviceDayTrafficMapper extends BaseMapper { +} diff --git a/src/main/java/com/bcrjl/miwifi/mapper/DeviceDayTrafficMapper.xml b/src/main/java/com/bcrjl/miwifi/mapper/DeviceDayTrafficMapper.xml new file mode 100644 index 0000000..1e70e1c --- /dev/null +++ b/src/main/java/com/bcrjl/miwifi/mapper/DeviceDayTrafficMapper.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/main/java/com/bcrjl/miwifi/model/domain/DeviceDayTraffic.java b/src/main/java/com/bcrjl/miwifi/model/domain/DeviceDayTraffic.java new file mode 100644 index 0000000..e63a189 --- /dev/null +++ b/src/main/java/com/bcrjl/miwifi/model/domain/DeviceDayTraffic.java @@ -0,0 +1,35 @@ +package com.bcrjl.miwifi.model.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 设备每日流量统计表 + * + * @author yanqs + */ +@Data +@TableName("device_day_traffic") +public class DeviceDayTraffic implements Serializable { + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField("date") + private String date; + @TableField("ip") + private String ip; + @TableField("mac") + private String mac; + @TableField("device_name") + private String deviceName; + @TableField("upload") + private String upload; + @TableField("download") + private String download; + @TableField("total") + private String total; +} diff --git a/src/main/java/com/bcrjl/miwifi/service/DeviceDayTrafficService.java b/src/main/java/com/bcrjl/miwifi/service/DeviceDayTrafficService.java new file mode 100644 index 0000000..81b561c --- /dev/null +++ b/src/main/java/com/bcrjl/miwifi/service/DeviceDayTrafficService.java @@ -0,0 +1,69 @@ +package com.bcrjl.miwifi.service; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bcrjl.miwifi.common.util.MiWifiUtil; +import com.bcrjl.miwifi.mapper.DeviceDayTrafficMapper; +import com.bcrjl.miwifi.model.domain.DeviceDayTraffic; +import com.bcrjl.miwifi.model.result.StatusResult; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +/** + * 设备每日流量 Service + * + * @author yanqs + */ +@Service +@AllArgsConstructor +public class DeviceDayTrafficService extends ServiceImpl { + + private final MiWifiUtil miWifiUtil; + + /** + * 定时任务写入每日数据 + */ + public void writeEverydayDeviceTraffic() { + dayTraffic(); + } + + /** + * 系统启动初始化数据 + */ + public void initTraffic() { + List list = this.list(); + if (CollUtil.isEmpty(list)) { + dayTraffic(); + } + } + + /** + * 每日流量写入 + */ + private void dayTraffic() { + StatusResult status = miWifiUtil.getStatus(); + if (Objects.nonNull(status) && CollUtil.isNotEmpty(status.getDev())) { + List dbList = new ArrayList<>(); + Date date = DateUtil.date(); + String dateStr = DateUtil.format(date, "yyyy-MM-dd"); + status.getDev().forEach(dev -> { + DeviceDayTraffic deviceDayTraffic = new DeviceDayTraffic(); + deviceDayTraffic.setMac(dev.getMac()); + deviceDayTraffic.setDate(dateStr); + deviceDayTraffic.setDeviceName(dev.getDevName()); + deviceDayTraffic.setUpload(dev.getUpload()); + deviceDayTraffic.setDownload(dev.getDownload()); + Long total = Long.parseLong(dev.getUpload()) + Long.valueOf(dev.getDownload()); + deviceDayTraffic.setTotal(String.valueOf(total)); + dbList.add(deviceDayTraffic); + }); + this.saveBatch(dbList); + } + } +} diff --git a/src/main/resources/application-mi.yml b/src/main/resources/application-mi.yml index 4bcaaf5..ca93d26 100644 --- a/src/main/resources/application-mi.yml +++ b/src/main/resources/application-mi.yml @@ -1,4 +1,11 @@ bmw: url: 192.168.31.1 password: 123456 - web-password: 123456 \ No newline at end of file + web-password: 123456 + db: + path: ${user.home}/.miwifi-agent/db/agent + +spring: + datasource: + url: jdbc:sqlite:${bmw.db.path}.db + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c7c4737..c2142d8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -32,6 +32,9 @@ spring: web: resources: static-locations: classpath:/static/ + datasource: + driver-class-name: org.sqlite.JDBC + ############## Sa-Token 配置 (文档: https://sa-token.cc) ############## sa-token: @@ -52,4 +55,4 @@ sa-token: log: path: log/ - encoder: UTF-8 \ No newline at end of file + encoder: UTF-8 diff --git a/src/main/resources/db/migration-sqlite/V1__Base_version.sql b/src/main/resources/db/migration-sqlite/V1__Base_version.sql new file mode 100644 index 0000000..9abe8dd --- /dev/null +++ b/src/main/resources/db/migration-sqlite/V1__Base_version.sql @@ -0,0 +1,12 @@ +CREATE TABLE "device_day_traffic" +( + "id" integer NOT NULL, + "date" text, + "mac" TEXT, + "device_name" TEXT, + "ip" TEXT, + "upload" TEXT, + "download" TEXT, + "total" TEXT, + PRIMARY KEY ("id") +);