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")
+);