update:功能
This commit is contained in:
67
README.md
67
README.md
@@ -1 +1,66 @@
|
|||||||
# 项目架构
|
# 项目架构
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
本项目是一个基于 Spring Boot 的多模块 Maven 项目,采用分层架构设计,旨在提供一个可扩展和可维护的应用程序结构。项目使用 Java 21 版本,并集成了 Spring Security、MyBatis 等主流框架。
|
||||||
|
|
||||||
|
## 模块结构
|
||||||
|
|
||||||
|
项目由以下核心模块组成:
|
||||||
|
|
||||||
|
### ski-dashboard-model
|
||||||
|
- **作用**: 数据模型层,定义了应用程序的核心数据结构和实体类
|
||||||
|
- **依赖**: 无外部依赖,仅依赖父项目
|
||||||
|
|
||||||
|
### ski-dashboard-common
|
||||||
|
- **作用**: 公共组件层,包含通用工具类、公共配置和数据访问接口
|
||||||
|
- **主要功能**:
|
||||||
|
- 工具类和辅助函数
|
||||||
|
- MyBatis Mapper 接口定义
|
||||||
|
- JWT 认证相关工具
|
||||||
|
- **依赖**:
|
||||||
|
- ski-dashboard-model
|
||||||
|
- MyBatis Spring Boot Starter
|
||||||
|
|
||||||
|
### ski-dashboard-service
|
||||||
|
- **作用**: 业务逻辑层,实现核心业务逻辑和服务接口
|
||||||
|
- **主要功能**:
|
||||||
|
- 业务逻辑处理
|
||||||
|
- 数据访问服务实现
|
||||||
|
- **依赖**:
|
||||||
|
- ski-dashboard-model
|
||||||
|
- ski-dashboard-common
|
||||||
|
|
||||||
|
### ski-dashboard-admin
|
||||||
|
- **作用**: 应用入口和管理控制台,提供 REST API 和 Web 管理界面
|
||||||
|
- **主要功能**:
|
||||||
|
- RESTful API 接口
|
||||||
|
- Swagger API 文档
|
||||||
|
- Web 安全配置
|
||||||
|
- **依赖**:
|
||||||
|
- ski-dashboard-model
|
||||||
|
- ski-dashboard-common
|
||||||
|
- ski-dashboard-service
|
||||||
|
- SpringDoc OpenAPI UI
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
- **核心框架**: Spring Boot 3.5.7
|
||||||
|
- **编程语言**: Java 21
|
||||||
|
- **安全框架**: Spring Security
|
||||||
|
- **Web 框架**: Spring Web MVC
|
||||||
|
- **持久层框架**: MyBatis
|
||||||
|
- **数据库**: PostgreSQL
|
||||||
|
- **会话管理**: Spring Session JDBC
|
||||||
|
- **API 文档**: SpringDoc OpenAPI
|
||||||
|
- **JWT 认证**: java-jwt 4.4.0
|
||||||
|
- **构建工具**: Maven
|
||||||
|
- **代码简化**: Lombok
|
||||||
|
|
||||||
|
## 架构特点
|
||||||
|
|
||||||
|
1. **分层架构**: 清晰分离数据模型、公共组件、业务逻辑和应用入口
|
||||||
|
2. **模块化设计**: 各模块职责明确,便于独立开发和维护
|
||||||
|
3. **松耦合**: 模块间通过接口依赖,降低耦合度
|
||||||
|
4. **可扩展性**: 易于添加新功能模块或替换现有组件
|
||||||
|
5. **安全性**: 集成 Spring Security 和 JWT 实现认证授权
|
||||||
66
absolute/path/to/file
Normal file
66
absolute/path/to/file
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ski.lichuan.mapper.TrailPositionMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="com.ski.lichuan.model.dashboard.TrailPosition">
|
||||||
|
<id column="id" jdbcType="INTEGER" property="id"/>
|
||||||
|
<result column="trail_id" jdbcType="INTEGER" property="trailId"/>
|
||||||
|
<result column="position" jdbcType="VARCHAR" property="position"/>
|
||||||
|
<result column="name" jdbcType="VARCHAR" property="name"/>
|
||||||
|
<result column="snow_machine_id" jdbcType="INTEGER" property="snowMachineId"/>
|
||||||
|
<result column="snow_machine_status" jdbcType="INTEGER" property="snowMachineStatus"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="selectByTrailId" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position WHERE trail_id = #{trailId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectById" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position WHERE id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAll" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取所有未绑定雪机的雪道位置信息 -->
|
||||||
|
<select id="selectUnboundPositions" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position WHERE snow_machine_id IS NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectBoundPositions" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position WHERE snow_machine_id IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insert" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
|
||||||
|
INSERT INTO trail_position (trail_id, position, name)
|
||||||
|
VALUES (#{trailId}, #{position}, #{name})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="update">
|
||||||
|
UPDATE trail_position
|
||||||
|
SET trail_id = #{trailId}, position = #{position}, name = #{name}
|
||||||
|
WHERE id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="clearSnowMachine">
|
||||||
|
UPDATE trail_position
|
||||||
|
SET snow_machine_status = 0, snow_machine_id = NULL
|
||||||
|
WHERE id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="updateSnowMachine">
|
||||||
|
UPDATE trail_position
|
||||||
|
SET snow_machine_status = #{snowMachineStatus}, snow_machine_id = #{snowMachineId}
|
||||||
|
WHERE id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!-- 根据雪道位置ID列表查询造雪机设备ID列表 -->
|
||||||
|
<select id="selectDeviceIdsByTrailPositionIds" resultType="java.lang.Integer">
|
||||||
|
SELECT snow_machine_id FROM trail_position WHERE id IN
|
||||||
|
<foreach collection="list" item="id" open="(" close=")" separator=",">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
23
pom.xml
23
pom.xml
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@@ -22,10 +22,11 @@
|
|||||||
<developer/>
|
<developer/>
|
||||||
</developers>
|
</developers>
|
||||||
<modules>
|
<modules>
|
||||||
<module>ski-dashboard-admin</module>
|
<!-- 修改模块顺序以确保正确的构建顺序 -->
|
||||||
<module>ski-dashboard-service</module>
|
|
||||||
<module>ski-dashboard-common</module>
|
|
||||||
<module>ski-dashboard-model</module>
|
<module>ski-dashboard-model</module>
|
||||||
|
<module>ski-dashboard-common</module>
|
||||||
|
<module>ski-dashboard-service</module>
|
||||||
|
<module>ski-dashboard-admin</module>
|
||||||
</modules>
|
</modules>
|
||||||
<scm>
|
<scm>
|
||||||
<connection/>
|
<connection/>
|
||||||
@@ -40,10 +41,22 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mybatis.spring.boot</groupId>
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
@@ -121,4 +134,4 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -24,13 +24,13 @@
|
|||||||
<version>2.8.14</version>
|
<version>2.8.14</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ski.lichuan</groupId>
|
<groupId>com.ski</groupId>
|
||||||
<artifactId>ski-dashboard-common</artifactId>
|
<artifactId>ski-dashboard-common</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ski.lichuan</groupId>
|
<groupId>com.ski</groupId>
|
||||||
<artifactId>ski-dashboard-service</artifactId>
|
<artifactId>ski-dashboard-service</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ package com.ski.lichuan.admin;
|
|||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
@SpringBootApplication(scanBasePackages = {"com.ski.lichuan"})
|
@SpringBootApplication(scanBasePackages = {"com.ski.lichuan"})
|
||||||
@MapperScan("com.ski.lichuan.mapper")
|
@MapperScan("com.ski.lichuan.mapper")
|
||||||
|
@EnableScheduling
|
||||||
public class SkiDashboardAdminApplication {
|
public class SkiDashboardAdminApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(SkiDashboardAdminApplication.class, args);
|
SpringApplication.run(SkiDashboardAdminApplication.class, args);
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public class SecurityConfig {
|
|||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
// 放行 Swagger UI 相关路径
|
// 放行 Swagger UI 相关路径
|
||||||
.requestMatchers(
|
.requestMatchers(
|
||||||
|
"/**",
|
||||||
"/api/auth/login",
|
"/api/auth/login",
|
||||||
"/swagger-ui.html",
|
"/swagger-ui.html",
|
||||||
"/swagger-ui/**",
|
"/swagger-ui/**",
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package com.ski.lichuan.admin.controller;
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.common.HttpResponseData;
|
||||||
|
import com.ski.lichuan.model.dashboard.TrailPosition;
|
||||||
|
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
|
||||||
|
import com.ski.lichuan.services.SnowMachineDeviceService;
|
||||||
|
import com.ski.lichuan.services.TrailPositionService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/options")
|
||||||
|
@CrossOrigin(origins = "*")
|
||||||
|
@Tag(name = "公共选项", description = "提供公共的选项数据")
|
||||||
|
public class OptionsController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TrailPositionService trailPositionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SnowMachineDeviceService snowMachineDeviceService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有已绑定雪机的雪道位置信息
|
||||||
|
*
|
||||||
|
* @return 已绑定雪机的雪道位置列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/boundTrailPositions")
|
||||||
|
@Operation(summary = "获取已绑定雪机的雪道位置信息", description = "获取所有已绑定雪机的雪道位置信息,用于下拉框选项")
|
||||||
|
public HttpResponseData<List<TrailPosition>> getBoundTrailPositions() {
|
||||||
|
HttpResponseData<List<TrailPosition>> responseData = new HttpResponseData<>();
|
||||||
|
try {
|
||||||
|
List<TrailPosition> boundPositions = trailPositionService.getBoundTrailPositions();
|
||||||
|
return responseData.success(boundPositions);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return responseData.error("获取已绑定雪机的雪道位置信息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有未绑定位置的雪机设备信息
|
||||||
|
*
|
||||||
|
* @return 未绑定位置的雪机设备列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/unboundSnowMachines")
|
||||||
|
@Operation(summary = "获取未绑定位置的雪机设备信息", description = "获取所有未绑定位置的雪机设备信息,用于下拉框选项")
|
||||||
|
public HttpResponseData<List<SnowMachineDevice>> getUnboundSnowMachines() {
|
||||||
|
HttpResponseData<List<SnowMachineDevice>> responseData = new HttpResponseData<>();
|
||||||
|
try {
|
||||||
|
List<SnowMachineDevice> unboundMachines = snowMachineDeviceService.selectUnboundMachines();
|
||||||
|
return responseData.success(unboundMachines);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return responseData.error("获取未绑定位置的雪机设备信息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有未绑定雪机的雪道位置信息
|
||||||
|
*
|
||||||
|
* @return 未绑定雪机的雪道位置列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/unboundTrailPositions")
|
||||||
|
@Operation(summary = "获取未绑定雪机的雪道位置信息", description = "获取所有未绑定雪机的雪道位置信息,用于下拉框选项")
|
||||||
|
public HttpResponseData<List<TrailPosition>> getUnboundTrailPositions() {
|
||||||
|
HttpResponseData<List<TrailPosition>> responseData = new HttpResponseData<>();
|
||||||
|
try {
|
||||||
|
List<TrailPosition> unboundPositions = trailPositionService.getUnboundTrailPositions();
|
||||||
|
return responseData.success(unboundPositions);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return responseData.error("获取未绑定雪机的雪道位置信息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有雪机设备信息
|
||||||
|
*
|
||||||
|
* @return 所有雪机设备列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/snowMachineDevices")
|
||||||
|
@Operation(summary = "获取所有雪机设备信息", description = "获取所有雪机设备信息,用于下拉框选项")
|
||||||
|
public HttpResponseData<List<SnowMachineDevice>> getAllSnowMachineDevices() {
|
||||||
|
HttpResponseData<List<SnowMachineDevice>> responseData = new HttpResponseData<>();
|
||||||
|
try {
|
||||||
|
List<SnowMachineDevice> allDevices = snowMachineDeviceService.selectAllDevices();
|
||||||
|
return responseData.success(allDevices);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return responseData.error("获取所有雪机设备信息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -77,7 +77,7 @@ public class AuthController {
|
|||||||
* @return 用户信息
|
* @return 用户信息
|
||||||
*/
|
*/
|
||||||
@GetMapping("/userinfo")
|
@GetMapping("/userinfo")
|
||||||
@Operation(summary = "获取当前用户信息", description = "根据JWT Token获取当前登录用户的基本信息",)
|
@Operation(summary = "获取当前用户信息", description = "根据JWT Token获取当前登录用户的基本信息")
|
||||||
public ResponseEntity<Map<String, Object>> getUserInfo() {
|
public ResponseEntity<Map<String, Object>> getUserInfo() {
|
||||||
log.info("获取用户信息请求");
|
log.info("获取用户信息请求");
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,96 @@
|
|||||||
package com.ski.lichuan.admin.controller.device;
|
package com.ski.lichuan.admin.controller.device;
|
||||||
|
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.common.HttpResponseData;
|
||||||
|
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
|
||||||
|
import com.ski.lichuan.services.SnowMachineDeviceService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/device/snowmachine")
|
||||||
|
@CrossOrigin(origins = "*") // 根据实际需要调整CORS策略
|
||||||
|
@Tag(name = "造雪机设备", description = "造雪机设备的基本信息管理")
|
||||||
public class SnowMachineController {
|
public class SnowMachineController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SnowMachineDeviceService snowMachineDeviceService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1.造雪机设备的基本信息管理,增删查改
|
* 添加造雪机设备
|
||||||
|
*
|
||||||
|
* @param snowMachineDevice 造雪机设备信息
|
||||||
|
* @return 添加结果
|
||||||
*/
|
*/
|
||||||
}
|
@PostMapping("/")
|
||||||
|
@Operation(summary = "添加造雪机设备")
|
||||||
|
public HttpResponseData<Boolean> addSnowMachine(@RequestBody SnowMachineDevice snowMachineDevice) {
|
||||||
|
// 调用服务层添加设备
|
||||||
|
int result = snowMachineDeviceService.addSnowMachineDevice(snowMachineDevice);
|
||||||
|
return HttpResponseData.ok(result > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新造雪机设备信息
|
||||||
|
*
|
||||||
|
* @param id 设备ID
|
||||||
|
* @param snowMachineDevice 更新的设备信息
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
@Operation(summary = "更新造雪机设备信息")
|
||||||
|
public HttpResponseData<Boolean> updateSnowMachine(@PathVariable Integer id, @RequestBody SnowMachineDevice snowMachineDevice) {
|
||||||
|
snowMachineDevice.setId(id);
|
||||||
|
int result = snowMachineDeviceService.updateSnowMachineDevice(snowMachineDevice);
|
||||||
|
return HttpResponseData.ok(result > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除造雪机设备
|
||||||
|
*
|
||||||
|
* @param id 设备ID
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
@Operation(summary = "删除造雪机设备")
|
||||||
|
public HttpResponseData<Boolean> deleteSnowMachine(@PathVariable Integer id) {
|
||||||
|
// 调用服务层删除设备
|
||||||
|
int result = snowMachineDeviceService.deleteSnowMachineDevice(id);
|
||||||
|
return HttpResponseData.ok(result > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID获取造雪机设备信息
|
||||||
|
*
|
||||||
|
* @param id 设备ID
|
||||||
|
* @return 设备信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
@Operation(summary = "根据ID获取造雪机设备信息")
|
||||||
|
public HttpResponseData<SnowMachineDevice> getSnowMachineById(@PathVariable Integer id) {
|
||||||
|
// 调用服务层获取设备信息
|
||||||
|
SnowMachineDevice result = snowMachineDeviceService.getSnowMachineDeviceById(id);
|
||||||
|
log.info("根据ID获取造雪机设备信息,ID:{}", id);
|
||||||
|
return HttpResponseData.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有造雪机设备列表
|
||||||
|
*
|
||||||
|
* @return 设备列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/")
|
||||||
|
@Operation(summary = "获取所有造雪机设备列表")
|
||||||
|
public HttpResponseData<List<SnowMachineDevice>> getAllSnowMachines() {
|
||||||
|
// 调用服务层获取所有设备
|
||||||
|
List<SnowMachineDevice> result = snowMachineDeviceService.getAllSnowMachineDevices();
|
||||||
|
return HttpResponseData.ok(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,177 @@
|
|||||||
package com.ski.lichuan.admin.controller.monitor;
|
package com.ski.lichuan.admin.controller.monitor;
|
||||||
|
|
||||||
public class SkiResortController {
|
import com.ski.lichuan.model.common.DeviceEnum;
|
||||||
/**
|
import com.ski.lichuan.model.common.HttpResponseData;
|
||||||
* 1.获取滑雪场雪道和造雪机关联信息
|
import com.ski.lichuan.model.dashboard.*;
|
||||||
* 2.提供滑雪场雪道和造雪机的关联移除(上下机)接口
|
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
|
||||||
* 3.提供滑雪场造雪机的群控功能(只对滑雪场内的造雪机生效)
|
import com.ski.lichuan.model.device.config.SnowMachineDeviceParams;
|
||||||
*/
|
import com.ski.lichuan.model.device.config.SnowMachineDevicePitchHorizontalParams;
|
||||||
|
import com.ski.lichuan.services.TrailPositionService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/dashboard")
|
||||||
|
@CrossOrigin(origins = "*") // 根据实际需要调整CORS策略
|
||||||
|
@Tag(name = "首页", description = "首页信息展示")
|
||||||
|
public class SkiResortController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TrailPositionService trailPositionService;
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
@Operation(summary = "首页-获取滑雪场雪道和造雪机关联信息")
|
||||||
|
public HttpResponseData<List<List<TrailPosition>>> getDashboardInfo() {
|
||||||
|
HttpResponseData<List<List<TrailPosition>>> responseData = new HttpResponseData<>();
|
||||||
|
List<List<TrailPosition>> result = trailPositionService.getAllTrailPositions();
|
||||||
|
return responseData.success(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/positionInfo")
|
||||||
|
@Operation(summary = "获取雪道坑位的详细信息(造雪机)")
|
||||||
|
public HttpResponseData<TrailPositionInfo> getPositionInfo(Integer trailPositionId) {
|
||||||
|
HttpResponseData<TrailPositionInfo> responseData = new HttpResponseData<>();
|
||||||
|
TrailPositionInfo result = new TrailPositionInfo();
|
||||||
|
|
||||||
|
Integer trailId = trailPositionId / 10;
|
||||||
|
Integer position = trailPositionId % 10;
|
||||||
|
|
||||||
|
// 雪机设备
|
||||||
|
SnowMachineDevice snowMachineDevice = new SnowMachineDevice();
|
||||||
|
snowMachineDevice.setLora("1234567890123456");
|
||||||
|
snowMachineDevice.setId(1000000000 + trailPositionId);
|
||||||
|
snowMachineDevice.setName("造雪机-" + trailPositionId);
|
||||||
|
snowMachineDevice.setType(DeviceEnum.SNOW_MAKER.getValue());
|
||||||
|
// 雪道位置信息
|
||||||
|
TrailPosition trailPosition = new TrailPosition();
|
||||||
|
trailPosition.setId(trailPositionId);
|
||||||
|
trailPosition.setTrailId(trailId);
|
||||||
|
trailPosition.setPosition(position);
|
||||||
|
trailPosition.setName(trailId + "-" + position);
|
||||||
|
trailPosition.setSnowMachineStatus(1);
|
||||||
|
trailPosition.setSnowMachineId(snowMachineDevice.getId());
|
||||||
|
// 雪道位置状态信息
|
||||||
|
TrailPositionMonitorInfo trailPositionMonitorInfo = new TrailPositionMonitorInfo();
|
||||||
|
trailPositionMonitorInfo.setTrailPosition(trailPosition);
|
||||||
|
trailPositionMonitorInfo.setSnowMakerName(snowMachineDevice.getName());
|
||||||
|
|
||||||
|
trailPositionMonitorInfo.setPriority(1);
|
||||||
|
trailPositionMonitorInfo.setEnvironmentTemperature(-3.5);
|
||||||
|
trailPositionMonitorInfo.setEnvironmentHumidity(50.0);
|
||||||
|
trailPositionMonitorInfo.setWetBulbTemperature(0.5);
|
||||||
|
trailPositionMonitorInfo.setCommunicationStatus(true);
|
||||||
|
trailPositionMonitorInfo.setIsNormal(true);
|
||||||
|
trailPositionMonitorInfo.setIsRunning(true);
|
||||||
|
trailPositionMonitorInfo.setTemperatureConditionSatisfied(true);
|
||||||
|
trailPositionMonitorInfo.setWindSpeed(5.0);
|
||||||
|
trailPositionMonitorInfo.setWindDirection(180.0);
|
||||||
|
// 造雪机设备状态
|
||||||
|
SnowMachineDeviceInfo snowMachineDeviceInfo = new SnowMachineDeviceInfo();
|
||||||
|
snowMachineDeviceInfo.setSnowMachineDevice(snowMachineDevice);
|
||||||
|
snowMachineDeviceInfo.setFrontWaterPressure(0.5 + Math.random() * 0.3); // 前端水压 0.5-0.8 MPa
|
||||||
|
snowMachineDeviceInfo.setBackWaterPressure(0.4 + Math.random() * 0.2); // 后端水压 0.4-0.6 MPa
|
||||||
|
snowMachineDeviceInfo.setPressure(0.8 + Math.random() * 0.2); // 气压 0.8-1.0 MPa
|
||||||
|
snowMachineDeviceInfo.setTemperature(2.5 + Math.random() * 2.0); // 水温 2.5-4.5 ℃
|
||||||
|
snowMachineDeviceInfo.setGivenAngle(45.0 + Math.random() * 10.0); // 给定开度 45-55°
|
||||||
|
snowMachineDeviceInfo.setActualAngle(44.0 + Math.random() * 12.0); // 实际开度 44-56°
|
||||||
|
snowMachineDeviceInfo.setIsNormal(Math.random() > 0.1); // 是否正常 90%概率正常
|
||||||
|
snowMachineDeviceInfo.setMode((int)(Math.random() * 3) + 1); // 模式 1-3随机
|
||||||
|
snowMachineDeviceInfo.setCompressorStatus((int)(Math.random() * 2) + 1); // 空压机状态 1-2随机
|
||||||
|
snowMachineDeviceInfo.setFanStatus((int)(Math.random() * 2) + 1); // 风机状态 1-2随机
|
||||||
|
snowMachineDeviceInfo.setHeatingRingStatus((int)(Math.random() * 2) + 1); // 加热环状态 1-2随机
|
||||||
|
snowMachineDeviceInfo.setValveStatus((int)(Math.random() * 2) + 1); // 电磁阀状态1 1-2随机
|
||||||
|
snowMachineDeviceInfo.setValveStatus2((int)(Math.random() * 2) + 1); // 电磁阀状态2 1-2随机
|
||||||
|
snowMachineDeviceInfo.setValveStatus3((int)(Math.random() * 2) + 1); // 电磁阀状态3 1-2随机
|
||||||
|
snowMachineDeviceInfo.setPitchMode((int)(Math.random() * 3) + 1); // 俯仰模式 1-3随机
|
||||||
|
snowMachineDeviceInfo.setPitchAngle(15.0 + Math.random() * 20.0); // 俯仰角度 15-35°
|
||||||
|
snowMachineDeviceInfo.setPitchStatus((int)(Math.random() * 2) + 1); // 俯仰状态 1-2随机
|
||||||
|
snowMachineDeviceInfo.setYawMode((int)(Math.random() * 3) + 1); // 摆头模式 1-3随机
|
||||||
|
snowMachineDeviceInfo.setYawAngle(30.0 + Math.random() * 40.0); // 摆头角度 30-70°
|
||||||
|
snowMachineDeviceInfo.setYawStatus((int)(Math.random() * 2) + 1); // 摆头状态 1-2随机
|
||||||
|
// 造雪机配置
|
||||||
|
SnowMachineDeviceParams snowMakerDeviceParams = new SnowMachineDeviceParams();
|
||||||
|
snowMakerDeviceParams.setWorkMode((int)(Math.random() * 3) + 1); // 工作模式 1-3随机
|
||||||
|
snowMakerDeviceParams.setPriority((int)(Math.random() * 5) + 1); // 优先级 1-5随机
|
||||||
|
snowMakerDeviceParams.setSnowQuality((int)(Math.random() * 5) + 1); // 雪质 1-5随机
|
||||||
|
snowMakerDeviceParams.setStartTemperature(-5.0 + Math.random() * 10.0); // 启动温度 -5.0 ~ 5.0
|
||||||
|
snowMakerDeviceParams.setStopTemperature(-5.0 + Math.random() * 10.0); // 停止温度 -5.0 ~ 5.0
|
||||||
|
snowMakerDeviceParams.setFlowAdjustment((int)(Math.random() * 50)); // 流量调节 0 ~ 50
|
||||||
|
|
||||||
|
// 数据统计
|
||||||
|
TrailPositionStatisticsInfo trailPositionStatisticsInfo = new TrailPositionStatisticsInfo();
|
||||||
|
trailPositionStatisticsInfo.setRunningDuration(120.5 + Math.random() * 100.0); // 运行时长 120.5-220.5分钟
|
||||||
|
trailPositionStatisticsInfo.setFlowStatistics(1000.0 + Math.random() * 500.0); // 流量统计 1000-1500 L/H
|
||||||
|
trailPositionStatisticsInfo.setSnowArea(500.0 + Math.random() * 300.0); // 造雪面积 500-800 平方米
|
||||||
|
|
||||||
|
result.setTrailPositionMonitorInfo(trailPositionMonitorInfo);
|
||||||
|
result.setSnowMakerInfo(snowMachineDeviceInfo);
|
||||||
|
result.setSnowMakerDeviceParams(snowMakerDeviceParams);
|
||||||
|
result.setTrailPositionStatisticsInfo(trailPositionStatisticsInfo);
|
||||||
|
|
||||||
|
return responseData.success(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/connectDevice")
|
||||||
|
@Operation(summary = "雪道造雪机(上机)")
|
||||||
|
public HttpResponseData<Boolean> connectDevice(Integer trailPositionId, Integer deviceId) {
|
||||||
|
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
|
||||||
|
return responseData.success(trailPositionService.connectDevice(trailPositionId, deviceId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/disconnectDevice")
|
||||||
|
@Operation(summary = "雪道造雪机(下机)")
|
||||||
|
public HttpResponseData<Boolean> disconnectDevice(Integer trailPositionId) {
|
||||||
|
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
|
||||||
|
return responseData.success(trailPositionService.disconnectDevice(trailPositionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/groupControl")
|
||||||
|
@Operation(summary = "雪道造雪机(群控)")
|
||||||
|
public HttpResponseData<Boolean> groupControl(@RequestBody GroupControlRequest request) {
|
||||||
|
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
|
||||||
|
|
||||||
|
return responseData.success(trailPositionService.groupControl(request.getTrailPositionList(), request.getParams()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 俯仰水平控制
|
||||||
|
@PostMapping("/pitchHorizontalControl")
|
||||||
|
@Operation(summary = "雪道造雪机俯仰水平控制")
|
||||||
|
public HttpResponseData<Boolean> pitchHorizontalControl(@RequestBody PitchHorizontalControlRequest request) {
|
||||||
|
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
|
||||||
|
return responseData.success(trailPositionService.pitchHorizontalControl(request.getTrailPosition(), request.getParams()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/saveSnowMakerDeviceParams")
|
||||||
|
@Operation(summary = "保存造雪机参数")
|
||||||
|
public HttpResponseData<Boolean> groupControl(@RequestBody GroupControlSingleRequest request) {
|
||||||
|
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
|
||||||
|
return responseData.success(trailPositionService.saveSnowMakerDeviceParams(request.getTrailPosition(), request.getParams()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class GroupControlRequest {
|
||||||
|
private List<Integer> trailPositionList;
|
||||||
|
private SnowMachineDeviceParams params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class GroupControlSingleRequest {
|
||||||
|
private Integer trailPosition;
|
||||||
|
private SnowMachineDeviceParams params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class PitchHorizontalControlRequest {
|
||||||
|
private Integer trailPosition;
|
||||||
|
private SnowMachineDevicePitchHorizontalParams params;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.ski.lichuan.admin.filter;
|
package com.ski.lichuan.admin.filter;
|
||||||
|
|
||||||
import com.ski.lichuan.common.utils.JwtUtils;
|
import com.ski.lichuan.common.utils.JwtUtils;
|
||||||
|
import com.ski.lichuan.model.auth.SysUser;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
@@ -15,6 +17,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -36,6 +39,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
|
|
||||||
// 2. 验证 Token 并获取用户名
|
// 2. 验证 Token 并获取用户名
|
||||||
if (jwtUtils.validateToken(token)) {
|
if (jwtUtils.validateToken(token)) {
|
||||||
|
// 鉴权通过,从 Token 中获取用户名
|
||||||
String username = jwtUtils.getUsernameFromToken(token);
|
String username = jwtUtils.getUsernameFromToken(token);
|
||||||
// 3. 加载用户信息并设置认证状态
|
// 3. 加载用户信息并设置认证状态
|
||||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
spring.application.name=ski-dashboard-admin
|
||||||
|
|
||||||
|
server.port=8080
|
||||||
|
|
||||||
|
# postgresql
|
||||||
|
spring.datasource.url=jdbc:postgresql://localhost:5432/ski_dashboard
|
||||||
|
spring.datasource.username=postgres
|
||||||
|
spring.datasource.password=tanlifan
|
||||||
|
|
||||||
|
|
||||||
|
# Spring Session
|
||||||
|
spring.session.store-type=jdbc
|
||||||
|
spring.session.jdbc.initialize-schema=always
|
||||||
|
spring.session.jdbc.table-name=SPRING_SESSION
|
||||||
|
|
||||||
|
JWT_SECRET=vf4JZhcyfdK7tJs0GZ3Qjf0dSv4BId9ITjsM2fol26gOBxM17nUySiMcV0Lo2u0Y
|
||||||
|
|
||||||
|
# Logging levels for development
|
||||||
|
logging.level.com.ski.lichuan=DEBUG
|
||||||
|
logging.level.org.springframework.web=DEBUG
|
||||||
|
logging.level.org.mybatis=DEBUG
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
spring.application.name=ski-dashboard-admin
|
||||||
|
|
||||||
|
server.port=8080
|
||||||
|
|
||||||
|
# postgresql
|
||||||
|
spring.datasource.url=jdbc:postgresql://localhost:8081/ski_dashboard
|
||||||
|
spring.datasource.username=postgres
|
||||||
|
spring.datasource.password=postgres
|
||||||
|
|
||||||
|
|
||||||
|
# Spring Session
|
||||||
|
spring.session.store-type=jdbc
|
||||||
|
spring.session.jdbc.initialize-schema=always
|
||||||
|
spring.session.jdbc.table-name=SPRING_SESSION
|
||||||
|
|
||||||
|
JWT_SECRET=vf4JZhcyfdK7tJs0GZ3Qjf0dSv4BId9ITjsM2fol26gOBxM17nUySiMcV0Lo2u0Y
|
||||||
|
|
||||||
|
# Logging levels for production
|
||||||
|
logging.level.com.ski.lichuan=INFO
|
||||||
|
logging.level.org.springframework.web=WARN
|
||||||
|
logging.level.org.mybatis=WARN
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
spring.application.name=ski-dashboard-admin
|
spring.application.name=ski-dashboard-admin
|
||||||
|
|
||||||
# ??????? postgresql
|
spring.profiles.active=prod
|
||||||
spring.datasource.url=jdbc:postgresql://localhost:5432/ski_dashboard
|
|
||||||
spring.datasource.username=postgres
|
|
||||||
spring.datasource.password=tanlifan
|
|
||||||
|
|
||||||
# Spring Session??
|
# Spring Session
|
||||||
spring.session.store-type=jdbc
|
spring.session.store-type=jdbc
|
||||||
spring.session.jdbc.initialize-schema=always
|
spring.session.jdbc.initialize-schema=always
|
||||||
spring.session.jdbc.table-name=SPRING_SESSION
|
spring.session.jdbc.table-name=SPRING_SESSION
|
||||||
|
|
||||||
JWT_SECRET=vf4JZhcyfdK7tJs0GZ3Qjf0dSv4BId9ITjsM2fol26gOBxM17nUySiMcV0Lo2u0Y
|
# MyBatis configuration - enable camel case mapping
|
||||||
|
mybatis.configuration.map-underscore-to-camel-case=true
|
||||||
|
mybatis.mapper-locations=classpath*:mapper/*.xml
|
||||||
|
|
||||||
|
thingsboard.client.url=https://tb.ski.bkiiot.com
|
||||||
|
thingsboard.client.username=tenant@thingsboard.org
|
||||||
|
thingsboard.client.password=tenant
|
||||||
57
ski-dashboard-admin/src/main/resources/logback-spring.xml
Normal file
57
ski-dashboard-admin/src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<!-- 定义日志文件的存储路径 -->
|
||||||
|
<property name="LOG_HOME" value="logs" />
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- INFO级别的日志输出到 info.log -->
|
||||||
|
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${LOG_HOME}/info.log</file>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<level>INFO</level>
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
|
<fileNamePattern>${LOG_HOME}/info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||||
|
<maxFileSize>10MB</maxFileSize>
|
||||||
|
<maxHistory>30</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- ERROR级别的日志输出到 error.log -->
|
||||||
|
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${LOG_HOME}/error.log</file>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<level>ERROR</level>
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
|
<fileNamePattern>${LOG_HOME}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||||
|
<maxFileSize>10MB</maxFileSize>
|
||||||
|
<maxHistory>30</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 根日志配置 -->
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="CONSOLE" />
|
||||||
|
<appender-ref ref="INFO_FILE" />
|
||||||
|
<appender-ref ref="ERROR_FILE" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
@@ -8,8 +8,6 @@
|
|||||||
<artifactId>ski-dashboard</artifactId>
|
<artifactId>ski-dashboard</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.ski.lichuan</groupId>
|
|
||||||
<artifactId>ski-dashboard-common</artifactId>
|
<artifactId>ski-dashboard-common</artifactId>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -38,4 +36,16 @@
|
|||||||
<version>3.0.5</version>
|
<version>3.0.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- 排除Spring Boot Maven插件,因为这是一个数据模型模块,不是可执行应用程序 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.ski.lichuan.common;
|
|
||||||
|
|
||||||
//TIP 要<b>运行</b>代码,请按 <shortcut actionId="Run"/> 或
|
|
||||||
// 点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
//TIP 当文本光标位于高亮显示的文本处时按 <shortcut actionId="ShowIntentionActions"/>
|
|
||||||
// 查看 IntelliJ IDEA 建议如何修正。
|
|
||||||
System.out.printf("Hello and welcome!");
|
|
||||||
|
|
||||||
for (int i = 1; i <= 5; i++) {
|
|
||||||
//TIP 按 <shortcut actionId="Debug"/> 开始调试代码。我们已经设置了一个 <icon src="AllIcons.Debugger.Db_set_breakpoint"/> 断点
|
|
||||||
// 但您始终可以通过按 <shortcut actionId="ToggleLineBreakpoint"/> 添加更多断点。
|
|
||||||
System.out.println("i = " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.ski.lichuan.common.exception;
|
||||||
|
|
||||||
|
public class BusinessException extends RuntimeException {
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
public BusinessException(String message) {
|
||||||
|
super(message);
|
||||||
|
this.code = 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(Integer code, String message) {
|
||||||
|
super(message);
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(Integer code, String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(Integer code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.ski.lichuan.common.exception;
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.common.HttpResponseData;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.validation.BindException;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.validation.FieldError;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局异常处理器
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理自定义业务异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(BusinessException.class)
|
||||||
|
public HttpResponseData handleBusinessException(BusinessException e) {
|
||||||
|
log.error("业务异常: ", e);
|
||||||
|
return new HttpResponseData<>().error(e.getCode(), e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理参数验证异常(MethodArgumentNotValidException)
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
|
public HttpResponseData handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||||
|
log.error("参数校验异常: ", e);
|
||||||
|
BindingResult bindingResult = e.getBindingResult();
|
||||||
|
StringBuilder errorMsg = new StringBuilder();
|
||||||
|
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
|
||||||
|
fieldErrors.forEach(error ->
|
||||||
|
errorMsg.append(error.getField()).append(": ").append(error.getDefaultMessage()).append("; ")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HttpResponseData<>().error(400, "参数校验失败: " + errorMsg.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理参数绑定异常(BindException)
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(BindException.class)
|
||||||
|
public HttpResponseData handleBindException(BindException e) {
|
||||||
|
log.error("参数绑定异常: ", e);
|
||||||
|
BindingResult bindingResult = e.getBindingResult();
|
||||||
|
StringBuilder errorMsg = new StringBuilder();
|
||||||
|
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
|
||||||
|
fieldErrors.forEach(error ->
|
||||||
|
errorMsg.append(error.getField()).append(": ").append(error.getDefaultMessage()).append("; ")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HttpResponseData<>().error(400, "参数绑定失败: " + errorMsg.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理IllegalArgumentException异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(IllegalArgumentException.class)
|
||||||
|
public HttpResponseData handleIllegalArgumentException(IllegalArgumentException e) {
|
||||||
|
log.error("非法参数异常: ", e);
|
||||||
|
return new HttpResponseData<>().error(400, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理其他所有异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(Exception.class)
|
||||||
|
public HttpResponseData handleException(Exception e) {
|
||||||
|
log.error("系统异常: ", e);
|
||||||
|
return new HttpResponseData<>().error(500, "系统内部错误,请联系管理员");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.ski.lichuan.common.utils;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MD5加密工具类
|
||||||
|
*/
|
||||||
|
public class MD5Util {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对字符串进行MD5加密
|
||||||
|
* @param input 待加密的字符串
|
||||||
|
* @return 加密后的十六进制字符串
|
||||||
|
*/
|
||||||
|
public static String encrypt(String input) {
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
BigInteger no = new BigInteger(1, messageDigest);
|
||||||
|
StringBuilder hashText = new StringBuilder(no.toString(16));
|
||||||
|
|
||||||
|
// 补齐前面的0,确保是32位
|
||||||
|
while (hashText.length() < 32) {
|
||||||
|
hashText.insert(0, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashText.toString();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new RuntimeException("MD5 algorithm not found", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证明文与MD5密文是否匹配
|
||||||
|
* @param rawText 明文
|
||||||
|
* @param md5Text MD5密文
|
||||||
|
* @return 是否匹配
|
||||||
|
*/
|
||||||
|
public static boolean verify(String rawText, String md5Text) {
|
||||||
|
if (rawText == null || md5Text == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return md5Text.equals(encrypt(rawText));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,5 +16,26 @@
|
|||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger.core.v3</groupId>
|
||||||
|
<artifactId>swagger-annotations-jakarta</artifactId>
|
||||||
|
<version>2.2.38</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- 排除Spring Boot Maven插件,因为这是一个数据模型模块,不是可执行应用程序 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.ski.lichuan.mapper;
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SnowMachineMapper {
|
||||||
|
|
||||||
|
int insert(SnowMachineDevice snowMachineDevice);
|
||||||
|
|
||||||
|
int insertById(SnowMachineDevice snowMachineDevice);
|
||||||
|
|
||||||
|
List<SnowMachineDevice> selectAll();
|
||||||
|
|
||||||
|
SnowMachineDevice selectById(Integer id);
|
||||||
|
|
||||||
|
SnowMachineDevice selectByLora(String lora);
|
||||||
|
|
||||||
|
List<SnowMachineDevice> selectUnboundMachines();
|
||||||
|
|
||||||
|
int count();
|
||||||
|
|
||||||
|
int updateName(SnowMachineDevice snowMachineDevice);
|
||||||
|
|
||||||
|
int updateNameAndLora(SnowMachineDevice snowMachineDevice);
|
||||||
|
|
||||||
|
int deleteById(Integer id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.ski.lichuan.mapper;
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.dashboard.TrailPosition;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface TrailPositionMapper {
|
||||||
|
|
||||||
|
List<TrailPosition> selectByTrailId(Integer trailId);
|
||||||
|
|
||||||
|
TrailPosition selectById(Integer id);
|
||||||
|
|
||||||
|
List<TrailPosition> selectAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有未绑定雪机的雪道位置信息
|
||||||
|
*/
|
||||||
|
List<TrailPosition> selectUnboundPositions();
|
||||||
|
|
||||||
|
List<TrailPosition> selectBoundPositions();
|
||||||
|
|
||||||
|
int insert(TrailPosition trailPosition);
|
||||||
|
|
||||||
|
int update(TrailPosition trailPosition);
|
||||||
|
|
||||||
|
int clearSnowMachine(Integer id);
|
||||||
|
|
||||||
|
int updateSnowMachine(Integer id, Integer snowMachineId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据雪道位置ID列表查询造雪机设备ID列表
|
||||||
|
*
|
||||||
|
* @param trailPositionIds 雪道位置ID列表
|
||||||
|
* @return 造雪机设备ID列表
|
||||||
|
*/
|
||||||
|
List<Integer> selectDeviceIdsByTrailPositionIds(List<Integer> trailPositionIds);
|
||||||
|
}
|
||||||
@@ -7,12 +7,20 @@ import org.springframework.security.core.userdetails.UserDetails;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema
|
||||||
@Data
|
@Data
|
||||||
public class SysUser implements UserDetails {
|
public class SysUser implements UserDetails {
|
||||||
|
@Schema(description = "用户ID")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
@Schema(description = "用户名")
|
||||||
private String username;
|
private String username;
|
||||||
|
@Schema(description = "密码")
|
||||||
private String password;
|
private String password;
|
||||||
|
@Schema(description = "昵称")
|
||||||
private String nickname;
|
private String nickname;
|
||||||
|
@Schema(description = "状态")
|
||||||
private Integer status; // 1-正常,0-禁用
|
private Integer status; // 1-正常,0-禁用
|
||||||
|
|
||||||
// 实现 UserDetails 接口方法
|
// 实现 UserDetails 接口方法
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.ski.lichuan.model.common;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum DeviceEnum {
|
||||||
|
SNOW_MAKER("雪机", 1),
|
||||||
|
WATER_PUMP("水泵", 2),
|
||||||
|
;
|
||||||
|
private final String name;
|
||||||
|
private final Integer value;
|
||||||
|
|
||||||
|
DeviceEnum(String name, Integer value) {
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package com.ski.lichuan.model.common;
|
|||||||
|
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class HttpResponseData<T> {
|
public class HttpResponseData<T> {
|
||||||
@@ -45,4 +44,17 @@ public class HttpResponseData<T> {
|
|||||||
response.setMessage(message);
|
response.setMessage(message);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// 增加静态方法便于使用
|
||||||
|
public static <T> HttpResponseData<T> ok(T data) {
|
||||||
|
return new HttpResponseData<>(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> HttpResponseData<T> fail(String message) {
|
||||||
|
return new HttpResponseData<T>().error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> HttpResponseData<T> fail(Integer code, String message) {
|
||||||
|
return new HttpResponseData<T>().error(code, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.ski.lichuan.model.dashboard;
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "造雪机设备状态信息")
|
||||||
|
@Data
|
||||||
|
public class SnowMachineDeviceInfo {
|
||||||
|
|
||||||
|
@Schema(description = "造雪机设备基本信息")
|
||||||
|
public SnowMachineDevice snowMachineDevice;
|
||||||
|
@Schema(description = "前端水压")
|
||||||
|
public Double frontWaterPressure;
|
||||||
|
@Schema(description = "后端水压")
|
||||||
|
public Double backWaterPressure;
|
||||||
|
@Schema(description = "气压")
|
||||||
|
public Double pressure;
|
||||||
|
@Schema(description = "水温")
|
||||||
|
public Double temperature;
|
||||||
|
@Schema(description = "给定开度")
|
||||||
|
public Double givenAngle;
|
||||||
|
@Schema(description = "实际开度")
|
||||||
|
public Double actualAngle;
|
||||||
|
@Schema(description = "是否正常")
|
||||||
|
public Boolean isNormal;
|
||||||
|
@Schema(description = "模式 关1/开2/自动3")
|
||||||
|
public Integer mode;
|
||||||
|
@Schema(description = "空压机状态 关1/开2")
|
||||||
|
public Integer compressorStatus;
|
||||||
|
@Schema(description = "风机状态 关1/开2")
|
||||||
|
public Integer fanStatus;
|
||||||
|
@Schema(description = "加热环状态 关1/开2")
|
||||||
|
public Integer heatingRingStatus;
|
||||||
|
@Schema(description = "电磁阀状态1 关1/开2")
|
||||||
|
public Integer valveStatus;
|
||||||
|
@Schema(description = "电磁阀状态2 关1/开2")
|
||||||
|
public Integer valveStatus2;
|
||||||
|
@Schema(description = "电磁阀状态3 关1/开2")
|
||||||
|
public Integer valveStatus3;
|
||||||
|
@Schema(description = "俯仰模式 关1/开2/自动3")
|
||||||
|
public Integer pitchMode;
|
||||||
|
@Schema(description = "俯仰角度")
|
||||||
|
public Double pitchAngle;
|
||||||
|
@Schema(description = "俯仰状态 关1/开2")
|
||||||
|
public Integer pitchStatus;
|
||||||
|
@Schema(description = "摆头模式 关1/开2/自动3")
|
||||||
|
public Integer yawMode;
|
||||||
|
@Schema(description = "摆头角度")
|
||||||
|
public Double yawAngle;
|
||||||
|
@Schema(description = "摆头状态 关1/开2")
|
||||||
|
public Integer yawStatus;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.ski.lichuan.model.dashboard;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "雪道位置信息")
|
||||||
|
@Data
|
||||||
|
public class TrailPosition {
|
||||||
|
@Schema(description = "ID")
|
||||||
|
public Integer id;
|
||||||
|
@Schema(description = "雪道ID")
|
||||||
|
public Integer trailId;
|
||||||
|
@Schema(description = "位置")
|
||||||
|
public Integer position;
|
||||||
|
@Schema(description = "名称")
|
||||||
|
public String name;
|
||||||
|
@Schema(description = "雪机状态 0无 1正常 2停止")
|
||||||
|
public Integer snowMachineStatus;
|
||||||
|
@Schema(description = "造雪机ID")
|
||||||
|
public Integer snowMachineId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.ski.lichuan.model.dashboard;
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.device.config.SnowMachineDeviceParams;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "雪道位置状态")
|
||||||
|
@Data
|
||||||
|
public class TrailPositionInfo {
|
||||||
|
|
||||||
|
@Schema(description = "雪道位置状态信息")
|
||||||
|
public TrailPositionMonitorInfo trailPositionMonitorInfo;
|
||||||
|
// 造雪机信息
|
||||||
|
@Schema(description = "造雪机设备状态信息")
|
||||||
|
public SnowMachineDeviceInfo snowMakerInfo;
|
||||||
|
// 雪机配置
|
||||||
|
@Schema(description = "造雪机配置信息")
|
||||||
|
public SnowMachineDeviceParams snowMakerDeviceParams;
|
||||||
|
// 统计信息
|
||||||
|
@Schema(description = "统计信息")
|
||||||
|
public TrailPositionStatisticsInfo trailPositionStatisticsInfo;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package com.ski.lichuan.model.dashboard;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "雪道位置状态信息")
|
||||||
|
@Data
|
||||||
|
public class TrailPositionMonitorInfo {
|
||||||
|
|
||||||
|
@Schema(description = "雪道位置信息")
|
||||||
|
public TrailPosition trailPosition;
|
||||||
|
|
||||||
|
// 造雪机名称
|
||||||
|
@Schema(description = "造雪机名称")
|
||||||
|
public String snowMakerName;
|
||||||
|
|
||||||
|
// 是否有造雪机
|
||||||
|
@Schema(description = "是否有造雪机")
|
||||||
|
public Boolean hasSnowMaker;
|
||||||
|
// 优先级
|
||||||
|
@Schema(description = "优先级")
|
||||||
|
public Integer priority;
|
||||||
|
// 环境温度
|
||||||
|
@Schema(description = "环境温度")
|
||||||
|
public Double environmentTemperature;
|
||||||
|
// 环境湿度
|
||||||
|
@Schema(description = "环境湿度")
|
||||||
|
public Double environmentHumidity;
|
||||||
|
// 湿球温度
|
||||||
|
@Schema(description = "湿球温度")
|
||||||
|
public Double wetBulbTemperature;
|
||||||
|
|
||||||
|
// 通讯状态
|
||||||
|
@Schema(description = "通讯状态")
|
||||||
|
public Boolean communicationStatus;
|
||||||
|
// 自动模式
|
||||||
|
@Schema(description = "自动模式")
|
||||||
|
public Boolean autoMode;
|
||||||
|
// 是否正常
|
||||||
|
@Schema(description = "是否正常")
|
||||||
|
public Boolean isNormal;
|
||||||
|
// 正常运行
|
||||||
|
@Schema(description = "正常运行")
|
||||||
|
public Boolean isRunning;
|
||||||
|
// 温度条件满足
|
||||||
|
@Schema(description = "温度条件满足")
|
||||||
|
public Boolean temperatureConditionSatisfied;
|
||||||
|
// 风速
|
||||||
|
@Schema(description = "风速")
|
||||||
|
public Double windSpeed;
|
||||||
|
// 风向
|
||||||
|
@Schema(description = "风向")
|
||||||
|
public Double windDirection;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.ski.lichuan.model.dashboard;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "雪道位置统计信息")
|
||||||
|
@Data
|
||||||
|
public class TrailPositionStatisticsInfo {
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "运行时长")
|
||||||
|
public Double runningDuration;
|
||||||
|
@Schema(description = "流量统计")
|
||||||
|
public Double flowStatistics;
|
||||||
|
@Schema(description = "造雪面积")
|
||||||
|
public Double snowArea;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ski.lichuan.model.device;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "设备")
|
||||||
|
@Data
|
||||||
|
public abstract class Device {
|
||||||
|
@Schema(description = "设备名称")
|
||||||
|
public String name;
|
||||||
|
@Schema(description = "设备类型")
|
||||||
|
public Integer type;
|
||||||
|
@Schema(description = "设备ID")
|
||||||
|
public Integer id;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.ski.lichuan.model.device.Impl;
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.common.DeviceEnum;
|
||||||
|
import com.ski.lichuan.model.device.Device;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "造雪机设备")
|
||||||
|
public class SnowMachineDevice extends Device {
|
||||||
|
|
||||||
|
// 设备的LORA地址
|
||||||
|
@Schema(description = "设备的LORA地址")
|
||||||
|
public String lora;
|
||||||
|
|
||||||
|
public SnowMachineDevice() {
|
||||||
|
this.type = DeviceEnum.SNOW_MAKER.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.ski.lichuan.model.device.Impl;
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.common.DeviceEnum;
|
||||||
|
import com.ski.lichuan.model.device.Device;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "水泵设备")
|
||||||
|
public class WaterPumpDevice extends Device {
|
||||||
|
|
||||||
|
@Schema(description = "LoRa MAC地址")
|
||||||
|
public String loraMac;
|
||||||
|
|
||||||
|
public WaterPumpDevice() {
|
||||||
|
this.type = DeviceEnum.WATER_PUMP.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.ski.lichuan.model.device.config;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "造雪机设备参数")
|
||||||
|
public class SnowMachineDeviceParams {
|
||||||
|
|
||||||
|
// 工作模式 关1/开2/自动3
|
||||||
|
@Schema(description = "工作模式 关1/开2/自动3")
|
||||||
|
public Integer workMode;
|
||||||
|
// 优先级 1-5
|
||||||
|
@Schema(description = "优先级 1-5")
|
||||||
|
public Integer priority;
|
||||||
|
// 雪质 1-5
|
||||||
|
@Schema(description = "雪质 1-5")
|
||||||
|
public Integer snowQuality;
|
||||||
|
// 启动温度 -5.0 ~ 5.0
|
||||||
|
@Schema(description = "启动温度 -5.0 ~ 5.0")
|
||||||
|
public Double startTemperature;
|
||||||
|
// 停止温度 -5.0 ~ 5.0
|
||||||
|
@Schema(description = "停止温度 -5.0 ~ 5.0")
|
||||||
|
public Double stopTemperature;
|
||||||
|
// 流量调节 0 ~ 50
|
||||||
|
@Schema(description = "流量调节 0 ~ 50")
|
||||||
|
public Integer flowAdjustment;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.ski.lichuan.model.device.config;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "造雪机俯仰水平控制参数")
|
||||||
|
public class SnowMachineDevicePitchHorizontalParams {
|
||||||
|
|
||||||
|
|
||||||
|
// 雪机工作模式 关1/开2/自动3
|
||||||
|
@Schema(description = "工作模式 关1/开2/自动3")
|
||||||
|
public Integer workMode;
|
||||||
|
// 俯仰工作模式 关1/开2/自动3
|
||||||
|
@Schema(description = "俯仰工作模式 关1/开2/自动3")
|
||||||
|
public Integer pitchWorkMode;
|
||||||
|
// 水平工作模式 关1/开2/自动3
|
||||||
|
@Schema(description = "水平工作模式 关1/开2/自动3")
|
||||||
|
public Integer horizontalWorkMode;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.ski.lichuan.model.log;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "设备警告记录")
|
||||||
|
public class DeviceWarningRecord {
|
||||||
|
@Schema(description = "警告记录ID")
|
||||||
|
public Integer id;
|
||||||
|
@Schema(description = "警告记录内容")
|
||||||
|
public String content;
|
||||||
|
@Schema(description = "警告记录类型")
|
||||||
|
public String warningType;
|
||||||
|
@Schema(description = "警告记录设备")
|
||||||
|
public String warningDevice;
|
||||||
|
@Schema(description = "警告记录时间")
|
||||||
|
public LocalDateTime warningTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.ski.lichuan.model.log;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "操作记录")
|
||||||
|
public class OperationRecord {
|
||||||
|
|
||||||
|
@Schema(description = "操作记录ID")
|
||||||
|
public Integer id;
|
||||||
|
@Schema(description = "操作记录操作人")
|
||||||
|
public String operator;
|
||||||
|
@Schema(description = "操作记录内容")
|
||||||
|
public String content;
|
||||||
|
@Schema(description = "操作记录类型")
|
||||||
|
public String operationType;
|
||||||
|
@Schema(description = "操作记录时间")
|
||||||
|
public LocalDateTime operationTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ski.lichuan.mapper.SnowMachineMapper">
|
||||||
|
|
||||||
|
<!-- 结果映射 -->
|
||||||
|
<resultMap id="SnowMachineResultMap" type="com.ski.lichuan.model.device.Impl.SnowMachineDevice">
|
||||||
|
<id column="id" property="id"/>
|
||||||
|
<result column="name" property="name"/>
|
||||||
|
<result column="lora" property="lora"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<!-- 插入造雪机设备 -->
|
||||||
|
<insert id="insert" parameterType="com.ski.lichuan.model.device.Impl.SnowMachineDevice">
|
||||||
|
INSERT INTO snow_machine (name, lora) VALUES (#{name}, #{lora})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<!-- 查询所有造雪机设备 -->
|
||||||
|
<select id="selectAll" resultMap="SnowMachineResultMap">
|
||||||
|
SELECT * FROM snow_machine
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 根据ID查询造雪机设备 -->
|
||||||
|
<select id="selectById" parameterType="java.lang.Integer" resultMap="SnowMachineResultMap">
|
||||||
|
SELECT * FROM snow_machine WHERE id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 根据Lora地址查询造雪机设备 -->
|
||||||
|
<select id="selectByLora" parameterType="java.lang.String" resultMap="SnowMachineResultMap">
|
||||||
|
SELECT * FROM snow_machine WHERE lora = #{lora}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询未绑定的造雪机设备 -->
|
||||||
|
<select id="selectUnboundMachines" resultMap="SnowMachineResultMap">
|
||||||
|
SELECT sm.* FROM snow_machine sm LEFT JOIN trail_position tp ON sm.id = tp.snow_machine_id WHERE tp.snow_machine_id IS NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 统计造雪机设备数量 -->
|
||||||
|
<select id="count" resultType="int">
|
||||||
|
SELECT count(*) FROM snow_machine
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 更新造雪机设备名称 -->
|
||||||
|
<update id="updateName" parameterType="com.ski.lichuan.model.device.Impl.SnowMachineDevice">
|
||||||
|
UPDATE snow_machine SET name = #{name} WHERE id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!-- 更新造雪机设备名称和Lora地址 -->
|
||||||
|
<update id="updateNameAndLora" parameterType="com.ski.lichuan.model.device.Impl.SnowMachineDevice">
|
||||||
|
UPDATE snow_machine SET name = #{name}, lora = #{lora} WHERE id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!-- 根据ID删除造雪机设备 -->
|
||||||
|
<delete id="deleteById" parameterType="java.lang.Integer">
|
||||||
|
DELETE FROM snow_machine WHERE id = #{id}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<!-- 根据ID插入造雪机设备 -->
|
||||||
|
<insert id="insertById" parameterType="com.ski.lichuan.model.device.Impl.SnowMachineDevice">
|
||||||
|
INSERT INTO snow_machine (id, name, lora) VALUES (#{id}, #{name}, #{lora})
|
||||||
|
</insert>
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ski.lichuan.mapper.TrailPositionMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="com.ski.lichuan.model.dashboard.TrailPosition">
|
||||||
|
<id column="id" jdbcType="INTEGER" property="id"/>
|
||||||
|
<result column="trail_id" jdbcType="INTEGER" property="trailId"/>
|
||||||
|
<result column="position" jdbcType="VARCHAR" property="position"/>
|
||||||
|
<result column="name" jdbcType="VARCHAR" property="name"/>
|
||||||
|
<result column="snow_machine_id" jdbcType="INTEGER" property="snowMachineId"/>
|
||||||
|
<result column="snow_machine_status" jdbcType="INTEGER" property="snowMachineStatus"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="selectByTrailId" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position WHERE trail_id = #{trailId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectById" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position WHERE id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAll" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取所有未绑定雪机的雪道位置信息 -->
|
||||||
|
<select id="selectUnboundPositions" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position WHERE snow_machine_id IS NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectBoundPositions" resultMap="BaseResultMap">
|
||||||
|
SELECT * FROM trail_position WHERE snow_machine_id IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insert" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
|
||||||
|
INSERT INTO trail_position (trail_id, position, name)
|
||||||
|
VALUES (#{trailId}, #{position}, #{name})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="update">
|
||||||
|
UPDATE trail_position
|
||||||
|
SET trail_id = #{trailId}, position = #{position}, name = #{name}
|
||||||
|
WHERE id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="clearSnowMachine">
|
||||||
|
UPDATE trail_position
|
||||||
|
SET snow_machine_status = 0, snow_machine_id = NULL
|
||||||
|
WHERE id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="updateSnowMachine">
|
||||||
|
UPDATE trail_position
|
||||||
|
SET snow_machine_id = #{snowMachineId}
|
||||||
|
WHERE id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!-- 根据雪道位置ID列表查询造雪机设备ID列表 -->
|
||||||
|
<select id="selectDeviceIdsByTrailPositionIds" resultType="java.lang.Integer">
|
||||||
|
SELECT snow_machine_id FROM trail_position WHERE id IN
|
||||||
|
<foreach collection="list" item="id" open="(" close=")" separator=",">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 清空指定ID列表外的绑定 -->
|
||||||
|
<update id="clearUnboundPositions">
|
||||||
|
UPDATE trail_position
|
||||||
|
SET snow_machine_status = 0, snow_machine_id = NULL
|
||||||
|
WHERE id NOT IN
|
||||||
|
<foreach collection="list" item="id" open="(" close=")" separator=",">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</update>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.ski.lichuan</groupId>
|
|
||||||
<artifactId>ski-dashboard-service</artifactId>
|
<artifactId>ski-dashboard-service</artifactId>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -17,6 +16,35 @@
|
|||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<!-- ThingsBoard 官方仓库 -->
|
||||||
|
<repository>
|
||||||
|
<id>thingsboard</id>
|
||||||
|
<name>ThingsBoard Repository</name>
|
||||||
|
<url>https://repo.thingsboard.io/artifactory/libs-release-public</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
<!-- 阿里云镜像配置 -->
|
||||||
|
<repository>
|
||||||
|
<id>aliyunmaven</id>
|
||||||
|
<name>aliyunmaven</name>
|
||||||
|
<url>https://maven.aliyun.com/repository/public</url>
|
||||||
|
<layout>default</layout>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ski</groupId>
|
<groupId>com.ski</groupId>
|
||||||
@@ -25,11 +53,55 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ski.lichuan</groupId>
|
<groupId>com.ski</groupId>
|
||||||
<artifactId>ski-dashboard-common</artifactId>
|
<artifactId>ski-dashboard-common</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.thingsboard</groupId>
|
||||||
|
<artifactId>rest-client</artifactId>
|
||||||
|
<version>4.2.1</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<pluginRepositories>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>aliyunmaven</id>
|
||||||
|
<name>aliyunmaven</name>
|
||||||
|
<url>https://maven.aliyun.com/repository/public</url>
|
||||||
|
<layout>default</layout>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</pluginRepository>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>thingsboard</id>
|
||||||
|
<name>ThingsBoard Repository</name>
|
||||||
|
<url>https://repo.thingsboard.io/artifactory/libs-release-public</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- 排除Spring Boot Maven插件,因为这是一个数据模型模块,不是可执行应用程序 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
119
ski-dashboard-service/src/main/java/com/ski/lichuan/Demo.java
Normal file
119
ski-dashboard-service/src/main/java/com/ski/lichuan/Demo.java
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
package com.ski.lichuan;
|
||||||
|
|
||||||
|
import org.thingsboard.rest.client.RestClient;
|
||||||
|
import org.thingsboard.server.common.data.Dashboard;
|
||||||
|
import org.thingsboard.server.common.data.DashboardInfo;
|
||||||
|
import org.thingsboard.server.common.data.Device;
|
||||||
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
|
import org.thingsboard.server.common.data.query.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Demo {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
List<Device> devicesList = getDevices();
|
||||||
|
// List<DashboardInfo> dashboardsList = getDashboards();
|
||||||
|
for (Device device : devicesList) {
|
||||||
|
if (!device.getName().equals("iot_snowmaker_m005")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
System.out.println("找到指定设备");
|
||||||
|
getDataByDevice(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取ThingsBoard客户端
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<Device> getDevices() {
|
||||||
|
|
||||||
|
String url = "https://tb.ski.bkiiot.com";
|
||||||
|
String username = "tenant@thingsboard.org";
|
||||||
|
String password = "tenant";
|
||||||
|
|
||||||
|
List<Device> devicesList = new ArrayList<>();
|
||||||
|
|
||||||
|
RestClient client = new RestClient(url);
|
||||||
|
client.login(username, password);
|
||||||
|
|
||||||
|
PageData<Device> devices;
|
||||||
|
PageLink pageLink = new PageLink(10);
|
||||||
|
do {
|
||||||
|
devices = client.getTenantDevices("", pageLink);
|
||||||
|
devices.getData().forEach(System.out::println);
|
||||||
|
devicesList.addAll(devices.getData());
|
||||||
|
pageLink = pageLink.nextPageLink();
|
||||||
|
} while (devices.hasNext());
|
||||||
|
client.logout();
|
||||||
|
client.close();
|
||||||
|
return devicesList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取仪表盘
|
||||||
|
*/
|
||||||
|
public static List<DashboardInfo> getDashboards() {
|
||||||
|
|
||||||
|
String url = "https://tb.ski.bkiiot.com";
|
||||||
|
String username = "tenant@thingsboard.org";
|
||||||
|
String password = "tenant";
|
||||||
|
List<DashboardInfo> dashboardsList = new ArrayList<>();
|
||||||
|
|
||||||
|
RestClient client = new RestClient(url);
|
||||||
|
client.login(username, password);
|
||||||
|
PageData<DashboardInfo> dashboards;
|
||||||
|
PageLink pageLink = new PageLink(10);
|
||||||
|
do {
|
||||||
|
dashboards = client.getTenantDashboards(pageLink);
|
||||||
|
dashboards.getData().forEach(System.out::println);
|
||||||
|
dashboardsList.addAll(dashboards.getData());
|
||||||
|
pageLink = pageLink.nextPageLink();
|
||||||
|
} while (dashboards.hasNext());
|
||||||
|
client.logout();
|
||||||
|
client.close();
|
||||||
|
return dashboardsList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备属性
|
||||||
|
*/
|
||||||
|
public static void getDeviceAttributes(Device device) {
|
||||||
|
|
||||||
|
String url = "https://tb.ski.bkiiot.com";
|
||||||
|
String username = "tenant@thingsboard.org";
|
||||||
|
String password = "tenant";
|
||||||
|
|
||||||
|
RestClient client = new RestClient(url);
|
||||||
|
client.login(username, password);
|
||||||
|
// 获取属性
|
||||||
|
List<String> keys = client.getAttributeKeys(device.getId());
|
||||||
|
client.getAttributeKvEntries(device.getId(), keys).forEach(System.out::println);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备数据
|
||||||
|
*/
|
||||||
|
public static void getDataByDevice(Device device) {
|
||||||
|
String url = "https://tb.ski.bkiiot.com";
|
||||||
|
String username = "tenant@thingsboard.org";
|
||||||
|
String password = "tenant";
|
||||||
|
|
||||||
|
RestClient client = new RestClient(url);
|
||||||
|
client.login(username, password);
|
||||||
|
|
||||||
|
client.getLatestTimeseries(device.getId(), List.of()).forEach(System.out::println);
|
||||||
|
|
||||||
|
client.logout();
|
||||||
|
client.close();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
package com.ski.lichuan.initializer;
|
package com.ski.lichuan.initializer;
|
||||||
|
|
||||||
|
import com.ski.lichuan.common.utils.MD5Util;
|
||||||
import com.ski.lichuan.mapper.UserMapper;
|
import com.ski.lichuan.mapper.UserMapper;
|
||||||
import com.ski.lichuan.model.auth.SysUser;
|
import com.ski.lichuan.model.auth.SysUser;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.CommandLineRunner;
|
import org.springframework.boot.CommandLineRunner;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@Slf4j
|
||||||
public class AdminUserInitializer implements CommandLineRunner {
|
public class AdminUserInitializer implements CommandLineRunner {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -24,15 +27,16 @@ public class AdminUserInitializer implements CommandLineRunner {
|
|||||||
// 创建默认管理员用户
|
// 创建默认管理员用户
|
||||||
SysUser adminUser = new SysUser();
|
SysUser adminUser = new SysUser();
|
||||||
adminUser.setUsername("admin");
|
adminUser.setUsername("admin");
|
||||||
// 默认密码为 admin123,实际使用时应修改为更安全的密码
|
// 默认密码为 123456,实际使用时应修改为更安全的密码 使用MD5加密
|
||||||
adminUser.setPassword(passwordEncoder.encode("admin123"));
|
String text = MD5Util.encrypt("123456");
|
||||||
|
adminUser.setPassword(passwordEncoder.encode(text));
|
||||||
adminUser.setNickname("系统管理员");
|
adminUser.setNickname("系统管理员");
|
||||||
adminUser.setStatus(1); // 启用状态
|
adminUser.setStatus(1); // 启用状态
|
||||||
// 插入用户到数据库
|
// 插入用户到数据库
|
||||||
userMapper.insertUser(adminUser);
|
userMapper.insertUser(adminUser);
|
||||||
System.out.println("默认管理员用户已创建,用户名: admin, 密码: admin123 (请登录后及时修改密码)");
|
log.info("默认管理员用户已创建,用户名: admin, 密码: 123456 (请登录后及时修改密码)");
|
||||||
} else {
|
} else {
|
||||||
System.out.println("管理员用户已存在");
|
log.info("管理员用户已存在");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.ski.lichuan.initializer;
|
||||||
|
|
||||||
|
import com.ski.lichuan.mapper.TrailPositionMapper;
|
||||||
|
import com.ski.lichuan.model.dashboard.TrailPosition;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.CommandLineRunner;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class TrailInitializer implements CommandLineRunner {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TrailPositionMapper trailPositionMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(String... args) throws Exception {
|
||||||
|
List<TrailPosition> trailPositions = trailPositionMapper.selectAll();
|
||||||
|
if (trailPositions.isEmpty()) {
|
||||||
|
log.info("数据库中不存在坑位数据,开始初始化...");
|
||||||
|
Integer[][] positions = {
|
||||||
|
{1, 1},
|
||||||
|
{1, 2},
|
||||||
|
{1, 3},
|
||||||
|
{1, 4},
|
||||||
|
{2, 1},
|
||||||
|
{2, 2},
|
||||||
|
{2, 3},
|
||||||
|
{2, 4},
|
||||||
|
{2, 5},
|
||||||
|
{2, 6},
|
||||||
|
{3, 1},
|
||||||
|
{3, 2},
|
||||||
|
{3, 3},
|
||||||
|
{3, 4},
|
||||||
|
{3, 5},
|
||||||
|
{3, 6},
|
||||||
|
{4, 1},
|
||||||
|
{4, 2},
|
||||||
|
{4, 3}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (Integer[] position : positions) {
|
||||||
|
TrailPosition trailPosition = new TrailPosition();
|
||||||
|
trailPosition.setTrailId(position[0]);
|
||||||
|
trailPosition.setPosition(position[1]);
|
||||||
|
trailPosition.setName(position[0] + "-" + position[1]);
|
||||||
|
trailPositionMapper.insert(trailPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
package com.ski.lichuan.services;
|
||||||
|
|
||||||
|
import com.ski.lichuan.model.dashboard.TrailPosition;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.thingsboard.rest.client.RestClient;
|
||||||
|
import org.thingsboard.server.common.data.Device;
|
||||||
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class DeviceDataPollingService {
|
||||||
|
|
||||||
|
// 高优先级查询列表(造雪机)
|
||||||
|
public static final List<String> HIGH_PRIORITY_SNOWMACHINE_IDS = Arrays.asList();
|
||||||
|
// 高优先级查询列表(水泵)
|
||||||
|
public static final List<String> HIGH_PRIORITY_PUMP_IDS = Arrays.asList();
|
||||||
|
@Value("${thingsboard.client.url:https://tb.ski.bkiiot.com}")
|
||||||
|
private String clientUrl;
|
||||||
|
@Value("${thingsboard.client.username:tenant@thingsboard.org}")
|
||||||
|
private String clientUsername;
|
||||||
|
@Value("${thingsboard.client.password:tenant}")
|
||||||
|
private String clientPassword;
|
||||||
|
// 客户端
|
||||||
|
private RestClient client;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TrailPositionService trailPositionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SnowMachineDeviceService snowMachineDeviceService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时轮询设备状态
|
||||||
|
*/
|
||||||
|
@Scheduled(fixedRate = 60000)
|
||||||
|
public void pollDeviceStatus() {
|
||||||
|
/**
|
||||||
|
* 核心逻辑:每60秒轮询一次所有设备状态,查询所有坑位上的雪机和水泵的状态
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时轮询设备数据
|
||||||
|
* 每15秒执行一次
|
||||||
|
*/
|
||||||
|
@Scheduled(fixedRate = 15000)
|
||||||
|
public void pollDeviceData() {
|
||||||
|
/**
|
||||||
|
* 核心逻辑:每15秒轮询一次所有设备数据,查询所有坑位上的雪机和水泵的状态
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时轮询设备列表(造雪机、水泵)
|
||||||
|
* 每120秒执行一次
|
||||||
|
*/
|
||||||
|
@Scheduled(fixedRate = 120000)
|
||||||
|
public void pollDevices() {
|
||||||
|
/**
|
||||||
|
* 核心逻辑:每120秒轮询一次所有设备列表,更新造雪机设备和水泵
|
||||||
|
*/
|
||||||
|
log.info("开始查询设备列表");
|
||||||
|
List<Device> devices = getDevices();
|
||||||
|
|
||||||
|
List<TrailPosition> trailPositions = trailPositionService.getAllTrailPositionList();
|
||||||
|
// 转为Map,方便查询 (TrailId,Position) -> TrailPosition
|
||||||
|
Map<Integer, TrailPosition> trailPositionMap = trailPositions.stream()
|
||||||
|
.collect(Collectors.toMap(trailPosition -> trailPosition.getTrailId() * 10000 + trailPosition.getPosition(), trailPosition -> trailPosition));
|
||||||
|
|
||||||
|
for (Device device : devices) {
|
||||||
|
//s-{id}-{trailId}-{position}-{disable}
|
||||||
|
if (device.getLabel() != null && device.getLabel().startsWith("s-")) {
|
||||||
|
String[] parts = device.getLabel().split("-");
|
||||||
|
if (parts.length < 3) {
|
||||||
|
// 异常的设备
|
||||||
|
log.warn("异常的造雪机设备标签格式:{}", device.getLabel());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (parts.length >= 4 && "disable".equals(parts[3])) {
|
||||||
|
// 禁用状态,跳过
|
||||||
|
log.info("造雪机设备 {} 已禁用,跳过", device.getLabel());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 说明是造雪机设备
|
||||||
|
String id = parts[1];
|
||||||
|
String trailId = parts[2];
|
||||||
|
String position = parts[3];
|
||||||
|
|
||||||
|
// 判断是数字
|
||||||
|
if (!trailId.matches("\\d+") || !position.matches("\\d+")) {
|
||||||
|
// 不是数字,跳过
|
||||||
|
log.warn("造雪机设备 {} 标签格式错误,跳过", device.getLabel());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// id 不为空
|
||||||
|
if (id.isEmpty()) {
|
||||||
|
// 空id,跳过
|
||||||
|
log.warn("造雪机设备 {} 标签格式错误,跳过", device.getLabel());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer idValue = Integer.parseInt(id);
|
||||||
|
Integer trailIdValue = Integer.parseInt(trailId);
|
||||||
|
Integer positionValue = Integer.parseInt(position);
|
||||||
|
|
||||||
|
// 更新雪机信息
|
||||||
|
String name = device.getName() != null ? device.getName() : "雪机" + trailId + position;
|
||||||
|
try {
|
||||||
|
snowMachineDeviceService.updateSnowMachineDeviceNameAndLora(idValue, name, device.getId().toString());
|
||||||
|
log.info("更新造雪机设备信息 {} 成功", device.getLabel());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新造雪机设备信息 {} 失败:{}", device.getLabel(), e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否存在对应的雪道位置
|
||||||
|
TrailPosition trailPosition = trailPositionMap.get(trailIdValue * 10000 + positionValue);
|
||||||
|
if (trailPosition == null) {
|
||||||
|
// 雪道位置不存在,跳过
|
||||||
|
log.warn("造雪机设备 {} 对应的雪道位置不存在,跳过", device.getLabel());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新雪道位置的造雪机ID
|
||||||
|
trailPosition.setSnowMachineId(idValue);
|
||||||
|
trailPositionService.updateTrailPositionSnowMachineId(trailPosition.getId(), idValue);
|
||||||
|
// 从Map中删除该雪道位置,防止重复处理
|
||||||
|
trailPositionMap.remove(trailIdValue * 10000 + positionValue);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清楚Map中剩余的雪道位置
|
||||||
|
List<Integer> mapIdList = trailPositionMap.values().stream().map(TrailPosition::getId).collect(Collectors.toList());
|
||||||
|
try {
|
||||||
|
trailPositionService.clearTrailPositionSnowMachineIdBatch(mapIdList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("清除雪道位置 {} 造雪机ID失败:{}", mapIdList, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RestClient getClient() {
|
||||||
|
if (client == null) {
|
||||||
|
client = new RestClient(clientUrl);
|
||||||
|
client.login(clientUsername, clientPassword);
|
||||||
|
}
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Device> getDevices() {
|
||||||
|
RestClient client = getClient();
|
||||||
|
List<Device> devicesList = new ArrayList<>();
|
||||||
|
|
||||||
|
PageData<Device> devices;
|
||||||
|
PageLink pageLink = new PageLink(10);
|
||||||
|
do {
|
||||||
|
devices = client.getTenantDevices("", pageLink);
|
||||||
|
devices.getData().forEach(device -> log.info("获取到的造雪机设备:{}", device));
|
||||||
|
devicesList.addAll(devices.getData());
|
||||||
|
pageLink = pageLink.nextPageLink();
|
||||||
|
} while (devices.hasNext());
|
||||||
|
return devicesList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.ski.lichuan.services;
|
||||||
|
|
||||||
|
public class IoTService {
|
||||||
|
}
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
package com.ski.lichuan.services;
|
||||||
|
|
||||||
|
import com.ski.lichuan.mapper.SnowMachineMapper;
|
||||||
|
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
|
||||||
|
import com.ski.lichuan.model.device.config.SnowMachineDeviceParams;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SnowMachineDeviceService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SnowMachineMapper snowMachineMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增造雪机设备
|
||||||
|
*
|
||||||
|
* @param snowMachineDevice 造雪机设备
|
||||||
|
* @return 新增结果
|
||||||
|
*/
|
||||||
|
public int addSnowMachineDevice(SnowMachineDevice snowMachineDevice) {
|
||||||
|
// 检查是否已存在相同LORA地址的造雪机设备
|
||||||
|
if (snowMachineMapper.selectByLora(snowMachineDevice.getLora()) != null) {
|
||||||
|
throw new IllegalArgumentException("造雪机设备已存在相同LORA地址");
|
||||||
|
}
|
||||||
|
return snowMachineMapper.insert(snowMachineDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有未绑定位置的造雪机设备
|
||||||
|
*
|
||||||
|
* @return 未绑定位置的造雪机设备列表
|
||||||
|
*/
|
||||||
|
public List<SnowMachineDevice> selectUnboundMachines() {
|
||||||
|
return snowMachineMapper.selectUnboundMachines();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有造雪机设备
|
||||||
|
*
|
||||||
|
* @return 所有造雪机设备列表
|
||||||
|
*/
|
||||||
|
public List<SnowMachineDevice> getAllSnowMachineDevices() {
|
||||||
|
return snowMachineMapper.selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询造雪机设备
|
||||||
|
*
|
||||||
|
* @param id 造雪机设备ID
|
||||||
|
* @return 造雪机设备
|
||||||
|
*/
|
||||||
|
public SnowMachineDevice getSnowMachineDeviceById(Integer id) {
|
||||||
|
// 检查是否存在该ID的造雪机设备
|
||||||
|
if (snowMachineMapper.selectById(id) == null) {
|
||||||
|
throw new IllegalArgumentException("造雪机设备不存在");
|
||||||
|
}
|
||||||
|
return snowMachineMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据LORA地址查询造雪机设备
|
||||||
|
*
|
||||||
|
* @param lora 造雪机设备LORA地址
|
||||||
|
* @return 造雪机设备
|
||||||
|
*/
|
||||||
|
public SnowMachineDevice selectByLora(String lora) {
|
||||||
|
return snowMachineMapper.selectByLora(lora);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 统计造雪机设备数量
|
||||||
|
*
|
||||||
|
* @return 造雪机设备数量
|
||||||
|
*/
|
||||||
|
public int count() {
|
||||||
|
return snowMachineMapper.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新造雪机设备名称
|
||||||
|
*
|
||||||
|
* @param snowMachineDevice 造雪机设备
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
public int updateSnowMachineDevice(SnowMachineDevice snowMachineDevice) {
|
||||||
|
if (snowMachineMapper.selectById(snowMachineDevice.getId()) == null) {
|
||||||
|
throw new IllegalArgumentException("造雪机设备不存在");
|
||||||
|
}
|
||||||
|
return snowMachineMapper.updateName(snowMachineDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新造雪机信息
|
||||||
|
*
|
||||||
|
* @param id 造雪机设备ID
|
||||||
|
* @param name 造雪机设备名称
|
||||||
|
* @param lora 造雪机设备LORA地址
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
public int updateSnowMachineDeviceNameAndLora(Integer id, String name, String lora) {
|
||||||
|
// 检查是否存在该ID的造雪机设备
|
||||||
|
if (snowMachineMapper.selectById(id) == null) {
|
||||||
|
// 则新增
|
||||||
|
SnowMachineDevice newSnowMachineDevice = new SnowMachineDevice();
|
||||||
|
newSnowMachineDevice.setId(id);
|
||||||
|
newSnowMachineDevice.setName(name);
|
||||||
|
newSnowMachineDevice.setLora(lora);
|
||||||
|
return snowMachineMapper.insertById(newSnowMachineDevice);
|
||||||
|
} else {
|
||||||
|
// 更新造雪机设备信息
|
||||||
|
SnowMachineDevice snowMachineDevice = snowMachineMapper.selectById(id);
|
||||||
|
snowMachineDevice.setName(name);
|
||||||
|
snowMachineDevice.setLora(lora);
|
||||||
|
return snowMachineMapper.updateName(snowMachineDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除造雪机设备
|
||||||
|
*
|
||||||
|
* @param id 造雪机设备ID
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
public int deleteSnowMachineDevice(Integer id) {
|
||||||
|
return snowMachineMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有雪机设备信息
|
||||||
|
*
|
||||||
|
* @return 所有雪机设备列表
|
||||||
|
*/
|
||||||
|
public List<SnowMachineDevice> selectAllDevices() {
|
||||||
|
return snowMachineMapper.selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群控雪机设备
|
||||||
|
* @param deviceList 雪机设备列表
|
||||||
|
* @param params 造雪机设备参数
|
||||||
|
* @return 群控结果
|
||||||
|
*/
|
||||||
|
public boolean groupControl(List<SnowMachineDevice> deviceList, SnowMachineDeviceParams params) {
|
||||||
|
// 检查是否存在该ID的造雪机设备
|
||||||
|
if (deviceList.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("造雪机设备不存在");
|
||||||
|
}
|
||||||
|
// 群控雪机设备
|
||||||
|
for (SnowMachineDevice device : deviceList) {
|
||||||
|
// 发送群控指令
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,310 @@
|
|||||||
|
package com.ski.lichuan.services;
|
||||||
|
|
||||||
|
import com.ski.lichuan.mapper.SnowMachineMapper;
|
||||||
|
import com.ski.lichuan.mapper.TrailPositionMapper;
|
||||||
|
import com.ski.lichuan.model.common.DeviceEnum;
|
||||||
|
import com.ski.lichuan.model.dashboard.*;
|
||||||
|
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
|
||||||
|
import com.ski.lichuan.model.device.config.SnowMachineDeviceParams;
|
||||||
|
import com.ski.lichuan.model.device.config.SnowMachineDevicePitchHorizontalParams;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TrailPositionService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TrailPositionMapper trailPositionMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SnowMachineMapper snowMachineDeviceMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有已绑定雪机的雪道位置信息
|
||||||
|
*/
|
||||||
|
public List<TrailPosition> getBoundTrailPositions() {
|
||||||
|
return trailPositionMapper.selectBoundPositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有未绑定雪机的雪道位置信息
|
||||||
|
*/
|
||||||
|
public List<TrailPosition> getUnboundTrailPositions() {
|
||||||
|
return trailPositionMapper.selectUnboundPositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有雪道及位置信息
|
||||||
|
*/
|
||||||
|
public List<List<TrailPosition>> getAllTrailPositions() {
|
||||||
|
List<TrailPosition> allTrailPositions = trailPositionMapper.selectAll();
|
||||||
|
List<List<TrailPosition>> result = new ArrayList<>();
|
||||||
|
for (int i = 1; i <= 4; i++) {
|
||||||
|
int finalI = i;
|
||||||
|
List<TrailPosition> trailPositions = allTrailPositions.stream()
|
||||||
|
.filter(trailPosition -> trailPosition.getTrailId().equals(finalI))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
result.add(trailPositions);
|
||||||
|
}
|
||||||
|
// 遍历result,将每个雪道的位置信息按position排序
|
||||||
|
for (List<TrailPosition> trailPositions : result) {
|
||||||
|
// 更新trailPosition状态
|
||||||
|
for (TrailPosition trailPosition : trailPositions) {
|
||||||
|
if (trailPosition.getSnowMachineStatus() == 0) {
|
||||||
|
// 暂时随机
|
||||||
|
trailPosition.setSnowMachineStatus((int) (Math.random() * 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trailPositions.sort((p1, p2) -> p1.getPosition().compareTo(p2.getPosition()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取雪道位置的详细信息(造雪机)
|
||||||
|
*/
|
||||||
|
public TrailPositionInfo getTrailPositionInfo(Integer id) {
|
||||||
|
TrailPosition trailPosition = trailPositionMapper.selectById(id);
|
||||||
|
if (trailPosition == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
TrailPositionInfo result = new TrailPositionInfo();
|
||||||
|
|
||||||
|
Integer trailId = id / 10;
|
||||||
|
Integer position = id % 10;
|
||||||
|
|
||||||
|
// 雪机设备
|
||||||
|
SnowMachineDevice snowMachineDevice = new SnowMachineDevice();
|
||||||
|
snowMachineDevice.setLora("1234567890123456");
|
||||||
|
snowMachineDevice.setId(1000000000 + id);
|
||||||
|
snowMachineDevice.setName("造雪机-" + id);
|
||||||
|
snowMachineDevice.setType(DeviceEnum.SNOW_MAKER.getValue());
|
||||||
|
// 雪道位置信息
|
||||||
|
trailPosition.setSnowMachineStatus(1);
|
||||||
|
// 雪道位置状态信息
|
||||||
|
TrailPositionMonitorInfo trailPositionMonitorInfo = new TrailPositionMonitorInfo();
|
||||||
|
trailPositionMonitorInfo.setTrailPosition(trailPosition);
|
||||||
|
trailPositionMonitorInfo.setSnowMakerName(snowMachineDevice.getName());
|
||||||
|
|
||||||
|
trailPositionMonitorInfo.setPriority(1);
|
||||||
|
trailPositionMonitorInfo.setEnvironmentTemperature(-3.5);
|
||||||
|
trailPositionMonitorInfo.setEnvironmentHumidity(50.0);
|
||||||
|
trailPositionMonitorInfo.setWetBulbTemperature(0.5);
|
||||||
|
trailPositionMonitorInfo.setCommunicationStatus(true);
|
||||||
|
trailPositionMonitorInfo.setIsNormal(true);
|
||||||
|
trailPositionMonitorInfo.setIsRunning(true);
|
||||||
|
trailPositionMonitorInfo.setTemperatureConditionSatisfied(true);
|
||||||
|
trailPositionMonitorInfo.setWindSpeed(5.0);
|
||||||
|
trailPositionMonitorInfo.setWindDirection(180.0);
|
||||||
|
// 造雪机设备状态
|
||||||
|
SnowMachineDeviceInfo snowMachineDeviceInfo = new SnowMachineDeviceInfo();
|
||||||
|
snowMachineDeviceInfo.setSnowMachineDevice(snowMachineDevice);
|
||||||
|
snowMachineDeviceInfo.setFrontWaterPressure(0.5 + Math.random() * 0.3); // 前端水压 0.5-0.8 MPa
|
||||||
|
snowMachineDeviceInfo.setBackWaterPressure(0.4 + Math.random() * 0.2); // 后端水压 0.4-0.6 MPa
|
||||||
|
snowMachineDeviceInfo.setPressure(0.8 + Math.random() * 0.2); // 气压 0.8-1.0 MPa
|
||||||
|
snowMachineDeviceInfo.setTemperature(2.5 + Math.random() * 2.0); // 水温 2.5-4.5 ℃
|
||||||
|
snowMachineDeviceInfo.setGivenAngle(45.0 + Math.random() * 10.0); // 给定开度 45-55°
|
||||||
|
snowMachineDeviceInfo.setActualAngle(44.0 + Math.random() * 12.0); // 实际开度 44-56°
|
||||||
|
snowMachineDeviceInfo.setIsNormal(Math.random() > 0.1); // 是否正常 90%概率正常
|
||||||
|
snowMachineDeviceInfo.setMode((int) (Math.random() * 3) + 1); // 模式 1-3随机
|
||||||
|
snowMachineDeviceInfo.setCompressorStatus((int) (Math.random() * 2) + 1); // 空压机状态 1-2随机
|
||||||
|
snowMachineDeviceInfo.setFanStatus((int) (Math.random() * 2) + 1); // 风机状态 1-2随机
|
||||||
|
snowMachineDeviceInfo.setHeatingRingStatus((int) (Math.random() * 2) + 1); // 加热环状态 1-2随机
|
||||||
|
snowMachineDeviceInfo.setValveStatus((int) (Math.random() * 2) + 1); // 电磁阀状态1 1-2随机
|
||||||
|
snowMachineDeviceInfo.setValveStatus2((int) (Math.random() * 2) + 1); // 电磁阀状态2 1-2随机
|
||||||
|
snowMachineDeviceInfo.setValveStatus3((int) (Math.random() * 2) + 1); // 电磁阀状态3 1-2随机
|
||||||
|
snowMachineDeviceInfo.setPitchMode((int) (Math.random() * 3) + 1); // 俯仰模式 1-3随机
|
||||||
|
snowMachineDeviceInfo.setPitchAngle(15.0 + Math.random() * 20.0); // 俯仰角度 15-35°
|
||||||
|
snowMachineDeviceInfo.setPitchStatus((int) (Math.random() * 2) + 1); // 俯仰状态 1-2随机
|
||||||
|
snowMachineDeviceInfo.setYawMode((int) (Math.random() * 3) + 1); // 摆头模式 1-3随机
|
||||||
|
snowMachineDeviceInfo.setYawAngle(30.0 + Math.random() * 40.0); // 摆头角度 30-70°
|
||||||
|
snowMachineDeviceInfo.setYawStatus((int) (Math.random() * 2) + 1); // 摆头状态 1-2随机
|
||||||
|
// 造雪机配置
|
||||||
|
SnowMachineDeviceParams snowMakerDeviceParams = new SnowMachineDeviceParams();
|
||||||
|
snowMakerDeviceParams.setWorkMode((int) (Math.random() * 3) + 1); // 工作模式 1-3随机
|
||||||
|
snowMakerDeviceParams.setPriority((int) (Math.random() * 5) + 1); // 优先级 1-5随机
|
||||||
|
snowMakerDeviceParams.setSnowQuality((int) (Math.random() * 5) + 1); // 雪质 1-5随机
|
||||||
|
snowMakerDeviceParams.setStartTemperature(-5.0 + Math.random() * 10.0); // 启动温度 -5.0 ~ 5.0
|
||||||
|
snowMakerDeviceParams.setStopTemperature(-5.0 + Math.random() * 10.0); // 停止温度 -5.0 ~ 5.0
|
||||||
|
snowMakerDeviceParams.setFlowAdjustment((int) (Math.random() * 50)); // 流量调节 0 ~ 50
|
||||||
|
|
||||||
|
// 数据统计
|
||||||
|
TrailPositionStatisticsInfo trailPositionStatisticsInfo = new TrailPositionStatisticsInfo();
|
||||||
|
trailPositionStatisticsInfo.setRunningDuration(120.5 + Math.random() * 100.0); // 运行时长 120.5-220.5分钟
|
||||||
|
trailPositionStatisticsInfo.setFlowStatistics(1000.0 + Math.random() * 500.0); // 流量统计 1000-1500 L/H
|
||||||
|
trailPositionStatisticsInfo.setSnowArea(500.0 + Math.random() * 300.0); // 造雪面积 500-800 平方米
|
||||||
|
|
||||||
|
result.setTrailPositionMonitorInfo(trailPositionMonitorInfo);
|
||||||
|
result.setSnowMakerInfo(snowMachineDeviceInfo);
|
||||||
|
result.setSnowMakerDeviceParams(snowMakerDeviceParams);
|
||||||
|
result.setTrailPositionStatisticsInfo(trailPositionStatisticsInfo);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联造雪机设备
|
||||||
|
*/
|
||||||
|
public boolean connectDevice(Integer trailPositionId, Integer deviceId) {
|
||||||
|
TrailPosition trailPosition = trailPositionMapper.selectById(trailPositionId);
|
||||||
|
if (trailPosition == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SnowMachineDevice snowMachineDevice = snowMachineDeviceMapper.selectById(deviceId);
|
||||||
|
if (snowMachineDevice == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
trailPosition.setSnowMachineId(deviceId);
|
||||||
|
trailPosition.setSnowMachineStatus(1);
|
||||||
|
trailPositionMapper.updateSnowMachine(trailPositionId, trailPosition.getSnowMachineId());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消关联造雪机设备
|
||||||
|
*/
|
||||||
|
public boolean disconnectDevice(Integer trailPositionId) {
|
||||||
|
TrailPosition trailPosition = trailPositionMapper.selectById(trailPositionId);
|
||||||
|
if (trailPosition == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
trailPosition.setSnowMachineId(null);
|
||||||
|
trailPosition.setSnowMachineStatus(0);
|
||||||
|
trailPositionMapper.clearSnowMachine(trailPositionId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群控造雪机设备
|
||||||
|
*
|
||||||
|
* @param trailPositionIds 雪道位置ID列表
|
||||||
|
* @param params 造雪机设备参数
|
||||||
|
* @return 群控结果
|
||||||
|
*/
|
||||||
|
public boolean groupControl(List<Integer> trailPositionIds, SnowMachineDeviceParams params) {
|
||||||
|
// 检查是否存在该ID的造雪机设备
|
||||||
|
if (trailPositionIds.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("雪道位置不存在");
|
||||||
|
}
|
||||||
|
// 反查造雪机设备ID
|
||||||
|
List<Integer> deviceIds = trailPositionMapper.selectDeviceIdsByTrailPositionIds(trailPositionIds);
|
||||||
|
if (deviceIds.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("造雪机设备不存在");
|
||||||
|
}
|
||||||
|
// 群控雪机设备
|
||||||
|
for (Integer deviceId : deviceIds) {
|
||||||
|
// 发送群控指令
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 俯仰水平控制
|
||||||
|
*
|
||||||
|
* @param trailPositionId 雪道位置ID
|
||||||
|
* @param params 俯仰水平参数
|
||||||
|
* @return 控制结果
|
||||||
|
*/
|
||||||
|
public Boolean pitchHorizontalControl(Integer trailPositionId, SnowMachineDevicePitchHorizontalParams params) {
|
||||||
|
// 检查是否存在该ID的造雪机设备
|
||||||
|
TrailPosition trailPosition = trailPositionMapper.selectById(trailPositionId);
|
||||||
|
if (trailPosition == null) {
|
||||||
|
throw new IllegalArgumentException("雪道位置不存在");
|
||||||
|
}
|
||||||
|
// 反查造雪机设备ID
|
||||||
|
SnowMachineDevice snowMachineDevice = snowMachineDeviceMapper.selectById(trailPosition.getSnowMachineId());
|
||||||
|
if (snowMachineDevice == null) {
|
||||||
|
throw new IllegalArgumentException("造雪机设备不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送俯仰水平控制指令
|
||||||
|
// ...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存造雪机参数
|
||||||
|
*
|
||||||
|
* @param trailPosition 雪道位置ID
|
||||||
|
* @param params 造雪机设备参数
|
||||||
|
* @return 保存结果
|
||||||
|
*/
|
||||||
|
public Boolean saveSnowMakerDeviceParams(Integer trailPosition, SnowMachineDeviceParams params) {
|
||||||
|
// 检查是否存在该ID的造雪机设备
|
||||||
|
TrailPosition trailPositionEntity = trailPositionMapper.selectById(trailPosition);
|
||||||
|
if (trailPositionEntity == null) {
|
||||||
|
throw new IllegalArgumentException("雪道位置不存在");
|
||||||
|
}
|
||||||
|
// 反查造雪机设备ID
|
||||||
|
SnowMachineDevice snowMachineDevice = snowMachineDeviceMapper.selectById(trailPositionEntity.getSnowMachineId());
|
||||||
|
if (snowMachineDevice == null) {
|
||||||
|
throw new IllegalArgumentException("造雪机设备不存在");
|
||||||
|
}
|
||||||
|
// 保存造雪机参数
|
||||||
|
// ...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新雪道坑位雪机信息
|
||||||
|
*
|
||||||
|
* @param trailPositionId 雪道位置ID
|
||||||
|
* @param snowMachineId 造雪机设备ID
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
public Boolean updateTrailPositionSnowMachineId(Integer trailPositionId, Integer snowMachineId) {
|
||||||
|
// 检查是否存在该ID的雪道位置
|
||||||
|
TrailPosition trailPosition = trailPositionMapper.selectById(trailPositionId);
|
||||||
|
if (trailPosition == null) {
|
||||||
|
throw new IllegalArgumentException("雪道位置不存在");
|
||||||
|
}
|
||||||
|
// 更新雪道位置雪机信息
|
||||||
|
trailPosition.setSnowMachineId(snowMachineId);
|
||||||
|
trailPositionMapper.updateSnowMachine(trailPositionId, snowMachineId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空雪道位置雪机信息
|
||||||
|
*
|
||||||
|
* @param trailPositionIds 雪道位置ID列表
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
public Boolean clearTrailPositionSnowMachineIdBatch(List<Integer> trailPositionIds) {
|
||||||
|
// 检查是否存在该ID的雪道位置
|
||||||
|
if (trailPositionIds.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("雪道位置不存在");
|
||||||
|
}
|
||||||
|
// 清空雪道位置雪机信息
|
||||||
|
for (Integer trailPositionId : trailPositionIds) {
|
||||||
|
TrailPosition trailPosition = trailPositionMapper.selectById(trailPositionId);
|
||||||
|
if (trailPosition == null) {
|
||||||
|
throw new IllegalArgumentException("雪道位置不存在");
|
||||||
|
}
|
||||||
|
trailPosition.setSnowMachineId(null);
|
||||||
|
trailPosition.setSnowMachineStatus(0);
|
||||||
|
trailPositionMapper.clearSnowMachine(trailPositionId);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平铺返回所有雪道位置信息
|
||||||
|
*
|
||||||
|
* @return 所有雪道位置信息列表
|
||||||
|
*/
|
||||||
|
public List<TrailPosition> getAllTrailPositionList() {
|
||||||
|
return trailPositionMapper.selectAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,4 +10,33 @@ CREATE TABLE sys_user (
|
|||||||
COMMENT ON COLUMN sys_user.username IS '用户名';
|
COMMENT ON COLUMN sys_user.username IS '用户名';
|
||||||
COMMENT ON COLUMN sys_user.password IS '加密后的密码(BCrypt)';
|
COMMENT ON COLUMN sys_user.password IS '加密后的密码(BCrypt)';
|
||||||
COMMENT ON COLUMN sys_user.nickname IS '昵称';
|
COMMENT ON COLUMN sys_user.nickname IS '昵称';
|
||||||
COMMENT ON COLUMN sys_user.status IS '状态(1-正常,0-禁用)';
|
COMMENT ON COLUMN sys_user.status IS '状态(1-正常,0-禁用)';
|
||||||
|
|
||||||
|
CREATE TABLE snow_machine (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
type SMALLINT DEFAULT 1,
|
||||||
|
name VARCHAR(255),
|
||||||
|
lora VARCHAR(255),
|
||||||
|
CONSTRAINT uk_lora UNIQUE (lora)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN snow_machine.type IS '类型1雪机2水泵';
|
||||||
|
COMMENT ON COLUMN snow_machine.name IS '名称';
|
||||||
|
COMMENT ON COLUMN snow_machine.lora IS 'Lora 地址';
|
||||||
|
|
||||||
|
CREATE TABLE trail_position (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
trail_id BIGINT NOT NULL,
|
||||||
|
position SMALLINT,
|
||||||
|
trail_name VARCHAR(255),
|
||||||
|
snow_machine_id BIGINT,
|
||||||
|
snow_machine_status SMALLINT DEFAULT 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN trail_position.trail_id IS '雪道ID';
|
||||||
|
COMMENT ON COLUMN trail_position.position IS '位置';
|
||||||
|
COMMENT ON COLUMN trail_position.trail_name IS '雪道名称';
|
||||||
|
COMMENT ON COLUMN trail_position.snow_machine_id IS '雪机ID';
|
||||||
|
COMMENT ON COLUMN trail_position.snow_machine_status IS '雪机状态 0无 1正常 2停止';
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
spring.application.name=ski-dashboard
|
|
||||||
# ??????? postgresql
|
|
||||||
spring.datasource.url=jdbc:postgresql://localhost:5432/ski_dashboard
|
|
||||||
spring.datasource.username=postgres
|
|
||||||
spring.datasource.password=tanlifan
|
|
||||||
|
|
||||||
JWT_SECRET=vf4JZhcyfdK7tJs0GZ3Qjf0dSv4BId9ITjsM2fol26gOBxM17nUySiMcV0Lo2u0Y
|
|
||||||
Reference in New Issue
Block a user